mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-25 14:46:24 +00:00
fix(scripts/Naxx): The art of Naxxramas (1/2) (#4076)
This commit is contained in:
@@ -14,6 +14,12 @@ enum Says
|
||||
EMOTE_LOCUST = 3
|
||||
};
|
||||
|
||||
enum GuardSays
|
||||
{
|
||||
EMOTE_SPAWN = 1,
|
||||
EMOTE_SCARAB = 2
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_IMPALE_10 = 28783,
|
||||
@@ -22,14 +28,15 @@ enum Spells
|
||||
SPELL_LOCUST_SWARM_25 = 54021,
|
||||
SPELL_SUMMON_CORPSE_SCRABS_5 = 29105,
|
||||
SPELL_SUMMON_CORPSE_SCRABS_10 = 28864,
|
||||
SPELL_BERSERK = 26662,
|
||||
SPELL_BERSERK = 26662
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_IMPALE = 1,
|
||||
EVENT_SPELL_LOCUST_SWARM = 2,
|
||||
EVENT_SPELL_BERSERK = 3,
|
||||
EVENT_IMPALE = 1,
|
||||
EVENT_LOCUST_SWARM = 2,
|
||||
EVENT_BERSERK = 3,
|
||||
EVENT_SPAWN_GUARD = 4
|
||||
};
|
||||
|
||||
enum Misc
|
||||
@@ -37,7 +44,7 @@ enum Misc
|
||||
NPC_CORPSE_SCARAB = 16698,
|
||||
NPC_CRYPT_GUARD = 16573,
|
||||
|
||||
ACHIEV_TIMED_START_EVENT = 9891,
|
||||
ACHIEV_TIMED_START_EVENT = 9891
|
||||
};
|
||||
|
||||
class boss_anubrekhan : public CreatureScript
|
||||
@@ -67,8 +74,8 @@ public:
|
||||
{
|
||||
if (Is25ManRaid())
|
||||
{
|
||||
me->SummonCreature(NPC_CRYPT_GUARD, 3299.825f, -3502.27f, 287.16f, M_PI, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000);
|
||||
me->SummonCreature(NPC_CRYPT_GUARD, 3299.087f, -3450.93f, 287.16f, M_PI, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000);
|
||||
me->SummonCreature(NPC_CRYPT_GUARD, 3299.732f, -3502.489f, 287.077f, 2.378f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000);
|
||||
me->SummonCreature(NPC_CRYPT_GUARD, 3299.086f, -3450.929f, 287.077f, 3.999f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,35 +85,41 @@ public:
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
SummonCryptGuards();
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_ANUB_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) override
|
||||
{
|
||||
if (me->IsInCombat())
|
||||
cr->SetInCombatWithZone();
|
||||
if (cr->GetEntry() == NPC_CORPSE_SCARAB)
|
||||
{
|
||||
cr->SetReactState(REACT_PASSIVE);
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
cr->AI()->AttackStart(target);
|
||||
cr->SetInCombatWithZone();
|
||||
if (cr->GetEntry() == NPC_CRYPT_GUARD)
|
||||
{
|
||||
cr->AI()->Talk(EMOTE_SPAWN, me);
|
||||
}
|
||||
}
|
||||
|
||||
summons.Summon(cr);
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* cr, Unit*) override
|
||||
{
|
||||
if (cr->GetEntry() == NPC_CRYPT_GUARD)
|
||||
{
|
||||
cr->CastSpell(cr, SPELL_SUMMON_CORPSE_SCRABS_10, true, nullptr, nullptr, me->GetGUID());
|
||||
cr->AI()->Talk(EMOTE_SCARAB);
|
||||
}
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* cr) override { summons.Despawn(cr); }
|
||||
void SummonedCreatureDespawn(Creature* cr) override
|
||||
{
|
||||
summons.Despawn(cr);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
@@ -124,31 +137,36 @@ public:
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
//Force the player to spawn corpse scarabs via spell
|
||||
victim->CastSpell(victim, SPELL_SUMMON_CORPSE_SCRABS_5, true, nullptr, nullptr, me->GetGUID());
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who) override
|
||||
{
|
||||
BossAI::EnterCombat(who);
|
||||
me->CallForHelp(30.0f); // catch helpers
|
||||
me->CallForHelp(30.0f);
|
||||
Talk(SAY_AGGRO);
|
||||
if (pInstance)
|
||||
{
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_ANUB_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_IMPALE, 15000);
|
||||
events.ScheduleEvent(EVENT_SPELL_LOCUST_SWARM, 70000 + urand(0, 50000));
|
||||
events.ScheduleEvent(EVENT_SPELL_BERSERK, 600000);
|
||||
|
||||
events.ScheduleEvent(EVENT_IMPALE, 15000);
|
||||
events.ScheduleEvent(EVENT_LOCUST_SWARM, urand(70000, 120000));
|
||||
events.ScheduleEvent(EVENT_BERSERK, 600000);
|
||||
if (!summons.HasEntry(NPC_CRYPT_GUARD))
|
||||
{
|
||||
SummonCryptGuards();
|
||||
}
|
||||
if (!Is25ManRaid())
|
||||
{
|
||||
events.ScheduleEvent(EVENT_SPAWN_GUARD, urand(15000, 20000));
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
@@ -158,12 +176,26 @@ public:
|
||||
Talk(SAY_GREET);
|
||||
sayGreet = true;
|
||||
}
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!me->IsInCombat() && sayGreet)
|
||||
{
|
||||
for( std::list<uint64>::iterator itr = summons.begin(); itr != summons.end(); ++itr )
|
||||
{
|
||||
if (pInstance)
|
||||
{
|
||||
if (Creature* cr = pInstance->instance->GetCreature(*itr))
|
||||
{
|
||||
if (cr->IsInCombat())
|
||||
DoZoneInCombat();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
@@ -173,27 +205,26 @@ public:
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_IMPALE:
|
||||
case EVENT_IMPALE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
me->CastSpell(target, RAID_MODE(SPELL_IMPALE_10, SPELL_IMPALE_25), false);
|
||||
}
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
case EVENT_SPELL_LOCUST_SWARM:
|
||||
{
|
||||
Talk(EMOTE_LOCUST);
|
||||
me->CastSpell(me, RAID_MODE(SPELL_LOCUST_SWARM_10, SPELL_LOCUST_SWARM_25), false);
|
||||
Position pos;
|
||||
me->GetNearPosition(pos, 10.0f, rand_norm() * 2 * M_PI);
|
||||
me->SummonCreature(NPC_CRYPT_GUARD, pos);
|
||||
events.RepeatEvent(90000);
|
||||
break;
|
||||
}
|
||||
case EVENT_SPELL_BERSERK:
|
||||
case EVENT_LOCUST_SWARM:
|
||||
Talk(EMOTE_LOCUST);
|
||||
me->CastSpell(me, RAID_MODE(SPELL_LOCUST_SWARM_10, SPELL_LOCUST_SWARM_25), false);
|
||||
events.ScheduleEvent(EVENT_SPAWN_GUARD, 3000);
|
||||
events.RepeatEvent(90000);
|
||||
break;
|
||||
case EVENT_SPAWN_GUARD:
|
||||
me->SummonCreature(NPC_CRYPT_GUARD, 3331.217f, -3476.607f, 287.074f, 3.269f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000);
|
||||
break;
|
||||
case EVENT_BERSERK:
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -27,19 +27,22 @@ enum Spells
|
||||
SPELL_FRENZY_10 = 28798,
|
||||
SPELL_FRENZY_25 = 54100,
|
||||
SPELL_WIDOWS_EMBRACE = 28732,
|
||||
SPELL_MINION_WIDOWS_EMBRACE = 54097
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_POISON_BOLT = 1,
|
||||
EVENT_SPELL_RAIN_OF_FIRE = 2,
|
||||
EVENT_SPELL_FRENZY = 3,
|
||||
EVENT_POISON_BOLT = 1,
|
||||
EVENT_RAIN_OF_FIRE = 2,
|
||||
EVENT_FRENZY = 3
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_NAXXRAMAS_WORSHIPPER = 16506,
|
||||
NPC_NAXXRAMAS_FOLLOWER = 16505,
|
||||
|
||||
SPIDER_WEB_ENTRANCE = 181235
|
||||
};
|
||||
|
||||
class boss_faerlina : public CreatureScript
|
||||
@@ -71,8 +74,6 @@ public:
|
||||
me->SummonCreature(NPC_NAXXRAMAS_WORSHIPPER, 3344.3f, -3618.31f, 261.08f, 4.69494f);
|
||||
me->SummonCreature(NPC_NAXXRAMAS_WORSHIPPER, 3356.71f, -3620.05f, 261.08f, 4.57276f);
|
||||
me->SummonCreature(NPC_NAXXRAMAS_WORSHIPPER, 3350.26f, -3619.11f, 261.08f, 4.67748f);
|
||||
|
||||
// Followers
|
||||
if (Is25ManRaid())
|
||||
{
|
||||
me->SummonCreature(NPC_NAXXRAMAS_FOLLOWER, 3347.49f, -3617.59f, 261.0f, 4.49f);
|
||||
@@ -80,7 +81,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) override { summons.Summon(cr); }
|
||||
void JustSummoned(Creature* cr) override
|
||||
{
|
||||
summons.Summon(cr);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
@@ -88,6 +92,10 @@ public:
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
SummonHelpers();
|
||||
if (GameObject* go = me->FindNearestGameObject(SPIDER_WEB_ENTRANCE, 100.0f))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who) override
|
||||
@@ -96,10 +104,14 @@ public:
|
||||
me->CallForHelp(VISIBLE_RANGE);
|
||||
summons.DoZoneInCombat();
|
||||
Talk(SAY_AGGRO);
|
||||
events.ScheduleEvent(EVENT_SPELL_POISON_BOLT, urand(12000, 15000));
|
||||
events.ScheduleEvent(EVENT_SPELL_RAIN_OF_FIRE, urand(6000, 18000));
|
||||
events.ScheduleEvent(EVENT_SPELL_FRENZY, urand(60000, 80000), 1);
|
||||
events.ScheduleEvent(EVENT_POISON_BOLT, urand(7000, 15000));
|
||||
events.ScheduleEvent(EVENT_RAIN_OF_FIRE, urand(8000, 18000));
|
||||
events.ScheduleEvent(EVENT_FRENZY, urand(60000, 80000), 1);
|
||||
events.SetPhase(1);
|
||||
if (GameObject* go = me->FindNearestGameObject(SPIDER_WEB_ENTRANCE, 100.0f))
|
||||
{
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
@@ -109,7 +121,6 @@ public:
|
||||
Talk(SAY_GREET);
|
||||
sayGreet = true;
|
||||
}
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
@@ -119,20 +130,42 @@ public:
|
||||
return;
|
||||
|
||||
if (!urand(0, 3))
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
}
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
Talk(SAY_DEATH);
|
||||
if (GameObject* go = me->FindNearestGameObject(SPIDER_WEB_ENTRANCE, 100.0f))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!me->IsInCombat() && sayGreet)
|
||||
{
|
||||
for( std::list<uint64>::iterator itr = summons.begin(); itr != summons.end(); ++itr )
|
||||
{
|
||||
if (pInstance)
|
||||
{
|
||||
if (Creature* cr = pInstance->instance->GetCreature(*itr))
|
||||
{
|
||||
if (cr->IsInCombat())
|
||||
DoZoneInCombat();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
@@ -142,17 +175,21 @@ public:
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_POISON_BOLT:
|
||||
if (!me->HasAura(SPELL_WIDOWS_EMBRACE))
|
||||
me->CastCustomSpell(RAID_MODE(SPELL_POISON_BOLT_VOLLEY_10, SPELL_POISON_BOLT_VOLLEY_25), SPELLVALUE_MAX_TARGETS, 3, me, false);
|
||||
events.RepeatEvent(14000);
|
||||
case EVENT_POISON_BOLT:
|
||||
if (!me->HasAura(RAID_MODE(SPELL_WIDOWS_EMBRACE, SPELL_MINION_WIDOWS_EMBRACE)))
|
||||
{
|
||||
me->CastCustomSpell(RAID_MODE(SPELL_POISON_BOLT_VOLLEY_10, SPELL_POISON_BOLT_VOLLEY_25), SPELLVALUE_MAX_TARGETS, RAID_MODE(3, 10), me, false);
|
||||
}
|
||||
events.RepeatEvent(urand(7000, 15000));
|
||||
break;
|
||||
case EVENT_SPELL_RAIN_OF_FIRE:
|
||||
case EVENT_RAIN_OF_FIRE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
me->CastSpell(target, RAID_MODE(SPELL_RAIN_OF_FIRE_10, SPELL_RAIN_OF_FIRE_25), false);
|
||||
events.RepeatEvent(12000);
|
||||
}
|
||||
events.RepeatEvent(urand(8000, 18000));
|
||||
break;
|
||||
case EVENT_SPELL_FRENZY:
|
||||
case EVENT_FRENZY:
|
||||
if (!me->HasAura(RAID_MODE(SPELL_FRENZY_10, SPELL_FRENZY_25)))
|
||||
{
|
||||
Talk(SAY_FRENZY);
|
||||
@@ -161,25 +198,29 @@ public:
|
||||
events.RepeatEvent(60000);
|
||||
}
|
||||
else
|
||||
{
|
||||
events.RepeatEvent(30000);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, const SpellInfo* spell) override
|
||||
void SpellHit(Unit* caster, const SpellInfo* spell) override
|
||||
{
|
||||
if (spell->Id == SPELL_WIDOWS_EMBRACE)
|
||||
if (spell->Id == RAID_MODE(SPELL_WIDOWS_EMBRACE, SPELL_MINION_WIDOWS_EMBRACE))
|
||||
{
|
||||
Talk(EMOTE_WIDOWS_EMBRACE);
|
||||
if (me->HasAura(RAID_MODE(SPELL_FRENZY_10, SPELL_FRENZY_25)))
|
||||
{
|
||||
me->RemoveAurasDueToSpell(RAID_MODE(SPELL_FRENZY_10, SPELL_FRENZY_25));
|
||||
events.RescheduleEvent(EVENT_SPELL_FRENZY, 60000);
|
||||
events.RescheduleEvent(EVENT_FRENZY, 60000);
|
||||
}
|
||||
|
||||
pInstance->SetData(DATA_FRENZY_REMOVED, 0);
|
||||
if (Is25ManRaid())
|
||||
{
|
||||
Unit::Kill(caster, caster);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -12,44 +12,39 @@
|
||||
enum Spells
|
||||
{
|
||||
SPELL_BERSERK = 26662,
|
||||
|
||||
// Marks
|
||||
SPELL_MARK_OF_KORTHAZZ = 28832,
|
||||
SPELL_MARK_OF_BLAUMEUX = 28833,
|
||||
SPELL_MARK_OF_RIVENDARE = 28834,
|
||||
SPELL_MARK_OF_ZELIEK = 28835,
|
||||
SPELL_MARK_DAMAGE = 28836,
|
||||
|
||||
// Korth'azz
|
||||
SPELL_KORTHAZZ_METEOR_10 = 28884,
|
||||
SPELL_KORTHAZZ_METEOR_25 = 57467,
|
||||
|
||||
// Blaumeux
|
||||
SPELL_BLAUMEUX_SHADOW_BOLT_10 = 57374,
|
||||
SPELL_BLAUMEUX_SHADOW_BOLT_25 = 57464,
|
||||
SPELL_BLAUMEUX_VOID_ZONE_10 = 28863,
|
||||
SPELL_BLAUMEUX_VOID_ZONE_25 = 57463,
|
||||
SPELL_BLAUMEUX_UNYIELDING_PAIN = 57381,
|
||||
|
||||
// Zeliek
|
||||
SPELL_ZELIEK_HOLY_WRATH_10 = 28883,
|
||||
SPELL_ZELIEK_HOLY_WRATH_25 = 57466,
|
||||
SPELL_ZELIEK_HOLY_BOLT_10 = 57376,
|
||||
SPELL_ZELIEK_HOLY_BOLT_25 = 57465,
|
||||
SPELL_ZELIEK_CONDEMNATION = 57377,
|
||||
|
||||
// Rivendare
|
||||
SPELL_RIVENDARE_UNHOLY_SHADOW_10 = 28882,
|
||||
SPELL_RIVENDARE_UNHOLY_SHADOW_25 = 57369,
|
||||
SPELL_RIVENDARE_UNHOLY_SHADOW_25 = 57369
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_MARK_CAST = 1,
|
||||
EVENT_SPELL_PRIMARY = 2,
|
||||
EVENT_SPELL_SECONDARY = 3,
|
||||
EVENT_SPELL_PUNISH = 4,
|
||||
EVENT_BERSERK = 5,
|
||||
EVENT_MARK_CAST = 1,
|
||||
EVENT_PRIMARY_SPELL = 2,
|
||||
EVENT_SECONDARY_SPELL = 3,
|
||||
EVENT_PUNISH = 4,
|
||||
EVENT_BERSERK = 5
|
||||
};
|
||||
|
||||
enum Misc
|
||||
@@ -58,12 +53,11 @@ enum Misc
|
||||
MOVE_PHASE_NONE = 0,
|
||||
MOVE_PHASE_STARTED = 1,
|
||||
MOVE_PHASE_FINISHED = 2,
|
||||
|
||||
// Horseman
|
||||
HORSEMAN_ZELIEK = 0,
|
||||
HORSEMAN_BLAUMEUX = 1,
|
||||
HORSEMAN_RIVENDARE = 2,
|
||||
HORSEMAN_KORTHAZZ = 3,
|
||||
HORSEMAN_KORTHAZZ = 3
|
||||
};
|
||||
|
||||
enum FourHorsemen
|
||||
@@ -72,20 +66,21 @@ enum FourHorsemen
|
||||
SAY_TAUNT = 1,
|
||||
SAY_SPECIAL = 2,
|
||||
SAY_SLAY = 3,
|
||||
SAY_DEATH = 4
|
||||
SAY_DEATH = 4,
|
||||
EMOTE_RAGECAST = 7
|
||||
};
|
||||
|
||||
// MARKS
|
||||
const uint32 TABLE_SPELL_MARK[4] = {SPELL_MARK_OF_ZELIEK, SPELL_MARK_OF_BLAUMEUX, SPELL_MARK_OF_RIVENDARE, SPELL_MARK_OF_KORTHAZZ};
|
||||
|
||||
// SPELL PRIMARY
|
||||
// PRIMARY SPELL
|
||||
const uint32 TABLE_SPELL_PRIMARY_10[4] = {SPELL_ZELIEK_HOLY_BOLT_10, SPELL_BLAUMEUX_SHADOW_BOLT_10, SPELL_RIVENDARE_UNHOLY_SHADOW_10, SPELL_KORTHAZZ_METEOR_10};
|
||||
const uint32 TABLE_SPELL_PRIMARY_25[4] = {SPELL_ZELIEK_HOLY_BOLT_25, SPELL_BLAUMEUX_SHADOW_BOLT_25, SPELL_RIVENDARE_UNHOLY_SHADOW_25, SPELL_KORTHAZZ_METEOR_25};
|
||||
|
||||
// PUNISH
|
||||
const uint32 TABLE_SPELL_PUNISH[4] = {SPELL_ZELIEK_CONDEMNATION, SPELL_BLAUMEUX_UNYIELDING_PAIN, 0, 0};
|
||||
|
||||
// SPELL SECONDARY
|
||||
// SECONDARY SPELL
|
||||
const uint32 TABLE_SPELL_SECONDARY_10[4] = {SPELL_ZELIEK_HOLY_WRATH_10, SPELL_BLAUMEUX_VOID_ZONE_10, 0, 0};
|
||||
const uint32 TABLE_SPELL_SECONDARY_25[4] = {SPELL_ZELIEK_HOLY_WRATH_25, SPELL_BLAUMEUX_VOID_ZONE_25, 0, 0};
|
||||
|
||||
@@ -106,7 +101,7 @@ const Position WaypointPositions[12] =
|
||||
// Sir waypoints
|
||||
{2534.5f, -2921.7f, 241.53f, 1.363f},
|
||||
{2523.5f, -2902.8f, 241.28f, 2.095f},
|
||||
{2517.8f, -2896.6f, 241.28f, 2.315f},
|
||||
{2517.8f, -2896.6f, 241.28f, 2.315f}
|
||||
};
|
||||
|
||||
class boss_four_horsemen : public CreatureScript
|
||||
@@ -174,7 +169,6 @@ public:
|
||||
EnterEvadeMode();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -186,17 +180,16 @@ public:
|
||||
currentWaypoint = 0;
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
events.Reset();
|
||||
|
||||
// Schedule Events
|
||||
events.RescheduleEvent(EVENT_SPELL_MARK_CAST, 24000);
|
||||
events.RescheduleEvent(EVENT_BERSERK, 100 * 15000);
|
||||
|
||||
events.RescheduleEvent(EVENT_MARK_CAST, 24000);
|
||||
events.RescheduleEvent(EVENT_BERSERK, 600000);
|
||||
if ((me->GetEntry() != NPC_LADY_BLAUMEUX && me->GetEntry() != NPC_SIR_ZELIEK))
|
||||
events.RescheduleEvent(EVENT_SPELL_PRIMARY, 10000 + rand() % 5000);
|
||||
{
|
||||
events.RescheduleEvent(EVENT_PRIMARY_SPELL, 10000 + rand() % 5000);
|
||||
}
|
||||
else
|
||||
{
|
||||
events.RescheduleEvent(EVENT_SPELL_PUNISH, 5000);
|
||||
events.RescheduleEvent(EVENT_SPELL_SECONDARY, 15000);
|
||||
events.RescheduleEvent(EVENT_PUNISH, 5000);
|
||||
events.RescheduleEvent(EVENT_SECONDARY_SPELL, 15000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,14 +203,12 @@ public:
|
||||
{
|
||||
movementPhase = MOVE_PHASE_FINISHED;
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
me->SetInCombatWithZone();
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (me->GetEntry() == NPC_LADY_BLAUMEUX || me->GetEntry() == NPC_SIR_ZELIEK)
|
||||
{
|
||||
me->GetMotionMaster()->Clear(false);
|
||||
@@ -225,7 +216,6 @@ public:
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
currentWaypoint = id + 1;
|
||||
}
|
||||
|
||||
@@ -234,9 +224,13 @@ public:
|
||||
if (movementPhase == MOVE_PHASE_FINISHED)
|
||||
{
|
||||
if (me->GetEntry() == NPC_LADY_BLAUMEUX || me->GetEntry() == NPC_SIR_ZELIEK)
|
||||
{
|
||||
me->Attack(who, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
ScriptedAI::AttackStart(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,9 +240,10 @@ public:
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
@@ -259,11 +254,14 @@ public:
|
||||
if (pInstance->GetBossState(BOSS_HORSEMAN) == DONE)
|
||||
{
|
||||
if (!me->GetMap()->GetPlayers().isEmpty())
|
||||
{
|
||||
if (Player* player = me->GetMap()->GetPlayers().getFirst()->GetSource())
|
||||
{
|
||||
player->SummonGameObject(RAID_MODE(GO_HORSEMEN_CHEST_10, GO_HORSEMEN_CHEST_25), 2514.8f, -2944.9f, 245.55f, 5.51f, 0, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
@@ -273,7 +271,6 @@ public:
|
||||
if (movementPhase == MOVE_PHASE_NONE)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
movementPhase = MOVE_PHASE_STARTED;
|
||||
me->SetSpeed(MOVE_RUN, me->GetSpeedRate(MOVE_RUN), true);
|
||||
@@ -301,27 +298,28 @@ public:
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_MARK_CAST:
|
||||
case EVENT_MARK_CAST:
|
||||
me->CastSpell(me, TABLE_SPELL_MARK[horsemanId], false);
|
||||
events.RepeatEvent((me->GetEntry() == NPC_LADY_BLAUMEUX || me->GetEntry() == NPC_SIR_ZELIEK) ? 15000 : 12000);
|
||||
return;
|
||||
case EVENT_BERSERK:
|
||||
Talk(SAY_SPECIAL);
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
|
||||
return;
|
||||
case EVENT_SPELL_PRIMARY:
|
||||
case EVENT_PRIMARY_SPELL:
|
||||
Talk(SAY_TAUNT);
|
||||
|
||||
me->CastSpell(me->GetVictim(), RAID_MODE(TABLE_SPELL_PRIMARY_10[horsemanId], TABLE_SPELL_PRIMARY_25[horsemanId]), false);
|
||||
events.RepeatEvent(15000);
|
||||
return;
|
||||
case EVENT_SPELL_PUNISH:
|
||||
case EVENT_PUNISH:
|
||||
if (!SelectTarget(SELECT_TARGET_NEAREST, 0, 45.0f, true))
|
||||
{
|
||||
me->CastSpell(me, TABLE_SPELL_PUNISH[horsemanId], false);
|
||||
events.RepeatEvent(3000);
|
||||
Talk(EMOTE_RAGECAST);
|
||||
}
|
||||
events.RepeatEvent(2010);
|
||||
return;
|
||||
case EVENT_SPELL_SECONDARY:
|
||||
case EVENT_SECONDARY_SPELL:
|
||||
me->CastSpell(me->GetVictim(), RAID_MODE(TABLE_SPELL_SECONDARY_10[horsemanId], TABLE_SPELL_SECONDARY_25[horsemanId]), false);
|
||||
events.RepeatEvent(15000);
|
||||
return;
|
||||
@@ -330,10 +328,14 @@ public:
|
||||
if ((me->GetEntry() == NPC_LADY_BLAUMEUX || me->GetEntry() == NPC_SIR_ZELIEK))
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_NEAREST, 0, 45.0f, true))
|
||||
{
|
||||
me->CastSpell(target, RAID_MODE(TABLE_SPELL_PRIMARY_10[horsemanId], TABLE_SPELL_PRIMARY_25[horsemanId]), false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -361,23 +363,25 @@ public:
|
||||
damage = 500;
|
||||
break;
|
||||
case 3:
|
||||
damage = 1000;
|
||||
break;
|
||||
case 4:
|
||||
damage = 1500;
|
||||
break;
|
||||
case 5:
|
||||
case 4:
|
||||
damage = 4000;
|
||||
break;
|
||||
case 6:
|
||||
case 5:
|
||||
damage = 12000;
|
||||
break;
|
||||
case 6:
|
||||
damage = 20000;
|
||||
break;
|
||||
default:
|
||||
damage = 20000 + 1000 * (GetStackAmount() - 7);
|
||||
break;
|
||||
}
|
||||
if (damage)
|
||||
{
|
||||
caster->CastCustomSpell(SPELL_MARK_DAMAGE, SPELLVALUE_BASE_POINT0, damage, GetTarget());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,38 +17,38 @@ enum Spells
|
||||
SPELL_DECIMATE_25 = 54426,
|
||||
SPELL_BERSERK = 26662,
|
||||
SPELL_INFECTED_WOUND = 29306,
|
||||
SPELL_CHOW_SEARCHER = 28404,
|
||||
SPELL_CHOW_SEARCHER = 28404
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_MORTAL_WOUND = 1,
|
||||
EVENT_SPELL_ENRAGE = 2,
|
||||
EVENT_SPELL_DECIMATE = 3,
|
||||
EVENT_SPELL_BERSERK = 4,
|
||||
EVENT_MORTAL_WOUND = 1,
|
||||
EVENT_ENRAGE = 2,
|
||||
EVENT_DECIMATE = 3,
|
||||
EVENT_BERSERK = 4,
|
||||
EVENT_SUMMON_ZOMBIE = 5,
|
||||
EVENT_CAN_EAT_ZOMBIE = 6,
|
||||
EVENT_CAN_EAT_ZOMBIE = 6
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_ZOMBIE_CHOW = 16360,
|
||||
NPC_ZOMBIE_CHOW = 16360
|
||||
};
|
||||
|
||||
enum Emotes
|
||||
{
|
||||
EMOTE_SPOTS_ONE = 0,
|
||||
EMOTE_DECIMATE = 1,
|
||||
EMOTE_ENRAGE = 2,
|
||||
EMOTE_DEVOURS_ALL = 3,
|
||||
EMOTE_BERSERK = 4
|
||||
EMOTE_SPOTS_ONE = 0,
|
||||
EMOTE_DECIMATE = 1,
|
||||
EMOTE_ENRAGE = 2,
|
||||
EMOTE_DEVOURS_ALL = 3,
|
||||
EMOTE_BERSERK = 4
|
||||
};
|
||||
|
||||
const Position zombiePos[3] =
|
||||
{
|
||||
{3267.9f, -3172.1f, 297.42f, 0.94f},
|
||||
{3253.2f, -3132.3f, 297.42f, 0},
|
||||
{3308.3f, -3185.8f, 297.42f, 1.58f},
|
||||
{3308.3f, -3185.8f, 297.42f, 1.58f}
|
||||
};
|
||||
|
||||
class boss_gluth : public CreatureScript
|
||||
@@ -91,7 +91,9 @@ public:
|
||||
Talk(EMOTE_SPOTS_ONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,10 +101,10 @@ public:
|
||||
{
|
||||
BossAI::EnterCombat(who);
|
||||
me->SetInCombatWithZone();
|
||||
events.ScheduleEvent(EVENT_SPELL_MORTAL_WOUND, 10000);
|
||||
events.ScheduleEvent(EVENT_SPELL_ENRAGE, 30000);
|
||||
events.ScheduleEvent(EVENT_SPELL_DECIMATE, 105000);
|
||||
events.ScheduleEvent(EVENT_SPELL_BERSERK, 8 * 60000);
|
||||
events.ScheduleEvent(EVENT_MORTAL_WOUND, 10000);
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 22000);
|
||||
events.ScheduleEvent(EVENT_DECIMATE, RAID_MODE(110000, 90000));
|
||||
events.ScheduleEvent(EVENT_BERSERK, 360000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_ZOMBIE, 10000);
|
||||
events.ScheduleEvent(EVENT_CAN_EAT_ZOMBIE, 1000);
|
||||
}
|
||||
@@ -110,8 +112,9 @@ public:
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
if (summon->GetEntry() == NPC_ZOMBIE_CHOW)
|
||||
{
|
||||
summon->AI()->AttackStart(me);
|
||||
|
||||
}
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
@@ -120,10 +123,13 @@ public:
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (me->IsAlive() && who->GetEntry() == NPC_ZOMBIE_CHOW)
|
||||
{
|
||||
me->ModifyHealth(int32(me->GetMaxHealth() * 0.05f));
|
||||
|
||||
}
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
@@ -143,13 +149,13 @@ public:
|
||||
Player* player = itr.GetSource();
|
||||
if (!player || !player->IsAlive())
|
||||
continue;
|
||||
|
||||
if (player->GetPositionZ() > 300.0f || me->GetExactDist(player) > 50.0f)
|
||||
continue;
|
||||
|
||||
AttackStart(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -164,23 +170,22 @@ public:
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_BERSERK:
|
||||
case EVENT_BERSERK:
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
|
||||
break;
|
||||
case EVENT_SPELL_ENRAGE:
|
||||
case EVENT_ENRAGE:
|
||||
Talk(EMOTE_ENRAGE);
|
||||
me->CastSpell(me, RAID_MODE(SPELL_ENRAGE_10, SPELL_ENRAGE_25), true);
|
||||
events.RepeatEvent(30000);
|
||||
events.RepeatEvent(22000);
|
||||
break;
|
||||
case EVENT_SPELL_MORTAL_WOUND:
|
||||
case EVENT_MORTAL_WOUND:
|
||||
me->CastSpell(me->GetVictim(), SPELL_MORTAL_WOUND, false);
|
||||
events.RepeatEvent(10000);
|
||||
break;
|
||||
case EVENT_SPELL_DECIMATE:
|
||||
case EVENT_DECIMATE:
|
||||
Talk(EMOTE_DECIMATE);
|
||||
me->CastSpell(me, RAID_MODE(SPELL_DECIMATE_10, SPELL_DECIMATE_25), false);
|
||||
events.RepeatEvent(105000);
|
||||
events.RepeatEvent(RAID_MODE(110000, 90000));
|
||||
break;
|
||||
case EVENT_SUMMON_ZOMBIE:
|
||||
{
|
||||
@@ -191,12 +196,15 @@ public:
|
||||
// \1 |0 /2 pos
|
||||
// In 25 man raid - should spawn from all 3 gates
|
||||
if (me->GetMap()->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)
|
||||
{
|
||||
me->SummonCreature(NPC_ZOMBIE_CHOW, zombiePos[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
me->SummonCreature(NPC_ZOMBIE_CHOW, zombiePos[urand(0, 2)]);
|
||||
}
|
||||
(rand == 2 ? rand = 0 : rand++);
|
||||
}
|
||||
|
||||
events.RepeatEvent(10000);
|
||||
break;
|
||||
}
|
||||
@@ -210,7 +218,6 @@ public:
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
@@ -241,7 +248,6 @@ public:
|
||||
Unit::DealDamage(GetCaster(), cTarget, damage);
|
||||
return;
|
||||
}
|
||||
|
||||
GetCaster()->CastCustomSpell(28375, SPELLVALUE_BASE_POINT0, damage, unitTarget);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,51 +11,52 @@
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_INTRO_1 = 0,
|
||||
SAY_INTRO_2 = 1,
|
||||
SAY_INTRO_3 = 2,
|
||||
SAY_INTRO_4 = 3,
|
||||
SAY_PHASE_TWO = 4,
|
||||
SAY_DEATH = 5,
|
||||
SAY_KILL = 6,
|
||||
SAY_INTRO_1 = 0,
|
||||
SAY_INTRO_2 = 1,
|
||||
SAY_INTRO_3 = 2,
|
||||
SAY_INTRO_4 = 3,
|
||||
SAY_PHASE_TWO = 4,
|
||||
SAY_DEATH = 5,
|
||||
SAY_KILL = 6,
|
||||
|
||||
EMOTE_PHASE_TWO = 7,
|
||||
EMOTE_GATE_OPENED = 8
|
||||
EMOTE_PHASE_TWO = 7,
|
||||
EMOTE_GATE_OPENED = 8
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// Gothik
|
||||
SPELL_HARVEST_SOUL = 28679,
|
||||
SPELL_SHADOW_BOLT_10 = 29317,
|
||||
SPELL_SHADOW_BOLT_25 = 56405,
|
||||
// Teleport spells
|
||||
SPELL_TELEPORT_DEAD = 28025,
|
||||
SPELL_TELEPORT_LIVE = 28026,
|
||||
// Visual spells
|
||||
SPELL_INFORM_LIVING_TRAINEE = 27892,
|
||||
SPELL_INFORM_LIVING_KNIGHT = 27928,
|
||||
SPELL_INFORM_LIVING_RIDER = 27935,
|
||||
SPELL_INFORM_DEAD_TRAINEE = 27915,
|
||||
SPELL_INFORM_DEAD_KNIGHT = 27931,
|
||||
SPELL_INFORM_DEAD_RIDER = 27937,
|
||||
|
||||
// TRAINEES
|
||||
SPELL_DEATH_PLAGUE = 55604, // LIVING TRAINEE
|
||||
SPELL_ARCANE_EXPLOSION = 27989, // DEAD TRAINEE (20y)
|
||||
|
||||
// KNIGHT
|
||||
SPELL_SHADOW_MARK = 27825, // LIVING KNIGHT
|
||||
SPELL_WHIRLWIND = 56408, // DEAD KNIGHT
|
||||
|
||||
// RIDER
|
||||
SPELL_BLOOD_PRESENCE = 55212, // LIVING RIDER
|
||||
SPELL_DEATH_COIL = 55209, // LIVING RIDER
|
||||
SPELL_HASTE_AURA = 13589, // LIVING RIDER
|
||||
SPELL_HYSTERIA = 55213, // LIVING RIDER
|
||||
SPELL_INTIMIDATING_SHOUT = 5246, // LIVING RIDER
|
||||
SPELL_VEIL_OF_DARKNESS = 28350, // LIVING RIDER
|
||||
SPELL_DRAIN_LIFE = 27994, // DEAD RIDER
|
||||
SPELL_UNHOLY_AURA = 55606, // DEAD RIDER
|
||||
SPELL_UNHOLY_FRENZY = 55648, // DEAD RIDER
|
||||
|
||||
// HORSE
|
||||
SPELL_STOMP = 27993 // DEAD HORSE
|
||||
/*SPELL_ANCHOR_2_TRAINEE = 27893,
|
||||
SPELL_ANCHOR_2_DK = 27929,
|
||||
SPELL_ANCHOR_2_RIDER = 27936, fix me */
|
||||
// Living trainee
|
||||
SPELL_DEATH_PLAGUE = 55604,
|
||||
// Dead trainee
|
||||
SPELL_ARCANE_EXPLOSION = 27989,
|
||||
// Living knight
|
||||
SPELL_SHADOW_MARK = 27825,
|
||||
// Dead knight
|
||||
SPELL_WHIRLWIND = 56408,
|
||||
// Living rider
|
||||
SPELL_SHADOW_BOLT_VOLLEY = 27831,
|
||||
// Dead rider
|
||||
SPELL_DRAIN_LIFE = 27994,
|
||||
SPELL_UNHOLY_FRENZY = 55648,
|
||||
// Horse
|
||||
SPELL_STOMP = 27993
|
||||
};
|
||||
|
||||
enum Misc
|
||||
@@ -67,44 +68,37 @@ enum Misc
|
||||
NPC_DEAD_KNIGHT = 16148,
|
||||
NPC_DEAD_HORSE = 16149,
|
||||
NPC_DEAD_RIDER = 16150,
|
||||
|
||||
ACTION_GATE_OPEN = 1,
|
||||
//NPC_TRIGGER = 16137, fix me
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
// Gothik
|
||||
EVENT_SUMMON_ADDS = 1,
|
||||
EVENT_SPELL_HARVEST_SOUL = 2,
|
||||
EVENT_SPELL_SHADOW_BOLT = 3,
|
||||
EVENT_HARVEST_SOUL = 2,
|
||||
EVENT_SHADOW_BOLT = 3,
|
||||
EVENT_TELEPORT = 4,
|
||||
EVENT_CHECK_HEALTH = 5,
|
||||
EVENT_CHECK_PLAYERS = 6,
|
||||
|
||||
// TRAINEES
|
||||
EVENT_SPELL_DEATH_PLAGUE = 7,
|
||||
EVENT_SPELL_ARCANE_EXPLOSION = 8,
|
||||
|
||||
// KNIGHT
|
||||
EVENT_SPELL_SHADOW_MARK = 9,
|
||||
EVENT_SPELL_WHIRLWIND = 10,
|
||||
|
||||
// RIDER
|
||||
EVENT_SPELL_BLOOD_PRESENCE = 11,
|
||||
EVENT_SPELL_DEATH_COIL = 12,
|
||||
EVENT_SPELL_HASTE_AURA = 13,
|
||||
EVENT_SPELL_HYSTERIA = 14,
|
||||
EVENT_SPELL_INTIMIDATING_SHOUT = 15,
|
||||
EVENT_SPELL_VEIL_OF_DARKNESS = 16,
|
||||
EVENT_SPELL_DRAIN_LIFE = 17,
|
||||
EVENT_SPELL_UNHOLY_AURA = 18,
|
||||
EVENT_SPELL_UNHOLY_FRENZY = 19,
|
||||
|
||||
// Living trainee
|
||||
EVENT_DEATH_PLAGUE = 7,
|
||||
// Dead trainee
|
||||
EVENT_ARCANE_EXPLOSION = 8,
|
||||
// Living knight
|
||||
EVENT_SHADOW_MARK = 9,
|
||||
// Dead knight
|
||||
EVENT_WHIRLWIND = 10,
|
||||
// Living rider
|
||||
EVENT_SHADOW_BOLT_VOLLEY = 11,
|
||||
// Dead rider
|
||||
EVENT_DRAIN_LIFE = 12,
|
||||
EVENT_UNHOLY_FRENZY = 13,
|
||||
// HORSE
|
||||
EVENT_SPELL_STOMP = 20,
|
||||
|
||||
EVENT_INTRO_2 = 21,
|
||||
EVENT_INTRO_3 = 22,
|
||||
EVENT_INTRO_4 = 23,
|
||||
EVENT_STOMP = 14,
|
||||
// Intro
|
||||
EVENT_INTRO_2 = 15,
|
||||
EVENT_INTRO_3 = 16,
|
||||
EVENT_INTRO_4 = 17
|
||||
};
|
||||
|
||||
const uint32 gothikWaves[24][2] =
|
||||
@@ -142,7 +136,7 @@ const Position PosSummonLiving[6] =
|
||||
{2714.4f, -3428.76f, 268.56f, 1.6f},
|
||||
{2669.7f, -3431.67f, 268.56f, 1.6f},
|
||||
{2692.1f, -3431.67f, 268.56f, 1.6f},
|
||||
{2714.4f, -3431.67f, 268.56f, 1.6f},
|
||||
{2714.4f, -3431.67f, 268.56f, 1.6f}
|
||||
};
|
||||
|
||||
const Position PosSummonDead[5] =
|
||||
@@ -151,7 +145,7 @@ const Position PosSummonDead[5] =
|
||||
{2699.3f, -3322.8f, 268.60f, 3.3f},
|
||||
{2733.1f, -3348.5f, 268.84f, 3.1f},
|
||||
{2682.8f, -3304.2f, 268.85f, 3.9f},
|
||||
{2664.8f, -3340.7f, 268.23f, 3.7f},
|
||||
{2664.8f, -3340.7f, 268.23f, 3.7f}
|
||||
};
|
||||
|
||||
const Position PosGroundLivingSide = {2691.2f, -3387.0f, 267.68f, 1.52f};
|
||||
@@ -193,7 +187,6 @@ public:
|
||||
{
|
||||
pInstance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
InstanceScript* pInstance;
|
||||
@@ -208,7 +201,6 @@ public:
|
||||
EnterEvadeMode();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -217,20 +209,26 @@ public:
|
||||
BossAI::Reset();
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_DISABLE_MOVE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_DISABLE_MOVE);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
secondPhase = false;
|
||||
gateOpened = false;
|
||||
waveCount = 0;
|
||||
|
||||
me->NearTeleportTo(2642.139f, -3386.959f, 285.492f, 6.265f);
|
||||
if (pInstance)
|
||||
{
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_ENTER_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_INNER_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_EXIT_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,31 +240,43 @@ public:
|
||||
events.ScheduleEvent(EVENT_INTRO_2, 4000);
|
||||
events.ScheduleEvent(EVENT_INTRO_3, 9000);
|
||||
events.ScheduleEvent(EVENT_INTRO_4, 14000);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_DISABLE_MOVE);
|
||||
me->NearTeleportTo(PosPlatform.GetPositionX(), PosPlatform.GetPositionY(), PosPlatform.GetPositionZ(), PosPlatform.GetOrientation());
|
||||
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
|
||||
events.ScheduleEvent(EVENT_SUMMON_ADDS, 30000);
|
||||
events.ScheduleEvent(EVENT_CHECK_PLAYERS, 120000);
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_ENTER_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_INNER_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
if (gateOpened)
|
||||
summon->AI()->DoAction(ACTION_GATE_OPEN);
|
||||
|
||||
summons.Summon(summon);
|
||||
summon->SetInCombatWithZone();
|
||||
if (gateOpened)
|
||||
{
|
||||
summons.DoZoneInCombat();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Unit* target = me->SelectNearestTarget(50.0f))
|
||||
{
|
||||
AttackStart(target);
|
||||
DoZoneInCombat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* cr) override { summons.Despawn(cr); }
|
||||
void SummonedCreatureDespawn(Creature* cr) override
|
||||
{
|
||||
summons.Despawn(cr);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
@@ -274,9 +284,10 @@ public:
|
||||
return;
|
||||
|
||||
Talk(SAY_KILL);
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
@@ -284,15 +295,20 @@ public:
|
||||
BossAI::JustDied(killer);
|
||||
Talk(SAY_DEATH);
|
||||
summons.DespawnAll();
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_ENTER_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_INNER_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_EXIT_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,12 +320,16 @@ public:
|
||||
me->SummonCreature(NPC_LIVING_TRAINEE, PosSummonLiving[0].GetPositionX(), PosSummonLiving[0].GetPositionY(), PosSummonLiving[0].GetPositionZ(), PosSummonLiving[0].GetOrientation());
|
||||
me->SummonCreature(NPC_LIVING_TRAINEE, PosSummonLiving[1].GetPositionX(), PosSummonLiving[1].GetPositionY(), PosSummonLiving[1].GetPositionZ(), PosSummonLiving[1].GetOrientation());
|
||||
if (Is25ManRaid())
|
||||
{
|
||||
me->SummonCreature(NPC_LIVING_TRAINEE, PosSummonLiving[2].GetPositionX(), PosSummonLiving[2].GetPositionY(), PosSummonLiving[2].GetPositionZ(), PosSummonLiving[2].GetOrientation());
|
||||
}
|
||||
break;
|
||||
case NPC_LIVING_KNIGHT:
|
||||
me->SummonCreature(NPC_LIVING_KNIGHT, PosSummonLiving[3].GetPositionX(), PosSummonLiving[3].GetPositionY(), PosSummonLiving[3].GetPositionZ(), PosSummonLiving[3].GetOrientation());
|
||||
if (Is25ManRaid())
|
||||
{
|
||||
me->SummonCreature(NPC_LIVING_KNIGHT, PosSummonLiving[5].GetPositionX(), PosSummonLiving[5].GetPositionY(), PosSummonLiving[5].GetPositionZ(), PosSummonLiving[5].GetOrientation());
|
||||
}
|
||||
break;
|
||||
case NPC_LIVING_RIDER:
|
||||
me->SummonCreature(NPC_LIVING_RIDER, PosSummonLiving[4].GetPositionX(), PosSummonLiving[4].GetPositionY(), PosSummonLiving[4].GetPositionZ(), PosSummonLiving[4].GetOrientation());
|
||||
@@ -328,17 +348,21 @@ public:
|
||||
{
|
||||
Player* player = i.GetSource();
|
||||
if (player->IsAlive() &&
|
||||
player->GetPositionX() <= POS_X_NORTH &&
|
||||
player->GetPositionX() >= POS_X_SOUTH &&
|
||||
player->GetPositionY() <= POS_Y_GATE &&
|
||||
player->GetPositionY() >= POS_Y_EAST)
|
||||
checklife = true;
|
||||
player->GetPositionX() <= POS_X_NORTH &&
|
||||
player->GetPositionX() >= POS_X_SOUTH &&
|
||||
player->GetPositionY() <= POS_Y_GATE &&
|
||||
player->GetPositionY() >= POS_Y_EAST)
|
||||
{
|
||||
checklife = true;
|
||||
}
|
||||
else if (player->IsAlive() &&
|
||||
player->GetPositionX() <= POS_X_NORTH &&
|
||||
player->GetPositionX() >= POS_X_SOUTH &&
|
||||
player->GetPositionY() >= POS_Y_GATE &&
|
||||
player->GetPositionY() <= POS_Y_WEST)
|
||||
checkdead = true;
|
||||
{
|
||||
checkdead = true;
|
||||
}
|
||||
|
||||
if (checklife && checkdead)
|
||||
return true;
|
||||
@@ -363,14 +387,15 @@ public:
|
||||
me->SummonCreature(NPC_DEAD_HORSE, PosSummonDead[pos].GetPositionX(), PosSummonDead[pos].GetPositionY(), PosSummonDead[pos].GetPositionZ(), PosSummonDead[pos].GetOrientation());
|
||||
break;
|
||||
}
|
||||
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_SPELL_CAST);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (!secondPhase)
|
||||
{
|
||||
damage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
@@ -389,31 +414,31 @@ public:
|
||||
{
|
||||
case EVENT_INTRO_2:
|
||||
Talk(SAY_INTRO_2);
|
||||
|
||||
break;
|
||||
case EVENT_INTRO_3:
|
||||
Talk(SAY_INTRO_3);
|
||||
|
||||
break;
|
||||
case EVENT_INTRO_4:
|
||||
Talk(SAY_INTRO_4);
|
||||
|
||||
break;
|
||||
case EVENT_SPELL_SHADOW_BOLT:
|
||||
case EVENT_SHADOW_BOLT:
|
||||
me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_SHADOW_BOLT_10, SPELL_SHADOW_BOLT_25), false);
|
||||
events.RepeatEvent(2000);
|
||||
events.RepeatEvent(1010);
|
||||
break;
|
||||
case EVENT_SPELL_HARVEST_SOUL:
|
||||
case EVENT_HARVEST_SOUL:
|
||||
me->CastSpell(me, SPELL_HARVEST_SOUL, false);
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
case EVENT_TELEPORT:
|
||||
me->AttackStop();
|
||||
if (IN_LIVE_SIDE(me))
|
||||
me->NearTeleportTo(PosGroundDeadSide.GetPositionX(), PosGroundDeadSide.GetPositionY(), PosGroundDeadSide.GetPositionZ(), PosGroundDeadSide.GetOrientation());
|
||||
{
|
||||
me->CastSpell(me, SPELL_TELEPORT_DEAD, false);
|
||||
}
|
||||
else
|
||||
me->NearTeleportTo(PosGroundLivingSide.GetPositionX(), PosGroundLivingSide.GetPositionY(), PosGroundLivingSide.GetPositionZ(), PosGroundLivingSide.GetOrientation());
|
||||
|
||||
{
|
||||
me->CastSpell(me, SPELL_TELEPORT_LIVE, false);
|
||||
}
|
||||
me->getThreatManager().resetAggro(NotOnSameSide(me));
|
||||
if (Unit* pTarget = SelectTarget(SELECT_TARGET_NEAREST, 0))
|
||||
{
|
||||
@@ -426,10 +451,10 @@ public:
|
||||
if (me->HealthBelowPct(30) && pInstance)
|
||||
{
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_INNER_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
|
||||
}
|
||||
events.CancelEvent(EVENT_TELEPORT);
|
||||
|
||||
break;
|
||||
}
|
||||
events.RepeatEvent(1000);
|
||||
@@ -445,35 +470,31 @@ public:
|
||||
secondPhase = true;
|
||||
Talk(SAY_PHASE_TWO);
|
||||
Talk(EMOTE_PHASE_TWO);
|
||||
me->NearTeleportTo(PosGroundLivingSide.GetPositionX(), PosGroundLivingSide.GetPositionY(), PosGroundLivingSide.GetPositionZ(), PosGroundLivingSide.GetOrientation());
|
||||
me->CastSpell(me, SPELL_TELEPORT_LIVE, false);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_DISABLE_MOVE);
|
||||
|
||||
summons.DoAction(ACTION_GATE_OPEN);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_DISABLE_MOVE);
|
||||
me->RemoveAllAuras();
|
||||
summons.DoZoneInCombat();
|
||||
events.ScheduleEvent(EVENT_SPELL_SHADOW_BOLT, 1000);
|
||||
events.ScheduleEvent(EVENT_SPELL_HARVEST_SOUL, urand(5000, 15000));
|
||||
events.ScheduleEvent(EVENT_SHADOW_BOLT, 1000);
|
||||
events.ScheduleEvent(EVENT_HARVEST_SOUL, urand(5000, 15000));
|
||||
events.ScheduleEvent(EVENT_TELEPORT, 20000);
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
|
||||
}
|
||||
|
||||
waveCount++;
|
||||
break;
|
||||
case EVENT_CHECK_PLAYERS:
|
||||
if (!CheckGroupSplitted())
|
||||
{
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_INNER_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
|
||||
summons.DoAction(ACTION_GATE_OPEN);
|
||||
}
|
||||
summons.DoZoneInCombat();
|
||||
gateOpened = true;
|
||||
Talk(EMOTE_GATE_OPENED);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
@@ -494,63 +515,58 @@ public:
|
||||
explicit npc_boss_gothik_minionAI(Creature* c) : CombatAI(c)
|
||||
{
|
||||
livingSide = IN_LIVE_SIDE(me);
|
||||
gateOpened = false;
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
bool livingSide;
|
||||
bool gateOpened;
|
||||
|
||||
bool IsOnSameSide(Unit const* who) const { return livingSide == IN_LIVE_SIDE(who); }
|
||||
bool CanAIAttack(Unit const* target) const override { return gateOpened || IsOnSameSide(target); }
|
||||
|
||||
void Reset() override { events.Reset(); }
|
||||
void Reset() override
|
||||
{
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->SetNoCallAssistance(false);
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case NPC_LIVING_TRAINEE:
|
||||
events.ScheduleEvent(EVENT_SPELL_DEATH_PLAGUE, 2000);
|
||||
events.ScheduleEvent(EVENT_DEATH_PLAGUE, 3000);
|
||||
break;
|
||||
case NPC_DEAD_TRAINEE:
|
||||
events.ScheduleEvent(EVENT_SPELL_ARCANE_EXPLOSION, 2000);
|
||||
events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, 2500);
|
||||
break;
|
||||
case NPC_LIVING_KNIGHT:
|
||||
events.ScheduleEvent(EVENT_SPELL_SHADOW_MARK, 2000);
|
||||
events.ScheduleEvent(EVENT_SHADOW_MARK, 3000);
|
||||
break;
|
||||
case NPC_DEAD_KNIGHT:
|
||||
events.ScheduleEvent(EVENT_SPELL_WHIRLWIND, 2000);
|
||||
events.ScheduleEvent(EVENT_WHIRLWIND, 2000);
|
||||
break;
|
||||
case NPC_LIVING_RIDER:
|
||||
events.ScheduleEvent(EVENT_SPELL_BLOOD_PRESENCE, 1);
|
||||
events.ScheduleEvent(EVENT_SPELL_DEATH_COIL, 3000);
|
||||
events.ScheduleEvent(EVENT_SPELL_HYSTERIA, 10000);
|
||||
events.ScheduleEvent(EVENT_SPELL_HASTE_AURA, 1000);
|
||||
events.ScheduleEvent(EVENT_SPELL_INTIMIDATING_SHOUT, urand(4000, 9000));
|
||||
events.ScheduleEvent(EVENT_SPELL_VEIL_OF_DARKNESS, urand(5000, 7000));
|
||||
events.ScheduleEvent(EVENT_SHADOW_BOLT_VOLLEY, 3000);
|
||||
break;
|
||||
case NPC_DEAD_RIDER:
|
||||
events.ScheduleEvent(EVENT_SPELL_DRAIN_LIFE, urand(2000, 3500));
|
||||
events.ScheduleEvent(EVENT_SPELL_UNHOLY_AURA, 1);
|
||||
events.ScheduleEvent(EVENT_SPELL_UNHOLY_FRENZY, urand(5000, 9000));
|
||||
events.ScheduleEvent(EVENT_DRAIN_LIFE, urand(2000, 3500));
|
||||
events.ScheduleEvent(EVENT_UNHOLY_FRENZY, urand(5000, 9000));
|
||||
break;
|
||||
case NPC_DEAD_HORSE:
|
||||
events.ScheduleEvent(EVENT_SPELL_STOMP, urand(2000, 5000));
|
||||
events.ScheduleEvent(EVENT_STOMP, urand(2000, 5000));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (!attacker || (!gateOpened && !IsOnSameSide(attacker)))
|
||||
if (!attacker && !IsOnSameSide(attacker))
|
||||
{
|
||||
damage = 0;
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == ACTION_GATE_OPEN)
|
||||
gateOpened = true;
|
||||
}
|
||||
if (!me->IsInCombat())
|
||||
{
|
||||
me->CallForHelp(25.0f);
|
||||
AttackStart(attacker);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
@@ -572,89 +588,82 @@ public:
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && me->GetInstanceScript())
|
||||
{
|
||||
me->GetInstanceScript()->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
if (me->GetUnitState() == UNIT_STATE_CASTING)
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_DEATH_PLAGUE:
|
||||
case EVENT_DEATH_PLAGUE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_DEATH_PLAGUE, false);
|
||||
events.RepeatEvent(urand(15000, 20000));
|
||||
events.RepeatEvent(urand(4000, 7000));
|
||||
break;
|
||||
case EVENT_SPELL_ARCANE_EXPLOSION:
|
||||
case EVENT_ARCANE_EXPLOSION:
|
||||
if (Unit* victim = me->GetVictim())
|
||||
{
|
||||
if (victim->IsWithinDist(me, 20))
|
||||
{
|
||||
me->CastSpell(victim, SPELL_ARCANE_EXPLOSION, false);
|
||||
events.RepeatEvent(urand(5000, 10000));
|
||||
}
|
||||
}
|
||||
events.RepeatEvent(2500);
|
||||
break;
|
||||
case EVENT_SPELL_SHADOW_MARK:
|
||||
case EVENT_SHADOW_MARK:
|
||||
if (Unit* victim = me->GetVictim())
|
||||
{
|
||||
if (!victim->HasAura(SPELL_SHADOW_MARK))
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), SPELL_SHADOW_MARK, false);
|
||||
events.RepeatEvent(urand(15000, 20000));
|
||||
}
|
||||
}
|
||||
events.RepeatEvent(urand(5000, 7000));
|
||||
break;
|
||||
case EVENT_SPELL_WHIRLWIND:
|
||||
case EVENT_WHIRLWIND:
|
||||
if (Unit* victim = me->GetVictim())
|
||||
{
|
||||
if (victim->IsWithinDist(me, 10))
|
||||
{
|
||||
me->CastSpell(victim, SPELL_WHIRLWIND, false);
|
||||
events.RepeatEvent(urand(5000, 8000));
|
||||
}
|
||||
}
|
||||
events.RepeatEvent(urand(4000, 6000));
|
||||
break;
|
||||
case EVENT_SPELL_BLOOD_PRESENCE:
|
||||
if (!me->HasAura(SPELL_BLOOD_PRESENCE))
|
||||
me->CastSpell(me, SPELL_BLOOD_PRESENCE, false);
|
||||
case EVENT_SHADOW_BOLT_VOLLEY:
|
||||
me->CastSpell(me->GetVictim(), SPELL_SHADOW_BOLT_VOLLEY, false);
|
||||
events.RepeatEvent(5000);
|
||||
break;
|
||||
case EVENT_SPELL_HASTE_AURA:
|
||||
if (!me->HasAura(SPELL_HASTE_AURA))
|
||||
me->CastSpell(me, SPELL_HASTE_AURA, false);
|
||||
break;
|
||||
case EVENT_SPELL_DEATH_COIL:
|
||||
me->CastSpell(me->GetVictim(), SPELL_DEATH_COIL, false);
|
||||
events.RepeatEvent(urand(5000, 9000));
|
||||
break;
|
||||
case EVENT_SPELL_HYSTERIA:
|
||||
if (!me->HasAura(SPELL_HYSTERIA))
|
||||
me->CastSpell(me, SPELL_HYSTERIA, false);
|
||||
events.RepeatEvent(urand(15000, 20000));
|
||||
break;
|
||||
case EVENT_SPELL_INTIMIDATING_SHOUT:
|
||||
case EVENT_DRAIN_LIFE:
|
||||
if (Unit* victim = me->GetVictim())
|
||||
{
|
||||
if (victim->IsWithinDist(me, 20))
|
||||
{
|
||||
me->CastSpell(victim, SPELL_DRAIN_LIFE, false);
|
||||
}
|
||||
}
|
||||
events.RepeatEvent(urand(8000, 12000));
|
||||
break;
|
||||
case EVENT_UNHOLY_FRENZY:
|
||||
me->AddAura(SPELL_UNHOLY_FRENZY, me);
|
||||
events.RepeatEvent(urand(15000, 17000));
|
||||
break;
|
||||
case EVENT_STOMP:
|
||||
if (Unit* victim = me->GetVictim())
|
||||
{
|
||||
if (victim->IsWithinDist(me, 10))
|
||||
me->CastSpell(victim, SPELL_INTIMIDATING_SHOUT, false);
|
||||
events.RepeatEvent(urand(14000, 22000));
|
||||
break;
|
||||
case EVENT_SPELL_VEIL_OF_DARKNESS:
|
||||
me->CastSpell(me->GetVictim(), SPELL_VEIL_OF_DARKNESS, false);
|
||||
events.RepeatEvent(urand(13000, 19000));
|
||||
break;
|
||||
case EVENT_SPELL_DRAIN_LIFE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_DRAIN_LIFE, false);
|
||||
events.RepeatEvent(urand(6000, 15000));
|
||||
break;
|
||||
case EVENT_SPELL_UNHOLY_AURA:
|
||||
if (!me->HasAura(SPELL_UNHOLY_AURA))
|
||||
me->CastSpell(me, SPELL_UNHOLY_AURA, false);
|
||||
events.RepeatEvent(urand(2000, 5000));
|
||||
break;
|
||||
case EVENT_SPELL_UNHOLY_FRENZY:
|
||||
if (!me->HasAura(SPELL_UNHOLY_FRENZY))
|
||||
me->CastSpell(me, SPELL_UNHOLY_FRENZY, false);
|
||||
events.RepeatEvent(urand(2000, 5000));
|
||||
break;
|
||||
case NPC_DEAD_HORSE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_STOMP, false);
|
||||
{
|
||||
me->CastSpell(victim, SPELL_STOMP, false);
|
||||
}
|
||||
}
|
||||
events.RepeatEvent(urand(4000, 9000));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -7,31 +7,33 @@
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_POISON_CLOUD = 28240,
|
||||
SPELL_MUTATING_INJECTION = 28169,
|
||||
SPELL_MUTATING_EXPLOSION = 28206,
|
||||
SPELL_SLIME_SPRAY_10 = 28157,
|
||||
SPELL_SLIME_SPRAY_25 = 54364,
|
||||
SPELL_POISON_CLOUD_DAMAGE_AURA_10 = 28158,
|
||||
SPELL_POISON_CLOUD_DAMAGE_AURA_25 = 54362,
|
||||
SPELL_BERSERK = 26662,
|
||||
|
||||
SPELL_BOMBARD_SLIME = 28280, // Spawn slime when hit by slime spray
|
||||
SPELL_BOMBARD_SLIME = 28280
|
||||
};
|
||||
|
||||
enum Emotes
|
||||
{
|
||||
EMOTE_SLIME = 0
|
||||
EMOTE_SLIME = 0
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_BERSERK = 1,
|
||||
EVENT_SPELL_POISON_CLOUD = 2,
|
||||
EVENT_SPELL_SLIME_SPRAY = 3,
|
||||
EVENT_SPELL_MUTATING_INJECTION = 4,
|
||||
EVENT_BERSERK = 1,
|
||||
EVENT_POISON_CLOUD = 2,
|
||||
EVENT_SLIME_SPRAY = 3,
|
||||
EVENT_MUTATING_INJECTION = 4
|
||||
};
|
||||
|
||||
enum Misc
|
||||
@@ -78,7 +80,9 @@ public:
|
||||
for (std::list<Creature*>::const_iterator itr = StichedGiants.begin(); itr != StichedGiants.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->GetGUID())
|
||||
{
|
||||
(*itr)->ToCreature()->AI()->AttackStart(me->GetVictim());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,27 +91,33 @@ public:
|
||||
BossAI::EnterCombat(who);
|
||||
PullChamberAdds();
|
||||
me->SetInCombatWithZone();
|
||||
events.ScheduleEvent(EVENT_SPELL_POISON_CLOUD, 15000);
|
||||
events.ScheduleEvent(EVENT_SPELL_MUTATING_INJECTION, 20000);
|
||||
events.ScheduleEvent(EVENT_SPELL_SLIME_SPRAY, 10000);
|
||||
events.ScheduleEvent(EVENT_SPELL_BERSERK, RAID_MODE(12 * MINUTE * IN_MILLISECONDS, 9 * MINUTE * IN_MILLISECONDS));
|
||||
events.ScheduleEvent(EVENT_POISON_CLOUD, 15000);
|
||||
events.ScheduleEvent(EVENT_MUTATING_INJECTION, 20000);
|
||||
events.ScheduleEvent(EVENT_SLIME_SPRAY, 10000);
|
||||
events.ScheduleEvent(EVENT_BERSERK, RAID_MODE(720000, 540000));
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, const SpellInfo* spellInfo) override
|
||||
{
|
||||
if (spellInfo->Id == RAID_MODE(SPELL_SLIME_SPRAY_10, SPELL_SLIME_SPRAY_25) && target->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
me->SummonCreature(NPC_FALLOUT_SLIME, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) override
|
||||
{
|
||||
if (cr->GetEntry() == NPC_FALLOUT_SLIME)
|
||||
{
|
||||
cr->SetInCombatWithZone();
|
||||
|
||||
}
|
||||
summons.Summon(cr);
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* summon) override { summons.Despawn(summon); }
|
||||
void SummonedCreatureDespawn(Creature* summon) override
|
||||
{
|
||||
summons.Despawn(summon);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
@@ -118,18 +128,20 @@ public:
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
// Some nice visuals
|
||||
dropSludgeTimer += diff;
|
||||
if (!me->IsInCombat() && dropSludgeTimer >= 5000)
|
||||
{
|
||||
if (me->IsWithinDist3d(3178, -3305, 319, 5.0f) && !summons.HasEntry(NPC_SEWAGE_SLIME))
|
||||
{
|
||||
me->CastSpell(3128.96f + irand(-20, 20), -3312.96f + irand(-20, 20), 293.25f, SPELL_BOMBARD_SLIME, false);
|
||||
|
||||
}
|
||||
dropSludgeTimer = 0;
|
||||
}
|
||||
|
||||
@@ -142,27 +154,26 @@ public:
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_POISON_CLOUD:
|
||||
case EVENT_POISON_CLOUD:
|
||||
me->CastSpell(me, SPELL_POISON_CLOUD, true);
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
case EVENT_SPELL_BERSERK:
|
||||
case EVENT_BERSERK:
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
|
||||
break;
|
||||
case EVENT_SPELL_SLIME_SPRAY:
|
||||
case EVENT_SLIME_SPRAY:
|
||||
Talk(EMOTE_SLIME);
|
||||
me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_SLIME_SPRAY_10, SPELL_SLIME_SPRAY_25), false);
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
case EVENT_SPELL_MUTATING_INJECTION:
|
||||
case EVENT_MUTATING_INJECTION:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true, -SPELL_MUTATING_INJECTION))
|
||||
{
|
||||
me->CastSpell(target, SPELL_MUTATING_INJECTION, false);
|
||||
|
||||
events.RepeatEvent(8000 + uint32(120 * me->GetHealthPct()));
|
||||
}
|
||||
events.RepeatEvent(6000 + uint32(120 * me->GetHealthPct()));
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
@@ -190,19 +201,20 @@ public:
|
||||
sizeTimer = 0;
|
||||
auraVisualTimer = 1;
|
||||
me->SetFloatValue(UNIT_FIELD_COMBATREACH, 2.0f);
|
||||
me->setFaction(21); // Grobbulus one
|
||||
me->setFaction(21);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && me->GetInstanceScript())
|
||||
{
|
||||
me->GetInstanceScript()->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
// this has to be delayed to be visible :/
|
||||
if (auraVisualTimer)
|
||||
if (auraVisualTimer) // this has to be delayed to be visible
|
||||
{
|
||||
auraVisualTimer += diff;
|
||||
if (auraVisualTimer >= 1000)
|
||||
@@ -211,9 +223,7 @@ public:
|
||||
auraVisualTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
sizeTimer += diff;
|
||||
// increase size to 15yd in 60 seconds, 0.00025 is the growth of size in 1ms
|
||||
sizeTimer += diff; // increase size to 15yd in 60 seconds, 0.00025 is the growth of size in 1ms
|
||||
me->SetFloatValue(UNIT_FIELD_COMBATREACH, 2.0f + (0.00025f * sizeTimer));
|
||||
}
|
||||
};
|
||||
@@ -232,12 +242,17 @@ public:
|
||||
{
|
||||
std::list<WorldObject*> tmplist;
|
||||
for (auto& target : targets)
|
||||
{
|
||||
if (GetCaster()->IsWithinDist3d(target, 0.0f))
|
||||
{
|
||||
tmplist.push_back(target);
|
||||
|
||||
}
|
||||
}
|
||||
targets.clear();
|
||||
for (auto& itr : tmplist)
|
||||
{
|
||||
targets.push_back(itr);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
@@ -252,9 +267,52 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class spell_grobbulus_mutating_injection : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_grobbulus_mutating_injection() : SpellScriptLoader("spell_grobbulus_mutating_injection") { }
|
||||
|
||||
class spell_grobbulus_mutating_injection_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_grobbulus_mutating_injection_AuraScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_MUTATING_EXPLOSION });
|
||||
}
|
||||
|
||||
void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
switch (GetTargetApplication()->GetRemoveMode())
|
||||
{
|
||||
case AURA_REMOVE_BY_ENEMY_SPELL:
|
||||
case AURA_REMOVE_BY_EXPIRE:
|
||||
if (auto caster = GetCaster())
|
||||
{
|
||||
caster->CastSpell(GetTarget(), SPELL_MUTATING_EXPLOSION, true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_grobbulus_mutating_injection_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_grobbulus_mutating_injection_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_grobbulus()
|
||||
{
|
||||
new boss_grobbulus();
|
||||
new boss_grobbulus_poison_cloud();
|
||||
new spell_grobbulus_mutating_injection();
|
||||
new spell_grobbulus_poison();
|
||||
}
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
|
||||
enum Says
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_TAUNT = 2,
|
||||
SAY_DEATH = 3,
|
||||
EMOTE_DANCE = 4,
|
||||
EMOTE_DANCE_END = 5,
|
||||
SAY_DANCE = 6
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_TAUNT = 2,
|
||||
EMOTE_DEATH = 3,
|
||||
EMOTE_DANCE = 4,
|
||||
EMOTE_DANCE_END = 5,
|
||||
SAY_DANCE = 6
|
||||
};
|
||||
|
||||
enum Spells
|
||||
@@ -24,21 +24,23 @@ enum Spells
|
||||
SPELL_DECREPIT_FEVER_10 = 29998,
|
||||
SPELL_DECREPIT_FEVER_25 = 55011,
|
||||
SPELL_PLAGUE_CLOUD = 29350,
|
||||
SPELL_TELEPORT_SELF = 30211
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_SPELL_DISRUPTION = 1,
|
||||
EVENT_SPELL_DECEPIT_FEVER = 2,
|
||||
EVENT_DISRUPTION = 1,
|
||||
EVENT_DECEPIT_FEVER = 2,
|
||||
EVENT_ERUPT_SECTION = 3,
|
||||
EVENT_SWITCH_PHASE = 4,
|
||||
EVENT_SAFETY_DANCE = 5,
|
||||
EVENT_PLAGUE_CLOUD = 6
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
PHASE_SLOW_DANCE = 0,
|
||||
PHASE_FAST_DANCE = 1,
|
||||
PHASE_FAST_DANCE = 1
|
||||
};
|
||||
|
||||
class boss_heigan : public CreatureScript
|
||||
@@ -71,11 +73,12 @@ public:
|
||||
currentPhase = 0;
|
||||
currentSection = 3;
|
||||
moveRight = true;
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_HEIGAN_ENTER_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,15 +88,16 @@ public:
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
Talk(SAY_DEATH);
|
||||
Talk(EMOTE_DEATH);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who) override
|
||||
@@ -104,9 +108,10 @@ public:
|
||||
if (pInstance)
|
||||
{
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_HEIGAN_ENTER_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
}
|
||||
|
||||
StartFightPhase(PHASE_SLOW_DANCE);
|
||||
}
|
||||
|
||||
@@ -117,22 +122,25 @@ public:
|
||||
events.Reset();
|
||||
if (phase == PHASE_SLOW_DANCE)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_SPELL_SPELL_DISRUPTION, 0);
|
||||
events.ScheduleEvent(EVENT_SPELL_DECEPIT_FEVER, 12000);
|
||||
events.ScheduleEvent(EVENT_ERUPT_SECTION, 10000);
|
||||
me->CastStop();
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
DoZoneInCombat();
|
||||
events.ScheduleEvent(EVENT_DISRUPTION, urand(12000, 15000));
|
||||
events.ScheduleEvent(EVENT_DECEPIT_FEVER, 17000);
|
||||
events.ScheduleEvent(EVENT_ERUPT_SECTION, 15000);
|
||||
events.ScheduleEvent(EVENT_SWITCH_PHASE, 90000);
|
||||
}
|
||||
else // if (phase == PHASE_FAST_DANCE)
|
||||
{
|
||||
Talk(EMOTE_DANCE);
|
||||
Talk(SAY_DANCE);
|
||||
// teleport
|
||||
float x, y, z, o;
|
||||
me->GetHomePosition(x, y, z, o);
|
||||
me->NearTeleportTo(x, y, z, o);
|
||||
|
||||
me->CastSpell(me, SPELL_PLAGUE_CLOUD, false);
|
||||
events.ScheduleEvent(EVENT_ERUPT_SECTION, 4000);
|
||||
me->AttackStop();
|
||||
me->StopMoving();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->CastSpell(me, SPELL_TELEPORT_SELF, false);
|
||||
me->SetFacingTo(2.40f);
|
||||
events.ScheduleEvent(EVENT_PLAGUE_CLOUD, 1000);
|
||||
events.ScheduleEvent(EVENT_ERUPT_SECTION, 7000);
|
||||
events.ScheduleEvent(EVENT_SWITCH_PHASE, 45000);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_SAFETY_DANCE, 5000);
|
||||
@@ -144,9 +152,9 @@ public:
|
||||
{
|
||||
if (who->GetGUID() == me->GetGUID())
|
||||
EnterEvadeMode();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -159,18 +167,19 @@ public:
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
//if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
// return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_SPELL_DISRUPTION:
|
||||
case EVENT_DISRUPTION:
|
||||
me->CastSpell(me, SPELL_SPELL_DISRUPTION, false);
|
||||
events.RepeatEvent(10000);
|
||||
break;
|
||||
case EVENT_SPELL_DECEPIT_FEVER:
|
||||
case EVENT_DECEPIT_FEVER:
|
||||
me->CastSpell(me, RAID_MODE(SPELL_DECREPIT_FEVER_10, SPELL_DECREPIT_FEVER_25), false);
|
||||
events.RepeatEvent(20000);
|
||||
events.RepeatEvent(urand(22000, 25000));
|
||||
break;
|
||||
case EVENT_PLAGUE_CLOUD:
|
||||
me->CastSpell(me, SPELL_PLAGUE_CLOUD, false);
|
||||
break;
|
||||
case EVENT_SWITCH_PHASE:
|
||||
if (currentPhase == PHASE_SLOW_DANCE)
|
||||
@@ -180,31 +189,33 @@ public:
|
||||
else
|
||||
{
|
||||
StartFightPhase(PHASE_SLOW_DANCE);
|
||||
Talk(EMOTE_DANCE_END); // we put this here to avoid play the emote on aggro.
|
||||
Talk(EMOTE_DANCE_END); // avoid play the emote on aggro
|
||||
}
|
||||
// no pop, there is reset in start fight
|
||||
break;
|
||||
case EVENT_ERUPT_SECTION:
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_HEIGAN_ERUPTION, currentSection);
|
||||
if (currentSection == 3)
|
||||
{
|
||||
moveRight = false;
|
||||
}
|
||||
else if (currentSection == 0)
|
||||
{
|
||||
moveRight = true;
|
||||
|
||||
}
|
||||
moveRight ? currentSection++ : currentSection--;
|
||||
}
|
||||
|
||||
if (currentPhase == PHASE_SLOW_DANCE)
|
||||
{
|
||||
Talk(SAY_TAUNT);
|
||||
|
||||
}
|
||||
events.RepeatEvent(currentPhase == PHASE_SLOW_DANCE ? 10000 : 4000);
|
||||
break;
|
||||
case EVENT_SAFETY_DANCE:
|
||||
{
|
||||
Map::PlayerList const& pList = me->GetMap()->GetPlayers();
|
||||
for(const auto& itr : pList)
|
||||
for (const auto& itr : pList)
|
||||
{
|
||||
if (IsInRoom(itr.GetSource()) && !itr.GetSource()->IsAlive())
|
||||
{
|
||||
@@ -217,7 +228,6 @@ public:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -10,23 +10,25 @@
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_TAUNT = 6,
|
||||
SAY_AGGRO = 7,
|
||||
SAY_SLAY = 8,
|
||||
SAY_DEATH = 9,
|
||||
SAY_CHAIN = 10,
|
||||
SAY_FROST_BLAST = 11,
|
||||
SAY_REQUEST_AID = 12, //start of phase 3
|
||||
SAY_ANSWER_REQUEST = 3, //lich king answer
|
||||
SAY_SUMMON_MINIONS = 14, //start of phase 1
|
||||
SAY_SPECIAL = 15,
|
||||
SAY_ANSWER_REQUEST = 3,
|
||||
SAY_TAUNT = 6,
|
||||
SAY_AGGRO = 7,
|
||||
SAY_SLAY = 8,
|
||||
SAY_DEATH = 9,
|
||||
SAY_CHAIN = 10,
|
||||
SAY_FROST_BLAST = 11,
|
||||
SAY_REQUEST_AID = 12,
|
||||
EMOTE_PHASE_TWO = 13,
|
||||
SAY_SUMMON_MINIONS = 14,
|
||||
SAY_SPECIAL = 15,
|
||||
|
||||
EMOTE_GUARDIAN_FLEE = 0,
|
||||
EMOTE_GUARDIAN_APPEAR = 1
|
||||
EMOTE_GUARDIAN_FLEE = 0,
|
||||
EMOTE_GUARDIAN_APPEAR = 1
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// Kel'Thzuad
|
||||
SPELL_FROST_BOLT_SINGLE_10 = 28478,
|
||||
SPELL_FROST_BOLT_SINGLE_25 = 55802,
|
||||
SPELL_FROST_BOLT_MULTI_10 = 28479,
|
||||
@@ -36,13 +38,14 @@ enum Spells
|
||||
SPELL_DETONATE_MANA = 27819,
|
||||
SPELL_MANA_DETONATION_DAMAGE = 27820,
|
||||
SPELL_FROST_BLAST = 27808,
|
||||
SPELL_CHAINS_OF_KELTHUZAD = 28410, //28408 script effect
|
||||
SPELL_CHAINS_OF_KELTHUZAD = 28410, // 28408 script effect
|
||||
SPELL_BERSERK = 28498,
|
||||
SPELL_KELTHUZAD_CHANNEL = 29423,
|
||||
|
||||
// Minions
|
||||
SPELL_FRENZY = 28468,
|
||||
SPELL_MORTAL_WOUND = 28467,
|
||||
SPELL_BLOOD_TAP = 28470,
|
||||
SPELL_BLOOD_TAP = 28470
|
||||
};
|
||||
|
||||
enum Misc
|
||||
@@ -55,6 +58,7 @@ enum Misc
|
||||
ACTION_CALL_HELP_ON = 1,
|
||||
ACTION_CALL_HELP_OFF = 2,
|
||||
ACTION_SECOND_PHASE = 3,
|
||||
ACTION_GUARDIANS_OFF = 4
|
||||
};
|
||||
|
||||
enum Event
|
||||
@@ -63,41 +67,35 @@ enum Event
|
||||
EVENT_SUMMON_SOLDIER = 1,
|
||||
EVENT_SUMMON_UNSTOPPABLE_ABOMINATION = 2,
|
||||
EVENT_SUMMON_SOUL_WEAVER = 3,
|
||||
EVENT_START_SECOND_PHASE = 4,
|
||||
EVENT_SPELL_FROST_BOLT_SINGLE = 5,
|
||||
EVENT_SPELL_FROST_BOLT_MULTI = 6,
|
||||
EVENT_SPELL_DETONATE_MANA = 7,
|
||||
EVENT_SECOND_PHASE_HEALTH_CHECK = 8,
|
||||
EVENT_THIRD_PHASE_LICH_KING_SAY = 9,
|
||||
EVENT_SPELL_SHADOW_FISSURE = 10,
|
||||
EVENT_SPELL_FROST_BLAST = 11,
|
||||
EVENT_SPELL_CHAINS = 12,
|
||||
EVENT_PHASE_2 = 4,
|
||||
EVENT_FROST_BOLT_SINGLE = 5,
|
||||
EVENT_FROST_BOLT_MULTI = 6,
|
||||
EVENT_DETONATE_MANA = 7,
|
||||
EVENT_PHASE_3 = 8,
|
||||
EVENT_P3_LICH_KING_SAY = 9,
|
||||
EVENT_SHADOW_FISSURE = 10,
|
||||
EVENT_FROST_BLAST = 11,
|
||||
EVENT_CHAINS = 12,
|
||||
EVENT_SUMMON_GUARDIAN_OF_ICECROWN = 13,
|
||||
EVENT_FLOOR_CHANGE = 14,
|
||||
EVENT_ENRAGE = 15,
|
||||
EVENT_SPAWN_POOL = 16,
|
||||
|
||||
// Minions
|
||||
EVENT_MINION_SPELL_FRENZY = 100,
|
||||
EVENT_MINION_SPELL_MORTAL_WOUND = 101,
|
||||
EVENT_MINION_SPELL_BLOOD_TAP = 102,
|
||||
EVENT_MINION_FRENZY = 17,
|
||||
EVENT_MINION_MORTAL_WOUND = 18,
|
||||
EVENT_MINION_BLOOD_TAP = 19
|
||||
};
|
||||
|
||||
const Position SummonPositions[12] =
|
||||
const Position SummonGroups[12] =
|
||||
{
|
||||
// Portals
|
||||
{3783.272705f, -5062.697266f, 143.711203f, 3.617599f}, //LEFT_FAR
|
||||
{3730.291260f, -5027.239258f, 143.956909f, 4.461900f}, //LEFT_MIDDLE
|
||||
{3683.868652f, -5057.281250f, 143.183884f, 5.237086f}, //LEFT_NEAR
|
||||
{3759.355225f, -5174.128418f, 143.802383f, 2.170104f}, //RIGHT_FAR
|
||||
{3700.724365f, -5185.123047f, 143.928024f, 1.309310f}, //RIGHT_MIDDLE
|
||||
{3665.121094f, -5138.679199f, 143.183212f, 0.604023f}, //RIGHT_NEAR
|
||||
|
||||
// Edges
|
||||
//{3754.431396f, -5080.727734f, 142.036316f, 3.736189f}, //LEFT_FAR
|
||||
// {3724.396484f, -5061.330566f, 142.032700f, 4.564785f}, //LEFT_MIDDLE
|
||||
//{3687.158424f, -5076.834473f, 142.017319f, 5.237086f}, //LEFT_NEAR
|
||||
//{3687.571777f, -5126.831055f, 142.017807f, 0.604023f}, //RIGHT_FAR
|
||||
//{3707.990733f, -5151.450195f, 142.032562f, 1.376855f}, //RIGHT_MIDDLE
|
||||
// {3739.500000f, -5141.883989f, 142.014113f, 2.121412f} //RIGHT_NEAR
|
||||
{3783.272705f, -5062.697266f, 143.711203f, 3.617599f}, // LEFT_FAR
|
||||
{3730.291260f, -5027.239258f, 143.956909f, 4.461900f}, // LEFT_MIDDLE
|
||||
{3683.868652f, -5057.281250f, 143.183884f, 5.237086f}, // LEFT_NEAR
|
||||
{3759.355225f, -5174.128418f, 143.802383f, 2.170104f}, // RIGHT_FAR
|
||||
{3700.724365f, -5185.123047f, 143.928024f, 1.309310f}, // RIGHT_MIDDLE
|
||||
{3665.121094f, -5138.679199f, 143.183212f, 0.604023f}, // RIGHT_NEAR
|
||||
|
||||
// Middle
|
||||
{3769.34f, -5071.80f, 143.2082f, 3.658f},
|
||||
@@ -108,6 +106,18 @@ const Position SummonPositions[12] =
|
||||
{3665.30f, -5141.55f, 143.1846f, 0.566f}
|
||||
};
|
||||
|
||||
const Position SpawnPool[7] =
|
||||
{
|
||||
// Portals
|
||||
{3783.272705f, -5062.697266f, 143.711203f, 3.617599f}, // LEFT_FAR
|
||||
{3730.291260f, -5027.239258f, 143.956909f, 4.461900f}, // LEFT_MIDDLE
|
||||
{3683.868652f, -5057.281250f, 143.183884f, 5.237086f}, // LEFT_NEAR
|
||||
{3759.355225f, -5174.128418f, 143.802383f, 2.170104f}, // RIGHT_FAR
|
||||
{3700.724365f, -5185.123047f, 143.928024f, 1.309310f}, // RIGHT_MIDDLE
|
||||
{3665.121094f, -5138.679199f, 143.183212f, 0.604023f}, // RIGHT_NEAR
|
||||
{3651.729980f, -5092.620117f, 143.380005f, 6.050000f} // GATE
|
||||
};
|
||||
|
||||
class boss_kelthuzad : public CreatureScript
|
||||
{
|
||||
public:
|
||||
@@ -133,34 +143,64 @@ public:
|
||||
|
||||
float NormalizeOrientation(float o)
|
||||
{
|
||||
// Only positive values will be passed
|
||||
return fmod(o, 2.0f * static_cast<float>(M_PI));
|
||||
return fmod(o, 2.0f * static_cast<float>(M_PI)); // Only positive values will be passed
|
||||
}
|
||||
|
||||
void SpawnHelpers()
|
||||
{
|
||||
// Ehhh...
|
||||
// in short: 6 rooms, 8 soldiers, 3 abominations and 1 weaver in each room
|
||||
// middle positions in table starts from 6
|
||||
// spawn at gate
|
||||
me->SummonCreature(NPC_UNSTOPPABLE_ABOMINATION, 3656.19f, -5093.78f, 143.33f, 6.08, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000);// abo center
|
||||
me->SummonCreature(NPC_UNSTOPPABLE_ABOMINATION, 3657.94f, -5087.68f, 143.60f, 6.08, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000);// abo left
|
||||
me->SummonCreature(NPC_UNSTOPPABLE_ABOMINATION, 3655.48f, -5100.05f, 143.53f, 6.08, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000);// abo right
|
||||
me->SummonCreature(NPC_SOUL_WEAVER, 3651.73f, -5092.62f, 143.38f, 6.05, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000); // soul behind
|
||||
me->SummonCreature(NPC_SOLDIER_OF_THE_FROZEN_WASTES, 3660.17f, -5092.45f, 143.37f, 6.07, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000); // ske front left
|
||||
me->SummonCreature(NPC_SOLDIER_OF_THE_FROZEN_WASTES, 3659.39f, -5096.21f, 143.29f, 6.07, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000); // ske front right
|
||||
me->SummonCreature(NPC_SOLDIER_OF_THE_FROZEN_WASTES, 3659.29f, -5090.19f, 143.48f, 6.07, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000); // ske left left
|
||||
me->SummonCreature(NPC_SOLDIER_OF_THE_FROZEN_WASTES, 3657.43f, -5098.03f, 143.41f, 6.07, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000); // ske right right
|
||||
me->SummonCreature(NPC_SOLDIER_OF_THE_FROZEN_WASTES, 3654.36f, -5090.51f, 143.48f, 6.09, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000); // ske behind left
|
||||
me->SummonCreature(NPC_SOLDIER_OF_THE_FROZEN_WASTES, 3653.35f, -5095.91f, 143.41f, 6.09, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000); // ske right right
|
||||
|
||||
// 6 rooms, 8 soldiers, 3 abominations and 1 weaver in each room | middle positions in table starts from 6
|
||||
for (uint8 i = 6; i < 12; ++i)
|
||||
{
|
||||
for (uint8 j = 0; j < 8; ++j)
|
||||
{
|
||||
float angle = M_PI * 2 / 8 * j;
|
||||
me->SummonCreature(NPC_SOLDIER_OF_THE_FROZEN_WASTES, SummonPositions[i].GetPositionX() + 6 * cos(angle), SummonPositions[i].GetPositionY() + 6 * sin(angle), SummonPositions[i].GetPositionZ(), SummonPositions[i].GetOrientation(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
|
||||
me->SummonCreature(NPC_SOLDIER_OF_THE_FROZEN_WASTES, SummonGroups[i].GetPositionX() + 6 * cos(angle), SummonGroups[i].GetPositionY() + 6 * sin(angle), SummonGroups[i].GetPositionZ(), SummonGroups[i].GetOrientation(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
|
||||
}
|
||||
}
|
||||
for (uint8 i = 6; i < 12; ++i)
|
||||
{
|
||||
for (uint8 j = 1; j < 4; ++j)
|
||||
{
|
||||
float dist = j == 2 ? 0.0f : 8.0f; // second in middle
|
||||
float angle = SummonPositions[i].GetOrientation() + M_PI * 2 / 4 * j;
|
||||
me->SummonCreature(NPC_UNSTOPPABLE_ABOMINATION, SummonPositions[i].GetPositionX() + dist * cos(angle), SummonPositions[i].GetPositionY() + dist * sin(angle), SummonPositions[i].GetPositionZ(), SummonPositions[i].GetOrientation(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
|
||||
float angle = SummonGroups[i].GetOrientation() + M_PI * 2 / 4 * j;
|
||||
me->SummonCreature(NPC_UNSTOPPABLE_ABOMINATION, SummonGroups[i].GetPositionX() + dist * cos(angle), SummonGroups[i].GetPositionY() + dist * sin(angle), SummonGroups[i].GetPositionZ(), SummonGroups[i].GetOrientation(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
|
||||
}
|
||||
}
|
||||
for (uint8 i = 6; i < 12; ++i)
|
||||
{
|
||||
for (uint8 j = 0; j < 1; ++j)
|
||||
{
|
||||
float angle = SummonPositions[i].GetOrientation() + M_PI;
|
||||
me->SummonCreature(NPC_SOUL_WEAVER, SummonPositions[i].GetPositionX() + 6 * cos(angle), SummonPositions[i].GetPositionY() + 6 * sin(angle), SummonPositions[i].GetPositionZ() + 0.5f, SummonPositions[i].GetOrientation(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
|
||||
float angle = SummonGroups[i].GetOrientation() + M_PI;
|
||||
me->SummonCreature(NPC_SOUL_WEAVER, SummonGroups[i].GetPositionX() + 6 * cos(angle), SummonGroups[i].GetPositionY() + 6 * sin(angle), SummonGroups[i].GetPositionZ() + 0.5f, SummonGroups[i].GetOrientation(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SummonHelper(uint32 entry, uint32 count)
|
||||
{
|
||||
for (uint8 i = 0; i < count; ++i)
|
||||
{
|
||||
if (Creature* cr = me->SummonCreature(entry, SpawnPool[urand(0, 6)], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000))
|
||||
{
|
||||
if (Unit* target = SelectTargetFromPlayerList(100.0f))
|
||||
{
|
||||
cr->AI()->DoAction(ACTION_CALL_HELP_OFF);
|
||||
cr->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
@@ -170,19 +210,35 @@ public:
|
||||
summons.DespawnAll();
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_FLOOR)))
|
||||
{
|
||||
go->SetPhaseMask(1, true);
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_GATE)))
|
||||
{
|
||||
if(!_justSpawned) /* Don't open the door if we just spawned and are still doing the RP */
|
||||
if(!_justSpawned) // Don't open the door if we just spawned and are still doing the conversation
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
_justSpawned = false;
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_PORTAL_1)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_PORTAL_2)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_PORTAL_3)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_PORTAL_4)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterEvadeMode() override
|
||||
@@ -197,25 +253,27 @@ public:
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
summons.DoAction(ACTION_GUARDIANS_OFF);
|
||||
if (Creature* guardian = summons.GetCreatureWithEntry(NPC_GUARDIAN_OF_ICECROWN))
|
||||
{
|
||||
guardian->AI()->Talk(EMOTE_GUARDIAN_FLEE);
|
||||
}
|
||||
summons.DespawnAll();
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,14 +291,13 @@ public:
|
||||
me->RemoveAllAttackers();
|
||||
me->SetTarget(0);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
|
||||
// Spawn helpers
|
||||
SpawnHelpers();
|
||||
|
||||
events.ScheduleEvent(EVENT_SUMMON_SOLDIER, 3200);
|
||||
me->CastSpell(me, SPELL_KELTHUZAD_CHANNEL, false);
|
||||
events.ScheduleEvent(EVENT_SPAWN_POOL, 5000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_SOLDIER, 6400);
|
||||
events.ScheduleEvent(EVENT_SUMMON_UNSTOPPABLE_ABOMINATION, 10000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_SOUL_WEAVER, 24000);
|
||||
events.ScheduleEvent(EVENT_START_SECOND_PHASE, 228000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_SOUL_WEAVER, 12000);
|
||||
events.ScheduleEvent(EVENT_PHASE_2, 228000);
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 900000);
|
||||
if (pInstance)
|
||||
{
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_FLOOR)))
|
||||
@@ -250,10 +307,23 @@ public:
|
||||
}
|
||||
}
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) override { summons.Summon(cr); }
|
||||
void JustSummoned(Creature* cr) override
|
||||
{
|
||||
summons.Summon(cr);
|
||||
if (!cr->IsInCombat())
|
||||
{
|
||||
cr->GetMotionMaster()->MoveRandom(5);
|
||||
}
|
||||
if (cr->GetEntry() == NPC_GUARDIAN_OF_ICECROWN)
|
||||
{
|
||||
cr->SetHomePosition(cr->GetPositionX(), cr->GetPositionY(), cr->GetPositionZ(), cr->GetOrientation());
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
@@ -261,8 +331,11 @@ public:
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
if (!me->HasAura(SPELL_KELTHUZAD_CHANNEL))
|
||||
{
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
@@ -276,90 +349,80 @@ public:
|
||||
go->SetPhaseMask(2, true);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case EVENT_SPAWN_POOL:
|
||||
SpawnHelpers();
|
||||
break;
|
||||
case EVENT_SUMMON_SOLDIER:
|
||||
if (Creature* cr = me->SummonCreature(NPC_SOLDIER_OF_THE_FROZEN_WASTES, SummonPositions[urand(0, 5)], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000))
|
||||
{
|
||||
if (Unit* target = SelectTargetFromPlayerList(100.0f))
|
||||
{
|
||||
cr->AI()->DoAction(ACTION_CALL_HELP_OFF);
|
||||
cr->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
|
||||
events.RepeatEvent(3200);
|
||||
SummonHelper(NPC_SOLDIER_OF_THE_FROZEN_WASTES, 1);
|
||||
events.RepeatEvent(3100);
|
||||
break;
|
||||
case EVENT_SUMMON_UNSTOPPABLE_ABOMINATION:
|
||||
if (Creature* cr = me->SummonCreature(NPC_UNSTOPPABLE_ABOMINATION, SummonPositions[urand(0, 5)], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000))
|
||||
{
|
||||
if (Unit* target = SelectTargetFromPlayerList(100.0f))
|
||||
{
|
||||
cr->AI()->DoAction(ACTION_CALL_HELP_OFF);
|
||||
cr->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
|
||||
events.RepeatEvent(30000);
|
||||
SummonHelper(NPC_UNSTOPPABLE_ABOMINATION, 1);
|
||||
events.RepeatEvent(18500);
|
||||
break;
|
||||
case EVENT_SUMMON_SOUL_WEAVER:
|
||||
if (Creature* cr = me->SummonCreature(NPC_SOUL_WEAVER, SummonPositions[urand(0, 5)], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000))
|
||||
{
|
||||
if (Unit* target = SelectTargetFromPlayerList(100.0f))
|
||||
{
|
||||
cr->AI()->DoAction(ACTION_CALL_HELP_OFF);
|
||||
cr->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
|
||||
SummonHelper(NPC_SOUL_WEAVER, 1);
|
||||
events.RepeatEvent(30000);
|
||||
break;
|
||||
case EVENT_START_SECOND_PHASE:
|
||||
// same as pop
|
||||
case EVENT_PHASE_2:
|
||||
Talk(EMOTE_PHASE_TWO);
|
||||
Talk(SAY_AGGRO);
|
||||
events.Reset();
|
||||
summons.DoAction(ACTION_SECOND_PHASE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE);
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
me->RemoveAura(SPELL_KELTHUZAD_CHANNEL);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
events.ScheduleEvent(EVENT_SPELL_FROST_BOLT_SINGLE, 2000);
|
||||
events.ScheduleEvent(EVENT_SPELL_FROST_BOLT_MULTI, 15000);
|
||||
events.ScheduleEvent(EVENT_SPELL_DETONATE_MANA, 20000);
|
||||
events.ScheduleEvent(EVENT_SECOND_PHASE_HEALTH_CHECK, 1000);
|
||||
events.ScheduleEvent(EVENT_SPELL_SHADOW_FISSURE, 25000);
|
||||
events.ScheduleEvent(EVENT_SPELL_FROST_BLAST, 45000);
|
||||
events.ScheduleEvent(EVENT_FROST_BOLT_SINGLE, urand(2000, 10000));
|
||||
events.ScheduleEvent(EVENT_FROST_BOLT_MULTI, urand(15000, 30000));
|
||||
events.ScheduleEvent(EVENT_DETONATE_MANA, 30000);
|
||||
events.ScheduleEvent(EVENT_PHASE_3, 1000);
|
||||
events.ScheduleEvent(EVENT_SHADOW_FISSURE, 25000);
|
||||
events.ScheduleEvent(EVENT_FROST_BLAST, 45000);
|
||||
if (Is25ManRaid())
|
||||
events.ScheduleEvent(EVENT_SPELL_CHAINS, 50000);
|
||||
{
|
||||
events.ScheduleEvent(EVENT_CHAINS, 90000);
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_FROST_BOLT_SINGLE:
|
||||
case EVENT_ENRAGE:
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
break;
|
||||
case EVENT_FROST_BOLT_SINGLE:
|
||||
me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_FROST_BOLT_SINGLE_10, SPELL_FROST_BOLT_SINGLE_25), false);
|
||||
events.RepeatEvent(urand(2000, 15000));
|
||||
events.RepeatEvent(urand(2000, 10000));
|
||||
break;
|
||||
case EVENT_SPELL_FROST_BOLT_MULTI:
|
||||
case EVENT_FROST_BOLT_MULTI:
|
||||
me->CastSpell(me, RAID_MODE(SPELL_FROST_BOLT_MULTI_10, SPELL_FROST_BOLT_MULTI_25), false);
|
||||
events.RepeatEvent(24000);
|
||||
events.RepeatEvent(urand(15000, 30000));
|
||||
break;
|
||||
case EVENT_SPELL_SHADOW_FISSURE:
|
||||
case EVENT_SHADOW_FISSURE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
|
||||
{
|
||||
me->CastSpell(target, SPELL_SHADOW_FISURE, false);
|
||||
}
|
||||
events.RepeatEvent(25000);
|
||||
break;
|
||||
case EVENT_SPELL_FROST_BLAST:
|
||||
case EVENT_FROST_BLAST:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, RAID_MODE(1, 0), 0, true))
|
||||
{
|
||||
me->CastSpell(target, SPELL_FROST_BLAST, false);
|
||||
|
||||
}
|
||||
Talk(SAY_FROST_BLAST);
|
||||
events.RepeatEvent(45000);
|
||||
break;
|
||||
case EVENT_SPELL_CHAINS:
|
||||
case EVENT_CHAINS:
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 200, true, -SPELL_CHAINS_OF_KELTHUZAD))
|
||||
{
|
||||
me->CastSpell(target, SPELL_CHAINS_OF_KELTHUZAD, true);
|
||||
|
||||
}
|
||||
}
|
||||
Talk(SAY_CHAIN);
|
||||
events.RepeatEvent(50000);
|
||||
events.RepeatEvent(90000);
|
||||
break;
|
||||
case EVENT_SPELL_DETONATE_MANA:
|
||||
case EVENT_DETONATE_MANA:
|
||||
{
|
||||
std::vector<Unit*> unitList;
|
||||
ThreatContainer::StorageType const& threatList = me->getThreatManager().getThreatList();
|
||||
@@ -368,9 +431,10 @@ public:
|
||||
if (itr->getTarget()->GetTypeId() == TYPEID_PLAYER
|
||||
&& itr->getTarget()->getPowerType() == POWER_MANA
|
||||
&& itr->getTarget()->GetPower(POWER_MANA))
|
||||
unitList.push_back(itr->getTarget());
|
||||
{
|
||||
unitList.push_back(itr->getTarget());
|
||||
}
|
||||
}
|
||||
|
||||
if (!unitList.empty())
|
||||
{
|
||||
auto itr = unitList.begin();
|
||||
@@ -378,39 +442,56 @@ public:
|
||||
me->CastSpell(*itr, SPELL_DETONATE_MANA, false);
|
||||
Talk(SAY_SPECIAL);
|
||||
}
|
||||
|
||||
events.RepeatEvent(30000);
|
||||
break;
|
||||
}
|
||||
case EVENT_SECOND_PHASE_HEALTH_CHECK:
|
||||
case EVENT_PHASE_3:
|
||||
if (me->HealthBelowPct(45))
|
||||
{
|
||||
Talk(SAY_REQUEST_AID);
|
||||
events.DelayEvents(5500);
|
||||
events.ScheduleEvent(EVENT_THIRD_PHASE_LICH_KING_SAY, 5000);
|
||||
events.ScheduleEvent(EVENT_P3_LICH_KING_SAY, 5000);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_PORTAL_1)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_PORTAL_2)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_PORTAL_3)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_PORTAL_4)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
events.RepeatEvent(1000);
|
||||
break;
|
||||
case EVENT_THIRD_PHASE_LICH_KING_SAY:
|
||||
case EVENT_P3_LICH_KING_SAY:
|
||||
if (pInstance)
|
||||
{
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, pInstance->GetData64(DATA_LICH_KING_BOSS)))
|
||||
{
|
||||
cr->AI()->Talk(SAY_ANSWER_REQUEST);
|
||||
|
||||
}
|
||||
}
|
||||
for (uint8 i = 0 ; i < RAID_MODE(2, 4); ++i)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_SUMMON_GUARDIAN_OF_ICECROWN, 10000 + (i * 5000));
|
||||
|
||||
}
|
||||
break;
|
||||
case EVENT_SUMMON_GUARDIAN_OF_ICECROWN:
|
||||
if (Creature* cr = me->SummonCreature(NPC_GUARDIAN_OF_ICECROWN, SummonPositions[RAND(0, 1, 3, 4)]))
|
||||
if (Creature* cr = me->SummonCreature(NPC_GUARDIAN_OF_ICECROWN, SpawnPool[RAND(0, 1, 3, 4)]))
|
||||
{
|
||||
cr->AI()->Talk(EMOTE_GUARDIAN_APPEAR);
|
||||
cr->AI()->AttackStart(me->GetVictim());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE))
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
@@ -444,13 +525,27 @@ public:
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == ACTION_CALL_HELP_ON)
|
||||
{
|
||||
callHelp = true;
|
||||
}
|
||||
else if (param == ACTION_CALL_HELP_OFF)
|
||||
{
|
||||
callHelp = false;
|
||||
}
|
||||
else if (param == ACTION_SECOND_PHASE)
|
||||
{
|
||||
if (!me->IsInCombat())
|
||||
{
|
||||
me->DespawnOrUnsummon(500);
|
||||
}
|
||||
}
|
||||
if (param == ACTION_GUARDIANS_OFF)
|
||||
{
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->RemoveAllAuras();
|
||||
EnterEvadeMode();
|
||||
me->SetPosition(me->GetHomePosition());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,7 +560,9 @@ public:
|
||||
void JustDied(Unit* ) override
|
||||
{
|
||||
if (me->GetEntry() == NPC_UNSTOPPABLE_ABOMINATION && me->GetInstanceScript())
|
||||
{
|
||||
me->GetInstanceScript()->SetData(DATA_ABOMINATION_KILLED, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
@@ -486,7 +583,9 @@ public:
|
||||
}
|
||||
|
||||
if (me->GetEntry() != NPC_UNSTOPPABLE_ABOMINATION && me->GetEntry() != NPC_GUARDIAN_OF_ICECROWN)
|
||||
{
|
||||
me->AddThreat(who, 1000000.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
@@ -494,17 +593,29 @@ public:
|
||||
me->SetInCombatWithZone();
|
||||
if (me->GetEntry() == NPC_UNSTOPPABLE_ABOMINATION)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_MINION_SPELL_FRENZY, 1000);
|
||||
events.ScheduleEvent(EVENT_MINION_SPELL_MORTAL_WOUND, 5000);
|
||||
events.ScheduleEvent(EVENT_MINION_FRENZY, 1000);
|
||||
events.ScheduleEvent(EVENT_MINION_MORTAL_WOUND, 5000);
|
||||
}
|
||||
else if (me->GetEntry() == NPC_GUARDIAN_OF_ICECROWN)
|
||||
events.ScheduleEvent(EVENT_MINION_SPELL_BLOOD_TAP, 15000);
|
||||
{
|
||||
events.ScheduleEvent(EVENT_MINION_BLOOD_TAP, 15000);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && me->GetInstanceScript())
|
||||
{
|
||||
me->GetInstanceScript()->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (me->GetEntry() == NPC_GUARDIAN_OF_ICECROWN)
|
||||
{
|
||||
me->DespawnOrUnsummon();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
@@ -518,25 +629,23 @@ public:
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_MINION_SPELL_MORTAL_WOUND:
|
||||
case EVENT_MINION_MORTAL_WOUND:
|
||||
me->CastSpell(me->GetVictim(), SPELL_MORTAL_WOUND, false);
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
case EVENT_MINION_SPELL_FRENZY:
|
||||
case EVENT_MINION_FRENZY:
|
||||
if (me->HealthBelowPct(35))
|
||||
{
|
||||
me->CastSpell(me, SPELL_FRENZY, true);
|
||||
|
||||
break;
|
||||
}
|
||||
events.RepeatEvent(1000);
|
||||
break;
|
||||
case EVENT_MINION_SPELL_BLOOD_TAP:
|
||||
case EVENT_MINION_BLOOD_TAP:
|
||||
me->CastSpell(me->GetVictim(), SPELL_BLOOD_TAP, false);
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
@@ -559,12 +668,17 @@ public:
|
||||
|
||||
std::list<WorldObject*> tmplist;
|
||||
for (auto& target : targets)
|
||||
{
|
||||
if (!target->ToUnit()->HasAura(SPELL_FROST_BLAST))
|
||||
{
|
||||
tmplist.push_back(target);
|
||||
|
||||
}
|
||||
}
|
||||
targets.clear();
|
||||
for (auto& itr : tmplist)
|
||||
{
|
||||
targets.push_back(itr);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
@@ -596,7 +710,6 @@ public:
|
||||
void HandleScript(AuraEffect const* aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
Unit* target = GetTarget();
|
||||
if (auto mana = int32(target->GetMaxPower(POWER_MANA) / 10))
|
||||
{
|
||||
|
||||
@@ -14,23 +14,25 @@ enum Spells
|
||||
SPELL_DEATHBLOOM_25 = 55053,
|
||||
SPELL_INEVITABLE_DOOM_10 = 29204,
|
||||
SPELL_INEVITABLE_DOOM_25 = 55052,
|
||||
SPELL_BERSERK = 26662,
|
||||
SPELL_BERSERK = 26662
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_NECROTIC_AURA = 1,
|
||||
EVENT_SPELL_DEATHBLOOM = 2,
|
||||
EVENT_SPELL_INEVITABLE_DOOM = 3,
|
||||
EVENT_SPELL_BERSERK = 4,
|
||||
EVENT_NECROTIC_AURA = 1,
|
||||
EVENT_DEATHBLOOM = 2,
|
||||
EVENT_INEVITABLE_DOOM = 3,
|
||||
EVENT_BERSERK = 4,
|
||||
EVENT_SUMMON_SPORE = 5,
|
||||
EVENT_NECROTIC_AURA_FADING = 6,
|
||||
EVENT_NECROTIC_AURA_REMOVED = 7
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_NECROTIC_AURA_APPLIED = 0,
|
||||
SAY_NECROTIC_AURA_REMOVED = 1,
|
||||
SAY_NECROTIC_AURA_FADING = 2,
|
||||
SAY_NECROTIC_AURA_APPLIED = 0,
|
||||
SAY_NECROTIC_AURA_REMOVED = 1,
|
||||
SAY_NECROTIC_AURA_FADING = 2
|
||||
};
|
||||
|
||||
class boss_loatheb : public CreatureScript
|
||||
@@ -52,6 +54,7 @@ public:
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
uint8 doomCounter;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
|
||||
@@ -60,11 +63,14 @@ public:
|
||||
BossAI::Reset();
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
doomCounter = 0;
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(BOSS_LOATHEB, NOT_STARTED);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_LOATHEB_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,38 +83,46 @@ public:
|
||||
void SummonedCreatureDies(Creature* /*cr*/, Unit*) override
|
||||
{
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_SPORE_KILLED, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who) override
|
||||
{
|
||||
BossAI::EnterCombat(who);
|
||||
me->SetInCombatWithZone();
|
||||
events.ScheduleEvent(EVENT_NECROTIC_AURA, 10000);
|
||||
events.ScheduleEvent(EVENT_DEATHBLOOM, 5000);
|
||||
events.ScheduleEvent(EVENT_INEVITABLE_DOOM, 120000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_SPORE, 15000);
|
||||
events.ScheduleEvent(EVENT_BERSERK, 720000);
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(BOSS_LOATHEB, IN_PROGRESS);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_LOATHEB_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
}
|
||||
|
||||
me->SetInCombatWithZone();
|
||||
events.ScheduleEvent(EVENT_SPELL_NECROTIC_AURA, 10000);
|
||||
events.ScheduleEvent(EVENT_SPELL_DEATHBLOOM, 6000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_SPORE, 12000);
|
||||
events.ScheduleEvent(EVENT_SPELL_BERSERK, 720000);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
if (pInstance)
|
||||
pInstance->SetData(BOSS_LOATHEB, DONE);
|
||||
summons.DespawnAll();
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(BOSS_LOATHEB, DONE);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
@@ -126,24 +140,39 @@ public:
|
||||
me->CastSpell(me, SPELL_SUMMON_SPORE, true);
|
||||
events.RepeatEvent(35000);
|
||||
break;
|
||||
case EVENT_SPELL_NECROTIC_AURA:
|
||||
case EVENT_NECROTIC_AURA:
|
||||
me->CastSpell(me, SPELL_NECROTIC_AURA, true);
|
||||
Talk(SAY_NECROTIC_AURA_APPLIED);
|
||||
events.ScheduleEvent(EVENT_NECROTIC_AURA_FADING, 14000);
|
||||
events.ScheduleEvent(EVENT_NECROTIC_AURA_REMOVED, 17000);
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
case EVENT_SPELL_DEATHBLOOM:
|
||||
case EVENT_DEATHBLOOM:
|
||||
me->CastSpell(me, RAID_MODE(SPELL_DEATHBLOOM_10, SPELL_DEATHBLOOM_25), false);
|
||||
events.RepeatEvent(30000);
|
||||
break;
|
||||
case EVENT_SPELL_INEVITABLE_DOOM:
|
||||
case EVENT_INEVITABLE_DOOM:
|
||||
me->CastSpell(me, RAID_MODE(SPELL_INEVITABLE_DOOM_10, SPELL_INEVITABLE_DOOM_25), false);
|
||||
events.RepeatEvent(events.GetTimer() < 5 * MINUTE * IN_MILLISECONDS ? 30000 : 15000);
|
||||
doomCounter++;
|
||||
if (doomCounter < 6)
|
||||
{
|
||||
events.RepeatEvent(30000);
|
||||
}
|
||||
else
|
||||
{
|
||||
events.RepeatEvent(15000);
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_BERSERK:
|
||||
case EVENT_BERSERK:
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
|
||||
break;
|
||||
case EVENT_NECROTIC_AURA_FADING:
|
||||
Talk(SAY_NECROTIC_AURA_FADING);
|
||||
break;
|
||||
case EVENT_NECROTIC_AURA_REMOVED:
|
||||
Talk(SAY_NECROTIC_AURA_REMOVED);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
@@ -162,44 +191,7 @@ public:
|
||||
};
|
||||
};
|
||||
|
||||
class spell_loatheb_necrotic_aura_warning : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_loatheb_necrotic_aura_warning() : SpellScriptLoader("spell_loatheb_necrotic_aura_warning") { }
|
||||
|
||||
class spell_loatheb_necrotic_aura_warning_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_loatheb_necrotic_aura_warning_AuraScript);
|
||||
|
||||
void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
Creature* target = GetTarget()->ToCreature();
|
||||
if (target->IsAIEnabled)
|
||||
target->AI()->Talk(SAY_NECROTIC_AURA_APPLIED);
|
||||
}
|
||||
|
||||
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
Creature* target = GetTarget()->ToCreature();
|
||||
if (target->IsAIEnabled)
|
||||
target->AI()->Talk(SAY_NECROTIC_AURA_REMOVED);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectApply += AuraEffectApplyFn(spell_loatheb_necrotic_aura_warning_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_loatheb_necrotic_aura_warning_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_loatheb_necrotic_aura_warning_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_loatheb()
|
||||
{
|
||||
new boss_loatheb();
|
||||
new spell_loatheb_necrotic_aura_warning();
|
||||
}
|
||||
|
||||
@@ -17,30 +17,30 @@ enum Spells
|
||||
SPELL_NECROTIC_POISON_10 = 54121,
|
||||
SPELL_NECROTIC_POISON_25 = 28776,
|
||||
SPELL_FRENZY_10 = 54123,
|
||||
SPELL_FRENZY_25 = 54124,
|
||||
SPELL_FRENZY_25 = 54124
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_WEB_SPRAY = 1,
|
||||
EVENT_SPELL_POISON_SHOCK = 2,
|
||||
EVENT_SPELL_NECROTIC_POISON = 3,
|
||||
EVENT_WEB_SPRAY = 1,
|
||||
EVENT_POISON_SHOCK = 2,
|
||||
EVENT_NECROTIC_POISON = 3,
|
||||
EVENT_WEB_WRAP = 4,
|
||||
EVENT_HEALTH_CHECK = 5,
|
||||
EVENT_SUMMON_SPIDERLINGS = 6,
|
||||
EVENT_SUMMON_SPIDERLINGS = 6
|
||||
};
|
||||
|
||||
enum Emotes
|
||||
{
|
||||
EMOTE_SPIDERS = 0,
|
||||
EMOTE_WEB_WRAP = 1,
|
||||
EMOTE_WEB_SPRAY = 2
|
||||
EMOTE_SPIDERS = 0,
|
||||
EMOTE_WEB_WRAP = 1,
|
||||
EMOTE_WEB_SPRAY = 2
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_WEB_WRAP = 16486,
|
||||
NPC_MAEXXNA_SPIDERLING = 17055,
|
||||
NPC_MAEXXNA_SPIDERLING = 17055
|
||||
};
|
||||
|
||||
const Position PosWrap[3] =
|
||||
@@ -78,7 +78,6 @@ public:
|
||||
EnterEvadeMode();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -87,11 +86,12 @@ public:
|
||||
BossAI::Reset();
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_MAEXXNA_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,16 +100,17 @@ public:
|
||||
BossAI::EnterCombat(who);
|
||||
me->SetInCombatWithZone();
|
||||
events.ScheduleEvent(EVENT_WEB_WRAP, 20000);
|
||||
events.ScheduleEvent(EVENT_SPELL_WEB_SPRAY, 40000);
|
||||
events.ScheduleEvent(EVENT_SPELL_POISON_SHOCK, 10000);
|
||||
events.ScheduleEvent(EVENT_SPELL_NECROTIC_POISON, 5000);
|
||||
events.ScheduleEvent(EVENT_WEB_SPRAY, 40000);
|
||||
events.ScheduleEvent(EVENT_POISON_SHOCK, 10000);
|
||||
events.ScheduleEvent(EVENT_NECROTIC_POISON, 5000);
|
||||
events.ScheduleEvent(EVENT_HEALTH_CHECK, 1000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_SPIDERLINGS, 30000);
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_MAEXXNA_GATE)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,16 +120,25 @@ public:
|
||||
{
|
||||
cr->SetInCombatWithZone();
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
cr->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
|
||||
summons.Summon(cr);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
summons.DespawnAll();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
@@ -145,53 +155,53 @@ public:
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_WEB_SPRAY:
|
||||
case EVENT_WEB_SPRAY:
|
||||
Talk(EMOTE_WEB_SPRAY);
|
||||
me->CastSpell(me, RAID_MODE(SPELL_WEB_SPRAY_10, SPELL_WEB_SPRAY_25), true);
|
||||
events.RepeatEvent(40000);
|
||||
break;
|
||||
case EVENT_SPELL_POISON_SHOCK:
|
||||
case EVENT_POISON_SHOCK:
|
||||
me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_POISON_SHOCK_10, SPELL_POISON_SHOCK_25), false);
|
||||
events.RepeatEvent(40000);
|
||||
events.RepeatEvent(10000);
|
||||
break;
|
||||
case EVENT_SPELL_NECROTIC_POISON:
|
||||
case EVENT_NECROTIC_POISON:
|
||||
me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_NECROTIC_POISON_10, SPELL_NECROTIC_POISON_25), false);
|
||||
events.RepeatEvent(30000);
|
||||
break;
|
||||
case EVENT_SUMMON_SPIDERLINGS:
|
||||
Talk(EMOTE_SPIDERS);
|
||||
for (uint8 i = 0; i < 8; ++i)
|
||||
{
|
||||
me->SummonCreature(NPC_MAEXXNA_SPIDERLING, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
|
||||
}
|
||||
events.RepeatEvent(40000);
|
||||
break;
|
||||
case EVENT_HEALTH_CHECK:
|
||||
if (me->GetHealthPct() < 30)
|
||||
{
|
||||
me->CastSpell(me, RAID_MODE(SPELL_FRENZY_10, SPELL_FRENZY_25), true);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
events.RepeatEvent(1000);
|
||||
break;
|
||||
case EVENT_WEB_WRAP:
|
||||
Talk(EMOTE_WEB_WRAP);
|
||||
for (uint8 i = 0; i < RAID_MODE(1, 2); ++i)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0, true, -SPELL_WEB_WRAP))
|
||||
{
|
||||
target->RemoveAura(RAID_MODE(SPELL_WEB_SPRAY_10, SPELL_WEB_SPRAY_25));
|
||||
uint8 pos = urand(0, 2);
|
||||
|
||||
if (Creature* wrap = me->SummonCreature(NPC_WEB_WRAP, PosWrap[pos].GetPositionX(), PosWrap[pos].GetPositionY(), PosWrap[pos].GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 60000))
|
||||
{
|
||||
wrap->AI()->SetGUID(target->GetGUID());
|
||||
target->GetMotionMaster()->MoveJump(PosWrap[pos].GetPositionX(), PosWrap[pos].GetPositionY(), PosWrap[pos].GetPositionZ(), 20, 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
events.RepeatEvent(40000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
@@ -216,15 +226,23 @@ public:
|
||||
{
|
||||
victimGUID = guid;
|
||||
if (me->m_spells[0] && victimGUID)
|
||||
{
|
||||
if (Unit* victim = ObjectAccessor::GetUnit(*me, victimGUID))
|
||||
{
|
||||
victim->CastSpell(victim, me->m_spells[0], true, nullptr, nullptr, me->GetGUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (me->m_spells[0] && victimGUID)
|
||||
{
|
||||
if (Unit* victim = ObjectAccessor::GetUnit(*me, victimGUID))
|
||||
{
|
||||
victim->RemoveAurasDueToSpell(me->m_spells[0], me->GetGUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -8,15 +8,15 @@
|
||||
|
||||
enum Says
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SUMMON = 1,
|
||||
SAY_SLAY = 2,
|
||||
SAY_DEATH = 3,
|
||||
EMOTE_SUMMON = 4,
|
||||
EMOTE_SUMMON_WAVE = 5,
|
||||
EMOTE_TELEPORT_BALCONY = 6,
|
||||
EMOTE_TELEPORT_BACK = 7,
|
||||
EMOTE_BLINK = 8
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SUMMON = 1,
|
||||
SAY_SLAY = 2,
|
||||
SAY_DEATH = 3,
|
||||
EMOTE_SUMMON = 4,
|
||||
EMOTE_SUMMON_WAVE = 5,
|
||||
EMOTE_TELEPORT_BALCONY = 6,
|
||||
EMOTE_TELEPORT_BACK = 7,
|
||||
EMOTE_BLINK = 8
|
||||
};
|
||||
|
||||
enum Spells
|
||||
@@ -27,20 +27,22 @@ enum Spells
|
||||
SPELL_CRIPPLE_25 = 54814,
|
||||
SPELL_SUMMON_PLAGUED_WARRIORS = 29237,
|
||||
SPELL_TELEPORT = 29216,
|
||||
SPELL_BLINK = 29208,
|
||||
SPELL_TELEPORT_BACK = 29231,
|
||||
SPELL_BERSERK = 68378,
|
||||
SPELL_BLINK = 29208
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_CURSE = 1,
|
||||
EVENT_SPELL_CRIPPLE = 2,
|
||||
EVENT_CURSE = 1,
|
||||
EVENT_CRIPPLE = 2,
|
||||
EVENT_SUMMON_PLAGUED_WARRIOR_ANNOUNCE = 3,
|
||||
EVENT_MOVE_TO_BALCONY = 4,
|
||||
EVENT_SPELL_BLINK = 5,
|
||||
EVENT_BLINK = 5,
|
||||
EVENT_MOVE_TO_GROUND = 6,
|
||||
EVENT_SUMMON_PLAGUED_WARRIOR_REAL = 7,
|
||||
EVENT_BALCONY_SUMMON_ANNOUNCE = 8,
|
||||
EVENT_BALCONY_SUMMON_REAL = 9,
|
||||
EVENT_BALCONY_SUMMON_REAL = 9
|
||||
};
|
||||
|
||||
enum Misc
|
||||
@@ -48,15 +50,17 @@ enum Misc
|
||||
NPC_PLAGUED_WARRIOR = 16984,
|
||||
NPC_PLAGUED_CHAMPION = 16983,
|
||||
NPC_PLAGUED_GUARDIAN = 16981,
|
||||
|
||||
NOTH_ROOM_ENTRANCE = 181200
|
||||
};
|
||||
|
||||
const Position summoningPosition[5] =
|
||||
{
|
||||
{2728.12f, -3544.43f, 261.91f, 6.04f},
|
||||
{2729.05f, -3544.47f, 261.91f, 5.58f},
|
||||
{2728.06f, -3535.38f, 263.21f, 2.75f},
|
||||
{2725.71f, -3514.80f, 263.23f, 2.86f},
|
||||
{2728.24f, -3465.08f, 264.20f, 3.56f},
|
||||
{2704.11f, -3456.81f, 265.53f, 4.51f},
|
||||
{2663.56f, -3464.43f, 262.66f, 5.20f},
|
||||
{2704.79f, -3459.17f, 263.74f, 4.25f},
|
||||
{2652.02f, -3459.13f, 262.50f, 5.39f}
|
||||
};
|
||||
|
||||
const Position nothPosition = {2684.94f, -3502.53f, 261.31f, 4.7f};
|
||||
@@ -79,6 +83,7 @@ public:
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
uint8 timesInBalcony;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
|
||||
@@ -87,14 +92,14 @@ public:
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_DISABLE_MOVE);
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
events.SetPhase(0);
|
||||
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_MOVE_TO_BALCONY, 110000);
|
||||
events.ScheduleEvent(EVENT_SPELL_CURSE, 15000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_PLAGUED_WARRIOR_ANNOUNCE, 25000);
|
||||
events.ScheduleEvent(EVENT_CURSE, 15000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_PLAGUED_WARRIOR_ANNOUNCE, 10000);
|
||||
if (Is25ManRaid())
|
||||
events.ScheduleEvent(EVENT_SPELL_BLINK, 26000);
|
||||
{
|
||||
events.ScheduleEvent(EVENT_BLINK, 26000);
|
||||
}
|
||||
}
|
||||
|
||||
void StartBalconyPhase()
|
||||
@@ -103,7 +108,6 @@ public:
|
||||
me->AttackStop();
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_DISABLE_MOVE);
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
events.SetPhase(1);
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_BALCONY_SUMMON_ANNOUNCE, 4000);
|
||||
events.ScheduleEvent(EVENT_MOVE_TO_GROUND, 70000);
|
||||
@@ -112,17 +116,18 @@ public:
|
||||
void SummonHelper(uint32 entry, uint32 count)
|
||||
{
|
||||
for (uint8 i = 0; i < count; ++i)
|
||||
{
|
||||
me->SummonCreature(entry, summoningPosition[urand(0, 4)]);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsInRoom()
|
||||
{
|
||||
if (me->GetPositionX() > 2730 || me->GetPositionX() < 2614 || me->GetPositionY() > -3455 || me->GetPositionY() < -3553)
|
||||
if (me->GetExactDist(2684.8f, -3502.5f, 261.3f) > 80.0f)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -131,9 +136,14 @@ public:
|
||||
BossAI::Reset();
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->CastSpell(me, SPELL_TELEPORT_BACK, true);
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
events.SetPhase(0);
|
||||
timesInBalcony = 0;
|
||||
if (GameObject* go = me->FindNearestGameObject(NOTH_ROOM_ENTRANCE, 100.0f))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterEvadeMode() override
|
||||
@@ -147,6 +157,10 @@ public:
|
||||
BossAI::EnterCombat(who);
|
||||
Talk(SAY_AGGRO);
|
||||
StartGroundPhase();
|
||||
if (GameObject* go = me->FindNearestGameObject(NOTH_ROOM_ENTRANCE, 100.0f))
|
||||
{
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
@@ -157,9 +171,17 @@ public:
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
me->NearTeleportTo(nothPosition.GetPositionX(), nothPosition.GetPositionY(), nothPosition.GetPositionZ(), nothPosition.GetOrientation(), true);
|
||||
if (me->GetPositionZ() > 270.27f)
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_DISABLE_MOVE);
|
||||
me->NearTeleportTo(nothPosition.GetPositionX(), nothPosition.GetPositionY(), nothPosition.GetPositionZ(), nothPosition.GetOrientation(), true);
|
||||
}
|
||||
BossAI::JustDied(killer);
|
||||
Talk(SAY_DEATH);
|
||||
if (GameObject* go = me->FindNearestGameObject(NOTH_ROOM_ENTRANCE, 100.0f))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
@@ -168,9 +190,10 @@ public:
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
@@ -188,15 +211,17 @@ public:
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
// GROUND
|
||||
case EVENT_SPELL_CURSE:
|
||||
case EVENT_CURSE:
|
||||
if (events.GetPhaseMask() == 0)
|
||||
{
|
||||
me->CastCustomSpell(RAID_MODE(SPELL_CURSE_OF_THE_PLAGUEBRINGER_10, SPELL_CURSE_OF_THE_PLAGUEBRINGER_25), SPELLVALUE_MAX_TARGETS, RAID_MODE(3, 10), me, false);
|
||||
}
|
||||
events.RepeatEvent(25000);
|
||||
break;
|
||||
case EVENT_SUMMON_PLAGUED_WARRIOR_ANNOUNCE:
|
||||
Talk(SAY_SUMMON);
|
||||
Talk(EMOTE_SUMMON);
|
||||
events.RepeatEvent(25000);
|
||||
events.RepeatEvent(30000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_PLAGUED_WARRIOR_REAL, 4000);
|
||||
break;
|
||||
case EVENT_SUMMON_PLAGUED_WARRIOR_REAL:
|
||||
@@ -207,9 +232,8 @@ public:
|
||||
Talk(EMOTE_TELEPORT_BALCONY);
|
||||
me->CastSpell(me, SPELL_TELEPORT, true);
|
||||
StartBalconyPhase();
|
||||
// events.Reset()!!
|
||||
break;
|
||||
case EVENT_SPELL_BLINK:
|
||||
case EVENT_BLINK:
|
||||
DoResetThreat();
|
||||
me->CastSpell(me, RAID_MODE(SPELL_CRIPPLE_10, SPELL_CRIPPLE_25), false);
|
||||
me->CastSpell(me, SPELL_BLINK, true);
|
||||
@@ -219,28 +243,36 @@ public:
|
||||
// BALCONY
|
||||
case EVENT_BALCONY_SUMMON_ANNOUNCE:
|
||||
Talk(EMOTE_SUMMON_WAVE);
|
||||
events.RepeatEvent(25000);
|
||||
events.RepeatEvent(30000);
|
||||
events.ScheduleEvent(EVENT_BALCONY_SUMMON_REAL, 4000);
|
||||
break;
|
||||
case EVENT_BALCONY_SUMMON_REAL:
|
||||
me->CastSpell(me, SPELL_SUMMON_PLAGUED_WARRIORS, true); // visual only
|
||||
if (events.GetPhaseMask() == 0)
|
||||
SummonHelper(NPC_PLAGUED_CHAMPION, RAID_MODE(2, 4));
|
||||
else if (events.GetPhaseMask() == 1)
|
||||
me->CastSpell(me, SPELL_SUMMON_PLAGUED_WARRIORS, true); // visual
|
||||
switch (timesInBalcony)
|
||||
{
|
||||
SummonHelper(NPC_PLAGUED_CHAMPION, RAID_MODE(1, 2));
|
||||
SummonHelper(NPC_PLAGUED_GUARDIAN, RAID_MODE(1, 2));
|
||||
case 0:
|
||||
SummonHelper(NPC_PLAGUED_CHAMPION, RAID_MODE(2, 4));
|
||||
break;
|
||||
case 1:
|
||||
SummonHelper(NPC_PLAGUED_CHAMPION, RAID_MODE(1, 2));
|
||||
SummonHelper(NPC_PLAGUED_GUARDIAN, RAID_MODE(1, 2));
|
||||
break;
|
||||
default:
|
||||
SummonHelper(NPC_PLAGUED_GUARDIAN, RAID_MODE(2, 4));
|
||||
break;
|
||||
}
|
||||
else
|
||||
SummonHelper(NPC_PLAGUED_GUARDIAN, RAID_MODE(2, 4));
|
||||
break;
|
||||
case EVENT_MOVE_TO_GROUND:
|
||||
Talk(EMOTE_TELEPORT_BACK);
|
||||
me->CastSpell(me, SPELL_TELEPORT_BACK, true);
|
||||
timesInBalcony++;
|
||||
if (timesInBalcony == 3)
|
||||
{
|
||||
DoCastSelf(SPELL_BERSERK);
|
||||
}
|
||||
StartGroundPhase();
|
||||
me->NearTeleportTo(nothPosition.GetPositionX(), nothPosition.GetPositionY(), nothPosition.GetPositionZ(), nothPosition.GetOrientation(), true);
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasReactState(REACT_AGGRESSIVE))
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_DEATH = 2,
|
||||
EMOTE_BERSERK = 3,
|
||||
EMOTE_ENRAGE = 4
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_DEATH = 2,
|
||||
EMOTE_BERSERK = 3,
|
||||
EMOTE_ENRAGE = 4
|
||||
};
|
||||
|
||||
enum Spells
|
||||
@@ -21,20 +21,20 @@ enum Spells
|
||||
SPELL_HATEFUL_STRIKE_25 = 59192,
|
||||
SPELL_FRENZY = 28131,
|
||||
SPELL_BERSERK = 26662,
|
||||
SPELL_SLIME_BOLT = 32309,
|
||||
SPELL_SLIME_BOLT = 32309
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_HEALTH_CHECK = 1,
|
||||
EVENT_SPELL_HATEFUL_STRIKE = 2,
|
||||
EVENT_SPELL_SLIME_BOLT = 3,
|
||||
EVENT_SPELL_BERSERK = 4,
|
||||
EVENT_HATEFUL_STRIKE = 2,
|
||||
EVENT_SLIME_BOLT = 3,
|
||||
EVENT_BERSERK = 4
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
ACHIEV_TIMED_START_EVENT = 10286,
|
||||
ACHIEV_TIMED_START_EVENT = 10286
|
||||
};
|
||||
|
||||
class boss_patchwerk : public CreatureScript
|
||||
@@ -69,10 +69,13 @@ public:
|
||||
return;
|
||||
|
||||
if (!urand(0, 3))
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
}
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
@@ -85,12 +88,10 @@ public:
|
||||
{
|
||||
BossAI::EnterCombat(who);
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
me->SetInCombatWithZone();
|
||||
events.ScheduleEvent(EVENT_SPELL_HATEFUL_STRIKE, 1200);
|
||||
events.ScheduleEvent(EVENT_SPELL_BERSERK, 360000);
|
||||
events.ScheduleEvent(EVENT_HATEFUL_STRIKE, 1500);
|
||||
events.ScheduleEvent(EVENT_BERSERK, 360000);
|
||||
events.ScheduleEvent(EVENT_HEALTH_CHECK, 1000);
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
|
||||
@@ -108,58 +109,60 @@ public:
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_HATEFUL_STRIKE:
|
||||
case EVENT_HATEFUL_STRIKE:
|
||||
{
|
||||
//Cast Hateful strike on the player with the highest
|
||||
//amount of HP within melee distance, and second threat amount
|
||||
// Cast Hateful strike on the player with the highest amount of HP within melee distance, and second threat amount
|
||||
std::list<Unit*> meleeRangeTargets;
|
||||
Unit* finalTarget = nullptr;
|
||||
uint8 counter = 0;
|
||||
|
||||
auto i = me->getThreatManager().getThreatList().begin();
|
||||
for (; i != me->getThreatManager().getThreatList().end(); ++i, ++counter)
|
||||
{
|
||||
// Gather all units with melee range
|
||||
Unit* target = (*i)->getTarget();
|
||||
if (me->IsWithinMeleeRange(target))
|
||||
{
|
||||
meleeRangeTargets.push_back(target);
|
||||
|
||||
}
|
||||
// and add threat to most hated
|
||||
if (counter < RAID_MODE(2, 3))
|
||||
{
|
||||
me->AddThreat(target, 500.0f);
|
||||
}
|
||||
}
|
||||
|
||||
counter = 0;
|
||||
list<Unit*, std::allocator<Unit*>>::iterator itr;
|
||||
for (itr = meleeRangeTargets.begin(); itr != meleeRangeTargets.end(); ++itr, ++counter)
|
||||
{
|
||||
// if there is only one target available
|
||||
if (meleeRangeTargets.size() == 1)
|
||||
{
|
||||
finalTarget = (*itr);
|
||||
}
|
||||
else if (counter > 0) // skip first target
|
||||
{
|
||||
if (!finalTarget || (*itr)->GetHealth() > finalTarget->GetHealth())
|
||||
{
|
||||
finalTarget = (*itr);
|
||||
|
||||
}
|
||||
// third loop
|
||||
if (counter >= 2)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (finalTarget)
|
||||
{
|
||||
me->CastSpell(finalTarget, RAID_MODE(SPELL_HATEFUL_STRIKE_10, SPELL_HATEFUL_STRIKE_25), false);
|
||||
|
||||
}
|
||||
events.RepeatEvent(1000);
|
||||
break;
|
||||
}
|
||||
case EVENT_SPELL_BERSERK:
|
||||
case EVENT_BERSERK:
|
||||
Talk(EMOTE_BERSERK);
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
events.ScheduleEvent(EVENT_SPELL_SLIME_BOLT, 2000);
|
||||
|
||||
events.ScheduleEvent(EVENT_SLIME_BOLT, 3000);
|
||||
break;
|
||||
case EVENT_SPELL_SLIME_BOLT:
|
||||
case EVENT_SLIME_BOLT:
|
||||
me->CastSpell(me, SPELL_SLIME_BOLT, false);
|
||||
events.RepeatEvent(3000);
|
||||
break;
|
||||
@@ -168,13 +171,11 @@ public:
|
||||
{
|
||||
Talk(EMOTE_ENRAGE);
|
||||
me->CastSpell(me, SPELL_FRENZY, true);
|
||||
|
||||
break;
|
||||
}
|
||||
events.RepeatEvent(1000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -8,40 +8,34 @@
|
||||
|
||||
enum Says
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_TAUNTED = 2,
|
||||
SAY_DEATH = 3,
|
||||
SAY_SHOUT = 4
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_TAUNTED = 2,
|
||||
SAY_DEATH = 3
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_UNBALANCING_STRIKE = 26613,
|
||||
SPELL_DISRUPTING_SHOUT_10 = 29107,
|
||||
SPELL_DISRUPTING_SHOUT_25 = 55543,
|
||||
SPELL_DISRUPTING_SHOUT_10 = 55543,
|
||||
SPELL_DISRUPTING_SHOUT_25 = 29107,
|
||||
SPELL_JAGGED_KNIFE = 55550,
|
||||
SPELL_HOPELESS = 29125,
|
||||
|
||||
SPELL_BONE_BARRIER = 29061,
|
||||
SPELL_BLOOD_STRIKE = 61696,
|
||||
SPELL_TAUNT = 29060
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_UNBALANCING_STRIKE = 1,
|
||||
EVENT_SPELL_DISRUPTING_SHOUT = 2,
|
||||
EVENT_SPELL_JAGGED_KNIFE = 3,
|
||||
EVENT_PLAY_COMMAND = 4,
|
||||
|
||||
EVENT_MINION_BLOOD_STRIKE = 10,
|
||||
EVENT_MINION_BONE_BARRIER = 11,
|
||||
EVENT_UNBALANCING_STRIKE = 1,
|
||||
EVENT_DISRUPTING_SHOUT = 2,
|
||||
EVENT_JAGGED_KNIFE = 3
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_DEATH_KNIGHT_UNDERSTUDY = 16803,
|
||||
NPC_RAZUVIOUS = 16061,
|
||||
NPC_RAZUVIOUS = 16061
|
||||
};
|
||||
|
||||
class boss_razuvious : public CreatureScript
|
||||
@@ -67,16 +61,19 @@ public:
|
||||
|
||||
void SpawnHelpers()
|
||||
{
|
||||
me->SummonCreature(NPC_DEATH_KNIGHT_UNDERSTUDY, 2782.45f, -3088.03f, 267.685f, 0.75f);
|
||||
me->SummonCreature(NPC_DEATH_KNIGHT_UNDERSTUDY, 2778.56f, -3113.74f, 267.685f, 5.28f);
|
||||
me->SummonCreature(NPC_DEATH_KNIGHT_UNDERSTUDY, 2762.23f, -3085.07f, 267.685f, 1.95f);
|
||||
me->SummonCreature(NPC_DEATH_KNIGHT_UNDERSTUDY, 2758.24f, -3110.97f, 267.685f, 3.94f);
|
||||
if (Is25ManRaid())
|
||||
{
|
||||
me->SummonCreature(NPC_DEATH_KNIGHT_UNDERSTUDY, 2762.23f, -3085.07f, 267.685f, 1.95f);
|
||||
me->SummonCreature(NPC_DEATH_KNIGHT_UNDERSTUDY, 2758.24f, -3110.97f, 267.685f, 3.94f);
|
||||
me->SummonCreature(NPC_DEATH_KNIGHT_UNDERSTUDY, 2782.45f, -3088.03f, 267.685f, 0.75f);
|
||||
me->SummonCreature(NPC_DEATH_KNIGHT_UNDERSTUDY, 2778.56f, -3113.74f, 267.685f, 5.28f);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) override { summons.Summon(cr); }
|
||||
void JustSummoned(Creature* cr) override
|
||||
{
|
||||
summons.Summon(cr);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
@@ -88,40 +85,50 @@ public:
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
if (roll_chance_i(30))
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
// Damage done by the controlled Death Knight understudies should also count toward damage done by players
|
||||
if(who && who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_DEATH_KNIGHT_UNDERSTUDY)
|
||||
{
|
||||
me->LowerPlayerDamageReq(damage);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
me->CastSpell(me, SPELL_HOPELESS, true);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, SpellInfo const* spell) override
|
||||
{
|
||||
if (spell->Id == SPELL_TAUNT)
|
||||
{
|
||||
Talk(SAY_TAUNTED, caster);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who) override
|
||||
{
|
||||
BossAI::EnterCombat(who);
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_UNBALANCING_STRIKE, 30000);
|
||||
events.ScheduleEvent(EVENT_SPELL_DISRUPTING_SHOUT, 25000);
|
||||
events.ScheduleEvent(EVENT_SPELL_JAGGED_KNIFE, 15000);
|
||||
events.ScheduleEvent(EVENT_PLAY_COMMAND, 40000);
|
||||
|
||||
events.ScheduleEvent(EVENT_UNBALANCING_STRIKE, 20000);
|
||||
events.ScheduleEvent(EVENT_DISRUPTING_SHOUT, 15000);
|
||||
events.ScheduleEvent(EVENT_JAGGED_KNIFE, 10000);
|
||||
summons.DoZoneInCombat();
|
||||
}
|
||||
|
||||
@@ -136,27 +143,22 @@ public:
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_UNBALANCING_STRIKE:
|
||||
case EVENT_UNBALANCING_STRIKE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_UNBALANCING_STRIKE, false);
|
||||
events.RepeatEvent(30000);
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
case EVENT_SPELL_DISRUPTING_SHOUT:
|
||||
Talk(SAY_SHOUT);
|
||||
case EVENT_DISRUPTING_SHOUT:
|
||||
me->CastSpell(me, RAID_MODE(SPELL_DISRUPTING_SHOUT_10, SPELL_DISRUPTING_SHOUT_25), false);
|
||||
events.RepeatEvent(25000);
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
case EVENT_SPELL_JAGGED_KNIFE:
|
||||
case EVENT_JAGGED_KNIFE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f))
|
||||
{
|
||||
me->CastSpell(target, SPELL_JAGGED_KNIFE, false);
|
||||
|
||||
events.RepeatEvent(25000);
|
||||
break;
|
||||
case EVENT_PLAY_COMMAND:
|
||||
Talk(SAY_TAUNTED);
|
||||
events.RepeatEvent(40000);
|
||||
}
|
||||
events.RepeatEvent(10000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
@@ -185,11 +187,13 @@ public:
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (me->GetInstanceScript())
|
||||
me->GetInstanceScript()->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
if (me->GetInstanceScript())
|
||||
{
|
||||
me->GetInstanceScript()->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who) override
|
||||
@@ -199,33 +203,18 @@ public:
|
||||
cr->SetInCombatWithZone();
|
||||
cr->AI()->AttackStart(who);
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_MINION_BLOOD_STRIKE, 4000);
|
||||
events.ScheduleEvent(EVENT_MINION_BONE_BARRIER, 9000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING) || me->IsCharmed())
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
if (UpdateVictim())
|
||||
{
|
||||
case EVENT_MINION_BLOOD_STRIKE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_BLOOD_STRIKE, false);
|
||||
events.RepeatEvent(8000);
|
||||
break;
|
||||
case EVENT_MINION_BONE_BARRIER:
|
||||
me->CastSpell(me, SPELL_BONE_BARRIER, true);
|
||||
events.RepeatEvent(40000);
|
||||
break;
|
||||
events.Update(diff);
|
||||
if (!me->HasUnitState(UNIT_STATE_CASTING) || !me->IsCharmed())
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -36,7 +36,7 @@ enum Spells
|
||||
SPELL_FROST_EXPLOSION = 28524,
|
||||
|
||||
// Visuals
|
||||
SPELL_SAPPHIRON_DIES = 29357,
|
||||
SPELL_SAPPHIRON_DIES = 29357
|
||||
};
|
||||
|
||||
enum Misc
|
||||
@@ -44,27 +44,25 @@ enum Misc
|
||||
GO_ICE_BLOCK = 181247,
|
||||
NPC_BLIZZARD = 16474,
|
||||
|
||||
POINT_CENTER = 1,
|
||||
FAKE_POINTER = 1,
|
||||
POINT_CENTER = 1
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
//EVENT_SAPPHIRON_BIRTH = 1,
|
||||
EVENT_BERSERK = 2,
|
||||
EVENT_SPELL_CLEAVE = 3,
|
||||
EVENT_SPELL_TAIL_SWEEP = 4,
|
||||
EVENT_SPELL_LIFE_DRAIN = 5,
|
||||
EVENT_SPELL_BLIZZARD = 6,
|
||||
EVENT_FLIGHT_START = 7,
|
||||
EVENT_FLIGHT_LIFTOFF = 8,
|
||||
EVENT_FLIGHT_ICEBOLT = 9,
|
||||
EVENT_FLIGHT_BREATH = 10,
|
||||
EVENT_FLIGHT_SPELL_EXPLOSION = 11,
|
||||
EVENT_FLIGHT_START_LAND = 12,
|
||||
EVENT_LAND = 13,
|
||||
EVENT_GROUND = 14,
|
||||
EVENT_HUNDRED_CLUB = 15,
|
||||
EVENT_BERSERK = 1,
|
||||
EVENT_CLEAVE = 2,
|
||||
EVENT_TAIL_SWEEP = 3,
|
||||
EVENT_LIFE_DRAIN = 4,
|
||||
EVENT_BLIZZARD = 5,
|
||||
EVENT_FLIGHT_START = 6,
|
||||
EVENT_FLIGHT_LIFTOFF = 7,
|
||||
EVENT_FLIGHT_ICEBOLT = 8,
|
||||
EVENT_FLIGHT_BREATH = 9,
|
||||
EVENT_FLIGHT_SPELL_EXPLOSION = 10,
|
||||
EVENT_FLIGHT_START_LAND = 11,
|
||||
EVENT_LAND = 12,
|
||||
EVENT_GROUND = 13,
|
||||
EVENT_HUNDRED_CLUB = 14
|
||||
};
|
||||
|
||||
class boss_sapphiron : public CreatureScript
|
||||
@@ -107,7 +105,6 @@ public:
|
||||
EnterEvadeMode();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -115,8 +112,9 @@ public:
|
||||
{
|
||||
BossAI::Reset();
|
||||
if (me->IsVisible())
|
||||
{
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
}
|
||||
events.Reset();
|
||||
iceboltCount = 0;
|
||||
spawnTimer = 0;
|
||||
@@ -129,12 +127,14 @@ public:
|
||||
Map::PlayerList const& PlList = me->GetMap()->GetPlayers();
|
||||
if (PlList.isEmpty())
|
||||
return;
|
||||
|
||||
for (const auto& i : PlList)
|
||||
{
|
||||
if (Player* player = i.GetSource())
|
||||
{
|
||||
if (player->IsGameMaster())
|
||||
continue;
|
||||
|
||||
if (player->IsAlive() && me->GetDistance(player) < 80.0f)
|
||||
{
|
||||
me->SetInCombatWith(player);
|
||||
@@ -150,12 +150,11 @@ public:
|
||||
BossAI::EnterCombat(who);
|
||||
EnterCombatSelfFunction();
|
||||
me->CastSpell(me, RAID_MODE(SPELL_FROST_AURA_10, SPELL_FROST_AURA_25), true);
|
||||
|
||||
events.ScheduleEvent(EVENT_BERSERK, 15 * 60000);
|
||||
events.ScheduleEvent(EVENT_SPELL_CLEAVE, 5000);
|
||||
events.ScheduleEvent(EVENT_SPELL_TAIL_SWEEP, 10000);
|
||||
events.ScheduleEvent(EVENT_SPELL_LIFE_DRAIN, 17000);
|
||||
events.ScheduleEvent(EVENT_SPELL_BLIZZARD, 17000);
|
||||
events.ScheduleEvent(EVENT_BERSERK, 900000);
|
||||
events.ScheduleEvent(EVENT_CLEAVE, 5000);
|
||||
events.ScheduleEvent(EVENT_TAIL_SWEEP, 10000);
|
||||
events.ScheduleEvent(EVENT_LIFE_DRAIN, 17000);
|
||||
events.ScheduleEvent(EVENT_BLIZZARD, 17000);
|
||||
events.ScheduleEvent(EVENT_FLIGHT_START, 45000);
|
||||
events.ScheduleEvent(EVENT_HUNDRED_CLUB, 5000);
|
||||
}
|
||||
@@ -169,13 +168,17 @@ public:
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == ACTION_SAPPHIRON_BIRTH)
|
||||
{
|
||||
spawnTimer = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id) override
|
||||
{
|
||||
if (type == POINT_MOTION_TYPE && id == POINT_CENTER)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_FLIGHT_LIFTOFF, 500);
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, const SpellInfo* spellInfo) override
|
||||
@@ -199,14 +202,15 @@ public:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
@@ -240,28 +244,33 @@ public:
|
||||
Talk(EMOTE_ENRAGE);
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
return;
|
||||
case EVENT_SPELL_CLEAVE:
|
||||
case EVENT_CLEAVE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
|
||||
events.RepeatEvent(10000);
|
||||
return;
|
||||
case EVENT_SPELL_TAIL_SWEEP:
|
||||
case EVENT_TAIL_SWEEP:
|
||||
me->CastSpell(me, RAID_MODE(SPELL_TAIL_SWEEP_10, SPELL_TAIL_SWEEP_25), false);
|
||||
events.RepeatEvent(10000);
|
||||
return;
|
||||
case EVENT_SPELL_LIFE_DRAIN:
|
||||
case EVENT_LIFE_DRAIN:
|
||||
me->CastCustomSpell(RAID_MODE(SPELL_LIFE_DRAIN_10, SPELL_LIFE_DRAIN_25), SPELLVALUE_MAX_TARGETS, RAID_MODE(2, 5), me, false);
|
||||
events.RepeatEvent(24000);
|
||||
return;
|
||||
case EVENT_SPELL_BLIZZARD:
|
||||
case EVENT_BLIZZARD:
|
||||
{
|
||||
Creature* cr;
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true))
|
||||
{
|
||||
cr = me->SummonCreature(NPC_BLIZZARD, *target, TEMPSUMMON_TIMED_DESPAWN, 16000);
|
||||
}
|
||||
else
|
||||
{
|
||||
cr = me->SummonCreature(NPC_BLIZZARD, *me, TEMPSUMMON_TIMED_DESPAWN, 16000);
|
||||
|
||||
}
|
||||
if (cr)
|
||||
{
|
||||
cr->GetMotionMaster()->MoveRandom(40);
|
||||
}
|
||||
events.RepeatEvent(RAID_MODE(8000, 6500));
|
||||
return;
|
||||
}
|
||||
@@ -279,6 +288,7 @@ public:
|
||||
me->GetMotionMaster()->MovePoint(POINT_CENTER, x, y, z);
|
||||
return;
|
||||
case EVENT_FLIGHT_LIFTOFF:
|
||||
Talk(EMOTE_AIR_PHASE);
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
me->SendMeleeAttackStop(me->GetVictim());
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
|
||||
@@ -291,26 +301,37 @@ public:
|
||||
case EVENT_FLIGHT_ICEBOLT:
|
||||
{
|
||||
if (currentTarget)
|
||||
{
|
||||
if (Unit* target = ObjectAccessor::GetUnit(*me, currentTarget))
|
||||
{
|
||||
me->SummonGameObject(GO_ICE_BLOCK, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Unit*> targets;
|
||||
auto i = me->getThreatManager().getThreatList().begin();
|
||||
for (; i != me->getThreatManager().getThreatList().end(); ++i)
|
||||
{
|
||||
if ((*i)->getTarget()->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
bool inList = false;
|
||||
if (!blockList.empty())
|
||||
{
|
||||
for (std::list<uint64>::const_iterator itr = blockList.begin(); itr != blockList.end(); ++itr)
|
||||
{
|
||||
if ((*i)->getTarget()->GetGUID() == *itr)
|
||||
{
|
||||
inList = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (!inList)
|
||||
{
|
||||
targets.push_back((*i)->getTarget());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!targets.empty() && iceboltCount)
|
||||
{
|
||||
@@ -323,7 +344,9 @@ public:
|
||||
events.ScheduleEvent(EVENT_FLIGHT_ICEBOLT, (me->GetExactDist(*itr) / 13.0f)*IN_MILLISECONDS);
|
||||
}
|
||||
else
|
||||
{
|
||||
events.ScheduleEvent(EVENT_FLIGHT_BREATH, 1000);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case EVENT_FLIGHT_BREATH:
|
||||
@@ -338,10 +361,15 @@ public:
|
||||
return;
|
||||
case EVENT_FLIGHT_START_LAND:
|
||||
if (!blockList.empty())
|
||||
{
|
||||
for (std::list<uint64>::const_iterator itr = blockList.begin(); itr != blockList.end(); ++itr)
|
||||
{
|
||||
if (Unit* block = ObjectAccessor::GetUnit(*me, *itr))
|
||||
{
|
||||
block->RemoveAurasDueToSpell(SPELL_ICEBOLT_TRIGGER);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
blockList.clear();
|
||||
me->RemoveAllGameObjects();
|
||||
events.ScheduleEvent(EVENT_LAND, 1000);
|
||||
@@ -349,12 +377,11 @@ public:
|
||||
case EVENT_LAND:
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
|
||||
me->SetDisableGravity(false);
|
||||
|
||||
me->SetHover(false);
|
||||
|
||||
events.ScheduleEvent(EVENT_GROUND, 1500);
|
||||
return;
|
||||
case EVENT_GROUND:
|
||||
Talk(EMOTE_GROUND_PHASE);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->SetInCombatWithZone();
|
||||
return;
|
||||
@@ -373,7 +400,6 @@ public:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
@@ -398,12 +424,15 @@ public:
|
||||
for (auto& target : targets)
|
||||
{
|
||||
if (CAST_AI(boss_sapphiron::boss_sapphironAI, caster->ToCreature()->AI())->IsValidExplosionTarget(target))
|
||||
{
|
||||
tmplist.push_back(target);
|
||||
}
|
||||
}
|
||||
|
||||
targets.clear();
|
||||
for (auto& itr : tmplist)
|
||||
{
|
||||
targets.push_back(itr);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
|
||||
@@ -11,36 +11,37 @@
|
||||
enum Says
|
||||
{
|
||||
// Stalagg
|
||||
SAY_STAL_AGGRO = 0,
|
||||
SAY_STAL_SLAY = 1,
|
||||
SAY_STAL_DEATH = 2,
|
||||
EMOTE_STAL_DEATH = 3,
|
||||
EMOTE_STAL_REVIVE = 4,
|
||||
SAY_STAL_AGGRO = 0,
|
||||
SAY_STAL_SLAY = 1,
|
||||
SAY_STAL_DEATH = 2,
|
||||
EMOTE_STAL_DEATH = 3,
|
||||
EMOTE_STAL_REVIVE = 4,
|
||||
|
||||
// Feugen
|
||||
SAY_FEUG_AGGRO = 0,
|
||||
SAY_FEUG_SLAY = 1,
|
||||
SAY_FEUG_DEATH = 2,
|
||||
EMOTE_FEUG_DEATH = 3,
|
||||
EMOTE_FEUG_REVIVE = 4,
|
||||
SAY_FEUG_AGGRO = 0,
|
||||
SAY_FEUG_SLAY = 1,
|
||||
SAY_FEUG_DEATH = 2,
|
||||
EMOTE_FEUG_DEATH = 3,
|
||||
EMOTE_FEUG_REVIVE = 4,
|
||||
|
||||
// Thaddius
|
||||
SAY_GREET = 0,
|
||||
SAY_AGGRO = 1,
|
||||
SAY_SLAY = 2,
|
||||
SAY_ELECT = 3,
|
||||
SAY_DEATH = 4,
|
||||
EMOTE_POLARITY_SHIFTED = 6,
|
||||
SAY_GREET = 0,
|
||||
SAY_AGGRO = 1,
|
||||
SAY_SLAY = 2,
|
||||
SAY_ELECT = 3,
|
||||
SAY_DEATH = 4,
|
||||
EMOTE_POLARITY_SHIFTED = 6,
|
||||
|
||||
// Tesla Coil
|
||||
EMOTE_TESLA_LINK_BREAKS = 0,
|
||||
EMOTE_TESLA_OVERLOAD = 1
|
||||
EMOTE_TESLA_LINK_BREAKS = 0,
|
||||
EMOTE_TESLA_OVERLOAD = 1
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_MAGNETIC_PULL = 28337,
|
||||
SPELL_TESLA_SHOCK = 28099,
|
||||
SPELL_SHOCK_VISUAL = 28159,
|
||||
|
||||
// Stalagg
|
||||
SPELL_POWER_SURGE_10 = 54529,
|
||||
@@ -58,7 +59,6 @@ enum Spells
|
||||
SPELL_CHAIN_LIGHTNING_10 = 28167,
|
||||
SPELL_CHAIN_LIGHTNING_25 = 54531,
|
||||
SPELL_BERSERK = 27680,
|
||||
|
||||
SPELL_THADDIUS_VISUAL_LIGHTNING = 28136,
|
||||
SPELL_THADDIUS_SPAWN_STUN = 28160,
|
||||
|
||||
@@ -67,22 +67,22 @@ enum Spells
|
||||
SPELL_NEGATIVE_CHARGE = 28085,
|
||||
SPELL_NEGATIVE_CHARGE_STACK = 29660,
|
||||
SPELL_POSITIVE_POLARITY = 28059,
|
||||
SPELL_NEGATIVE_POLARITY = 28084,
|
||||
SPELL_NEGATIVE_POLARITY = 28084
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_MINION_SPELL_POWER_SURGE = 1,
|
||||
EVENT_MINION_SPELL_MAGNETIC_PULL = 2,
|
||||
EVENT_MINION_POWER_SURGE = 1,
|
||||
EVENT_MINION_MAGNETIC_PULL = 2,
|
||||
EVENT_MINION_CHECK_DISTANCE = 3,
|
||||
EVENT_MINION_SPELL_STATIC_FIELD = 4,
|
||||
EVENT_MINION_STATIC_FIELD = 4,
|
||||
|
||||
EVENT_THADDIUS_START = 10,
|
||||
EVENT_THADDIUS_SPELL_CHAIN_LIGHTNING = 11,
|
||||
EVENT_THADDIUS_SPELL_BERSERK = 12,
|
||||
EVENT_THADDIUS_POLARITY_SHIFT = 13,
|
||||
EVENT_THADDIUS_START_2 = 14,
|
||||
EVENT_ACTIVATE_BALL_LIGHTNING = 15
|
||||
EVENT_THADDIUS_INIT = 5,
|
||||
EVENT_THADDIUS_ENTER_COMBAT = 6,
|
||||
EVENT_THADDIUS_CHAIN_LIGHTNING = 7,
|
||||
EVENT_THADDIUS_BERSERK = 8,
|
||||
EVENT_THADDIUS_POLARITY_SHIFT = 9,
|
||||
EVENT_ALLOW_BALL_LIGHTNING = 10
|
||||
};
|
||||
|
||||
enum Misc
|
||||
@@ -90,7 +90,10 @@ enum Misc
|
||||
ACTION_MAGNETIC_PULL = 1,
|
||||
ACTION_SUMMON_DIED = 2,
|
||||
ACTION_RESTORE = 3,
|
||||
NPC_TESLA_COIL = 16218, //the coils (emotes "Tesla Coil overloads!")
|
||||
GO_TESLA_COIL_LEFT = 181478,
|
||||
GO_TESLA_COIL_RIGHT = 181477,
|
||||
NPC_TESLA_COIL = 16218,
|
||||
THADDIUS_ROOM_DOOR = 181121
|
||||
};
|
||||
|
||||
class boss_thaddius : public CreatureScript
|
||||
@@ -118,27 +121,16 @@ public:
|
||||
uint32 resetTimer{};
|
||||
bool ballLightningEnabled;
|
||||
|
||||
void StartEvent()
|
||||
{
|
||||
me->RemoveAllAuras();
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->CastSpell(me, SPELL_THADDIUS_VISUAL_LIGHTNING, true);
|
||||
events.ScheduleEvent(EVENT_THADDIUS_START_2, 1000);
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == ACTION_SUMMON_DIED)
|
||||
{
|
||||
// Hooray, we did it!
|
||||
if (summonTimer)
|
||||
{
|
||||
summonTimer = 0;
|
||||
reviveTimer = 1;
|
||||
//events.ScheduleEvent(EVENT_THADDIUS_START, 12000);
|
||||
return;
|
||||
}
|
||||
|
||||
summonTimer = 1;
|
||||
}
|
||||
}
|
||||
@@ -149,6 +141,7 @@ public:
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
summonTimer = 0;
|
||||
reviveTimer = 0;
|
||||
resetTimer = 1;
|
||||
@@ -164,6 +157,7 @@ public:
|
||||
cr->CastSpell(cr, SPELL_FEUGEN_CHAIN, false);
|
||||
cr->SetDisableGravity(true);
|
||||
cr->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
|
||||
cr->SetControlled(true, UNIT_STATE_ROOT);
|
||||
}
|
||||
if (Creature* cr = me->SummonCreature(NPC_TESLA_COIL, 3487.04f, -2911.68f, 318.75f, 0.0f))
|
||||
{
|
||||
@@ -172,6 +166,20 @@ public:
|
||||
cr->CastSpell(cr, SPELL_STALAGG_CHAIN, false);
|
||||
cr->SetDisableGravity(true);
|
||||
cr->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
|
||||
cr->SetControlled(true, UNIT_STATE_ROOT);
|
||||
}
|
||||
|
||||
if (GameObject* go = me->FindNearestGameObject(GO_TESLA_COIL_LEFT, 100.0f))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
if (GameObject* go = me->FindNearestGameObject(GO_TESLA_COIL_RIGHT, 100.0f))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
if (GameObject* go = me->FindNearestGameObject(THADDIUS_ROOM_DOOR, 200.0f))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,9 +189,10 @@ public:
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
@@ -195,9 +204,16 @@ public:
|
||||
pInstance->DoRemoveAurasDueToSpellOnPlayers(28059);
|
||||
pInstance->DoRemoveAurasDueToSpellOnPlayers(28084);
|
||||
}
|
||||
if (GameObject* go = me->FindNearestGameObject(THADDIUS_ROOM_DOOR, 200.0f))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) override { summons.Summon(cr); }
|
||||
void JustSummoned(Creature* cr) override
|
||||
{
|
||||
summons.Summon(cr);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who) override
|
||||
{
|
||||
@@ -224,16 +240,19 @@ public:
|
||||
reviveTimer += diff;
|
||||
if (reviveTimer >= 12000)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_THADDIUS_START, 1500);
|
||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
{
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, (*itr)))
|
||||
{
|
||||
if (cr->GetEntry() == NPC_TESLA_COIL)
|
||||
{
|
||||
cr->AI()->Talk(EMOTE_TESLA_OVERLOAD);
|
||||
cr->CastSpell(me, SPELL_TESLA_SHOCK, true); // till smth better is found ;( ZOMG
|
||||
Unit::Kill(cr, cr);
|
||||
cr->CastSpell(me, SPELL_SHOCK_VISUAL, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
reviveTimer = 0;
|
||||
events.ScheduleEvent(EVENT_THADDIUS_INIT, 750);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -245,8 +264,7 @@ public:
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
// Revive code!
|
||||
if (summonTimer)
|
||||
if (summonTimer) // Revive
|
||||
{
|
||||
summonTimer += diff;
|
||||
if (summonTimer >= 5000)
|
||||
@@ -258,27 +276,46 @@ public:
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_THADDIUS_START:
|
||||
StartEvent();
|
||||
case EVENT_THADDIUS_INIT:
|
||||
{
|
||||
me->RemoveAllAuras();
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
{
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, (*itr)))
|
||||
{
|
||||
if (cr->GetEntry() == NPC_TESLA_COIL)
|
||||
{
|
||||
Unit::Kill(cr, cr);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (GameObject* go = me->FindNearestGameObject(GO_TESLA_COIL_LEFT, 100.0f))
|
||||
{
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
if (GameObject* go = me->FindNearestGameObject(GO_TESLA_COIL_RIGHT, 100.0f))
|
||||
{
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
me->CastSpell(me, SPELL_THADDIUS_VISUAL_LIGHTNING, true);
|
||||
events.ScheduleEvent(EVENT_THADDIUS_ENTER_COMBAT, 1000);
|
||||
break;
|
||||
case EVENT_THADDIUS_START_2:
|
||||
|
||||
}
|
||||
case EVENT_THADDIUS_ENTER_COMBAT:
|
||||
Talk(SAY_AGGRO);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->setAttackTimer(BASE_ATTACK, 4000);
|
||||
|
||||
events.ScheduleEvent(EVENT_THADDIUS_SPELL_CHAIN_LIGHTNING, 14000);
|
||||
events.ScheduleEvent(EVENT_THADDIUS_SPELL_BERSERK, 360000);
|
||||
events.ScheduleEvent(EVENT_THADDIUS_CHAIN_LIGHTNING, 14000);
|
||||
events.ScheduleEvent(EVENT_THADDIUS_BERSERK, 360000);
|
||||
events.ScheduleEvent(EVENT_THADDIUS_POLARITY_SHIFT, 30000);
|
||||
events.ScheduleEvent(EVENT_ACTIVATE_BALL_LIGHTNING, 5000);
|
||||
events.ScheduleEvent(EVENT_ALLOW_BALL_LIGHTNING, 5000);
|
||||
return;
|
||||
case EVENT_THADDIUS_SPELL_BERSERK:
|
||||
case EVENT_THADDIUS_BERSERK:
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
|
||||
break;
|
||||
case EVENT_THADDIUS_SPELL_CHAIN_LIGHTNING:
|
||||
case EVENT_THADDIUS_CHAIN_LIGHTNING:
|
||||
me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_CHAIN_LIGHTNING_10, SPELL_CHAIN_LIGHTNING_25), false);
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
@@ -286,17 +323,23 @@ public:
|
||||
me->CastSpell(me, SPELL_POLARITY_SHIFT, false);
|
||||
events.RepeatEvent(30000);
|
||||
break;
|
||||
case EVENT_ACTIVATE_BALL_LIGHTNING:
|
||||
case EVENT_ALLOW_BALL_LIGHTNING:
|
||||
ballLightningEnabled = true;
|
||||
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->IsWithinMeleeRange(me->GetVictim()))
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
else if (ballLightningEnabled)
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
|
||||
DoCast(target, SPELL_BALL_LIGHTNING);
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO))
|
||||
{
|
||||
me->CastSpell(target, SPELL_BALL_LIGHTNING, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -332,7 +375,6 @@ public:
|
||||
pullTimer = 0;
|
||||
visualTimer = 1;
|
||||
overload = false;
|
||||
|
||||
events.Reset();
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
if (Creature* cr = me->FindNearestCreature(NPC_TESLA_COIL, 150.0f))
|
||||
@@ -352,32 +394,38 @@ public:
|
||||
void EnterCombat(Unit* pWho) override
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
if (GameObject* go = me->FindNearestGameObject(THADDIUS_ROOM_DOOR, 200.0f))
|
||||
{
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
if (Creature* cr = me->FindNearestCreature(NPC_TESLA_COIL, 150.f, true))
|
||||
{
|
||||
myCoil = cr->GetGUID();
|
||||
|
||||
}
|
||||
if (me->GetEntry() == NPC_STALAGG)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_MINION_SPELL_POWER_SURGE, 10000);
|
||||
events.ScheduleEvent(EVENT_MINION_POWER_SURGE, 10000);
|
||||
Talk(SAY_STAL_AGGRO);
|
||||
}
|
||||
else
|
||||
{
|
||||
events.ScheduleEvent(EVENT_MINION_SPELL_STATIC_FIELD, 5000);
|
||||
events.ScheduleEvent(EVENT_MINION_STATIC_FIELD, 5000);
|
||||
Talk(SAY_FEUG_AGGRO);
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_MINION_CHECK_DISTANCE, 5000);
|
||||
|
||||
// This event needs synchronisation, called for stalagg only
|
||||
if (me->GetEntry() == NPC_STALAGG)
|
||||
events.ScheduleEvent(EVENT_MINION_SPELL_MAGNETIC_PULL, 25000);
|
||||
|
||||
if (me->GetEntry() == NPC_STALAGG) // This event needs synchronisation, called for stalagg only
|
||||
{
|
||||
events.ScheduleEvent(EVENT_MINION_MAGNETIC_PULL, 20000);
|
||||
}
|
||||
if (pInstance)
|
||||
{
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, pInstance->GetData64(DATA_THADDIUS_BOSS)))
|
||||
{
|
||||
cr->AI()->AttackStart(pWho);
|
||||
cr->AddThreat(pWho, 10.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
@@ -396,7 +444,9 @@ public:
|
||||
Talk(me->GetEntry() == NPC_STALAGG ? EMOTE_STAL_REVIVE : EMOTE_FEUG_REVIVE);
|
||||
}
|
||||
else
|
||||
{
|
||||
me->SetHealth(me->GetMaxHealth());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,8 +455,12 @@ public:
|
||||
Talk(me->GetEntry() == NPC_STALAGG ? SAY_STAL_DEATH : SAY_FEUG_DEATH);
|
||||
Talk(me->GetEntry() == NPC_STALAGG ? EMOTE_STAL_DEATH : EMOTE_FEUG_DEATH);
|
||||
if (pInstance)
|
||||
{
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, pInstance->GetData64(DATA_THADDIUS_BOSS)))
|
||||
{
|
||||
cr->AI()->DoAction(ACTION_SUMMON_DIED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
@@ -415,10 +469,13 @@ public:
|
||||
return;
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
|
||||
}
|
||||
if (!urand(0, 2))
|
||||
{
|
||||
Talk(me->GetEntry() == NPC_STALAGG ? SAY_STAL_SLAY : SAY_FEUG_SLAY);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
@@ -430,15 +487,16 @@ public:
|
||||
{
|
||||
visualTimer = 0;
|
||||
if (Creature* cr = me->FindNearestCreature(NPC_TESLA_COIL, 150.0f))
|
||||
{
|
||||
cr->CastSpell(cr, me->GetEntry() == NPC_STALAGG ? SPELL_STALAGG_CHAIN : SPELL_FEUGEN_CHAIN, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
// Disable AI during pull
|
||||
if (pullTimer)
|
||||
if (pullTimer) // Disable AI during pull
|
||||
{
|
||||
pullTimer += diff;
|
||||
if (pullTimer >= 3000)
|
||||
@@ -455,17 +513,18 @@ public:
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_MINION_SPELL_POWER_SURGE:
|
||||
case EVENT_MINION_POWER_SURGE:
|
||||
me->CastSpell(me, RAID_MODE(SPELL_POWER_SURGE_10, SPELL_POWER_SURGE_25), false);
|
||||
events.RepeatEvent(19000);
|
||||
break;
|
||||
case EVENT_MINION_SPELL_STATIC_FIELD:
|
||||
case EVENT_MINION_STATIC_FIELD:
|
||||
me->CastSpell(me, RAID_MODE(SPELL_STATIC_FIELD_10, SPELL_STATIC_FIELD_25), false);
|
||||
events.RepeatEvent(3000);
|
||||
break;
|
||||
case EVENT_MINION_SPELL_MAGNETIC_PULL:
|
||||
events.RepeatEvent(25000);
|
||||
case EVENT_MINION_MAGNETIC_PULL:
|
||||
events.RepeatEvent(20000);
|
||||
if (pInstance)
|
||||
{
|
||||
if (Creature* feugen = ObjectAccessor::GetCreature(*me, pInstance->GetData64(DATA_FEUGEN_BOSS)))
|
||||
{
|
||||
if (!feugen->IsAlive() || !feugen->GetVictim() || !me->GetVictim())
|
||||
@@ -486,7 +545,7 @@ public:
|
||||
me->CastSpell(tankFeugen, SPELL_MAGNETIC_PULL, true);
|
||||
DoAction(ACTION_MAGNETIC_PULL);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case EVENT_MINION_CHECK_DISTANCE:
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, myCoil))
|
||||
@@ -514,11 +573,9 @@ public:
|
||||
cr->CastSpell(cr, me->GetEntry() == NPC_STALAGG ? SPELL_STALAGG_CHAIN : SPELL_FEUGEN_CHAIN, false);
|
||||
}
|
||||
}
|
||||
|
||||
events.RepeatEvent(5000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
@@ -537,20 +594,29 @@ public:
|
||||
{
|
||||
uint8 count = 0;
|
||||
for (auto& ihit : targets)
|
||||
{
|
||||
if (ihit->GetGUID() != GetCaster()->GetGUID())
|
||||
{
|
||||
if (Player* target = ihit->ToPlayer())
|
||||
{
|
||||
if (target->HasAura(GetTriggeringSpell()->Id))
|
||||
{
|
||||
++count;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count)
|
||||
{
|
||||
uint32 spellId = 0;
|
||||
|
||||
if (GetSpellInfo()->Id == SPELL_POSITIVE_CHARGE)
|
||||
{
|
||||
spellId = SPELL_POSITIVE_CHARGE_STACK;
|
||||
}
|
||||
else // if (GetSpellInfo()->Id == SPELL_NEGATIVE_CHARGE)
|
||||
{
|
||||
spellId = SPELL_NEGATIVE_CHARGE_STACK;
|
||||
|
||||
}
|
||||
GetCaster()->SetAuraStack(spellId, GetCaster(), count);
|
||||
}
|
||||
}
|
||||
@@ -565,9 +631,13 @@ public:
|
||||
return;
|
||||
|
||||
if (target->HasAura(GetTriggeringSpell()->Id) || target->GetTypeId() != TYPEID_PLAYER)
|
||||
{
|
||||
SetHitDamage(0);
|
||||
}
|
||||
else if (target->GetInstanceScript())
|
||||
{
|
||||
target->GetInstanceScript()->SetData(DATA_CHARGES_CROSSED, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
@@ -601,18 +671,24 @@ public:
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
if (Unit* target = GetHitUnit())
|
||||
{
|
||||
target->CastSpell(target, roll_chance_i(50) ? SPELL_POSITIVE_POLARITY : SPELL_NEGATIVE_POLARITY, true, nullptr, nullptr, caster->GetGUID());
|
||||
}
|
||||
}
|
||||
|
||||
void HandleAfterCast()
|
||||
{
|
||||
if (GetCaster())
|
||||
{
|
||||
if (Creature* caster = GetCaster()->ToCreature())
|
||||
{
|
||||
if (caster->GetEntry() == NPC_THADDIUS)
|
||||
{
|
||||
caster->AI()->Talk(SAY_ELECT);
|
||||
caster->AI()->Talk(EMOTE_POLARITY_SHIFTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
@@ -661,7 +737,9 @@ public:
|
||||
return true;
|
||||
|
||||
if (Creature* thaddius = ObjectAccessor::GetCreature(*player, instance->GetData64(DATA_THADDIUS_BOSS)))
|
||||
{
|
||||
thaddius->AI()->Talk(SAY_GREET);
|
||||
}
|
||||
instance->SetData(DATA_HAD_THADDIUS_GREET, 1);
|
||||
|
||||
return true;
|
||||
@@ -673,9 +751,7 @@ void AddSC_boss_thaddius()
|
||||
new boss_thaddius();
|
||||
new boss_thaddius_summon();
|
||||
new npc_tesla();
|
||||
|
||||
new spell_thaddius_pos_neg_charge();
|
||||
new spell_thaddius_polarity_shift();
|
||||
|
||||
new at_thaddius_entrance();
|
||||
}
|
||||
|
||||
@@ -30,8 +30,10 @@ inline uint8 GetEruptionSection(float x, float y)
|
||||
|
||||
float slope = y / x;
|
||||
for (uint32 i = 0; i < 3; ++i)
|
||||
{
|
||||
if (slope > HeiganEruptionSlope[i])
|
||||
return i;
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
@@ -68,6 +70,10 @@ public:
|
||||
_horsemanGateGUID = 0;
|
||||
_kelthuzadfloorGUID = 0;
|
||||
_kelthuzadgateGUID = 0;
|
||||
_kelthuzadportal1GUID = 0;
|
||||
_kelthuzadportal2GUID = 0;
|
||||
_kelthuzadportal3GUID = 0;
|
||||
_kelthuzadportal4GUID = 0;
|
||||
_sapphironGateGUID = 0;
|
||||
_horsemanPortalGUID = 0;
|
||||
_loathebPortalGUID = 0;
|
||||
@@ -131,6 +137,10 @@ public:
|
||||
uint64 _horsemanGateGUID;
|
||||
uint64 _kelthuzadfloorGUID;
|
||||
uint64 _kelthuzadgateGUID;
|
||||
uint64 _kelthuzadportal1GUID;
|
||||
uint64 _kelthuzadportal2GUID;
|
||||
uint64 _kelthuzadportal3GUID;
|
||||
uint64 _kelthuzadportal4GUID;
|
||||
uint64 _sapphironGateGUID;
|
||||
uint64 _horsemanPortalGUID;
|
||||
uint64 _loathebPortalGUID;
|
||||
@@ -272,57 +282,79 @@ public:
|
||||
case GO_PATCHWERK_GATE:
|
||||
_patchwerkGateGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_PATCHWERK) == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case GO_GLUTH_GATE:
|
||||
_gluthGateGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_GLUTH) == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case GO_NOTH_GATE:
|
||||
_nothGateGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_NOTH) == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case GO_HEIGAN_ENTERANCE_GATE:
|
||||
_heiganGateGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_HEIGAN) == DONE || GetBossState(BOSS_NOTH) == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case GO_HEIGAN_EXIT_GATE:
|
||||
_heiganGateExitGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_HEIGAN) == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case GO_LOATHEB_GATE:
|
||||
_loathebGateGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_LOATHEB) == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case GO_ANUB_GATE:
|
||||
_anubGateGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_ANUB) == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case GO_ANUB_NEXT_GATE:
|
||||
_anubNextGateGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_ANUB) == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case GO_FAERLINA_GATE:
|
||||
_faerlinaGateGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_FAERLINA) == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case GO_MAEXXNA_GATE:
|
||||
_maexxnaGateGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_FAERLINA) == DONE) // faerlina is correct
|
||||
if (GetBossState(BOSS_FAERLINA) == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case GO_THADDIUS_GATE:
|
||||
_thaddiusGateGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_GLUTH) == DONE) // gluth is correct
|
||||
if (GetBossState(BOSS_GLUTH) == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case GO_GOTHIK_ENTER_GATE:
|
||||
_gothikEnterGateGUID = pGo->GetGUID();
|
||||
@@ -333,12 +365,16 @@ public:
|
||||
case GO_GOTHIK_EXIT_GATE:
|
||||
_gothikExitGateGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_GOTHIK) == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case GO_HORSEMAN_GATE:
|
||||
_horsemanGateGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_GOTHIK) == DONE) // correct
|
||||
if (GetBossState(BOSS_GOTHIK) == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case GO_KELTHUZAD_FLOOR:
|
||||
_kelthuzadfloorGUID = pGo->GetGUID();
|
||||
@@ -346,52 +382,84 @@ public:
|
||||
case GO_KELTHUZAD_GATE:
|
||||
_kelthuzadgateGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_SAPPHIRON) == DONE && _speakTimer == 0)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case GO_KELTHUZAD_PORTAL_1:
|
||||
_kelthuzadportal1GUID = pGo->GetGUID();
|
||||
break;
|
||||
case GO_KELTHUZAD_PORTAL_2:
|
||||
_kelthuzadportal2GUID = pGo->GetGUID();
|
||||
break;
|
||||
case GO_KELTHUZAD_PORTAL_3:
|
||||
_kelthuzadportal3GUID = pGo->GetGUID();
|
||||
break;
|
||||
case GO_KELTHUZAD_PORTAL_4:
|
||||
_kelthuzadportal4GUID = pGo->GetGUID();
|
||||
break;
|
||||
case GO_SAPPHIRON_GATE:
|
||||
_sapphironGateGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_SAPPHIRON) == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case GO_DEATHKNIGHT_WING:
|
||||
_loathebPortalGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_LOATHEB) == DONE)
|
||||
{
|
||||
pGo->SetPhaseMask(1, true);
|
||||
}
|
||||
break;
|
||||
case GO_THADDIUS_PORTAL:
|
||||
_thaddiusPortalGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_THADDIUS) == DONE)
|
||||
{
|
||||
pGo->SetPhaseMask(1, true);
|
||||
}
|
||||
break;
|
||||
case GO_MAEXXNA_PORTAL:
|
||||
_maexxnaPortalGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_MAEXXNA) == DONE)
|
||||
{
|
||||
pGo->SetPhaseMask(1, true);
|
||||
}
|
||||
break;
|
||||
case GO_HORSEMAN_PORTAL:
|
||||
_horsemanPortalGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_HORSEMAN) == DONE)
|
||||
{
|
||||
pGo->SetPhaseMask(1, true);
|
||||
}
|
||||
break;
|
||||
case GO_DEATHKNIGHT_EYE_PORTAL:
|
||||
_deathknightEyePortalGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_HORSEMAN) == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case GO_PLAGUE_EYE_PORTAL:
|
||||
_plagueEyePortalGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_LOATHEB) == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case GO_SPIDER_EYE_PORTAL:
|
||||
_spiderEyePortalGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_MAEXXNA) == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case GO_ABOM_EYE_PORTAL:
|
||||
_abomEyePortalGUID = pGo->GetGUID();
|
||||
if (GetBossState(BOSS_THADDIUS) == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -404,10 +472,13 @@ public:
|
||||
HeiganEruption[section].erase(pGo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pGo->GetEntry() == GO_SAPPHIRON_BIRTH)
|
||||
{
|
||||
if (Creature* cr = instance->GetCreature(_sapphironGUID))
|
||||
{
|
||||
cr->AI()->DoAction(ACTION_SAPPHIRON_BIRTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/, uint32 /*miscvalue1*/) override
|
||||
@@ -484,9 +555,10 @@ public:
|
||||
{
|
||||
uint8 count = 0;
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
|
||||
{
|
||||
if (GetBossState(i) == NOT_STARTED)
|
||||
++count;
|
||||
|
||||
}
|
||||
return !count && immortalAchievement;
|
||||
}
|
||||
|
||||
@@ -550,7 +622,9 @@ public:
|
||||
{
|
||||
Creature* trash = ObjectAccessor::GetCreature(*patch, itr);
|
||||
if (trash && trash->IsAlive() && !trash->IsInCombat())
|
||||
{
|
||||
trash->AI()->AttackStart(patch->GetVictim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -566,10 +640,11 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// All horsemans are killed
|
||||
if (Creature* cr = instance->GetCreature(_blaumeuxGUID))
|
||||
{
|
||||
cr->CastSpell(cr, 59450, true); // credit
|
||||
}
|
||||
}
|
||||
|
||||
// respawn
|
||||
@@ -578,45 +653,63 @@ public:
|
||||
Creature* cr;
|
||||
_horsemanKilled = 0;
|
||||
if ((cr = instance->GetCreature(_blaumeuxGUID)))
|
||||
{
|
||||
if (!cr->IsAlive())
|
||||
{
|
||||
cr->SetPosition(cr->GetHomePosition());
|
||||
cr->Respawn();
|
||||
}
|
||||
}
|
||||
if ((cr = instance->GetCreature(_rivendareGUID)))
|
||||
{
|
||||
if (!cr->IsAlive())
|
||||
{
|
||||
cr->SetPosition(cr->GetHomePosition());
|
||||
cr->Respawn();
|
||||
}
|
||||
}
|
||||
if ((cr = instance->GetCreature(_zeliekGUID)))
|
||||
{
|
||||
if (!cr->IsAlive())
|
||||
{
|
||||
cr->SetPosition(cr->GetHomePosition());
|
||||
cr->Respawn();
|
||||
}
|
||||
}
|
||||
if ((cr = instance->GetCreature(_korthazzGUID)))
|
||||
{
|
||||
if (!cr->IsAlive())
|
||||
{
|
||||
cr->SetPosition(cr->GetHomePosition());
|
||||
cr->Respawn();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (state == IN_PROGRESS)
|
||||
{
|
||||
Creature* cr;
|
||||
if ((cr = instance->GetCreature(_blaumeuxGUID)))
|
||||
{
|
||||
cr->SetInCombatWithZone();
|
||||
}
|
||||
if ((cr = instance->GetCreature(_rivendareGUID)))
|
||||
{
|
||||
cr->SetInCombatWithZone();
|
||||
}
|
||||
if ((cr = instance->GetCreature(_zeliekGUID)))
|
||||
{
|
||||
cr->SetInCombatWithZone();
|
||||
}
|
||||
if ((cr = instance->GetCreature(_korthazzGUID)))
|
||||
{
|
||||
cr->SetInCombatWithZone();
|
||||
}
|
||||
}
|
||||
|
||||
if (state == NOT_STARTED)
|
||||
{
|
||||
_horsemanTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!InstanceScript::SetBossState(bossId, state))
|
||||
@@ -627,23 +720,33 @@ public:
|
||||
{
|
||||
case BOSS_KELTHUZAD:
|
||||
if (state == NOT_STARTED)
|
||||
{
|
||||
abominationsKilled = 0;
|
||||
}
|
||||
break;
|
||||
case BOSS_FAERLINA:
|
||||
if (state == NOT_STARTED)
|
||||
{
|
||||
faerlinaAchievement = true;
|
||||
}
|
||||
break;
|
||||
case BOSS_THADDIUS:
|
||||
if (state == NOT_STARTED)
|
||||
{
|
||||
thaddiusAchievement = true;
|
||||
}
|
||||
break;
|
||||
case BOSS_LOATHEB:
|
||||
if (state == NOT_STARTED)
|
||||
{
|
||||
loathebAchievement = true;
|
||||
}
|
||||
break;
|
||||
case BOSS_HEIGAN:
|
||||
if (state == NOT_STARTED)
|
||||
{
|
||||
heiganAchievement = true;
|
||||
}
|
||||
break;
|
||||
case BOSS_SAPPHIRON:
|
||||
if (state == DONE)
|
||||
@@ -653,7 +756,9 @@ public:
|
||||
instance->LoadGrid(3763.43f, -5115.87f);
|
||||
}
|
||||
else if (state == NOT_STARTED)
|
||||
{
|
||||
sapphironAchievement = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -668,87 +773,133 @@ public:
|
||||
{
|
||||
case BOSS_PATCHWERK:
|
||||
if (GameObject* go = instance->GetGameObject(_patchwerkGateGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case BOSS_GLUTH:
|
||||
if (GameObject* go = instance->GetGameObject(_gluthGateGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
if (GameObject* go = instance->GetGameObject(_thaddiusGateGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case BOSS_NOTH:
|
||||
if (GameObject* go = instance->GetGameObject(_nothGateGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
if (GameObject* go = instance->GetGameObject(_heiganGateGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case BOSS_HEIGAN:
|
||||
if (GameObject* go = instance->GetGameObject(_heiganGateGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
if (GameObject* go = instance->GetGameObject(_heiganGateExitGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case BOSS_LOATHEB:
|
||||
if (GameObject* go = instance->GetGameObject(_loathebGateGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
if (GameObject* go = instance->GetGameObject(_loathebPortalGUID))
|
||||
{
|
||||
go->SetPhaseMask(1, true);
|
||||
}
|
||||
if (GameObject* go = instance->GetGameObject(_plagueEyePortalGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000);
|
||||
break;
|
||||
case BOSS_ANUB:
|
||||
if (GameObject* go = instance->GetGameObject(_anubGateGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
if (GameObject* go = instance->GetGameObject(_anubNextGateGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case BOSS_FAERLINA:
|
||||
if (GameObject* go = instance->GetGameObject(_faerlinaGateGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
if (GameObject* go = instance->GetGameObject(_maexxnaGateGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case BOSS_MAEXXNA:
|
||||
if (GameObject* go = instance->GetGameObject(_maexxnaGateGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
if (GameObject* go = instance->GetGameObject(_maexxnaPortalGUID))
|
||||
{
|
||||
go->SetPhaseMask(1, true);
|
||||
}
|
||||
if (GameObject* go = instance->GetGameObject(_spiderEyePortalGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000);
|
||||
break;
|
||||
case BOSS_GOTHIK:
|
||||
if (GameObject* go = instance->GetGameObject(_gothikEnterGateGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
if (GameObject* go = instance->GetGameObject(_gothikExitGateGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
if (GameObject* go = instance->GetGameObject(_horsemanGateGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case BOSS_SAPPHIRON:
|
||||
if (GameObject* go = instance->GetGameObject(_sapphironGateGUID))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
events.ScheduleEvent(EVENT_FROSTWYRM_WATERFALL_DOOR, 5000);
|
||||
break;
|
||||
case BOSS_THADDIUS:
|
||||
if (GameObject* go = instance->GetGameObject(_thaddiusPortalGUID))
|
||||
{
|
||||
go->SetPhaseMask(1, true);
|
||||
}
|
||||
if (GameObject* go = instance->GetGameObject(_abomEyePortalGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000);
|
||||
break;
|
||||
case BOSS_HORSEMAN:
|
||||
if (GameObject* go = instance->GetGameObject(_horsemanPortalGUID))
|
||||
{
|
||||
go->SetPhaseMask(1, true);
|
||||
}
|
||||
if (GameObject* go = instance->GetGameObject(_deathknightEyePortalGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -759,9 +910,13 @@ public:
|
||||
Creature* kel = instance->GetCreature(_kelthuzadGUID);
|
||||
Creature* lich = instance->GetCreature(_lichkingGUID);
|
||||
if (kel && lich)
|
||||
{
|
||||
_speakTimer += diff;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_speakTimer > 10000 && _speakTimer < 20000)
|
||||
{
|
||||
kel->AI()->Talk(SAY_SAPP_DIALOG1);
|
||||
@@ -792,13 +947,17 @@ public:
|
||||
kel->AI()->Talk(SAY_SAPP_DIALOG6);
|
||||
_speakTimer = 0;
|
||||
if (GameObject* go = instance->GetGameObject(_kelthuzadgateGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// And They would all
|
||||
if (_horsemanTimer)
|
||||
{
|
||||
_horsemanTimer += diff;
|
||||
}
|
||||
|
||||
if (_screamTimer && GetBossState(BOSS_THADDIUS) != DONE)
|
||||
{
|
||||
@@ -808,7 +967,9 @@ public:
|
||||
_screamTimer = (2 * MINUTE + urand(0, 30)) * IN_MILLISECONDS;
|
||||
}
|
||||
else
|
||||
{
|
||||
_screamTimer -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
@@ -818,9 +979,16 @@ public:
|
||||
// Loads Kel'Thuzad's grid. We need this as he must be active in order for his texts to work.
|
||||
instance->LoadGrid(3749.67f, -5114.06f);
|
||||
if (Creature* kelthuzad = instance->GetCreature(_kelthuzadGUID))
|
||||
{
|
||||
kelthuzad->AI()->Talk(_currentWingTaunt);
|
||||
}
|
||||
++_currentWingTaunt;
|
||||
|
||||
break;
|
||||
case EVENT_FROSTWYRM_WATERFALL_DOOR:
|
||||
if (GameObject* go = instance->GetGameObject(_sapphironGateGUID))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -848,6 +1016,14 @@ public:
|
||||
return _kelthuzadfloorGUID;
|
||||
case DATA_KELTHUZAD_GATE:
|
||||
return _kelthuzadgateGUID;
|
||||
case DATA_KELTHUZAD_PORTAL_1:
|
||||
return _kelthuzadportal1GUID;
|
||||
case DATA_KELTHUZAD_PORTAL_2:
|
||||
return _kelthuzadportal2GUID;
|
||||
case DATA_KELTHUZAD_PORTAL_3:
|
||||
return _kelthuzadportal3GUID;
|
||||
case DATA_KELTHUZAD_PORTAL_4:
|
||||
return _kelthuzadportal4GUID;
|
||||
|
||||
// NPCs
|
||||
case DATA_THADDIUS_BOSS:
|
||||
@@ -896,9 +1072,13 @@ public:
|
||||
uint32 tmpState;
|
||||
loadStream >> tmpState;
|
||||
if (tmpState == IN_PROGRESS)
|
||||
{
|
||||
tmpState = NOT_STARTED;
|
||||
}
|
||||
if (i == BOSS_HORSEMAN && tmpState == DONE)
|
||||
{
|
||||
_horsemanLoadDoneState = true;
|
||||
}
|
||||
SetBossState(i, EncounterState(tmpState));
|
||||
}
|
||||
loadStream >> immortalAchievement;
|
||||
@@ -906,7 +1086,9 @@ public:
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
else
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -963,7 +1145,9 @@ public:
|
||||
acore::UnitLastSearcher<acore::AnyUnfriendlyUnitInObjectRangeCheck> searcher(me, target, u_check);
|
||||
me->VisitNearbyObject(1.5f, searcher);
|
||||
if (target)
|
||||
{
|
||||
me->CastSpell(me, SPELL_FROGGER_EXPLODE, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -51,6 +51,10 @@ enum NXData
|
||||
DATA_IMMORTAL_FAIL = 119,
|
||||
DATA_KELTHUZAD_GATE = 120,
|
||||
DATA_HAD_THADDIUS_GREET = 121,
|
||||
DATA_KELTHUZAD_PORTAL_1 = 122,
|
||||
DATA_KELTHUZAD_PORTAL_2 = 123,
|
||||
DATA_KELTHUZAD_PORTAL_3 = 124,
|
||||
DATA_KELTHUZAD_PORTAL_4 = 125
|
||||
};
|
||||
|
||||
enum NXGOs
|
||||
@@ -78,19 +82,20 @@ enum NXGOs
|
||||
GO_SAPPHIRON_BIRTH = 181356,
|
||||
GO_KELTHUZAD_FLOOR = 181444,
|
||||
GO_KELTHUZAD_GATE = 181228,
|
||||
GO_KELTHUZAD_PORTAL_1 = 181402,
|
||||
GO_KELTHUZAD_PORTAL_2 = 181403,
|
||||
GO_KELTHUZAD_PORTAL_3 = 181404,
|
||||
GO_KELTHUZAD_PORTAL_4 = 181405,
|
||||
|
||||
GO_DEATHKNIGHT_WING = 181577, //Loatheb portal
|
||||
GO_THADDIUS_PORTAL = 181576, //Thadius portal
|
||||
GO_MAEXXNA_PORTAL = 181575, //Maexxna portal
|
||||
GO_HORSEMAN_PORTAL = 181578, //Four Horseman portal
|
||||
GO_DEATHKNIGHT_WING = 181577,
|
||||
GO_THADDIUS_PORTAL = 181576,
|
||||
GO_MAEXXNA_PORTAL = 181575,
|
||||
GO_HORSEMAN_PORTAL = 181578,
|
||||
|
||||
GO_DEATHKNIGHT_EYE_PORTAL = 181210,
|
||||
GO_PLAGUE_EYE_PORTAL = 181211,
|
||||
GO_SPIDER_EYE_PORTAL = 181212,
|
||||
GO_ABOM_EYE_PORTAL = 181213,
|
||||
|
||||
GO_CONS_NOX_TESLA_STALAGG = 268049,
|
||||
GO_CONS_NOX_TESLA_FEUGEN = 268050
|
||||
GO_ABOM_EYE_PORTAL = 181213
|
||||
};
|
||||
|
||||
enum NXNPCs
|
||||
@@ -130,14 +135,11 @@ enum NXNPCs
|
||||
|
||||
enum NXMisc
|
||||
{
|
||||
// Spells
|
||||
SPELL_ERUPTION = 29371,
|
||||
SPELL_FROGGER_EXPLODE = 28433,
|
||||
|
||||
// Actions
|
||||
ACTION_SAPPHIRON_BIRTH = 1,
|
||||
|
||||
// Sounds
|
||||
// Background screams in instance if Thaddius still alive, four of them from 8873 to 8876
|
||||
SOUND_SCREAM = 8873
|
||||
};
|
||||
@@ -156,8 +158,9 @@ enum NXSays
|
||||
|
||||
enum NXEvents
|
||||
{
|
||||
EVENT_THADDIUS_SCREAMS = 0,
|
||||
EVENT_KELTHUZAD_WING_TAUNT
|
||||
EVENT_THADDIUS_SCREAMS = 0,
|
||||
EVENT_KELTHUZAD_WING_TAUNT = 1,
|
||||
EVENT_FROSTWYRM_WATERFALL_DOOR = 2
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user