mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 01:08:35 +00:00
Merge pull request #5 from Garashan/Playerbot
Split Ulduar's script files
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "boss_assembly_of_iron.h"
|
||||
#include "AchievementCriteriaScript.h"
|
||||
#include "CreatureScript.h"
|
||||
#include "Player.h"
|
||||
@@ -24,123 +25,6 @@
|
||||
#include "SpellScriptLoader.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
enum AssemblySpells
|
||||
{
|
||||
// Any boss
|
||||
SPELL_SUPERCHARGE = 61920,
|
||||
SPELL_BERSERK = 47008,
|
||||
|
||||
// Steelbreaker
|
||||
SPELL_HIGH_VOLTAGE_10 = 61890,
|
||||
SPELL_HIGH_VOLTAGE_25 = 63498,
|
||||
SPELL_FUSION_PUNCH_10 = 61903,
|
||||
SPELL_FUSION_PUNCH_25 = 63493,
|
||||
SPELL_STATIC_DISRUPTION_10 = 61911,
|
||||
SPELL_STATIC_DISRUPTION_25 = 63495,
|
||||
SPELL_OVERWHELMING_POWER_10 = 64637,
|
||||
SPELL_OVERWHELMING_POWER_25 = 61888,
|
||||
SPELL_ELECTRICAL_CHARGE = 61902,
|
||||
|
||||
// Runemaster Molgeim
|
||||
SPELL_SHIELD_OF_RUNES_BUFF = 62277,
|
||||
SPELL_SHIELD_OF_RUNES_10 = 62274,
|
||||
SPELL_SHIELD_OF_RUNES_25 = 63489,
|
||||
SPELL_RUNE_OF_POWER = 61973,
|
||||
SPELL_RUNE_OF_DEATH_10 = 62269,
|
||||
SPELL_RUNE_OF_DEATH_25 = 63490,
|
||||
SPELL_RUNE_OF_SUMMONING = 62273,
|
||||
SPELL_RUNE_OF_SUMMONING_SUMMON = 62020,
|
||||
SPELL_LIGHTNING_BLAST_10 = 62054,
|
||||
SPELL_LIGHTNING_BLAST_25 = 63491,
|
||||
CREATURE_LIGHTNING_ELEMENTAL = 32958,
|
||||
CREATURE_RUNE_OF_SUMMONING = 33051,
|
||||
SPELL_RUNE_OF_POWER_OOC_CHANNEL = 61975,
|
||||
|
||||
// Stormcaller Brundir
|
||||
SPELL_CHAIN_LIGHTNING_10 = 61879,
|
||||
SPELL_CHAIN_LIGHTNING_25 = 63479,
|
||||
SPELL_OVERLOAD_10 = 61869,
|
||||
SPELL_OVERLOAD_25 = 63481,
|
||||
SPELL_LIGHTNING_WHIRL_10 = 61915,
|
||||
SPELL_LIGHTNING_WHIRL_25 = 63483,
|
||||
SPELL_LIGHTNING_TENDRILS_10 = 61887,
|
||||
SPELL_LIGHTNING_TENDRILS_25 = 63486,
|
||||
SPELL_STORMSHIELD = 64187,
|
||||
SPELL_LIGHTNING_CHANNEL_PRE = 61942,
|
||||
};
|
||||
|
||||
#define SPELL_HIGH_VOLTAGE RAID_MODE(SPELL_HIGH_VOLTAGE_10, SPELL_HIGH_VOLTAGE_25)
|
||||
#define SPELL_FUSION_PUNCH RAID_MODE(SPELL_FUSION_PUNCH_10, SPELL_FUSION_PUNCH_25)
|
||||
#define SPELL_STATIC_DISRUPTION RAID_MODE(SPELL_STATIC_DISRUPTION_10, SPELL_STATIC_DISRUPTION_25)
|
||||
#define SPELL_OVERWHELMING_POWER RAID_MODE(SPELL_OVERWHELMING_POWER_10, SPELL_OVERWHELMING_POWER_25)
|
||||
#define SPELL_SHIELD_OF_RUNES RAID_MODE(SPELL_SHIELD_OF_RUNES_10, SPELL_SHIELD_OF_RUNES_25)
|
||||
#define SPELL_RUNE_OF_DEATH RAID_MODE(SPELL_RUNE_OF_DEATH_10, SPELL_RUNE_OF_DEATH_25)
|
||||
#define SPELL_LIGHTNING_BLAST RAID_MODE(SPELL_LIGHTNING_BLAST_10, SPELL_LIGHTNING_BLAST_25)
|
||||
#define SPELL_CHAIN_LIGHTNING RAID_MODE(SPELL_CHAIN_LIGHTNING_10, SPELL_CHAIN_LIGHTNING_25)
|
||||
#define SPELL_OVERLOAD RAID_MODE(SPELL_OVERLOAD_10, SPELL_OVERLOAD_25)
|
||||
#define SPELL_LIGHTNING_WHIRL RAID_MODE(SPELL_LIGHTNING_WHIRL_10, SPELL_LIGHTNING_WHIRL_25)
|
||||
#define SPELL_LIGHTNING_TENDRILS RAID_MODE(SPELL_LIGHTNING_TENDRILS_10, SPELL_LIGHTNING_TENDRILS_25)
|
||||
|
||||
enum eEnums
|
||||
{
|
||||
// Steelbreaker
|
||||
EVENT_FUSION_PUNCH = 1,
|
||||
EVENT_STATIC_DISRUPTION = 2,
|
||||
EVENT_OVERWHELMING_POWER = 3,
|
||||
//EVENT_CHECK_MAIN_TANK = 4,
|
||||
|
||||
// Molgeim
|
||||
EVENT_RUNE_OF_POWER = 11,
|
||||
EVENT_SHIELD_OF_RUNES = 12,
|
||||
EVENT_RUNE_OF_DEATH = 13,
|
||||
EVENT_RUNE_OF_SUMMONING = 14,
|
||||
EVENT_LIGHTNING_BLAST = 15,
|
||||
|
||||
// Brundir
|
||||
EVENT_CHAIN_LIGHTNING = 21,
|
||||
EVENT_OVERLOAD = 22,
|
||||
EVENT_LIGHTNING_WHIRL = 23,
|
||||
EVENT_LIGHTNING_TENDRILS = 24,
|
||||
EVENT_LIGHTNING_LAND = 25,
|
||||
EVENT_LAND_LAND = 26,
|
||||
EVENT_LIGHTNING_FLIGHT = 27,
|
||||
|
||||
EVENT_ENRAGE = 30
|
||||
};
|
||||
|
||||
enum AssemblyYells
|
||||
{
|
||||
SAY_STEELBREAKER_AGGRO = 0,
|
||||
SAY_STEELBREAKER_SLAY = 1,
|
||||
SAY_STEELBREAKER_POWER = 2,
|
||||
SAY_STEELBREAKER_DEATH = 3,
|
||||
SAY_STEELBREAKER_ENCOUNTER_DEFEATED = 4,
|
||||
SAY_STEELBREAKER_BERSERK = 5,
|
||||
|
||||
SAY_MOLGEIM_AGGRO = 0,
|
||||
SAY_MOLGEIM_SLAY = 1,
|
||||
SAY_MOLGEIM_RUNE_DEATH = 2,
|
||||
SAY_MOLGEIM_SUMMON = 3,
|
||||
SAY_MOLGEIM_DEATH = 4,
|
||||
SAY_MOLGEIM_ENCOUNTER_DEFEATED = 5,
|
||||
SAY_MOLGEIM_BERSERK = 6,
|
||||
|
||||
SAY_BRUNDIR_AGGRO = 0,
|
||||
SAY_BRUNDIR_SLAY = 1,
|
||||
SAY_BRUNDIR_SPECIAL = 2,
|
||||
SAY_BRUNDIR_FLIGHT = 3,
|
||||
SAY_BRUNDIR_DEATH = 4,
|
||||
SAY_BRUNDIR_ENCOUNTER_DEFEATED = 5,
|
||||
SAY_BRUNDIR_BERSERK = 6,
|
||||
EMOTE_BRUNDIR_OVERLOAD = 7
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
ACTION_ADD_CHARGE = 1,
|
||||
POINT_CHANNEL_STEELBREAKER = 1
|
||||
};
|
||||
|
||||
bool IsEncounterComplete(InstanceScript* pInstance, Creature* me)
|
||||
{
|
||||
if (!pInstance || !me)
|
||||
@@ -193,783 +77,6 @@ void RestoreAssemblyHealth(ObjectGuid guid1, ObjectGuid guid2, Creature* me)
|
||||
cr2->SetHealth(cr2->GetMaxHealth());
|
||||
}
|
||||
|
||||
class boss_steelbreaker : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_steelbreaker() : CreatureScript("boss_steelbreaker") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<boss_steelbreakerAI>(pCreature);
|
||||
}
|
||||
|
||||
struct boss_steelbreakerAI : public ScriptedAI
|
||||
{
|
||||
boss_steelbreakerAI(Creature* c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = c->GetInstanceScript();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
InstanceScript* pInstance;
|
||||
uint8 _phase;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
me->SetLootMode(0);
|
||||
RespawnAssemblyOfIron(pInstance, me);
|
||||
|
||||
_phase = 0;
|
||||
events.Reset();
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_ASSEMBLY, NOT_STARTED);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
me->setActive(false);
|
||||
me->RemoveAllAuras();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_ASSEMBLY, IN_PROGRESS);
|
||||
|
||||
me->setActive(true);
|
||||
me->SetInCombatWithZone();
|
||||
me->CastSpell(me, SPELL_HIGH_VOLTAGE, true);
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 15min);
|
||||
UpdatePhase();
|
||||
|
||||
if (!pInstance)
|
||||
return;
|
||||
|
||||
if (Creature* boss = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_STEELBREAKER + urand(0, 2))))
|
||||
{
|
||||
switch (boss->GetEntry())
|
||||
{
|
||||
case NPC_STEELBREAKER:
|
||||
boss->AI()->Talk(SAY_STEELBREAKER_AGGRO);
|
||||
break;
|
||||
case NPC_MOLGEIM:
|
||||
boss->AI()->Talk(SAY_MOLGEIM_AGGRO);
|
||||
break;
|
||||
case NPC_BRUNDIR:
|
||||
boss->AI()->Talk(SAY_BRUNDIR_AGGRO);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
if (Creature* boss = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_STEELBREAKER + i)))
|
||||
if (!boss->IsInCombat())
|
||||
boss->AI()->AttackStart(who);
|
||||
}
|
||||
|
||||
void UpdatePhase()
|
||||
{
|
||||
if (_phase >= 3)
|
||||
return;
|
||||
|
||||
++_phase;
|
||||
|
||||
switch (_phase)
|
||||
{
|
||||
case 1:
|
||||
events.RescheduleEvent(EVENT_FUSION_PUNCH, 15s);
|
||||
break;
|
||||
case 2:
|
||||
events.RescheduleEvent(EVENT_STATIC_DISRUPTION, 20s);
|
||||
break;
|
||||
case 3:
|
||||
me->ResetLootMode();
|
||||
events.RescheduleEvent(EVENT_OVERWHELMING_POWER, 8s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*Killer*/) override
|
||||
{
|
||||
if (!pInstance)
|
||||
return;
|
||||
|
||||
if (IsEncounterComplete(pInstance, me))
|
||||
{
|
||||
pInstance->SetData(TYPE_ASSEMBLY, DONE);
|
||||
me->CastSpell(me, 65195, true); // credit
|
||||
Talk(SAY_STEELBREAKER_ENCOUNTER_DEFEATED);
|
||||
}
|
||||
else
|
||||
{
|
||||
RestoreAssemblyHealth(pInstance->GetGuidData(DATA_BRUNDIR), pInstance->GetGuidData(DATA_MOLGEIM), me);
|
||||
me->CastSpell(me, SPELL_SUPERCHARGE, true);
|
||||
Talk(SAY_STEELBREAKER_DEATH);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (_phase == 3)
|
||||
me->CastSpell(me, SPELL_ELECTRICAL_CHARGE, true);
|
||||
|
||||
Talk(SAY_STEELBREAKER_SLAY);
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == ACTION_ADD_CHARGE)
|
||||
me->CastSpell(me, SPELL_ELECTRICAL_CHARGE, true);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override
|
||||
{
|
||||
if (spellInfo->Id == SPELL_SUPERCHARGE)
|
||||
UpdatePhase();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch(events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_FUSION_PUNCH:
|
||||
me->CastSpell(me->GetVictim(), SPELL_FUSION_PUNCH, false);
|
||||
events.Repeat(15s, 20s);
|
||||
break;
|
||||
case EVENT_STATIC_DISRUPTION:
|
||||
if (Unit* pTarget = SelectTarget(SelectTargetMethod::MinDistance, 0, 0, true))
|
||||
me->CastSpell(pTarget, SPELL_STATIC_DISRUPTION, false);
|
||||
|
||||
events.Repeat(20s, 40s);
|
||||
break;
|
||||
case EVENT_OVERWHELMING_POWER:
|
||||
Talk(SAY_STEELBREAKER_POWER);
|
||||
me->CastSpell(me->GetVictim(), SPELL_OVERWHELMING_POWER, true);
|
||||
events.RepeatEvent(RAID_MODE(61000, 36000));
|
||||
break;
|
||||
case EVENT_ENRAGE:
|
||||
Talk(SAY_STEELBREAKER_BERSERK);
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class CastRunesEvent : public BasicEvent
|
||||
{
|
||||
public:
|
||||
CastRunesEvent(Creature& owner) : BasicEvent(), _owner(owner) { }
|
||||
|
||||
bool Execute(uint64 /*eventTime*/, uint32 /*diff*/) override
|
||||
{
|
||||
if (!_owner.IsInCombat())
|
||||
_owner.CastSpell(&_owner, SPELL_RUNE_OF_POWER_OOC_CHANNEL, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
Creature& _owner;
|
||||
};
|
||||
|
||||
class boss_runemaster_molgeim : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_runemaster_molgeim() : CreatureScript("boss_runemaster_molgeim") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<boss_runemaster_molgeimAI>(pCreature);
|
||||
}
|
||||
|
||||
struct boss_runemaster_molgeimAI : public ScriptedAI
|
||||
{
|
||||
boss_runemaster_molgeimAI(Creature* c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
pInstance = c->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
SummonList summons;
|
||||
EventMap events;
|
||||
uint8 _phase;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
me->SetLootMode(0);
|
||||
RespawnAssemblyOfIron(pInstance, me);
|
||||
|
||||
_phase = 0;
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_ASSEMBLY, NOT_STARTED);
|
||||
|
||||
me->m_Events.AddEvent(new CastRunesEvent(*me), me->m_Events.CalculateTime(8000));
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
me->setActive(false);
|
||||
me->RemoveAllAuras();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
me->setActive(true);
|
||||
me->SetInCombatWithZone();
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 15min);
|
||||
UpdatePhase();
|
||||
|
||||
if (!pInstance)
|
||||
return;
|
||||
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
if (Creature* boss = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_STEELBREAKER + i)))
|
||||
if (!boss->IsInCombat())
|
||||
boss->AI()->AttackStart(who);
|
||||
}
|
||||
|
||||
void UpdatePhase()
|
||||
{
|
||||
if (_phase >= 3)
|
||||
return;
|
||||
|
||||
++_phase;
|
||||
|
||||
switch (_phase)
|
||||
{
|
||||
case 1:
|
||||
events.RescheduleEvent(EVENT_SHIELD_OF_RUNES, 20s);
|
||||
events.RescheduleEvent(EVENT_RUNE_OF_POWER, 30s);
|
||||
break;
|
||||
case 2:
|
||||
events.RescheduleEvent(EVENT_RUNE_OF_DEATH, 35s);
|
||||
break;
|
||||
case 3:
|
||||
me->ResetLootMode();
|
||||
events.RescheduleEvent(EVENT_RUNE_OF_SUMMONING, 20s, 30s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (!pInstance)
|
||||
return;
|
||||
|
||||
if (IsEncounterComplete(pInstance, me))
|
||||
{
|
||||
pInstance->SetData(TYPE_ASSEMBLY, DONE);
|
||||
me->CastSpell(me, 65195, true); // credit
|
||||
Talk(SAY_MOLGEIM_ENCOUNTER_DEFEATED);
|
||||
}
|
||||
else
|
||||
{
|
||||
RestoreAssemblyHealth(pInstance->GetGuidData(DATA_STEELBREAKER), pInstance->GetGuidData(DATA_BRUNDIR), me);
|
||||
me->CastSpell(me, SPELL_SUPERCHARGE, true);
|
||||
Talk(SAY_MOLGEIM_DEATH);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Talk(SAY_MOLGEIM_SLAY);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override
|
||||
{
|
||||
if (spellInfo->Id == SPELL_SUPERCHARGE)
|
||||
UpdatePhase();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch(events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_RUNE_OF_POWER:
|
||||
{
|
||||
Unit* target = DoSelectLowestHpFriendly(60);
|
||||
if (!target || !target->IsAlive())
|
||||
target = me;
|
||||
|
||||
me->CastSpell(target, SPELL_RUNE_OF_POWER, true);
|
||||
events.Repeat(1min);
|
||||
break;
|
||||
}
|
||||
case EVENT_SHIELD_OF_RUNES:
|
||||
me->CastSpell(me, SPELL_SHIELD_OF_RUNES, false);
|
||||
events.RescheduleEvent(EVENT_SHIELD_OF_RUNES, 27s, 34s);
|
||||
break;
|
||||
case EVENT_RUNE_OF_DEATH:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
me->CastSpell(target, SPELL_RUNE_OF_DEATH, true);
|
||||
|
||||
Talk(SAY_MOLGEIM_RUNE_DEATH);
|
||||
events.Repeat(30s, 40s);
|
||||
break;
|
||||
case EVENT_RUNE_OF_SUMMONING:
|
||||
Talk(SAY_MOLGEIM_SUMMON);
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
me->CastSpell(target, SPELL_RUNE_OF_SUMMONING);
|
||||
events.Repeat(30s, 45s);
|
||||
break;
|
||||
case EVENT_ENRAGE:
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
Talk(SAY_MOLGEIM_BERSERK);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_assembly_lightning : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_assembly_lightning() : CreatureScript("npc_assembly_lightning") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<npc_assembly_lightningAI>(pCreature);
|
||||
}
|
||||
|
||||
struct npc_assembly_lightningAI : public ScriptedAI
|
||||
{
|
||||
npc_assembly_lightningAI(Creature* c) : ScriptedAI(c)
|
||||
{
|
||||
_boomed = false;
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit*) override {}
|
||||
void AttackStart(Unit*) override {}
|
||||
void UpdateAI(uint32) override {}
|
||||
void EnterEvadeMode(EvadeReason /* why */) override {}
|
||||
void OnCharmed(bool /*apply*/) override {}
|
||||
|
||||
bool _boomed;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
if (Player* target = SelectTargetFromPlayerList(150))
|
||||
me->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f);
|
||||
else
|
||||
me->DespawnOrUnsummon(1);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 /*id*/) override
|
||||
{
|
||||
if (type == FOLLOW_MOTION_TYPE && !_boomed)
|
||||
{
|
||||
_boomed = true;
|
||||
me->CastSpell(me, SPELL_LIGHTNING_BLAST, true);
|
||||
me->DespawnOrUnsummon(1000);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class boss_stormcaller_brundir : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_stormcaller_brundir() : CreatureScript("boss_stormcaller_brundir") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<boss_stormcaller_brundirAI>(pCreature);
|
||||
}
|
||||
|
||||
struct boss_stormcaller_brundirAI : public ScriptedAI
|
||||
{
|
||||
boss_stormcaller_brundirAI(Creature* c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = c->GetInstanceScript();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
InstanceScript* pInstance;
|
||||
uint32 _phase;
|
||||
ObjectGuid _flyTargetGUID;
|
||||
uint32 _channelTimer;
|
||||
|
||||
bool _stunnedAchievement;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
me->SetLootMode(0);
|
||||
RespawnAssemblyOfIron(pInstance, me);
|
||||
|
||||
_channelTimer = 0;
|
||||
_phase = 0;
|
||||
_flyTargetGUID.Clear();
|
||||
_stunnedAchievement = true;
|
||||
|
||||
events.Reset();
|
||||
|
||||
me->SetDisableGravity(false);
|
||||
me->SetRegeneratingHealth(true);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_ASSEMBLY, NOT_STARTED);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
me->setActive(false);
|
||||
me->RemoveAllAuras();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
me->setActive(true);
|
||||
me->SetInCombatWithZone();
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 15min);
|
||||
UpdatePhase();
|
||||
|
||||
if (!pInstance)
|
||||
return;
|
||||
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
if (Creature* boss = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_STEELBREAKER + i)))
|
||||
if (!boss->IsInCombat())
|
||||
boss->AI()->AttackStart(who);
|
||||
}
|
||||
|
||||
void UpdatePhase()
|
||||
{
|
||||
if (_phase >= 3)
|
||||
return;
|
||||
|
||||
++_phase;
|
||||
|
||||
switch (_phase)
|
||||
{
|
||||
case 1:
|
||||
events.RescheduleEvent(EVENT_CHAIN_LIGHTNING, 9s, 17s);
|
||||
events.RescheduleEvent(EVENT_OVERLOAD, 25s, 40s);
|
||||
break;
|
||||
case 2:
|
||||
events.RescheduleEvent(EVENT_LIGHTNING_WHIRL, 20s, 40s);
|
||||
break;
|
||||
case 3:
|
||||
me->ResetLootMode();
|
||||
me->CastSpell(me, SPELL_STORMSHIELD, true);
|
||||
events.RescheduleEvent(EVENT_LIGHTNING_TENDRILS, 15s, 16s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*Killer*/) override
|
||||
{
|
||||
if (!pInstance)
|
||||
return;
|
||||
me->NearTeleportTo(me->GetPositionX(), me->GetPositionY(), 427.5, me->GetOrientation());
|
||||
if (IsEncounterComplete(pInstance, me))
|
||||
{
|
||||
pInstance->SetData(TYPE_ASSEMBLY, DONE);
|
||||
me->CastSpell(me, 65195, true); // credit
|
||||
Talk(SAY_BRUNDIR_ENCOUNTER_DEFEATED);
|
||||
}
|
||||
else
|
||||
{
|
||||
RestoreAssemblyHealth(pInstance->GetGuidData(DATA_STEELBREAKER), pInstance->GetGuidData(DATA_MOLGEIM), me);
|
||||
me->CastSpell(me, SPELL_SUPERCHARGE, true);
|
||||
Talk(SAY_BRUNDIR_DEATH);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER || urand(0, 2))
|
||||
return;
|
||||
|
||||
Talk(SAY_BRUNDIR_SLAY);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override
|
||||
{
|
||||
if (spellInfo->Id == SPELL_SUPERCHARGE)
|
||||
UpdatePhase();
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* /*target*/, SpellInfo const* spellInfo) override
|
||||
{
|
||||
if (spellInfo->Id == SPELL_CHAIN_LIGHTNING || spellInfo->Id == uint32(RAID_MODE(61916, 63482))) // Lightning Whirl triggered
|
||||
_stunnedAchievement = false;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 param) const override
|
||||
{
|
||||
if (param == DATA_BRUNDIR)
|
||||
return _stunnedAchievement;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 point) override
|
||||
{
|
||||
if (type == POINT_MOTION_TYPE && point == POINT_CHANNEL_STEELBREAKER)
|
||||
me->CastSpell(me, SPELL_LIGHTNING_CHANNEL_PRE, true);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!me->IsInCombat() && me->GetReactState() == REACT_AGGRESSIVE)
|
||||
{
|
||||
_channelTimer += diff;
|
||||
if (_channelTimer >= 10000)
|
||||
{
|
||||
_channelTimer = 0;
|
||||
float o = urand(0, 5) * M_PI / 3.0f;
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
me->GetMotionMaster()->MovePoint(POINT_CHANNEL_STEELBREAKER, 1587.18f + 10.0f * cos(o), 121.02f + 10.0f * std::sin(o), 427.3f);
|
||||
}
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_CHAIN_LIGHTNING:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
me->CastSpell(target, SPELL_CHAIN_LIGHTNING, false);
|
||||
|
||||
events.Repeat(9s, 17s);
|
||||
break;
|
||||
case EVENT_OVERLOAD:
|
||||
Talk(EMOTE_BRUNDIR_OVERLOAD);
|
||||
me->CastSpell(me, SPELL_OVERLOAD, true);
|
||||
events.RescheduleEvent(EVENT_OVERLOAD, 25s, 40s);
|
||||
break;
|
||||
case EVENT_LIGHTNING_WHIRL:
|
||||
Talk(SAY_BRUNDIR_SPECIAL);
|
||||
me->CastSpell(me, SPELL_LIGHTNING_WHIRL, true);
|
||||
events.Repeat(10s, 25s);
|
||||
break;
|
||||
case EVENT_LIGHTNING_TENDRILS:
|
||||
{
|
||||
// Reschedule old
|
||||
events.Repeat(35s);
|
||||
events.DelayEvents(18s);
|
||||
Talk(SAY_BRUNDIR_FLIGHT);
|
||||
|
||||
Unit* oldVictim = me->GetVictim();
|
||||
_flyTargetGUID = oldVictim->GetGUID();
|
||||
me->SetRegeneratingHealth(false);
|
||||
me->SetDisableGravity(true);
|
||||
me->SetHover(true);
|
||||
|
||||
me->CombatStop();
|
||||
me->StopMoving();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetGuidValue(UNIT_FIELD_TARGET, ObjectGuid::Empty);
|
||||
me->SetUnitFlag(UNIT_FLAG_STUNNED);
|
||||
|
||||
me->CastSpell(me, SPELL_LIGHTNING_TENDRILS, true);
|
||||
me->CastSpell(me, 61883, true);
|
||||
events.ScheduleEvent(EVENT_LIGHTNING_LAND, 16s);
|
||||
events.ScheduleEvent(EVENT_LIGHTNING_FLIGHT, 1s);
|
||||
break;
|
||||
}
|
||||
case EVENT_LIGHTNING_LAND:
|
||||
{
|
||||
float speed = me->GetDistance(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()) / (1000.0f * 0.001f);
|
||||
me->MonsterMoveWithSpeed(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), speed);
|
||||
events.ScheduleEvent(EVENT_LAND_LAND, 1s);
|
||||
break;
|
||||
}
|
||||
case EVENT_LAND_LAND:
|
||||
me->SetCanFly(false);
|
||||
me->SetHover(false);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->SetDisableGravity(false);
|
||||
if (Unit* flyTarget = ObjectAccessor::GetUnit(*me, _flyTargetGUID))
|
||||
{
|
||||
me->Attack(flyTarget, false);
|
||||
}
|
||||
|
||||
me->SetRegeneratingHealth(true);
|
||||
_flyTargetGUID.Clear();
|
||||
me->RemoveAura(SPELL_LIGHTNING_TENDRILS);
|
||||
me->RemoveAura(61883);
|
||||
DoResetThreatList();
|
||||
events.CancelEvent(EVENT_LIGHTNING_FLIGHT);
|
||||
break;
|
||||
case EVENT_ENRAGE:
|
||||
Talk(SAY_BRUNDIR_BERSERK);
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
break;
|
||||
case EVENT_LIGHTNING_FLIGHT:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
|
||||
{
|
||||
me->GetMotionMaster()->MovePoint(0, *target);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_LIGHTNING_FLIGHT, 6s);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_shield_of_runes : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_shield_of_runes() : SpellScriptLoader("spell_shield_of_runes") { }
|
||||
|
||||
class spell_shield_of_runes_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_shield_of_runes_AuraScript);
|
||||
|
||||
void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* owner = GetUnitOwner())
|
||||
if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL && aurEff->GetAmount() <= 0)
|
||||
owner->CastSpell(owner, SPELL_SHIELD_OF_RUNES_BUFF, false);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_shield_of_runes_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_shield_of_runes_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_assembly_meltdown : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_assembly_meltdown() : SpellScriptLoader("spell_assembly_meltdown") { }
|
||||
|
||||
class spell_assembly_meltdown_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_assembly_meltdown_SpellScript);
|
||||
|
||||
void HandleInstaKill(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
|
||||
if (Creature* Steelbreaker = ObjectAccessor::GetCreature(*GetCaster(), instance->GetGuidData(DATA_STEELBREAKER)))
|
||||
Steelbreaker->AI()->DoAction(ACTION_ADD_CHARGE);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_assembly_meltdown_SpellScript::HandleInstaKill, EFFECT_1, SPELL_EFFECT_INSTAKILL);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_assembly_meltdown_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_assembly_rune_of_summoning : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_assembly_rune_of_summoning() : SpellScriptLoader("spell_assembly_rune_of_summoning") { }
|
||||
|
||||
class spell_assembly_rune_of_summoning_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_assembly_rune_of_summoning_AuraScript);
|
||||
|
||||
void OnPeriodic(AuraEffect const* aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
if (aurEff->GetTickNumber() % 2 == 0)
|
||||
GetTarget()->CastSpell(GetTarget(), SPELL_RUNE_OF_SUMMONING_SUMMON, true, nullptr, aurEff, GetTarget()->IsSummon() ? GetTarget()->ToTempSummon()->GetSummonerGUID() : ObjectGuid::Empty);
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (TempSummon* summ = GetTarget()->ToTempSummon())
|
||||
summ->DespawnOrUnsummon(1);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_assembly_rune_of_summoning_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
OnEffectRemove += AuraEffectRemoveFn(spell_assembly_rune_of_summoning_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_assembly_rune_of_summoning_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_assembly_of_iron : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_assembly_of_iron(char const* name, uint32 entry) : AchievementCriteriaScript(name),
|
||||
_targetEntry(entry)
|
||||
{
|
||||
}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
return target && target->GetAuraCount(SPELL_SUPERCHARGE) >= 2 && (!_targetEntry || target->GetEntry() == _targetEntry);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 const _targetEntry;
|
||||
};
|
||||
|
||||
class achievement_cant_do_that_while_stunned : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_cant_do_that_while_stunned() : AchievementCriteriaScript("achievement_cant_do_that_while_stunned") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
bool allow = target && target->GetAuraCount(SPELL_SUPERCHARGE) >= 2;
|
||||
if (!allow)
|
||||
return false;
|
||||
|
||||
if (InstanceScript* instance = target->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(DATA_BRUNDIR)))
|
||||
return cr->AI()->GetData(DATA_BRUNDIR);
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_assembly_of_iron()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,908 @@
|
||||
#ifndef BOSS_ASSEMBLY_OF_IRON_H_
|
||||
#define BOSS_ASSEMBLY_OF_IRON_H_
|
||||
|
||||
#include "AchievementCriteriaScript.h"
|
||||
#include "CreatureScript.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellScriptLoader.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
enum AssemblySpells
|
||||
{
|
||||
// Any boss
|
||||
SPELL_SUPERCHARGE = 61920,
|
||||
SPELL_BERSERK = 47008,
|
||||
|
||||
// Steelbreaker
|
||||
SPELL_HIGH_VOLTAGE_10 = 61890,
|
||||
SPELL_HIGH_VOLTAGE_25 = 63498,
|
||||
SPELL_FUSION_PUNCH_10 = 61903,
|
||||
SPELL_FUSION_PUNCH_25 = 63493,
|
||||
SPELL_STATIC_DISRUPTION_10 = 61911,
|
||||
SPELL_STATIC_DISRUPTION_25 = 63495,
|
||||
SPELL_OVERWHELMING_POWER_10 = 64637,
|
||||
SPELL_OVERWHELMING_POWER_25 = 61888,
|
||||
SPELL_ELECTRICAL_CHARGE = 61902,
|
||||
|
||||
// Runemaster Molgeim
|
||||
SPELL_SHIELD_OF_RUNES_BUFF = 62277,
|
||||
SPELL_SHIELD_OF_RUNES_10 = 62274,
|
||||
SPELL_SHIELD_OF_RUNES_25 = 63489,
|
||||
SPELL_RUNE_OF_POWER = 61973,
|
||||
SPELL_RUNE_OF_DEATH_10 = 62269,
|
||||
SPELL_RUNE_OF_DEATH_25 = 63490,
|
||||
SPELL_RUNE_OF_SUMMONING = 62273,
|
||||
SPELL_RUNE_OF_SUMMONING_SUMMON = 62020,
|
||||
SPELL_LIGHTNING_BLAST_10 = 62054,
|
||||
SPELL_LIGHTNING_BLAST_25 = 63491,
|
||||
CREATURE_LIGHTNING_ELEMENTAL = 32958,
|
||||
CREATURE_RUNE_OF_SUMMONING = 33051,
|
||||
SPELL_RUNE_OF_POWER_OOC_CHANNEL = 61975,
|
||||
|
||||
// Stormcaller Brundir
|
||||
SPELL_CHAIN_LIGHTNING_10 = 61879,
|
||||
SPELL_CHAIN_LIGHTNING_25 = 63479,
|
||||
SPELL_OVERLOAD_10 = 61869,
|
||||
SPELL_OVERLOAD_25 = 63481,
|
||||
SPELL_LIGHTNING_WHIRL_10 = 61915,
|
||||
SPELL_LIGHTNING_WHIRL_25 = 63483,
|
||||
SPELL_LIGHTNING_TENDRILS_10 = 61887,
|
||||
SPELL_LIGHTNING_TENDRILS_25 = 63486,
|
||||
SPELL_STORMSHIELD = 64187,
|
||||
SPELL_LIGHTNING_CHANNEL_PRE = 61942,
|
||||
};
|
||||
|
||||
#define SPELL_HIGH_VOLTAGE RAID_MODE(SPELL_HIGH_VOLTAGE_10, SPELL_HIGH_VOLTAGE_25)
|
||||
#define SPELL_FUSION_PUNCH RAID_MODE(SPELL_FUSION_PUNCH_10, SPELL_FUSION_PUNCH_25)
|
||||
#define SPELL_STATIC_DISRUPTION RAID_MODE(SPELL_STATIC_DISRUPTION_10, SPELL_STATIC_DISRUPTION_25)
|
||||
#define SPELL_OVERWHELMING_POWER RAID_MODE(SPELL_OVERWHELMING_POWER_10, SPELL_OVERWHELMING_POWER_25)
|
||||
#define SPELL_SHIELD_OF_RUNES RAID_MODE(SPELL_SHIELD_OF_RUNES_10, SPELL_SHIELD_OF_RUNES_25)
|
||||
#define SPELL_RUNE_OF_DEATH RAID_MODE(SPELL_RUNE_OF_DEATH_10, SPELL_RUNE_OF_DEATH_25)
|
||||
#define SPELL_LIGHTNING_BLAST RAID_MODE(SPELL_LIGHTNING_BLAST_10, SPELL_LIGHTNING_BLAST_25)
|
||||
#define SPELL_CHAIN_LIGHTNING RAID_MODE(SPELL_CHAIN_LIGHTNING_10, SPELL_CHAIN_LIGHTNING_25)
|
||||
#define SPELL_OVERLOAD RAID_MODE(SPELL_OVERLOAD_10, SPELL_OVERLOAD_25)
|
||||
#define SPELL_LIGHTNING_WHIRL RAID_MODE(SPELL_LIGHTNING_WHIRL_10, SPELL_LIGHTNING_WHIRL_25)
|
||||
#define SPELL_LIGHTNING_TENDRILS RAID_MODE(SPELL_LIGHTNING_TENDRILS_10, SPELL_LIGHTNING_TENDRILS_25)
|
||||
|
||||
enum eEnums
|
||||
{
|
||||
// Steelbreaker
|
||||
EVENT_FUSION_PUNCH = 1,
|
||||
EVENT_STATIC_DISRUPTION = 2,
|
||||
EVENT_OVERWHELMING_POWER = 3,
|
||||
//EVENT_CHECK_MAIN_TANK = 4,
|
||||
|
||||
// Molgeim
|
||||
EVENT_RUNE_OF_POWER = 11,
|
||||
EVENT_SHIELD_OF_RUNES = 12,
|
||||
EVENT_RUNE_OF_DEATH = 13,
|
||||
EVENT_RUNE_OF_SUMMONING = 14,
|
||||
EVENT_LIGHTNING_BLAST = 15,
|
||||
|
||||
// Brundir
|
||||
EVENT_CHAIN_LIGHTNING = 21,
|
||||
EVENT_OVERLOAD = 22,
|
||||
EVENT_LIGHTNING_WHIRL = 23,
|
||||
EVENT_LIGHTNING_TENDRILS = 24,
|
||||
EVENT_LIGHTNING_LAND = 25,
|
||||
EVENT_LAND_LAND = 26,
|
||||
EVENT_LIGHTNING_FLIGHT = 27,
|
||||
|
||||
EVENT_ENRAGE = 30
|
||||
};
|
||||
|
||||
enum AssemblyYells
|
||||
{
|
||||
SAY_STEELBREAKER_AGGRO = 0,
|
||||
SAY_STEELBREAKER_SLAY = 1,
|
||||
SAY_STEELBREAKER_POWER = 2,
|
||||
SAY_STEELBREAKER_DEATH = 3,
|
||||
SAY_STEELBREAKER_ENCOUNTER_DEFEATED = 4,
|
||||
SAY_STEELBREAKER_BERSERK = 5,
|
||||
|
||||
SAY_MOLGEIM_AGGRO = 0,
|
||||
SAY_MOLGEIM_SLAY = 1,
|
||||
SAY_MOLGEIM_RUNE_DEATH = 2,
|
||||
SAY_MOLGEIM_SUMMON = 3,
|
||||
SAY_MOLGEIM_DEATH = 4,
|
||||
SAY_MOLGEIM_ENCOUNTER_DEFEATED = 5,
|
||||
SAY_MOLGEIM_BERSERK = 6,
|
||||
|
||||
SAY_BRUNDIR_AGGRO = 0,
|
||||
SAY_BRUNDIR_SLAY = 1,
|
||||
SAY_BRUNDIR_SPECIAL = 2,
|
||||
SAY_BRUNDIR_FLIGHT = 3,
|
||||
SAY_BRUNDIR_DEATH = 4,
|
||||
SAY_BRUNDIR_ENCOUNTER_DEFEATED = 5,
|
||||
SAY_BRUNDIR_BERSERK = 6,
|
||||
EMOTE_BRUNDIR_OVERLOAD = 7
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
ACTION_ADD_CHARGE = 1,
|
||||
POINT_CHANNEL_STEELBREAKER = 1
|
||||
};
|
||||
|
||||
class boss_steelbreaker : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_steelbreaker() : CreatureScript("boss_steelbreaker") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<boss_steelbreakerAI>(pCreature);
|
||||
}
|
||||
|
||||
struct boss_steelbreakerAI : public ScriptedAI
|
||||
{
|
||||
boss_steelbreakerAI(Creature* c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = c->GetInstanceScript();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
InstanceScript* pInstance;
|
||||
uint8 _phase;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
me->SetLootMode(0);
|
||||
RespawnAssemblyOfIron(pInstance, me);
|
||||
|
||||
_phase = 0;
|
||||
events.Reset();
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_ASSEMBLY, NOT_STARTED);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
me->setActive(false);
|
||||
me->RemoveAllAuras();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_ASSEMBLY, IN_PROGRESS);
|
||||
|
||||
me->setActive(true);
|
||||
me->SetInCombatWithZone();
|
||||
me->CastSpell(me, SPELL_HIGH_VOLTAGE, true);
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 15min);
|
||||
UpdatePhase();
|
||||
|
||||
if (!pInstance)
|
||||
return;
|
||||
|
||||
if (Creature* boss = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_STEELBREAKER + urand(0, 2))))
|
||||
{
|
||||
switch (boss->GetEntry())
|
||||
{
|
||||
case NPC_STEELBREAKER:
|
||||
boss->AI()->Talk(SAY_STEELBREAKER_AGGRO);
|
||||
break;
|
||||
case NPC_MOLGEIM:
|
||||
boss->AI()->Talk(SAY_MOLGEIM_AGGRO);
|
||||
break;
|
||||
case NPC_BRUNDIR:
|
||||
boss->AI()->Talk(SAY_BRUNDIR_AGGRO);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
if (Creature* boss = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_STEELBREAKER + i)))
|
||||
if (!boss->IsInCombat())
|
||||
boss->AI()->AttackStart(who);
|
||||
}
|
||||
|
||||
void UpdatePhase()
|
||||
{
|
||||
if (_phase >= 3)
|
||||
return;
|
||||
|
||||
++_phase;
|
||||
|
||||
switch (_phase)
|
||||
{
|
||||
case 1:
|
||||
events.RescheduleEvent(EVENT_FUSION_PUNCH, 15s);
|
||||
break;
|
||||
case 2:
|
||||
events.RescheduleEvent(EVENT_STATIC_DISRUPTION, 20s);
|
||||
break;
|
||||
case 3:
|
||||
me->ResetLootMode();
|
||||
events.RescheduleEvent(EVENT_OVERWHELMING_POWER, 8s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*Killer*/) override
|
||||
{
|
||||
if (!pInstance)
|
||||
return;
|
||||
|
||||
if (IsEncounterComplete(pInstance, me))
|
||||
{
|
||||
pInstance->SetData(TYPE_ASSEMBLY, DONE);
|
||||
me->CastSpell(me, 65195, true); // credit
|
||||
Talk(SAY_STEELBREAKER_ENCOUNTER_DEFEATED);
|
||||
}
|
||||
else
|
||||
{
|
||||
RestoreAssemblyHealth(pInstance->GetGuidData(DATA_BRUNDIR), pInstance->GetGuidData(DATA_MOLGEIM), me);
|
||||
me->CastSpell(me, SPELL_SUPERCHARGE, true);
|
||||
Talk(SAY_STEELBREAKER_DEATH);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (_phase == 3)
|
||||
me->CastSpell(me, SPELL_ELECTRICAL_CHARGE, true);
|
||||
|
||||
Talk(SAY_STEELBREAKER_SLAY);
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == ACTION_ADD_CHARGE)
|
||||
me->CastSpell(me, SPELL_ELECTRICAL_CHARGE, true);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override
|
||||
{
|
||||
if (spellInfo->Id == SPELL_SUPERCHARGE)
|
||||
UpdatePhase();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch(events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_FUSION_PUNCH:
|
||||
me->CastSpell(me->GetVictim(), SPELL_FUSION_PUNCH, false);
|
||||
events.Repeat(15s, 20s);
|
||||
break;
|
||||
case EVENT_STATIC_DISRUPTION:
|
||||
if (Unit* pTarget = SelectTarget(SelectTargetMethod::MinDistance, 0, 0, true))
|
||||
me->CastSpell(pTarget, SPELL_STATIC_DISRUPTION, false);
|
||||
|
||||
events.Repeat(20s, 40s);
|
||||
break;
|
||||
case EVENT_OVERWHELMING_POWER:
|
||||
Talk(SAY_STEELBREAKER_POWER);
|
||||
me->CastSpell(me->GetVictim(), SPELL_OVERWHELMING_POWER, true);
|
||||
events.RepeatEvent(RAID_MODE(61000, 36000));
|
||||
break;
|
||||
case EVENT_ENRAGE:
|
||||
Talk(SAY_STEELBREAKER_BERSERK);
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class CastRunesEvent : public BasicEvent
|
||||
{
|
||||
public:
|
||||
CastRunesEvent(Creature& owner) : BasicEvent(), _owner(owner) { }
|
||||
|
||||
bool Execute(uint64 /*eventTime*/, uint32 /*diff*/) override
|
||||
{
|
||||
if (!_owner.IsInCombat())
|
||||
_owner.CastSpell(&_owner, SPELL_RUNE_OF_POWER_OOC_CHANNEL, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
Creature& _owner;
|
||||
};
|
||||
|
||||
class boss_runemaster_molgeim : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_runemaster_molgeim() : CreatureScript("boss_runemaster_molgeim") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<boss_runemaster_molgeimAI>(pCreature);
|
||||
}
|
||||
|
||||
struct boss_runemaster_molgeimAI : public ScriptedAI
|
||||
{
|
||||
boss_runemaster_molgeimAI(Creature* c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
pInstance = c->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
SummonList summons;
|
||||
EventMap events;
|
||||
uint8 _phase;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
me->SetLootMode(0);
|
||||
RespawnAssemblyOfIron(pInstance, me);
|
||||
|
||||
_phase = 0;
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_ASSEMBLY, NOT_STARTED);
|
||||
|
||||
me->m_Events.AddEvent(new CastRunesEvent(*me), me->m_Events.CalculateTime(8000));
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
me->setActive(false);
|
||||
me->RemoveAllAuras();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
me->setActive(true);
|
||||
me->SetInCombatWithZone();
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 15min);
|
||||
UpdatePhase();
|
||||
|
||||
if (!pInstance)
|
||||
return;
|
||||
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
if (Creature* boss = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_STEELBREAKER + i)))
|
||||
if (!boss->IsInCombat())
|
||||
boss->AI()->AttackStart(who);
|
||||
}
|
||||
|
||||
void UpdatePhase()
|
||||
{
|
||||
if (_phase >= 3)
|
||||
return;
|
||||
|
||||
++_phase;
|
||||
|
||||
switch (_phase)
|
||||
{
|
||||
case 1:
|
||||
events.RescheduleEvent(EVENT_SHIELD_OF_RUNES, 20s);
|
||||
events.RescheduleEvent(EVENT_RUNE_OF_POWER, 30s);
|
||||
break;
|
||||
case 2:
|
||||
events.RescheduleEvent(EVENT_RUNE_OF_DEATH, 35s);
|
||||
break;
|
||||
case 3:
|
||||
me->ResetLootMode();
|
||||
events.RescheduleEvent(EVENT_RUNE_OF_SUMMONING, 20s, 30s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (!pInstance)
|
||||
return;
|
||||
|
||||
if (IsEncounterComplete(pInstance, me))
|
||||
{
|
||||
pInstance->SetData(TYPE_ASSEMBLY, DONE);
|
||||
me->CastSpell(me, 65195, true); // credit
|
||||
Talk(SAY_MOLGEIM_ENCOUNTER_DEFEATED);
|
||||
}
|
||||
else
|
||||
{
|
||||
RestoreAssemblyHealth(pInstance->GetGuidData(DATA_STEELBREAKER), pInstance->GetGuidData(DATA_BRUNDIR), me);
|
||||
me->CastSpell(me, SPELL_SUPERCHARGE, true);
|
||||
Talk(SAY_MOLGEIM_DEATH);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Talk(SAY_MOLGEIM_SLAY);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override
|
||||
{
|
||||
if (spellInfo->Id == SPELL_SUPERCHARGE)
|
||||
UpdatePhase();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch(events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_RUNE_OF_POWER:
|
||||
{
|
||||
Unit* target = DoSelectLowestHpFriendly(60);
|
||||
if (!target || !target->IsAlive())
|
||||
target = me;
|
||||
|
||||
me->CastSpell(target, SPELL_RUNE_OF_POWER, true);
|
||||
events.Repeat(1min);
|
||||
break;
|
||||
}
|
||||
case EVENT_SHIELD_OF_RUNES:
|
||||
me->CastSpell(me, SPELL_SHIELD_OF_RUNES, false);
|
||||
events.RescheduleEvent(EVENT_SHIELD_OF_RUNES, 27s, 34s);
|
||||
break;
|
||||
case EVENT_RUNE_OF_DEATH:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
me->CastSpell(target, SPELL_RUNE_OF_DEATH, true);
|
||||
|
||||
Talk(SAY_MOLGEIM_RUNE_DEATH);
|
||||
events.Repeat(30s, 40s);
|
||||
break;
|
||||
case EVENT_RUNE_OF_SUMMONING:
|
||||
Talk(SAY_MOLGEIM_SUMMON);
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
me->CastSpell(target, SPELL_RUNE_OF_SUMMONING);
|
||||
events.Repeat(30s, 45s);
|
||||
break;
|
||||
case EVENT_ENRAGE:
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
Talk(SAY_MOLGEIM_BERSERK);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_assembly_lightning : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_assembly_lightning() : CreatureScript("npc_assembly_lightning") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<npc_assembly_lightningAI>(pCreature);
|
||||
}
|
||||
|
||||
struct npc_assembly_lightningAI : public ScriptedAI
|
||||
{
|
||||
npc_assembly_lightningAI(Creature* c) : ScriptedAI(c)
|
||||
{
|
||||
_boomed = false;
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit*) override {}
|
||||
void AttackStart(Unit*) override {}
|
||||
void UpdateAI(uint32) override {}
|
||||
void EnterEvadeMode(EvadeReason /* why */) override {}
|
||||
void OnCharmed(bool /*apply*/) override {}
|
||||
|
||||
bool _boomed;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
if (Player* target = SelectTargetFromPlayerList(150))
|
||||
me->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f);
|
||||
else
|
||||
me->DespawnOrUnsummon(1);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 /*id*/) override
|
||||
{
|
||||
if (type == FOLLOW_MOTION_TYPE && !_boomed)
|
||||
{
|
||||
_boomed = true;
|
||||
me->CastSpell(me, SPELL_LIGHTNING_BLAST, true);
|
||||
me->DespawnOrUnsummon(1000);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class boss_stormcaller_brundir : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_stormcaller_brundir() : CreatureScript("boss_stormcaller_brundir") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<boss_stormcaller_brundirAI>(pCreature);
|
||||
}
|
||||
|
||||
struct boss_stormcaller_brundirAI : public ScriptedAI
|
||||
{
|
||||
boss_stormcaller_brundirAI(Creature* c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = c->GetInstanceScript();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
InstanceScript* pInstance;
|
||||
uint32 _phase;
|
||||
ObjectGuid _flyTargetGUID;
|
||||
uint32 _channelTimer;
|
||||
|
||||
bool _stunnedAchievement;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
me->SetLootMode(0);
|
||||
RespawnAssemblyOfIron(pInstance, me);
|
||||
|
||||
_channelTimer = 0;
|
||||
_phase = 0;
|
||||
_flyTargetGUID.Clear();
|
||||
_stunnedAchievement = true;
|
||||
|
||||
events.Reset();
|
||||
|
||||
me->SetDisableGravity(false);
|
||||
me->SetRegeneratingHealth(true);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_ASSEMBLY, NOT_STARTED);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
me->setActive(false);
|
||||
me->RemoveAllAuras();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
me->setActive(true);
|
||||
me->SetInCombatWithZone();
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 15min);
|
||||
UpdatePhase();
|
||||
|
||||
if (!pInstance)
|
||||
return;
|
||||
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
if (Creature* boss = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_STEELBREAKER + i)))
|
||||
if (!boss->IsInCombat())
|
||||
boss->AI()->AttackStart(who);
|
||||
}
|
||||
|
||||
void UpdatePhase()
|
||||
{
|
||||
if (_phase >= 3)
|
||||
return;
|
||||
|
||||
++_phase;
|
||||
|
||||
switch (_phase)
|
||||
{
|
||||
case 1:
|
||||
events.RescheduleEvent(EVENT_CHAIN_LIGHTNING, 9s, 17s);
|
||||
events.RescheduleEvent(EVENT_OVERLOAD, 25s, 40s);
|
||||
break;
|
||||
case 2:
|
||||
events.RescheduleEvent(EVENT_LIGHTNING_WHIRL, 20s, 40s);
|
||||
break;
|
||||
case 3:
|
||||
me->ResetLootMode();
|
||||
me->CastSpell(me, SPELL_STORMSHIELD, true);
|
||||
events.RescheduleEvent(EVENT_LIGHTNING_TENDRILS, 15s, 16s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*Killer*/) override
|
||||
{
|
||||
if (!pInstance)
|
||||
return;
|
||||
me->NearTeleportTo(me->GetPositionX(), me->GetPositionY(), 427.5, me->GetOrientation());
|
||||
if (IsEncounterComplete(pInstance, me))
|
||||
{
|
||||
pInstance->SetData(TYPE_ASSEMBLY, DONE);
|
||||
me->CastSpell(me, 65195, true); // credit
|
||||
Talk(SAY_BRUNDIR_ENCOUNTER_DEFEATED);
|
||||
}
|
||||
else
|
||||
{
|
||||
RestoreAssemblyHealth(pInstance->GetGuidData(DATA_STEELBREAKER), pInstance->GetGuidData(DATA_MOLGEIM), me);
|
||||
me->CastSpell(me, SPELL_SUPERCHARGE, true);
|
||||
Talk(SAY_BRUNDIR_DEATH);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER || urand(0, 2))
|
||||
return;
|
||||
|
||||
Talk(SAY_BRUNDIR_SLAY);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override
|
||||
{
|
||||
if (spellInfo->Id == SPELL_SUPERCHARGE)
|
||||
UpdatePhase();
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* /*target*/, SpellInfo const* spellInfo) override
|
||||
{
|
||||
if (spellInfo->Id == SPELL_CHAIN_LIGHTNING || spellInfo->Id == uint32(RAID_MODE(61916, 63482))) // Lightning Whirl triggered
|
||||
_stunnedAchievement = false;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 param) const override
|
||||
{
|
||||
if (param == DATA_BRUNDIR)
|
||||
return _stunnedAchievement;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 point) override
|
||||
{
|
||||
if (type == POINT_MOTION_TYPE && point == POINT_CHANNEL_STEELBREAKER)
|
||||
me->CastSpell(me, SPELL_LIGHTNING_CHANNEL_PRE, true);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!me->IsInCombat() && me->GetReactState() == REACT_AGGRESSIVE)
|
||||
{
|
||||
_channelTimer += diff;
|
||||
if (_channelTimer >= 10000)
|
||||
{
|
||||
_channelTimer = 0;
|
||||
float o = urand(0, 5) * M_PI / 3.0f;
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
me->GetMotionMaster()->MovePoint(POINT_CHANNEL_STEELBREAKER, 1587.18f + 10.0f * cos(o), 121.02f + 10.0f * std::sin(o), 427.3f);
|
||||
}
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_CHAIN_LIGHTNING:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
me->CastSpell(target, SPELL_CHAIN_LIGHTNING, false);
|
||||
|
||||
events.Repeat(9s, 17s);
|
||||
break;
|
||||
case EVENT_OVERLOAD:
|
||||
Talk(EMOTE_BRUNDIR_OVERLOAD);
|
||||
me->CastSpell(me, SPELL_OVERLOAD, true);
|
||||
events.RescheduleEvent(EVENT_OVERLOAD, 25s, 40s);
|
||||
break;
|
||||
case EVENT_LIGHTNING_WHIRL:
|
||||
Talk(SAY_BRUNDIR_SPECIAL);
|
||||
me->CastSpell(me, SPELL_LIGHTNING_WHIRL, true);
|
||||
events.Repeat(10s, 25s);
|
||||
break;
|
||||
case EVENT_LIGHTNING_TENDRILS:
|
||||
{
|
||||
// Reschedule old
|
||||
events.Repeat(35s);
|
||||
events.DelayEvents(18s);
|
||||
Talk(SAY_BRUNDIR_FLIGHT);
|
||||
|
||||
Unit* oldVictim = me->GetVictim();
|
||||
_flyTargetGUID = oldVictim->GetGUID();
|
||||
me->SetRegeneratingHealth(false);
|
||||
me->SetDisableGravity(true);
|
||||
me->SetHover(true);
|
||||
|
||||
me->CombatStop();
|
||||
me->StopMoving();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetGuidValue(UNIT_FIELD_TARGET, ObjectGuid::Empty);
|
||||
me->SetUnitFlag(UNIT_FLAG_STUNNED);
|
||||
|
||||
me->CastSpell(me, SPELL_LIGHTNING_TENDRILS, true);
|
||||
me->CastSpell(me, 61883, true);
|
||||
events.ScheduleEvent(EVENT_LIGHTNING_LAND, 16s);
|
||||
events.ScheduleEvent(EVENT_LIGHTNING_FLIGHT, 1s);
|
||||
break;
|
||||
}
|
||||
case EVENT_LIGHTNING_LAND:
|
||||
{
|
||||
float speed = me->GetDistance(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()) / (1000.0f * 0.001f);
|
||||
me->MonsterMoveWithSpeed(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), speed);
|
||||
events.ScheduleEvent(EVENT_LAND_LAND, 1s);
|
||||
break;
|
||||
}
|
||||
case EVENT_LAND_LAND:
|
||||
me->SetCanFly(false);
|
||||
me->SetHover(false);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->SetDisableGravity(false);
|
||||
if (Unit* flyTarget = ObjectAccessor::GetUnit(*me, _flyTargetGUID))
|
||||
{
|
||||
me->Attack(flyTarget, false);
|
||||
}
|
||||
|
||||
me->SetRegeneratingHealth(true);
|
||||
_flyTargetGUID.Clear();
|
||||
me->RemoveAura(SPELL_LIGHTNING_TENDRILS);
|
||||
me->RemoveAura(61883);
|
||||
DoResetThreatList();
|
||||
events.CancelEvent(EVENT_LIGHTNING_FLIGHT);
|
||||
break;
|
||||
case EVENT_ENRAGE:
|
||||
Talk(SAY_BRUNDIR_BERSERK);
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
break;
|
||||
case EVENT_LIGHTNING_FLIGHT:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
|
||||
{
|
||||
me->GetMotionMaster()->MovePoint(0, *target);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_LIGHTNING_FLIGHT, 6s);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_shield_of_runes : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_shield_of_runes() : SpellScriptLoader("spell_shield_of_runes") { }
|
||||
|
||||
class spell_shield_of_runes_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_shield_of_runes_AuraScript);
|
||||
|
||||
void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* owner = GetUnitOwner())
|
||||
if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL && aurEff->GetAmount() <= 0)
|
||||
owner->CastSpell(owner, SPELL_SHIELD_OF_RUNES_BUFF, false);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_shield_of_runes_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_shield_of_runes_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_assembly_meltdown : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_assembly_meltdown() : SpellScriptLoader("spell_assembly_meltdown") { }
|
||||
|
||||
class spell_assembly_meltdown_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_assembly_meltdown_SpellScript);
|
||||
|
||||
void HandleInstaKill(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
|
||||
if (Creature* Steelbreaker = ObjectAccessor::GetCreature(*GetCaster(), instance->GetGuidData(DATA_STEELBREAKER)))
|
||||
Steelbreaker->AI()->DoAction(ACTION_ADD_CHARGE);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_assembly_meltdown_SpellScript::HandleInstaKill, EFFECT_1, SPELL_EFFECT_INSTAKILL);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_assembly_meltdown_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_assembly_rune_of_summoning : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_assembly_rune_of_summoning() : SpellScriptLoader("spell_assembly_rune_of_summoning") { }
|
||||
|
||||
class spell_assembly_rune_of_summoning_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_assembly_rune_of_summoning_AuraScript);
|
||||
|
||||
void OnPeriodic(AuraEffect const* aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
if (aurEff->GetTickNumber() % 2 == 0)
|
||||
GetTarget()->CastSpell(GetTarget(), SPELL_RUNE_OF_SUMMONING_SUMMON, true, nullptr, aurEff, GetTarget()->IsSummon() ? GetTarget()->ToTempSummon()->GetSummonerGUID() : ObjectGuid::Empty);
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (TempSummon* summ = GetTarget()->ToTempSummon())
|
||||
summ->DespawnOrUnsummon(1);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_assembly_rune_of_summoning_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
OnEffectRemove += AuraEffectRemoveFn(spell_assembly_rune_of_summoning_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_assembly_rune_of_summoning_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_assembly_of_iron : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_assembly_of_iron(char const* name, uint32 entry) : AchievementCriteriaScript(name),
|
||||
_targetEntry(entry)
|
||||
{
|
||||
}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
return target && target->GetAuraCount(SPELL_SUPERCHARGE) >= 2 && (!_targetEntry || target->GetEntry() == _targetEntry);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 const _targetEntry;
|
||||
};
|
||||
|
||||
class achievement_cant_do_that_while_stunned : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_cant_do_that_while_stunned() : AchievementCriteriaScript("achievement_cant_do_that_while_stunned") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
bool allow = target && target->GetAuraCount(SPELL_SUPERCHARGE) >= 2;
|
||||
if (!allow)
|
||||
return false;
|
||||
|
||||
if (InstanceScript* instance = target->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(DATA_BRUNDIR)))
|
||||
return cr->AI()->GetData(DATA_BRUNDIR);
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -15,6 +15,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "boss_auriaya.h"
|
||||
#include "AchievementCriteriaScript.h"
|
||||
#include "CreatureScript.h"
|
||||
#include "Player.h"
|
||||
@@ -24,472 +25,6 @@
|
||||
#include "SpellScriptLoader.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
enum AuriayaSpells
|
||||
{
|
||||
// BASIC
|
||||
SPELL_TERRIFYING_SCREECH = 64386,
|
||||
SPELL_SENTINEL_BLAST_10 = 64389,
|
||||
SPELL_SENTINEL_BLAST_25 = 64678,
|
||||
SPELL_SONIC_SCREECH_10 = 64422,
|
||||
SPELL_SONIC_SCREECH_25 = 64688,
|
||||
SPELL_GUARDIAN_SWARM = 64396,
|
||||
SPELL_ENRAGE = 47008,
|
||||
SPELL_ACTIVATE_FERAL_DEFENDER = 64449,
|
||||
|
||||
// Sanctum Sentry
|
||||
SPELL_SAVAGE_POUNCE_10 = 64666,
|
||||
SPELL_SAVAGE_POUNCE_25 = 64374,
|
||||
SPELL_RIP_FLESH_10 = 64375,
|
||||
SPELL_RIP_FLESH_25 = 64667,
|
||||
SPELL_STRENGTH_OF_THE_PACK = 64369,
|
||||
|
||||
// Feral Defender
|
||||
SPELL_FERAL_ESSENCE = 64455,
|
||||
SPELL_FERAL_POUNCE_10 = 64478,
|
||||
SPELL_FERAL_POUNCE_25 = 64669,
|
||||
SPELL_FERAL_RUSH_10 = 64496,
|
||||
SPELL_FERAL_RUSH_25 = 64674,
|
||||
//SPELL_SEEPING_FERAL_ESSENCE_SUMMON = 64457,
|
||||
SPELL_SEEPING_FERAL_ESSENCE_10 = 64458,
|
||||
SPELL_SEEPING_FERAL_ESSENCE_25 = 64676,
|
||||
};
|
||||
|
||||
#define SPELL_SONIC_SCREECH RAID_MODE(SPELL_SONIC_SCREECH_10, SPELL_SONIC_SCREECH_25)
|
||||
#define SPELL_SENTINEL_BLAST RAID_MODE(SPELL_SENTINEL_BLAST_10, SPELL_SENTINEL_BLAST_25)
|
||||
#define SPELL_SAVAGE_POUNCE RAID_MODE(SPELL_SAVAGE_POUNCE_10, SPELL_SAVAGE_POUNCE_25)
|
||||
#define SPELL_RIP_FLESH RAID_MODE(SPELL_RIP_FLESH_10, SPELL_RIP_FLESH_25)
|
||||
#define SPELL_FERAL_POUNCE RAID_MODE(SPELL_FERAL_POUNCE_10, SPELL_FERAL_POUNCE_25)
|
||||
#define SPELL_FERAL_RUSH RAID_MODE(SPELL_FERAL_RUSH_10, SPELL_FERAL_RUSH_25)
|
||||
//#define SPELL_SEEPING_FERAL_ESSENCE RAID_MODE(SPELL_SEEPING_FERAL_ESSENCE_10, SPELL_SEEPING_FERAL_ESSENCE_25)
|
||||
|
||||
enum AuriayaNPC
|
||||
{
|
||||
NPC_FERAL_DEFENDER = 34035,
|
||||
NPC_SANCTUM_SENTRY = 34014,
|
||||
NPC_SEEPING_FERAL_ESSENCE = 34098,
|
||||
};
|
||||
|
||||
enum AuriayaEvents
|
||||
{
|
||||
EVENT_SUMMON_FERAL_DEFENDER = 1,
|
||||
EVENT_TERRIFYING_SCREECH = 2,
|
||||
EVENT_SONIC_SCREECH = 3,
|
||||
EVENT_GUARDIAN_SWARM = 4,
|
||||
EVENT_SENTINEL_BLAST = 5,
|
||||
EVENT_REMOVE_IMMUNE = 6,
|
||||
|
||||
EVENT_RESPAWN_FERAL_DEFENDER = 9,
|
||||
EVENT_ENRAGE = 10,
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_BERSERK = 2,
|
||||
EMOTE_DEATH = 3,
|
||||
EMOTE_FEAR = 4,
|
||||
EMOTE_DEFFENDER = 5,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
ACTION_FERAL_RESPAWN = 1,
|
||||
ACTION_FERAL_DEATH = 2,
|
||||
ACTION_DESPAWN_ADDS = 3,
|
||||
ACTION_FERAL_DEATH_WITH_STACK = 4,
|
||||
|
||||
DATA_CRAZY_CAT = 10,
|
||||
DATA_NINE_LIVES = 11,
|
||||
};
|
||||
|
||||
class boss_auriaya : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_auriaya() : CreatureScript("boss_auriaya") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<boss_auriayaAI>(pCreature);
|
||||
}
|
||||
|
||||
struct boss_auriayaAI : public ScriptedAI
|
||||
{
|
||||
boss_auriayaAI(Creature* pCreature) : ScriptedAI(pCreature), summons(pCreature)
|
||||
{
|
||||
m_pInstance = pCreature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* m_pInstance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
|
||||
bool _feralDied;
|
||||
bool _nineLives;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_feralDied = false;
|
||||
_nineLives = false;
|
||||
|
||||
events.Reset();
|
||||
EntryCheckPredicate pred(NPC_FERAL_DEFENDER);
|
||||
summons.DoAction(ACTION_DESPAWN_ADDS, pred);
|
||||
summons.DespawnAll();
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_AURIAYA, NOT_STARTED);
|
||||
|
||||
for (uint8 i = 0; i < RAID_MODE(2, 4); ++i)
|
||||
me->SummonCreature(NPC_SANCTUM_SENTRY, me->GetPositionX() + urand(4, 12), me->GetPositionY() + urand(4, 12), me->GetPositionZ());
|
||||
|
||||
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false);
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 param) const override
|
||||
{
|
||||
if (param == DATA_CRAZY_CAT)
|
||||
return !_feralDied;
|
||||
else if (param == DATA_NINE_LIVES)
|
||||
return _nineLives;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) override
|
||||
{
|
||||
if (cr->GetEntry() == NPC_SANCTUM_SENTRY)
|
||||
cr->GetMotionMaster()->MoveFollow(me, 6, rand_norm() * 2 * 3.14f);
|
||||
else
|
||||
cr->SetInCombatWithZone();
|
||||
|
||||
summons.Summon(cr);
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* cr, Unit*) override
|
||||
{
|
||||
if (cr->GetEntry() == NPC_SANCTUM_SENTRY)
|
||||
_feralDied = true;
|
||||
}
|
||||
|
||||
void JustReachedHome() override { me->setActive(false); }
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_AURIAYA, IN_PROGRESS);
|
||||
|
||||
events.ScheduleEvent(EVENT_TERRIFYING_SCREECH, 35s);
|
||||
events.ScheduleEvent(EVENT_SONIC_SCREECH, 45s);
|
||||
events.ScheduleEvent(EVENT_GUARDIAN_SWARM, 70s);
|
||||
events.ScheduleEvent(EVENT_SUMMON_FERAL_DEFENDER, 60s);
|
||||
events.ScheduleEvent(EVENT_SENTINEL_BLAST, 36s);
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 10min);
|
||||
|
||||
summons.DoZoneInCombat(NPC_SANCTUM_SENTRY);
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
me->setActive(true);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() != TYPEID_PLAYER || urand(0, 2))
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_AURIAYA, DONE);
|
||||
|
||||
EntryCheckPredicate pred(NPC_FERAL_DEFENDER);
|
||||
summons.DoAction(ACTION_DESPAWN_ADDS, pred);
|
||||
summons.DespawnAll();
|
||||
Talk(EMOTE_DEATH);
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == ACTION_FERAL_DEATH_WITH_STACK)
|
||||
events.ScheduleEvent(EVENT_RESPAWN_FERAL_DEFENDER, 25s);
|
||||
else if (param == ACTION_FERAL_DEATH)
|
||||
_nineLives = true;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SUMMON_FERAL_DEFENDER:
|
||||
Talk(EMOTE_DEFFENDER);
|
||||
me->CastSpell(me, SPELL_ACTIVATE_FERAL_DEFENDER, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true);
|
||||
events.ScheduleEvent(EVENT_REMOVE_IMMUNE, 3s);
|
||||
break;
|
||||
case EVENT_REMOVE_IMMUNE:
|
||||
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false);
|
||||
break;
|
||||
case EVENT_TERRIFYING_SCREECH:
|
||||
Talk(EMOTE_FEAR);
|
||||
me->CastSpell(me, SPELL_TERRIFYING_SCREECH, false);
|
||||
events.Repeat(35s);
|
||||
break;
|
||||
case EVENT_SONIC_SCREECH:
|
||||
me->CastSpell(me, SPELL_SONIC_SCREECH, false);
|
||||
events.Repeat(50s);
|
||||
break;
|
||||
case EVENT_GUARDIAN_SWARM:
|
||||
me->CastSpell(me->GetVictim(), SPELL_GUARDIAN_SWARM, false);
|
||||
events.Repeat(40s);
|
||||
break;
|
||||
case EVENT_SENTINEL_BLAST:
|
||||
me->CastSpell(me, SPELL_SENTINEL_BLAST, false);
|
||||
events.Repeat(35s);
|
||||
events.DelayEvents(5000, 0);
|
||||
break;
|
||||
case EVENT_RESPAWN_FERAL_DEFENDER:
|
||||
{
|
||||
EntryCheckPredicate pred(NPC_FERAL_DEFENDER);
|
||||
summons.DoAction(ACTION_FERAL_RESPAWN, pred);
|
||||
break;
|
||||
}
|
||||
case EVENT_ENRAGE:
|
||||
Talk(SAY_BERSERK);
|
||||
me->CastSpell(me, SPELL_ENRAGE, true);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_auriaya_sanctum_sentry : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_auriaya_sanctum_sentry() : CreatureScript("npc_auriaya_sanctum_sentry") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<npc_auriaya_sanctum_sentryAI>(pCreature);
|
||||
}
|
||||
|
||||
struct npc_auriaya_sanctum_sentryAI : public ScriptedAI
|
||||
{
|
||||
npc_auriaya_sanctum_sentryAI(Creature* pCreature) : ScriptedAI(pCreature) { }
|
||||
|
||||
uint32 _savagePounceTimer;
|
||||
uint32 _ripFleshTimer;
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
if (me->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_AURIAYA)))
|
||||
cr->SetInCombatWithZone();
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_savagePounceTimer = 5000;
|
||||
_ripFleshTimer = 0;
|
||||
|
||||
me->CastSpell(me, SPELL_STRENGTH_OF_THE_PACK, true);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_savagePounceTimer += diff;
|
||||
_ripFleshTimer += diff;
|
||||
|
||||
if (_savagePounceTimer >= 5000)
|
||||
{
|
||||
float dist = me->GetDistance(me->GetVictim());
|
||||
if (dist >= 8 && dist < 25 && me->IsWithinLOSInMap(me->GetVictim()))
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), SPELL_SAVAGE_POUNCE, false);
|
||||
_savagePounceTimer = 0;
|
||||
return;
|
||||
}
|
||||
_savagePounceTimer = 200;
|
||||
}
|
||||
else if (_ripFleshTimer >= 10000)
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), SPELL_RIP_FLESH, false);
|
||||
_ripFleshTimer = 0;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_auriaya_feral_defender : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_auriaya_feral_defender() : CreatureScript("npc_auriaya_feral_defender") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<npc_auriaya_feral_defenderAI>(pCreature);
|
||||
}
|
||||
|
||||
struct npc_auriaya_feral_defenderAI : public ScriptedAI
|
||||
{
|
||||
npc_auriaya_feral_defenderAI(Creature* pCreature) : ScriptedAI(pCreature), summons(pCreature) { }
|
||||
|
||||
int32 _feralRushTimer;
|
||||
int32 _feralPounceTimer;
|
||||
uint8 _feralEssenceStack;
|
||||
SummonList summons;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
summons.DespawnAll();
|
||||
_feralRushTimer = 3000;
|
||||
_feralPounceTimer = 0;
|
||||
_feralEssenceStack = 8;
|
||||
|
||||
if (Aura* aur = me->AddAura(SPELL_FERAL_ESSENCE, me))
|
||||
aur->SetStackAmount(_feralEssenceStack);
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
// inform about our death, start timer
|
||||
if (me->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_AURIAYA)))
|
||||
cr->AI()->DoAction(_feralEssenceStack ? ACTION_FERAL_DEATH_WITH_STACK : ACTION_FERAL_DEATH);
|
||||
|
||||
if (_feralEssenceStack)
|
||||
{
|
||||
if (Creature* cr = me->SummonCreature(NPC_SEEPING_FERAL_ESSENCE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.0f))
|
||||
summons.Summon(cr);
|
||||
|
||||
--_feralEssenceStack;
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == ACTION_FERAL_RESPAWN)
|
||||
{
|
||||
me->setDeathState(DeathState::JustRespawned);
|
||||
|
||||
if (Player* target = SelectTargetFromPlayerList(200))
|
||||
AttackStart(target);
|
||||
else
|
||||
{
|
||||
summons.DespawnAll();
|
||||
me->DespawnOrUnsummon(1);
|
||||
}
|
||||
|
||||
if (_feralEssenceStack)
|
||||
if (Aura* aur = me->AddAura(SPELL_FERAL_ESSENCE, me))
|
||||
aur->SetStackAmount(_feralEssenceStack);
|
||||
}
|
||||
else if (param == ACTION_DESPAWN_ADDS)
|
||||
summons.DespawnAll();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_feralRushTimer += diff;
|
||||
_feralPounceTimer += diff;
|
||||
|
||||
if (_feralRushTimer >= 6000)
|
||||
{
|
||||
DoResetThreatList();
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
me->CastSpell(me->GetVictim(), SPELL_FERAL_RUSH, true);
|
||||
_feralRushTimer = 0;
|
||||
}
|
||||
else if (_feralPounceTimer >= 6000)
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), SPELL_FERAL_POUNCE, false);
|
||||
_feralPounceTimer = 0;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_auriaya_sentinel_blast : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_auriaya_sentinel_blast() : SpellScriptLoader("spell_auriaya_sentinel_blast") { }
|
||||
|
||||
class spell_auriaya_sentinel_blast_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_auriaya_sentinel_blast_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& unitList)
|
||||
{
|
||||
unitList.remove_if(PlayerOrPetCheck());
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auriaya_sentinel_blast_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_auriaya_sentinel_blast_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_auriaya_crazy_cat_lady : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_auriaya_crazy_cat_lady() : AchievementCriteriaScript("achievement_auriaya_crazy_cat_lady") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
if (target)
|
||||
if (InstanceScript* instance = target->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_AURIAYA)))
|
||||
return cr->AI()->GetData(DATA_CRAZY_CAT);
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_auriaya_nine_lives : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_auriaya_nine_lives() : AchievementCriteriaScript("achievement_auriaya_nine_lives") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
if (target)
|
||||
if (InstanceScript* instance = target->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_AURIAYA)))
|
||||
return cr->AI()->GetData(DATA_NINE_LIVES);
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_auriaya()
|
||||
{
|
||||
new boss_auriaya();
|
||||
|
||||
479
src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.h
Normal file
479
src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.h
Normal file
@@ -0,0 +1,479 @@
|
||||
#ifndef BOSS_AURIAYA_H_
|
||||
#define BOSS_AURIAYA_H_
|
||||
|
||||
#include "AchievementCriteriaScript.h"
|
||||
#include "CreatureScript.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellScriptLoader.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
enum AuriayaSpells
|
||||
{
|
||||
// BASIC
|
||||
SPELL_TERRIFYING_SCREECH = 64386,
|
||||
SPELL_SENTINEL_BLAST_10 = 64389,
|
||||
SPELL_SENTINEL_BLAST_25 = 64678,
|
||||
SPELL_SONIC_SCREECH_10 = 64422,
|
||||
SPELL_SONIC_SCREECH_25 = 64688,
|
||||
SPELL_GUARDIAN_SWARM = 64396,
|
||||
SPELL_ENRAGE = 47008,
|
||||
SPELL_ACTIVATE_FERAL_DEFENDER = 64449,
|
||||
|
||||
// Sanctum Sentry
|
||||
SPELL_SAVAGE_POUNCE_10 = 64666,
|
||||
SPELL_SAVAGE_POUNCE_25 = 64374,
|
||||
SPELL_RIP_FLESH_10 = 64375,
|
||||
SPELL_RIP_FLESH_25 = 64667,
|
||||
SPELL_STRENGTH_OF_THE_PACK = 64369,
|
||||
|
||||
// Feral Defender
|
||||
SPELL_FERAL_ESSENCE = 64455,
|
||||
SPELL_FERAL_POUNCE_10 = 64478,
|
||||
SPELL_FERAL_POUNCE_25 = 64669,
|
||||
SPELL_FERAL_RUSH_10 = 64496,
|
||||
SPELL_FERAL_RUSH_25 = 64674,
|
||||
//SPELL_SEEPING_FERAL_ESSENCE_SUMMON = 64457,
|
||||
SPELL_SEEPING_FERAL_ESSENCE_10 = 64458,
|
||||
SPELL_SEEPING_FERAL_ESSENCE_25 = 64676,
|
||||
};
|
||||
|
||||
#define SPELL_SONIC_SCREECH RAID_MODE(SPELL_SONIC_SCREECH_10, SPELL_SONIC_SCREECH_25)
|
||||
#define SPELL_SENTINEL_BLAST RAID_MODE(SPELL_SENTINEL_BLAST_10, SPELL_SENTINEL_BLAST_25)
|
||||
#define SPELL_SAVAGE_POUNCE RAID_MODE(SPELL_SAVAGE_POUNCE_10, SPELL_SAVAGE_POUNCE_25)
|
||||
#define SPELL_RIP_FLESH RAID_MODE(SPELL_RIP_FLESH_10, SPELL_RIP_FLESH_25)
|
||||
#define SPELL_FERAL_POUNCE RAID_MODE(SPELL_FERAL_POUNCE_10, SPELL_FERAL_POUNCE_25)
|
||||
#define SPELL_FERAL_RUSH RAID_MODE(SPELL_FERAL_RUSH_10, SPELL_FERAL_RUSH_25)
|
||||
//#define SPELL_SEEPING_FERAL_ESSENCE RAID_MODE(SPELL_SEEPING_FERAL_ESSENCE_10, SPELL_SEEPING_FERAL_ESSENCE_25)
|
||||
|
||||
enum AuriayaNPC
|
||||
{
|
||||
NPC_FERAL_DEFENDER = 34035,
|
||||
NPC_SANCTUM_SENTRY = 34014,
|
||||
NPC_SEEPING_FERAL_ESSENCE = 34098,
|
||||
};
|
||||
|
||||
enum AuriayaEvents
|
||||
{
|
||||
EVENT_SUMMON_FERAL_DEFENDER = 1,
|
||||
EVENT_TERRIFYING_SCREECH = 2,
|
||||
EVENT_SONIC_SCREECH = 3,
|
||||
EVENT_GUARDIAN_SWARM = 4,
|
||||
EVENT_SENTINEL_BLAST = 5,
|
||||
EVENT_REMOVE_IMMUNE = 6,
|
||||
|
||||
EVENT_RESPAWN_FERAL_DEFENDER = 9,
|
||||
EVENT_ENRAGE = 10,
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_BERSERK = 2,
|
||||
EMOTE_DEATH = 3,
|
||||
EMOTE_FEAR = 4,
|
||||
EMOTE_DEFFENDER = 5,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
ACTION_FERAL_RESPAWN = 1,
|
||||
ACTION_FERAL_DEATH = 2,
|
||||
ACTION_DESPAWN_ADDS = 3,
|
||||
ACTION_FERAL_DEATH_WITH_STACK = 4,
|
||||
|
||||
DATA_CRAZY_CAT = 10,
|
||||
DATA_NINE_LIVES = 11,
|
||||
};
|
||||
|
||||
class boss_auriaya : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_auriaya() : CreatureScript("boss_auriaya") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<boss_auriayaAI>(pCreature);
|
||||
}
|
||||
|
||||
struct boss_auriayaAI : public ScriptedAI
|
||||
{
|
||||
boss_auriayaAI(Creature* pCreature) : ScriptedAI(pCreature), summons(pCreature)
|
||||
{
|
||||
m_pInstance = pCreature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* m_pInstance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
|
||||
bool _feralDied;
|
||||
bool _nineLives;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_feralDied = false;
|
||||
_nineLives = false;
|
||||
|
||||
events.Reset();
|
||||
EntryCheckPredicate pred(NPC_FERAL_DEFENDER);
|
||||
summons.DoAction(ACTION_DESPAWN_ADDS, pred);
|
||||
summons.DespawnAll();
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_AURIAYA, NOT_STARTED);
|
||||
|
||||
for (uint8 i = 0; i < RAID_MODE(2, 4); ++i)
|
||||
me->SummonCreature(NPC_SANCTUM_SENTRY, me->GetPositionX() + urand(4, 12), me->GetPositionY() + urand(4, 12), me->GetPositionZ());
|
||||
|
||||
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false);
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 param) const override
|
||||
{
|
||||
if (param == DATA_CRAZY_CAT)
|
||||
return !_feralDied;
|
||||
else if (param == DATA_NINE_LIVES)
|
||||
return _nineLives;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) override
|
||||
{
|
||||
if (cr->GetEntry() == NPC_SANCTUM_SENTRY)
|
||||
cr->GetMotionMaster()->MoveFollow(me, 6, rand_norm() * 2 * 3.14f);
|
||||
else
|
||||
cr->SetInCombatWithZone();
|
||||
|
||||
summons.Summon(cr);
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* cr, Unit*) override
|
||||
{
|
||||
if (cr->GetEntry() == NPC_SANCTUM_SENTRY)
|
||||
_feralDied = true;
|
||||
}
|
||||
|
||||
void JustReachedHome() override { me->setActive(false); }
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_AURIAYA, IN_PROGRESS);
|
||||
|
||||
events.ScheduleEvent(EVENT_TERRIFYING_SCREECH, 35s);
|
||||
events.ScheduleEvent(EVENT_SONIC_SCREECH, 45s);
|
||||
events.ScheduleEvent(EVENT_GUARDIAN_SWARM, 70s);
|
||||
events.ScheduleEvent(EVENT_SUMMON_FERAL_DEFENDER, 60s);
|
||||
events.ScheduleEvent(EVENT_SENTINEL_BLAST, 36s);
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 10min);
|
||||
|
||||
summons.DoZoneInCombat(NPC_SANCTUM_SENTRY);
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
me->setActive(true);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() != TYPEID_PLAYER || urand(0, 2))
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_AURIAYA, DONE);
|
||||
|
||||
EntryCheckPredicate pred(NPC_FERAL_DEFENDER);
|
||||
summons.DoAction(ACTION_DESPAWN_ADDS, pred);
|
||||
summons.DespawnAll();
|
||||
Talk(EMOTE_DEATH);
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == ACTION_FERAL_DEATH_WITH_STACK)
|
||||
events.ScheduleEvent(EVENT_RESPAWN_FERAL_DEFENDER, 25s);
|
||||
else if (param == ACTION_FERAL_DEATH)
|
||||
_nineLives = true;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SUMMON_FERAL_DEFENDER:
|
||||
Talk(EMOTE_DEFFENDER);
|
||||
me->CastSpell(me, SPELL_ACTIVATE_FERAL_DEFENDER, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true);
|
||||
events.ScheduleEvent(EVENT_REMOVE_IMMUNE, 3s);
|
||||
break;
|
||||
case EVENT_REMOVE_IMMUNE:
|
||||
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false);
|
||||
break;
|
||||
case EVENT_TERRIFYING_SCREECH:
|
||||
Talk(EMOTE_FEAR);
|
||||
me->CastSpell(me, SPELL_TERRIFYING_SCREECH, false);
|
||||
events.Repeat(35s);
|
||||
break;
|
||||
case EVENT_SONIC_SCREECH:
|
||||
me->CastSpell(me, SPELL_SONIC_SCREECH, false);
|
||||
events.Repeat(50s);
|
||||
break;
|
||||
case EVENT_GUARDIAN_SWARM:
|
||||
me->CastSpell(me->GetVictim(), SPELL_GUARDIAN_SWARM, false);
|
||||
events.Repeat(40s);
|
||||
break;
|
||||
case EVENT_SENTINEL_BLAST:
|
||||
me->CastSpell(me, SPELL_SENTINEL_BLAST, false);
|
||||
events.Repeat(35s);
|
||||
events.DelayEvents(5000, 0);
|
||||
break;
|
||||
case EVENT_RESPAWN_FERAL_DEFENDER:
|
||||
{
|
||||
EntryCheckPredicate pred(NPC_FERAL_DEFENDER);
|
||||
summons.DoAction(ACTION_FERAL_RESPAWN, pred);
|
||||
break;
|
||||
}
|
||||
case EVENT_ENRAGE:
|
||||
Talk(SAY_BERSERK);
|
||||
me->CastSpell(me, SPELL_ENRAGE, true);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_auriaya_sanctum_sentry : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_auriaya_sanctum_sentry() : CreatureScript("npc_auriaya_sanctum_sentry") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<npc_auriaya_sanctum_sentryAI>(pCreature);
|
||||
}
|
||||
|
||||
struct npc_auriaya_sanctum_sentryAI : public ScriptedAI
|
||||
{
|
||||
npc_auriaya_sanctum_sentryAI(Creature* pCreature) : ScriptedAI(pCreature) { }
|
||||
|
||||
uint32 _savagePounceTimer;
|
||||
uint32 _ripFleshTimer;
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
if (me->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_AURIAYA)))
|
||||
cr->SetInCombatWithZone();
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_savagePounceTimer = 5000;
|
||||
_ripFleshTimer = 0;
|
||||
|
||||
me->CastSpell(me, SPELL_STRENGTH_OF_THE_PACK, true);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_savagePounceTimer += diff;
|
||||
_ripFleshTimer += diff;
|
||||
|
||||
if (_savagePounceTimer >= 5000)
|
||||
{
|
||||
float dist = me->GetDistance(me->GetVictim());
|
||||
if (dist >= 8 && dist < 25 && me->IsWithinLOSInMap(me->GetVictim()))
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), SPELL_SAVAGE_POUNCE, false);
|
||||
_savagePounceTimer = 0;
|
||||
return;
|
||||
}
|
||||
_savagePounceTimer = 200;
|
||||
}
|
||||
else if (_ripFleshTimer >= 10000)
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), SPELL_RIP_FLESH, false);
|
||||
_ripFleshTimer = 0;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_auriaya_feral_defender : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_auriaya_feral_defender() : CreatureScript("npc_auriaya_feral_defender") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<npc_auriaya_feral_defenderAI>(pCreature);
|
||||
}
|
||||
|
||||
struct npc_auriaya_feral_defenderAI : public ScriptedAI
|
||||
{
|
||||
npc_auriaya_feral_defenderAI(Creature* pCreature) : ScriptedAI(pCreature), summons(pCreature) { }
|
||||
|
||||
int32 _feralRushTimer;
|
||||
int32 _feralPounceTimer;
|
||||
uint8 _feralEssenceStack;
|
||||
SummonList summons;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
summons.DespawnAll();
|
||||
_feralRushTimer = 3000;
|
||||
_feralPounceTimer = 0;
|
||||
_feralEssenceStack = 8;
|
||||
|
||||
if (Aura* aur = me->AddAura(SPELL_FERAL_ESSENCE, me))
|
||||
aur->SetStackAmount(_feralEssenceStack);
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
// inform about our death, start timer
|
||||
if (me->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_AURIAYA)))
|
||||
cr->AI()->DoAction(_feralEssenceStack ? ACTION_FERAL_DEATH_WITH_STACK : ACTION_FERAL_DEATH);
|
||||
|
||||
if (_feralEssenceStack)
|
||||
{
|
||||
if (Creature* cr = me->SummonCreature(NPC_SEEPING_FERAL_ESSENCE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.0f))
|
||||
summons.Summon(cr);
|
||||
|
||||
--_feralEssenceStack;
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == ACTION_FERAL_RESPAWN)
|
||||
{
|
||||
me->setDeathState(DeathState::JustRespawned);
|
||||
|
||||
if (Player* target = SelectTargetFromPlayerList(200))
|
||||
AttackStart(target);
|
||||
else
|
||||
{
|
||||
summons.DespawnAll();
|
||||
me->DespawnOrUnsummon(1);
|
||||
}
|
||||
|
||||
if (_feralEssenceStack)
|
||||
if (Aura* aur = me->AddAura(SPELL_FERAL_ESSENCE, me))
|
||||
aur->SetStackAmount(_feralEssenceStack);
|
||||
}
|
||||
else if (param == ACTION_DESPAWN_ADDS)
|
||||
summons.DespawnAll();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_feralRushTimer += diff;
|
||||
_feralPounceTimer += diff;
|
||||
|
||||
if (_feralRushTimer >= 6000)
|
||||
{
|
||||
DoResetThreatList();
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
me->CastSpell(me->GetVictim(), SPELL_FERAL_RUSH, true);
|
||||
_feralRushTimer = 0;
|
||||
}
|
||||
else if (_feralPounceTimer >= 6000)
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), SPELL_FERAL_POUNCE, false);
|
||||
_feralPounceTimer = 0;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_auriaya_sentinel_blast : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_auriaya_sentinel_blast() : SpellScriptLoader("spell_auriaya_sentinel_blast") { }
|
||||
|
||||
class spell_auriaya_sentinel_blast_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_auriaya_sentinel_blast_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& unitList)
|
||||
{
|
||||
unitList.remove_if(PlayerOrPetCheck());
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auriaya_sentinel_blast_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_auriaya_sentinel_blast_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_auriaya_crazy_cat_lady : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_auriaya_crazy_cat_lady() : AchievementCriteriaScript("achievement_auriaya_crazy_cat_lady") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
if (target)
|
||||
if (InstanceScript* instance = target->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_AURIAYA)))
|
||||
return cr->AI()->GetData(DATA_CRAZY_CAT);
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_auriaya_nine_lives : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_auriaya_nine_lives() : AchievementCriteriaScript("achievement_auriaya_nine_lives") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
if (target)
|
||||
if (InstanceScript* instance = target->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_AURIAYA)))
|
||||
return cr->AI()->GetData(DATA_NINE_LIVES);
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
1902
src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.h
Normal file
1902
src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.h
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1271
src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.h
Normal file
1271
src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "boss_general_vezax.h"
|
||||
#include "AccountMgr.h"
|
||||
#include "AchievementCriteriaScript.h"
|
||||
#include "BanMgr.h"
|
||||
@@ -28,665 +29,6 @@
|
||||
#include "WorldSession.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
enum VezaxSpellData
|
||||
{
|
||||
SPELL_VEZAX_BERSERK = 26662,
|
||||
|
||||
SPELL_VEZAX_SHADOW_CRASH = 62660,
|
||||
SPELL_VEZAX_SHADOW_CRASH_DMG = 62659,
|
||||
SPELL_VEZAX_SHADOW_CRASH_AREA_AURA = 63277,
|
||||
SPELL_VEZAX_SHADOW_CRASH_AURA = 65269,
|
||||
|
||||
SPELL_SEARING_FLAMES = 62661,
|
||||
|
||||
SPELL_SURGE_OF_DARKNESS = 62662,
|
||||
|
||||
SPELL_MARK_OF_THE_FACELESS_AURA = 63276,
|
||||
SPELL_MARK_OF_THE_FACELESS_EFFECT = 63278,
|
||||
|
||||
SPELL_AURA_OF_DESPAIR_1 = 62692,
|
||||
SPELL_AURA_OF_DESPAIR_2 = 64848,
|
||||
SPELL_CORRUPTED_RAGE = 68415,
|
||||
SPELL_CORRUPTED_WISDOM = 64646,
|
||||
SPELL_SHAMANISTIC_RAGE = 30823,
|
||||
SPELL_JUDGEMENTS_OF_THE_WISDOM_RANK_1 = 31876,
|
||||
|
||||
SPELL_SUMMON_SARONITE_VAPORS = 63081,
|
||||
NPC_SARONITE_VAPORS = 33488,
|
||||
SPELL_SARONITE_VAPORS_DMG = 63338,
|
||||
SPELL_SARONITE_VAPORS_ENERGIZE = 63337,
|
||||
SPELL_SARONITE_VAPORS_AURA = 63323,
|
||||
SPELL_SARONITE_VAPORS_DUMMYAURA = 63322,
|
||||
|
||||
SPELL_SARONITE_ANIMUS_FORMATION_VISUAL = 63319,
|
||||
SPELL_SUMMON_SARONITE_ANIMUS = 63145,
|
||||
SPELL_SARONITE_BARRIER = 63364,
|
||||
SPELL_PROFOUND_DARKNESS = 63420,
|
||||
};
|
||||
|
||||
enum VezaxNpcs
|
||||
{
|
||||
// NPC_VEZAX = 33271,
|
||||
// NPC_VEZAX_BUNNY = 33500,
|
||||
NPC_SARONITE_ANIMUS = 33524,
|
||||
};
|
||||
|
||||
enum VezaxGOs
|
||||
{
|
||||
// GO_VEZAX_DOOR = 194750,
|
||||
};
|
||||
|
||||
enum VezaxEvents
|
||||
{
|
||||
EVENT_SPELL_VEZAX_SHADOW_CRASH = 1,
|
||||
EVENT_SPELL_SEARING_FLAMES = 2,
|
||||
EVENT_SPELL_SURGE_OF_DARKNESS = 3,
|
||||
EVENT_SPELL_MARK_OF_THE_FACELESS = 4,
|
||||
EVENT_SPELL_SUMMON_SARONITE_VAPORS = 5,
|
||||
EVENT_SARONITE_VAPORS_SWIRL = 6,
|
||||
EVENT_SPELL_SUMMON_SARONITE_ANIMUS = 7,
|
||||
EVENT_DESPAWN_SARONITE_VAPORS = 8,
|
||||
EVENT_SPELL_PROFOUND_DARKNESS = 9,
|
||||
EVENT_BERSERK = 10,
|
||||
EVENT_RESTORE_TARGET = 11,
|
||||
};
|
||||
|
||||
enum VezaxText
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_SURGE_OF_DARKNESS = 2,
|
||||
SAY_DEATH = 3,
|
||||
SAY_BERSERK = 4,
|
||||
SAY_HARDMODE = 5,
|
||||
SAY_EMOTE_ANIMUS = 6,
|
||||
SAY_EMOTE_BARRIER = 7,
|
||||
SAY_EMOTE_SURGE_OF_DARKNESS = 8,
|
||||
};
|
||||
|
||||
enum VaporsText
|
||||
{
|
||||
SAY_EMOTE_VAPORS = 0,
|
||||
};
|
||||
|
||||
class boss_vezax : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_vezax() : CreatureScript("boss_vezax") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<boss_vezaxAI>(pCreature);
|
||||
}
|
||||
|
||||
struct boss_vezaxAI : public ScriptedAI
|
||||
{
|
||||
boss_vezaxAI(Creature* pCreature) : ScriptedAI(pCreature), summons(me)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
uint8 vaporsCount;
|
||||
bool hardmodeAvailable;
|
||||
bool berserk;
|
||||
bool bAchievShadowdodger;
|
||||
|
||||
InstanceScript* pInstance;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
vaporsCount = 0;
|
||||
hardmodeAvailable = true;
|
||||
berserk = false;
|
||||
bAchievShadowdodger = true;
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->SetLootMode(1);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_VEZAX, NOT_STARTED);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
me->setActive(false);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*pWho*/) override
|
||||
{
|
||||
me->setActive(true);
|
||||
me->SetInCombatWithZone();
|
||||
|
||||
events.Reset();
|
||||
events.RescheduleEvent(EVENT_SPELL_VEZAX_SHADOW_CRASH, 13s);
|
||||
events.RescheduleEvent(EVENT_SPELL_SEARING_FLAMES, 10s, 1);
|
||||
events.RescheduleEvent(EVENT_SPELL_SURGE_OF_DARKNESS, 63s);
|
||||
events.RescheduleEvent(EVENT_SPELL_MARK_OF_THE_FACELESS, 20s);
|
||||
events.RescheduleEvent(EVENT_SPELL_SUMMON_SARONITE_VAPORS, 30s);
|
||||
events.RescheduleEvent(EVENT_BERSERK, 10min);
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_VEZAX, IN_PROGRESS);
|
||||
|
||||
me->CastSpell(me, SPELL_AURA_OF_DESPAIR_1, true);
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
switch( param )
|
||||
{
|
||||
case 1:
|
||||
hardmodeAvailable = false;
|
||||
break;
|
||||
case 2:
|
||||
me->RemoveAura(SPELL_SARONITE_BARRIER);
|
||||
me->SetLootMode(3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 id) const override
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case 1:
|
||||
return (me->GetLootMode() == 3 ? 1 : 0);
|
||||
case 2:
|
||||
return (bAchievShadowdodger ? 1 : 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, SpellInfo const* spell) override
|
||||
{
|
||||
if (target && spell && target->GetTypeId() == TYPEID_PLAYER && spell->Id == SPELL_VEZAX_SHADOW_CRASH_DMG)
|
||||
bAchievShadowdodger = false;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if( !UpdateVictim() )
|
||||
return;
|
||||
|
||||
if( !berserk && (me->GetPositionX() < 1720.0f || me->GetPositionX() > 1940.0f || me->GetPositionY() < 20.0f || me->GetPositionY() > 210.0f) )
|
||||
events.RescheduleEvent(EVENT_BERSERK, 1ms);
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if( me->HasUnitState(UNIT_STATE_CASTING) )
|
||||
return;
|
||||
|
||||
switch( events.ExecuteEvent() )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_BERSERK:
|
||||
berserk = true;
|
||||
me->CastSpell(me, SPELL_VEZAX_BERSERK, true);
|
||||
Talk(SAY_BERSERK);
|
||||
break;
|
||||
case EVENT_SPELL_VEZAX_SHADOW_CRASH:
|
||||
{
|
||||
events.Repeat(10s);
|
||||
|
||||
std::vector<Player*> players;
|
||||
Map::PlayerList const& pl = me->GetMap()->GetPlayers();
|
||||
for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
|
||||
{
|
||||
Player* temp = itr->GetSource();
|
||||
if( temp->IsAlive() && temp->GetDistance(me) > 15.0f )
|
||||
players.push_back(temp);
|
||||
}
|
||||
if (!players.empty())
|
||||
{
|
||||
me->setAttackTimer(BASE_ATTACK, 2000);
|
||||
Player* target = players.at(urand(0, players.size() - 1));
|
||||
me->SetGuidValue(UNIT_FIELD_TARGET, target->GetGUID());
|
||||
me->CastSpell(target, SPELL_VEZAX_SHADOW_CRASH, false);
|
||||
events.ScheduleEvent(EVENT_RESTORE_TARGET, 750ms);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EVENT_RESTORE_TARGET:
|
||||
if (me->GetVictim())
|
||||
me->SetGuidValue(UNIT_FIELD_TARGET, me->GetVictim()->GetGUID());
|
||||
break;
|
||||
case EVENT_SPELL_SEARING_FLAMES:
|
||||
if(!me->HasAura(SPELL_SARONITE_BARRIER))
|
||||
me->CastSpell(me->GetVictim(), SPELL_SEARING_FLAMES, false);
|
||||
events.Repeat(me->GetMap()->Is25ManRaid() ? 8s : 15s);
|
||||
break;
|
||||
case EVENT_SPELL_SURGE_OF_DARKNESS:
|
||||
Talk(SAY_SURGE_OF_DARKNESS);
|
||||
Talk(SAY_EMOTE_SURGE_OF_DARKNESS);
|
||||
me->CastSpell(me, SPELL_SURGE_OF_DARKNESS, false);
|
||||
events.Repeat(63s);
|
||||
events.DelayEvents(10000, 1);
|
||||
break;
|
||||
case EVENT_SPELL_MARK_OF_THE_FACELESS:
|
||||
{
|
||||
std::vector<Player*> outside;
|
||||
std::vector<Player*> inside;
|
||||
Map::PlayerList const& pl = me->GetMap()->GetPlayers();
|
||||
for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
|
||||
if( Player* tmp = itr->GetSource() )
|
||||
if( tmp->IsAlive() )
|
||||
{
|
||||
if( tmp->GetDistance(me) > 15.0f )
|
||||
outside.push_back(tmp);
|
||||
else
|
||||
inside.push_back(tmp);
|
||||
}
|
||||
|
||||
Player* t = nullptr;
|
||||
if( outside.size() >= uint8(me->GetMap()->Is25ManRaid() ? 9 : 4) )
|
||||
t = outside.at(urand(0, outside.size() - 1));
|
||||
else if( !inside.empty() )
|
||||
t = inside.at(urand(0, inside.size() - 1));
|
||||
|
||||
if (t)
|
||||
me->CastSpell(t, SPELL_MARK_OF_THE_FACELESS_AURA, false);
|
||||
|
||||
events.Repeat(40s);
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_SUMMON_SARONITE_VAPORS:
|
||||
{
|
||||
vaporsCount++;
|
||||
me->CastSpell(me, SPELL_SUMMON_SARONITE_VAPORS, false);
|
||||
|
||||
if( vaporsCount < 6 || !hardmodeAvailable )
|
||||
events.Repeat(30s);
|
||||
else
|
||||
{
|
||||
for (ObjectGuid const& guid : summons)
|
||||
if (Creature* sv = ObjectAccessor::GetCreature(*me, guid))
|
||||
{
|
||||
sv->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
sv->GetMotionMaster()->MoveIdle();
|
||||
sv->GetMotionMaster()->MoveCharge(1852.78f, 81.38f, 342.461f, 28.0f);
|
||||
}
|
||||
|
||||
events.DelayEvents(12000, 0);
|
||||
events.DelayEvents(12000, 1);
|
||||
events.ScheduleEvent(EVENT_SARONITE_VAPORS_SWIRL, 6s);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EVENT_SARONITE_VAPORS_SWIRL:
|
||||
if (summons.size())
|
||||
{
|
||||
Talk(SAY_EMOTE_ANIMUS);
|
||||
if( Creature* sv = ObjectAccessor::GetCreature(*me, *(summons.begin())) )
|
||||
sv->CastSpell(sv, SPELL_SARONITE_ANIMUS_FORMATION_VISUAL, true);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_SUMMON_SARONITE_ANIMUS, 2s);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_SUMMON_SARONITE_ANIMUS:
|
||||
if (summons.size())
|
||||
{
|
||||
Talk(SAY_HARDMODE);
|
||||
Talk(SAY_EMOTE_BARRIER);
|
||||
me->CastSpell(me, SPELL_SARONITE_BARRIER, true);
|
||||
if( Creature* sv = ObjectAccessor::GetCreature(*me, *(summons.begin())) )
|
||||
sv->CastSpell(sv, SPELL_SUMMON_SARONITE_ANIMUS, true);
|
||||
|
||||
events.ScheduleEvent(EVENT_DESPAWN_SARONITE_VAPORS, 2500ms);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case EVENT_DESPAWN_SARONITE_VAPORS:
|
||||
summons.DespawnEntry(NPC_SARONITE_VAPORS);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
summons.DespawnAll();
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_VEZAX, DONE);
|
||||
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if( GameObject* door = me->FindNearestGameObject(GO_VEZAX_DOOR, 500.0f) )
|
||||
if( door->GetGoState() != GO_STATE_ACTIVE )
|
||||
{
|
||||
door->SetLootState(GO_READY);
|
||||
door->UseDoorOrButton(0, false);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if( who->GetTypeId() == TYPEID_PLAYER )
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override {}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* s) override
|
||||
{
|
||||
summons.Despawn(s);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_ulduar_saronite_vapors : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_ulduar_saronite_vapors() : CreatureScript("npc_ulduar_saronite_vapors") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<npc_ulduar_saronite_vaporsAI>(pCreature);
|
||||
}
|
||||
|
||||
struct npc_ulduar_saronite_vaporsAI : public NullCreatureAI
|
||||
{
|
||||
npc_ulduar_saronite_vaporsAI(Creature* pCreature) : NullCreatureAI(pCreature)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
me->GetMotionMaster()->MoveRandom(4.0f);
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
me->CastSpell(me, SPELL_SARONITE_VAPORS_AURA, true);
|
||||
|
||||
// killed saronite vapors, hard mode unavailable
|
||||
if( pInstance )
|
||||
if( Creature* vezax = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(TYPE_VEZAX)) )
|
||||
vezax->AI()->DoAction(1);
|
||||
}
|
||||
|
||||
void IsSummonedBy(WorldObject* /*summoner*/) override
|
||||
{
|
||||
Talk(SAY_EMOTE_VAPORS);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_ulduar_saronite_animus : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_ulduar_saronite_animus() : CreatureScript("npc_ulduar_saronite_animus") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<npc_ulduar_saronite_animusAI>(pCreature);
|
||||
}
|
||||
|
||||
struct npc_ulduar_saronite_animusAI : public ScriptedAI
|
||||
{
|
||||
npc_ulduar_saronite_animusAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
if( pInstance )
|
||||
if( Creature* vezax = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(TYPE_VEZAX)) )
|
||||
vezax->AI()->JustSummoned(me);
|
||||
timer = 0;
|
||||
me->SetInCombatWithZone();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
uint16 timer;
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
me->DespawnOrUnsummon(3000);
|
||||
|
||||
if( pInstance )
|
||||
if( Creature* vezax = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(TYPE_VEZAX)) )
|
||||
vezax->AI()->DoAction(2);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
UpdateVictim();
|
||||
|
||||
timer += diff;
|
||||
if (timer >= 2000)
|
||||
{
|
||||
me->CastSpell(me, SPELL_PROFOUND_DARKNESS, true);
|
||||
timer -= 2000;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_aura_of_despair : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_aura_of_despair() : SpellScriptLoader("spell_aura_of_despair") { }
|
||||
|
||||
class spell_aura_of_despair_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_aura_of_despair_AuraScript)
|
||||
|
||||
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
if (Unit* target = GetTarget())
|
||||
{
|
||||
if (target->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
target->CastSpell(target, SPELL_AURA_OF_DESPAIR_2, true);
|
||||
if( target->HasSpell(SPELL_SHAMANISTIC_RAGE) )
|
||||
caster->CastSpell(target, SPELL_CORRUPTED_RAGE, true);
|
||||
else if( target->HasSpell(SPELL_JUDGEMENTS_OF_THE_WISDOM_RANK_1) || target->HasSpell(SPELL_JUDGEMENTS_OF_THE_WISDOM_RANK_1 + 1) || target->HasSpell(SPELL_JUDGEMENTS_OF_THE_WISDOM_RANK_1 + 2) )
|
||||
caster->CastSpell(target, SPELL_CORRUPTED_WISDOM, true);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* target = GetTarget())
|
||||
{
|
||||
target->RemoveAurasDueToSpell(SPELL_AURA_OF_DESPAIR_2);
|
||||
target->RemoveAurasDueToSpell(SPELL_CORRUPTED_RAGE);
|
||||
target->RemoveAurasDueToSpell(SPELL_CORRUPTED_WISDOM);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectApply += AuraEffectApplyFn(spell_aura_of_despair_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PREVENT_REGENERATE_POWER, AURA_EFFECT_HANDLE_REAL);
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_aura_of_despair_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PREVENT_REGENERATE_POWER, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_aura_of_despair_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_mark_of_the_faceless_periodic : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_mark_of_the_faceless_periodic() : SpellScriptLoader("spell_mark_of_the_faceless_periodic") { }
|
||||
|
||||
class spell_mark_of_the_faceless_periodic_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_mark_of_the_faceless_periodic_AuraScript)
|
||||
|
||||
void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
if (Unit* target = GetTarget())
|
||||
if (target->GetMapId() == 603)
|
||||
{
|
||||
int32 dmg = 5000;
|
||||
caster->CastCustomSpell(target, SPELL_MARK_OF_THE_FACELESS_EFFECT, 0, &dmg, 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_mark_of_the_faceless_periodic_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_mark_of_the_faceless_periodic_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_mark_of_the_faceless_drainhealth : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_mark_of_the_faceless_drainhealth() : SpellScriptLoader("spell_mark_of_the_faceless_drainhealth") { }
|
||||
|
||||
class spell_mark_of_the_faceless_drainhealth_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_mark_of_the_faceless_drainhealth_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.remove(GetExplTargetUnit());
|
||||
if (targets.empty())
|
||||
Cancel();
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mark_of_the_faceless_drainhealth_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_mark_of_the_faceless_drainhealth_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_saronite_vapors_dummy : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_saronite_vapors_dummy() : SpellScriptLoader("spell_saronite_vapors_dummy") { }
|
||||
|
||||
class spell_saronite_vapors_dummy_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_saronite_vapors_dummy_AuraScript)
|
||||
|
||||
void HandleAfterEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
int32 damage = 100 * pow(2.0f, (float)GetStackAmount());
|
||||
caster->CastCustomSpell(GetTarget(), SPELL_SARONITE_VAPORS_DMG, &damage, nullptr, nullptr, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectApply += AuraEffectApplyFn(spell_saronite_vapors_dummy_AuraScript::HandleAfterEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_saronite_vapors_dummy_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_saronite_vapors_damage : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_saronite_vapors_damage() : SpellScriptLoader("spell_saronite_vapors_damage") { }
|
||||
|
||||
class spell_saronite_vapors_damage_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_saronite_vapors_damage_SpellScript);
|
||||
|
||||
void HandleAfterHit()
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
if (GetHitDamage() > 2)
|
||||
{
|
||||
int32 mana = GetHitDamage() / 2;
|
||||
if (Unit* t = GetHitUnit())
|
||||
caster->CastCustomSpell(t, SPELL_SARONITE_VAPORS_ENERGIZE, &mana, nullptr, nullptr, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterHit += SpellHitFn(spell_saronite_vapors_damage_SpellScript::HandleAfterHit);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_saronite_vapors_damage_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_smell_saronite : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_smell_saronite() : AchievementCriteriaScript("achievement_smell_saronite") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
return target && target->GetEntry() == NPC_VEZAX && target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->AI()->GetData(1);
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_shadowdodger : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_shadowdodger() : AchievementCriteriaScript("achievement_shadowdodger") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
return target && target->GetEntry() == NPC_VEZAX && target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->AI()->GetData(2);
|
||||
}
|
||||
};
|
||||
|
||||
class go_ulduar_pure_saronite_deposit : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
go_ulduar_pure_saronite_deposit() : GameObjectScript("go_ulduar_pure_saronite_deposit") { }
|
||||
|
||||
bool OnGossipHello(Player* plr, GameObject* go) override
|
||||
{
|
||||
if (plr->IsGameMaster())
|
||||
return false;
|
||||
|
||||
if (InstanceScript* pInstance = go->GetInstanceScript())
|
||||
if (pInstance->GetData(TYPE_XT002) != DONE && pInstance->GetData(TYPE_MIMIRON) != DONE && pInstance->GetData(TYPE_THORIM) != DONE && pInstance->GetData(TYPE_FREYA) != DONE && pInstance->GetData(TYPE_HODIR) != DONE)
|
||||
{
|
||||
std::string accountName;
|
||||
AccountMgr::GetName(plr->GetSession()->GetAccountId(), accountName);
|
||||
sBan->BanAccount(accountName, "0s", "Tele hack", "Server");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_vezax()
|
||||
{
|
||||
new boss_vezax();
|
||||
|
||||
676
src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.h
Normal file
676
src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.h
Normal file
@@ -0,0 +1,676 @@
|
||||
#ifndef BOSS_GENERAL_VEZAX_H_
|
||||
#define BOSS_GENERAL_VEZAX_H_
|
||||
|
||||
#include "AccountMgr.h"
|
||||
#include "AchievementCriteriaScript.h"
|
||||
#include "BanMgr.h"
|
||||
#include "CreatureScript.h"
|
||||
#include "GameObjectScript.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellScriptLoader.h"
|
||||
#include "WorldSession.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
enum VezaxSpellData
|
||||
{
|
||||
SPELL_VEZAX_BERSERK = 26662,
|
||||
|
||||
SPELL_VEZAX_SHADOW_CRASH = 62660,
|
||||
SPELL_VEZAX_SHADOW_CRASH_DMG = 62659,
|
||||
SPELL_VEZAX_SHADOW_CRASH_AREA_AURA = 63277,
|
||||
SPELL_VEZAX_SHADOW_CRASH_AURA = 65269,
|
||||
|
||||
SPELL_SEARING_FLAMES = 62661,
|
||||
|
||||
SPELL_SURGE_OF_DARKNESS = 62662,
|
||||
|
||||
SPELL_MARK_OF_THE_FACELESS_AURA = 63276,
|
||||
SPELL_MARK_OF_THE_FACELESS_EFFECT = 63278,
|
||||
|
||||
SPELL_AURA_OF_DESPAIR_1 = 62692,
|
||||
SPELL_AURA_OF_DESPAIR_2 = 64848,
|
||||
SPELL_CORRUPTED_RAGE = 68415,
|
||||
SPELL_CORRUPTED_WISDOM = 64646,
|
||||
SPELL_SHAMANISTIC_RAGE = 30823,
|
||||
SPELL_JUDGEMENTS_OF_THE_WISDOM_RANK_1 = 31876,
|
||||
|
||||
SPELL_SUMMON_SARONITE_VAPORS = 63081,
|
||||
NPC_SARONITE_VAPORS = 33488,
|
||||
SPELL_SARONITE_VAPORS_DMG = 63338,
|
||||
SPELL_SARONITE_VAPORS_ENERGIZE = 63337,
|
||||
SPELL_SARONITE_VAPORS_AURA = 63323,
|
||||
SPELL_SARONITE_VAPORS_DUMMYAURA = 63322,
|
||||
|
||||
SPELL_SARONITE_ANIMUS_FORMATION_VISUAL = 63319,
|
||||
SPELL_SUMMON_SARONITE_ANIMUS = 63145,
|
||||
SPELL_SARONITE_BARRIER = 63364,
|
||||
SPELL_PROFOUND_DARKNESS = 63420,
|
||||
};
|
||||
|
||||
enum VezaxNpcs
|
||||
{
|
||||
// NPC_VEZAX = 33271,
|
||||
// NPC_VEZAX_BUNNY = 33500,
|
||||
NPC_SARONITE_ANIMUS = 33524,
|
||||
};
|
||||
|
||||
enum VezaxGOs
|
||||
{
|
||||
// GO_VEZAX_DOOR = 194750,
|
||||
};
|
||||
|
||||
enum VezaxEvents
|
||||
{
|
||||
EVENT_SPELL_VEZAX_SHADOW_CRASH = 1,
|
||||
EVENT_SPELL_SEARING_FLAMES = 2,
|
||||
EVENT_SPELL_SURGE_OF_DARKNESS = 3,
|
||||
EVENT_SPELL_MARK_OF_THE_FACELESS = 4,
|
||||
EVENT_SPELL_SUMMON_SARONITE_VAPORS = 5,
|
||||
EVENT_SARONITE_VAPORS_SWIRL = 6,
|
||||
EVENT_SPELL_SUMMON_SARONITE_ANIMUS = 7,
|
||||
EVENT_DESPAWN_SARONITE_VAPORS = 8,
|
||||
EVENT_SPELL_PROFOUND_DARKNESS = 9,
|
||||
EVENT_BERSERK = 10,
|
||||
EVENT_RESTORE_TARGET = 11,
|
||||
};
|
||||
|
||||
enum VezaxText
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_SURGE_OF_DARKNESS = 2,
|
||||
SAY_DEATH = 3,
|
||||
SAY_BERSERK = 4,
|
||||
SAY_HARDMODE = 5,
|
||||
SAY_EMOTE_ANIMUS = 6,
|
||||
SAY_EMOTE_BARRIER = 7,
|
||||
SAY_EMOTE_SURGE_OF_DARKNESS = 8,
|
||||
};
|
||||
|
||||
enum VaporsText
|
||||
{
|
||||
SAY_EMOTE_VAPORS = 0,
|
||||
};
|
||||
|
||||
class boss_vezax : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_vezax() : CreatureScript("boss_vezax") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<boss_vezaxAI>(pCreature);
|
||||
}
|
||||
|
||||
struct boss_vezaxAI : public ScriptedAI
|
||||
{
|
||||
boss_vezaxAI(Creature* pCreature) : ScriptedAI(pCreature), summons(me)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
uint8 vaporsCount;
|
||||
bool hardmodeAvailable;
|
||||
bool berserk;
|
||||
bool bAchievShadowdodger;
|
||||
|
||||
InstanceScript* pInstance;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
vaporsCount = 0;
|
||||
hardmodeAvailable = true;
|
||||
berserk = false;
|
||||
bAchievShadowdodger = true;
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->SetLootMode(1);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_VEZAX, NOT_STARTED);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
me->setActive(false);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*pWho*/) override
|
||||
{
|
||||
me->setActive(true);
|
||||
me->SetInCombatWithZone();
|
||||
|
||||
events.Reset();
|
||||
events.RescheduleEvent(EVENT_SPELL_VEZAX_SHADOW_CRASH, 13s);
|
||||
events.RescheduleEvent(EVENT_SPELL_SEARING_FLAMES, 10s, 1);
|
||||
events.RescheduleEvent(EVENT_SPELL_SURGE_OF_DARKNESS, 63s);
|
||||
events.RescheduleEvent(EVENT_SPELL_MARK_OF_THE_FACELESS, 20s);
|
||||
events.RescheduleEvent(EVENT_SPELL_SUMMON_SARONITE_VAPORS, 30s);
|
||||
events.RescheduleEvent(EVENT_BERSERK, 10min);
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_VEZAX, IN_PROGRESS);
|
||||
|
||||
me->CastSpell(me, SPELL_AURA_OF_DESPAIR_1, true);
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
switch( param )
|
||||
{
|
||||
case 1:
|
||||
hardmodeAvailable = false;
|
||||
break;
|
||||
case 2:
|
||||
me->RemoveAura(SPELL_SARONITE_BARRIER);
|
||||
me->SetLootMode(3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 id) const override
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case 1:
|
||||
return (me->GetLootMode() == 3 ? 1 : 0);
|
||||
case 2:
|
||||
return (bAchievShadowdodger ? 1 : 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, SpellInfo const* spell) override
|
||||
{
|
||||
if (target && spell && target->GetTypeId() == TYPEID_PLAYER && spell->Id == SPELL_VEZAX_SHADOW_CRASH_DMG)
|
||||
bAchievShadowdodger = false;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if( !UpdateVictim() )
|
||||
return;
|
||||
|
||||
if( !berserk && (me->GetPositionX() < 1720.0f || me->GetPositionX() > 1940.0f || me->GetPositionY() < 20.0f || me->GetPositionY() > 210.0f) )
|
||||
events.RescheduleEvent(EVENT_BERSERK, 1ms);
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if( me->HasUnitState(UNIT_STATE_CASTING) )
|
||||
return;
|
||||
|
||||
switch( events.ExecuteEvent() )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_BERSERK:
|
||||
berserk = true;
|
||||
me->CastSpell(me, SPELL_VEZAX_BERSERK, true);
|
||||
Talk(SAY_BERSERK);
|
||||
break;
|
||||
case EVENT_SPELL_VEZAX_SHADOW_CRASH:
|
||||
{
|
||||
events.Repeat(10s);
|
||||
|
||||
std::vector<Player*> players;
|
||||
Map::PlayerList const& pl = me->GetMap()->GetPlayers();
|
||||
for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
|
||||
{
|
||||
Player* temp = itr->GetSource();
|
||||
if( temp->IsAlive() && temp->GetDistance(me) > 15.0f )
|
||||
players.push_back(temp);
|
||||
}
|
||||
if (!players.empty())
|
||||
{
|
||||
me->setAttackTimer(BASE_ATTACK, 2000);
|
||||
Player* target = players.at(urand(0, players.size() - 1));
|
||||
me->SetGuidValue(UNIT_FIELD_TARGET, target->GetGUID());
|
||||
me->CastSpell(target, SPELL_VEZAX_SHADOW_CRASH, false);
|
||||
events.ScheduleEvent(EVENT_RESTORE_TARGET, 750ms);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EVENT_RESTORE_TARGET:
|
||||
if (me->GetVictim())
|
||||
me->SetGuidValue(UNIT_FIELD_TARGET, me->GetVictim()->GetGUID());
|
||||
break;
|
||||
case EVENT_SPELL_SEARING_FLAMES:
|
||||
if(!me->HasAura(SPELL_SARONITE_BARRIER))
|
||||
me->CastSpell(me->GetVictim(), SPELL_SEARING_FLAMES, false);
|
||||
events.Repeat(me->GetMap()->Is25ManRaid() ? 8s : 15s);
|
||||
break;
|
||||
case EVENT_SPELL_SURGE_OF_DARKNESS:
|
||||
Talk(SAY_SURGE_OF_DARKNESS);
|
||||
Talk(SAY_EMOTE_SURGE_OF_DARKNESS);
|
||||
me->CastSpell(me, SPELL_SURGE_OF_DARKNESS, false);
|
||||
events.Repeat(63s);
|
||||
events.DelayEvents(10000, 1);
|
||||
break;
|
||||
case EVENT_SPELL_MARK_OF_THE_FACELESS:
|
||||
{
|
||||
std::vector<Player*> outside;
|
||||
std::vector<Player*> inside;
|
||||
Map::PlayerList const& pl = me->GetMap()->GetPlayers();
|
||||
for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
|
||||
if( Player* tmp = itr->GetSource() )
|
||||
if( tmp->IsAlive() )
|
||||
{
|
||||
if( tmp->GetDistance(me) > 15.0f )
|
||||
outside.push_back(tmp);
|
||||
else
|
||||
inside.push_back(tmp);
|
||||
}
|
||||
|
||||
Player* t = nullptr;
|
||||
if( outside.size() >= uint8(me->GetMap()->Is25ManRaid() ? 9 : 4) )
|
||||
t = outside.at(urand(0, outside.size() - 1));
|
||||
else if( !inside.empty() )
|
||||
t = inside.at(urand(0, inside.size() - 1));
|
||||
|
||||
if (t)
|
||||
me->CastSpell(t, SPELL_MARK_OF_THE_FACELESS_AURA, false);
|
||||
|
||||
events.Repeat(40s);
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_SUMMON_SARONITE_VAPORS:
|
||||
{
|
||||
vaporsCount++;
|
||||
me->CastSpell(me, SPELL_SUMMON_SARONITE_VAPORS, false);
|
||||
|
||||
if( vaporsCount < 6 || !hardmodeAvailable )
|
||||
events.Repeat(30s);
|
||||
else
|
||||
{
|
||||
for (ObjectGuid const& guid : summons)
|
||||
if (Creature* sv = ObjectAccessor::GetCreature(*me, guid))
|
||||
{
|
||||
sv->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
sv->GetMotionMaster()->MoveIdle();
|
||||
sv->GetMotionMaster()->MoveCharge(1852.78f, 81.38f, 342.461f, 28.0f);
|
||||
}
|
||||
|
||||
events.DelayEvents(12000, 0);
|
||||
events.DelayEvents(12000, 1);
|
||||
events.ScheduleEvent(EVENT_SARONITE_VAPORS_SWIRL, 6s);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EVENT_SARONITE_VAPORS_SWIRL:
|
||||
if (summons.size())
|
||||
{
|
||||
Talk(SAY_EMOTE_ANIMUS);
|
||||
if( Creature* sv = ObjectAccessor::GetCreature(*me, *(summons.begin())) )
|
||||
sv->CastSpell(sv, SPELL_SARONITE_ANIMUS_FORMATION_VISUAL, true);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_SUMMON_SARONITE_ANIMUS, 2s);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_SUMMON_SARONITE_ANIMUS:
|
||||
if (summons.size())
|
||||
{
|
||||
Talk(SAY_HARDMODE);
|
||||
Talk(SAY_EMOTE_BARRIER);
|
||||
me->CastSpell(me, SPELL_SARONITE_BARRIER, true);
|
||||
if( Creature* sv = ObjectAccessor::GetCreature(*me, *(summons.begin())) )
|
||||
sv->CastSpell(sv, SPELL_SUMMON_SARONITE_ANIMUS, true);
|
||||
|
||||
events.ScheduleEvent(EVENT_DESPAWN_SARONITE_VAPORS, 2500ms);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case EVENT_DESPAWN_SARONITE_VAPORS:
|
||||
summons.DespawnEntry(NPC_SARONITE_VAPORS);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
summons.DespawnAll();
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_VEZAX, DONE);
|
||||
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if( GameObject* door = me->FindNearestGameObject(GO_VEZAX_DOOR, 500.0f) )
|
||||
if( door->GetGoState() != GO_STATE_ACTIVE )
|
||||
{
|
||||
door->SetLootState(GO_READY);
|
||||
door->UseDoorOrButton(0, false);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if( who->GetTypeId() == TYPEID_PLAYER )
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override {}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* s) override
|
||||
{
|
||||
summons.Despawn(s);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_ulduar_saronite_vapors : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_ulduar_saronite_vapors() : CreatureScript("npc_ulduar_saronite_vapors") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<npc_ulduar_saronite_vaporsAI>(pCreature);
|
||||
}
|
||||
|
||||
struct npc_ulduar_saronite_vaporsAI : public NullCreatureAI
|
||||
{
|
||||
npc_ulduar_saronite_vaporsAI(Creature* pCreature) : NullCreatureAI(pCreature)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
me->GetMotionMaster()->MoveRandom(4.0f);
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
me->CastSpell(me, SPELL_SARONITE_VAPORS_AURA, true);
|
||||
|
||||
// killed saronite vapors, hard mode unavailable
|
||||
if( pInstance )
|
||||
if( Creature* vezax = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(TYPE_VEZAX)) )
|
||||
vezax->AI()->DoAction(1);
|
||||
}
|
||||
|
||||
void IsSummonedBy(WorldObject* /*summoner*/) override
|
||||
{
|
||||
Talk(SAY_EMOTE_VAPORS);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_ulduar_saronite_animus : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_ulduar_saronite_animus() : CreatureScript("npc_ulduar_saronite_animus") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<npc_ulduar_saronite_animusAI>(pCreature);
|
||||
}
|
||||
|
||||
struct npc_ulduar_saronite_animusAI : public ScriptedAI
|
||||
{
|
||||
npc_ulduar_saronite_animusAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
if( pInstance )
|
||||
if( Creature* vezax = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(TYPE_VEZAX)) )
|
||||
vezax->AI()->JustSummoned(me);
|
||||
timer = 0;
|
||||
me->SetInCombatWithZone();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
uint16 timer;
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
me->DespawnOrUnsummon(3000);
|
||||
|
||||
if( pInstance )
|
||||
if( Creature* vezax = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(TYPE_VEZAX)) )
|
||||
vezax->AI()->DoAction(2);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
UpdateVictim();
|
||||
|
||||
timer += diff;
|
||||
if (timer >= 2000)
|
||||
{
|
||||
me->CastSpell(me, SPELL_PROFOUND_DARKNESS, true);
|
||||
timer -= 2000;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_aura_of_despair : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_aura_of_despair() : SpellScriptLoader("spell_aura_of_despair") { }
|
||||
|
||||
class spell_aura_of_despair_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_aura_of_despair_AuraScript)
|
||||
|
||||
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
if (Unit* target = GetTarget())
|
||||
{
|
||||
if (target->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
target->CastSpell(target, SPELL_AURA_OF_DESPAIR_2, true);
|
||||
if( target->HasSpell(SPELL_SHAMANISTIC_RAGE) )
|
||||
caster->CastSpell(target, SPELL_CORRUPTED_RAGE, true);
|
||||
else if( target->HasSpell(SPELL_JUDGEMENTS_OF_THE_WISDOM_RANK_1) || target->HasSpell(SPELL_JUDGEMENTS_OF_THE_WISDOM_RANK_1 + 1) || target->HasSpell(SPELL_JUDGEMENTS_OF_THE_WISDOM_RANK_1 + 2) )
|
||||
caster->CastSpell(target, SPELL_CORRUPTED_WISDOM, true);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* target = GetTarget())
|
||||
{
|
||||
target->RemoveAurasDueToSpell(SPELL_AURA_OF_DESPAIR_2);
|
||||
target->RemoveAurasDueToSpell(SPELL_CORRUPTED_RAGE);
|
||||
target->RemoveAurasDueToSpell(SPELL_CORRUPTED_WISDOM);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectApply += AuraEffectApplyFn(spell_aura_of_despair_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PREVENT_REGENERATE_POWER, AURA_EFFECT_HANDLE_REAL);
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_aura_of_despair_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PREVENT_REGENERATE_POWER, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_aura_of_despair_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_mark_of_the_faceless_periodic : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_mark_of_the_faceless_periodic() : SpellScriptLoader("spell_mark_of_the_faceless_periodic") { }
|
||||
|
||||
class spell_mark_of_the_faceless_periodic_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_mark_of_the_faceless_periodic_AuraScript)
|
||||
|
||||
void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
if (Unit* target = GetTarget())
|
||||
if (target->GetMapId() == 603)
|
||||
{
|
||||
int32 dmg = 5000;
|
||||
caster->CastCustomSpell(target, SPELL_MARK_OF_THE_FACELESS_EFFECT, 0, &dmg, 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_mark_of_the_faceless_periodic_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_mark_of_the_faceless_periodic_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_mark_of_the_faceless_drainhealth : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_mark_of_the_faceless_drainhealth() : SpellScriptLoader("spell_mark_of_the_faceless_drainhealth") { }
|
||||
|
||||
class spell_mark_of_the_faceless_drainhealth_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_mark_of_the_faceless_drainhealth_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.remove(GetExplTargetUnit());
|
||||
if (targets.empty())
|
||||
Cancel();
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mark_of_the_faceless_drainhealth_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_mark_of_the_faceless_drainhealth_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_saronite_vapors_dummy : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_saronite_vapors_dummy() : SpellScriptLoader("spell_saronite_vapors_dummy") { }
|
||||
|
||||
class spell_saronite_vapors_dummy_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_saronite_vapors_dummy_AuraScript)
|
||||
|
||||
void HandleAfterEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
int32 damage = 100 * pow(2.0f, (float)GetStackAmount());
|
||||
caster->CastCustomSpell(GetTarget(), SPELL_SARONITE_VAPORS_DMG, &damage, nullptr, nullptr, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectApply += AuraEffectApplyFn(spell_saronite_vapors_dummy_AuraScript::HandleAfterEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_saronite_vapors_dummy_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_saronite_vapors_damage : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_saronite_vapors_damage() : SpellScriptLoader("spell_saronite_vapors_damage") { }
|
||||
|
||||
class spell_saronite_vapors_damage_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_saronite_vapors_damage_SpellScript);
|
||||
|
||||
void HandleAfterHit()
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
if (GetHitDamage() > 2)
|
||||
{
|
||||
int32 mana = GetHitDamage() / 2;
|
||||
if (Unit* t = GetHitUnit())
|
||||
caster->CastCustomSpell(t, SPELL_SARONITE_VAPORS_ENERGIZE, &mana, nullptr, nullptr, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterHit += SpellHitFn(spell_saronite_vapors_damage_SpellScript::HandleAfterHit);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_saronite_vapors_damage_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_smell_saronite : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_smell_saronite() : AchievementCriteriaScript("achievement_smell_saronite") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
return target && target->GetEntry() == NPC_VEZAX && target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->AI()->GetData(1);
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_shadowdodger : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_shadowdodger() : AchievementCriteriaScript("achievement_shadowdodger") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
return target && target->GetEntry() == NPC_VEZAX && target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->AI()->GetData(2);
|
||||
}
|
||||
};
|
||||
|
||||
class go_ulduar_pure_saronite_deposit : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
go_ulduar_pure_saronite_deposit() : GameObjectScript("go_ulduar_pure_saronite_deposit") { }
|
||||
|
||||
bool OnGossipHello(Player* plr, GameObject* go) override
|
||||
{
|
||||
if (plr->IsGameMaster())
|
||||
return false;
|
||||
|
||||
if (InstanceScript* pInstance = go->GetInstanceScript())
|
||||
if (pInstance->GetData(TYPE_XT002) != DONE && pInstance->GetData(TYPE_MIMIRON) != DONE && pInstance->GetData(TYPE_THORIM) != DONE && pInstance->GetData(TYPE_FREYA) != DONE && pInstance->GetData(TYPE_HODIR) != DONE)
|
||||
{
|
||||
std::string accountName;
|
||||
AccountMgr::GetName(plr->GetSession()->GetAccountId(), accountName);
|
||||
sBan->BanAccount(accountName, "0s", "Tele hack", "Server");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
1594
src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.h
Normal file
1594
src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "boss_ignis.h"
|
||||
#include "AchievementCriteriaScript.h"
|
||||
#include "CreatureScript.h"
|
||||
#include "GameTime.h"
|
||||
@@ -27,527 +28,6 @@
|
||||
#include "Vehicle.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
#define SPELL_FLAME_JETS_10 62680
|
||||
#define SPELL_FLAME_JETS_25 63472
|
||||
#define S_FLAME_JETS RAID_MODE(SPELL_FLAME_JETS_10, SPELL_FLAME_JETS_25)
|
||||
#define SPELL_SCORCH_10 62546
|
||||
#define SPELL_SCORCH_25 63474
|
||||
#define S_SCORCH RAID_MODE(SPELL_SCORCH_10, SPELL_SCORCH_25)
|
||||
#define SPELL_ACTIVATE_CONSTRUCT 62488
|
||||
#define SPELL_STRENGTH_OF_THE_CREATOR 64473
|
||||
#define SPELL_SLAG_POT_10 62717
|
||||
#define SPELL_SLAG_POT_25 63477
|
||||
#define S_SLAG_POT RAID_MODE(SPELL_SLAG_POT_10, SPELL_SLAG_POT_25)
|
||||
#define SPELL_BERSERK 64238
|
||||
#define SPELL_GRAB 62707
|
||||
#define SPELL_GRAB_TRIGGERED 62708
|
||||
#define SPELL_GRAB_CONTROL_2 62711
|
||||
|
||||
#define SPELL_SCORCHED_GROUND_10 62548
|
||||
#define SPELL_SCORCHED_GROUND_25 63476
|
||||
#define S_SCORCHED_GROUND RAID_MODE(SPELL_SCORCHED_GROUND_10, SPELL_SCORCHED_GROUND_25)
|
||||
#define SPELL_HEAT_AREA 62343
|
||||
#define SPELL_HEAT_BUFF 65667
|
||||
#define SPELL_MOLTEN 62373
|
||||
#define SPELL_BRITTLE_10 62382
|
||||
#define SPELL_BRITTLE_25 67114
|
||||
#define S_BRITTLE RAID_MODE(SPELL_BRITTLE_10, SPELL_BRITTLE_25)
|
||||
#define SPELL_SHATTER 62383
|
||||
|
||||
#define BOSS_IGNIS 33118
|
||||
#define NPC_IRON_CONSTRUCT 33121
|
||||
#define NPC_SCORCHED_GROUND 33123
|
||||
#define NPC_WATER_TRIGGER 22515
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SUMMON = 1,
|
||||
SAY_SLAG_POT = 2,
|
||||
SAY_SCORCH = 3,
|
||||
SAY_SLAY = 4,
|
||||
SAY_BERSERK = 5,
|
||||
SAY_DEATH = 6,
|
||||
EMOTE_JETS = 7,
|
||||
};
|
||||
|
||||
#define ACHIEV_STOKIN_THE_FURNACE_EVENT 20951
|
||||
|
||||
enum eEvents
|
||||
{
|
||||
EVENT_NONE = 0,
|
||||
EVENT_ACTIVATE_CONSTRUCT,
|
||||
EVENT_SPELL_SCORCH,
|
||||
EVENT_ENABLE_ROTATE,
|
||||
EVENT_SPELL_FLAME_JETS,
|
||||
EVENT_GRAB,
|
||||
};
|
||||
|
||||
class npc_ulduar_iron_construct : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_ulduar_iron_construct() : CreatureScript("npc_ulduar_iron_construct") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<npc_ulduar_iron_constructAI>(pCreature);
|
||||
}
|
||||
|
||||
struct npc_ulduar_iron_constructAI : public ScriptedAI
|
||||
{
|
||||
npc_ulduar_iron_constructAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
me->CastSpell(me, 38757, true);
|
||||
}
|
||||
|
||||
uint16 timer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
timer = 1000;
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
me->CastSpell(me, 38757, true);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
|
||||
{
|
||||
if (spell->Id == SPELL_ACTIVATE_CONSTRUCT)
|
||||
{
|
||||
me->RemoveAura(38757);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (Creature* ignis = ObjectAccessor::GetCreature(*me, instance->GetGuidData(TYPE_IGNIS)))
|
||||
{
|
||||
ignis->CastSpell(ignis, SPELL_STRENGTH_OF_THE_CREATOR, true);
|
||||
AttackStart(ignis->GetVictim());
|
||||
DoZoneInCombat();
|
||||
}
|
||||
}
|
||||
else if (spell->Id == SPELL_HEAT_BUFF)
|
||||
{
|
||||
if (Aura* heat = me->GetAura(SPELL_HEAT_BUFF))
|
||||
{
|
||||
if (heat->GetStackAmount() >= 10)
|
||||
{
|
||||
if (heat->GetStackAmount() > 10)
|
||||
{
|
||||
heat->ModStackAmount(-1);
|
||||
}
|
||||
me->CastSpell(me, SPELL_MOLTEN, true);
|
||||
me->GetThreatMgr().ResetAllThreat();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if( damage >= RAID_MODE(3000U, 5000U) && me->GetAura(S_BRITTLE) )
|
||||
{
|
||||
me->CastSpell(me, SPELL_SHATTER, true);
|
||||
Unit::Kill(attacker, me);
|
||||
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (Creature* ignis = ObjectAccessor::GetCreature(*me, instance->GetGuidData(TYPE_IGNIS)))
|
||||
ignis->AI()->SetData(1337, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (Creature* ignis = ObjectAccessor::GetCreature(*me, instance->GetGuidData(TYPE_IGNIS)))
|
||||
ignis->RemoveAuraFromStack(SPELL_STRENGTH_OF_THE_CREATOR);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (timer <= diff)
|
||||
{
|
||||
timer = 1000;
|
||||
if (Aura* a = me->GetAura(SPELL_MOLTEN))
|
||||
if (me->FindNearestCreature(NPC_WATER_TRIGGER, 18.0f, true))
|
||||
{
|
||||
me->RemoveAura(a);
|
||||
me->CastSpell(me, S_BRITTLE, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override {}
|
||||
};
|
||||
};
|
||||
|
||||
class boss_ignis : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_ignis() : CreatureScript("boss_ignis") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<boss_ignisAI>(pCreature);
|
||||
}
|
||||
|
||||
struct boss_ignisAI : public ScriptedAI
|
||||
{
|
||||
boss_ignisAI(Creature* pCreature) : ScriptedAI(pCreature) { }
|
||||
|
||||
EventMap events;
|
||||
uint8 counter;
|
||||
bool bShattered;
|
||||
uint32 lastShatterMSTime;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
counter = 0;
|
||||
bShattered = false;
|
||||
lastShatterMSTime = 0;
|
||||
|
||||
if( InstanceScript* m_pInstance = me->GetInstanceScript() )
|
||||
{
|
||||
m_pInstance->SetData(TYPE_IGNIS, NOT_STARTED);
|
||||
m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_STOKIN_THE_FURNACE_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
me->setActive(true);
|
||||
|
||||
std::list<Creature*> icl;
|
||||
me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT);
|
||||
for( std::list<Creature*>::iterator itr = icl.begin(); itr != icl.end(); ++itr )
|
||||
{
|
||||
if (!(*itr)->IsAlive())
|
||||
{
|
||||
(*itr)->Respawn();
|
||||
(*itr)->UpdatePosition((*itr)->GetHomePosition(), true);
|
||||
(*itr)->StopMovingOnCurrentPos();
|
||||
}
|
||||
(*itr)->AI()->Reset();
|
||||
if (!(*itr)->HasAura(38757))
|
||||
(*itr)->CastSpell((*itr), 38757, true);
|
||||
}
|
||||
|
||||
bShattered = false;
|
||||
lastShatterMSTime = 0;
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_ACTIVATE_CONSTRUCT, RAID_MODE(40000, 30000));
|
||||
events.ScheduleEvent(EVENT_SPELL_SCORCH, 10s);
|
||||
events.ScheduleEvent(EVENT_SPELL_FLAME_JETS, 32s);
|
||||
events.ScheduleEvent(EVENT_GRAB, 25s);
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
DoZoneInCombat();
|
||||
|
||||
if( InstanceScript* m_pInstance = me->GetInstanceScript() )
|
||||
{
|
||||
m_pInstance->SetData(TYPE_IGNIS, IN_PROGRESS);
|
||||
m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_STOKIN_THE_FURNACE_EVENT);
|
||||
m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_STOKIN_THE_FURNACE_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 id, uint32 /*value*/) override
|
||||
{
|
||||
if (id == 1337)
|
||||
{
|
||||
if (lastShatterMSTime)
|
||||
if (getMSTimeDiff(lastShatterMSTime, GameTime::GetGameTimeMS().count()) <= 5000)
|
||||
bShattered = true;
|
||||
|
||||
lastShatterMSTime = GameTime::GetGameTimeMS().count();
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 id) const override
|
||||
{
|
||||
if (id == 1337)
|
||||
return (bShattered ? 1 : 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
me->setActive(false);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if( me->GetInstanceScript() )
|
||||
me->GetInstanceScript()->SetData(TYPE_IGNIS, DONE);
|
||||
|
||||
std::list<Creature*> icl;
|
||||
me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT);
|
||||
for( std::list<Creature*>::iterator itr = icl.begin(); itr != icl.end(); ++itr )
|
||||
if ((*itr)->IsAlive() && (*itr)->IsInCombat())
|
||||
Unit::Kill(*itr, *itr);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, SpellInfo const* spell) override
|
||||
{
|
||||
if (caster && spell->Id == SPELL_GRAB_CONTROL_2)
|
||||
{
|
||||
//caster->ClearUnitState(UNIT_STATE_ONVEHICLE);
|
||||
me->CastSpell(caster, S_SLAG_POT, true);
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override {}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if( me->GetPositionX() < 490.0f || me->GetPositionX() > 690.0f || me->GetPositionY() < 130.0f || me->GetPositionY() > 410.0f )
|
||||
{
|
||||
EnterEvadeMode(EVADE_REASON_OTHER);
|
||||
return;
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_ACTIVATE_CONSTRUCT:
|
||||
Talk(SAY_SUMMON);
|
||||
me->CastCustomSpell(SPELL_ACTIVATE_CONSTRUCT, SPELLVALUE_MAX_TARGETS, 1, (Unit*)nullptr, false);
|
||||
if (++counter >= 20)
|
||||
{
|
||||
Talk(SAY_BERSERK);
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
break;
|
||||
}
|
||||
events.RepeatEvent(RAID_MODE(40000, 30000));
|
||||
break;
|
||||
case EVENT_SPELL_SCORCH:
|
||||
Talk(SAY_SCORCH);
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(true);
|
||||
me->SendMovementFlagUpdate();
|
||||
me->CastSpell(me->GetVictim(), S_SCORCH, false);
|
||||
events.Repeat(20s);
|
||||
events.RescheduleEvent(EVENT_ENABLE_ROTATE, 3s);
|
||||
break;
|
||||
case EVENT_ENABLE_ROTATE:
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
break;
|
||||
case EVENT_SPELL_FLAME_JETS:
|
||||
Talk(EMOTE_JETS);
|
||||
me->CastSpell(me->GetVictim(), S_FLAME_JETS, false);
|
||||
events.Repeat(25s);
|
||||
break;
|
||||
case EVENT_GRAB:
|
||||
{
|
||||
std::list<Creature*> icl;
|
||||
me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT);
|
||||
|
||||
GuidVector playerGUIDs;
|
||||
Map::PlayerList const& pl = me->GetMap()->GetPlayers();
|
||||
Player* temp = nullptr;
|
||||
|
||||
for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
|
||||
{
|
||||
temp = itr->GetSource();
|
||||
if( !temp->IsAlive() || temp->GetExactDist2d(me) > 90.0f )
|
||||
continue;
|
||||
if( me->GetVictim() && temp->GetGUID() == me->GetVictim()->GetGUID() )
|
||||
continue;
|
||||
bool found = false;
|
||||
for (std::list<Creature*>::iterator iterator = icl.begin(); iterator != icl.end(); ++iterator)
|
||||
{
|
||||
if ((*iterator)->GetVictim() && (*iterator)->GetVictim()->GetGUID() == temp->GetGUID())
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !found )
|
||||
playerGUIDs.push_back(temp->GetGUID());
|
||||
}
|
||||
|
||||
if( !playerGUIDs.empty() )
|
||||
{
|
||||
int8 pos = urand(0, playerGUIDs.size() - 1);
|
||||
if( Player* pTarget = ObjectAccessor::GetPlayer(*me, playerGUIDs.at(pos)) )
|
||||
{
|
||||
Talk(SAY_SLAG_POT);
|
||||
me->CastSpell(pTarget, SPELL_GRAB, false);
|
||||
}
|
||||
}
|
||||
|
||||
events.Repeat(24s);
|
||||
events.DelayEvents(6s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
ScriptedAI::EnterEvadeMode(why);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_ignis_scorch : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ignis_scorch() : SpellScriptLoader("spell_ignis_scorch") { }
|
||||
|
||||
class spell_ignis_scorch_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_ignis_scorch_AuraScript)
|
||||
|
||||
void HandleEffectPeriodic(AuraEffect const* aurEff)
|
||||
{
|
||||
if (aurEff->GetTotalTicks() >= 0 && aurEff->GetTickNumber() == uint32(aurEff->GetTotalTicks()))
|
||||
if (Unit* c = GetCaster())
|
||||
if (Creature* s = c->SummonCreature(NPC_SCORCHED_GROUND, c->GetPositionX() + 20.0f * cos(c->GetOrientation()), c->GetPositionY() + 20.0f * std::sin(c->GetOrientation()), 361.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 30000))
|
||||
{
|
||||
if (!s->FindNearestCreature(NPC_WATER_TRIGGER, 25.0f, true)) // must be away from the water
|
||||
s->CastSpell(s, (aurEff->GetId() == 62546 ? SPELL_SCORCHED_GROUND_10 : SPELL_SCORCHED_GROUND_25), true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_ignis_scorch_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_ignis_scorch_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_ignis_grab_initial : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ignis_grab_initial() : SpellScriptLoader("spell_ignis_grab_initial") { }
|
||||
|
||||
class spell_ignis_grab_initial_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_ignis_grab_initial_SpellScript);
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Unit* t = GetHitUnit())
|
||||
t->CastSpell(t, SPELL_GRAB_TRIGGERED, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_ignis_grab_initial_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_ignis_grab_initial_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_ignis_slag_pot : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ignis_slag_pot() : SpellScriptLoader("spell_ignis_slag_pot") { }
|
||||
|
||||
class spell_ignis_slag_pot_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_ignis_slag_pot_AuraScript)
|
||||
|
||||
void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
if (Unit* c = GetCaster())
|
||||
if (Unit* t = GetTarget())
|
||||
c->CastSpell(t, (GetId() == 62717 ? 65722 : 65723), true);
|
||||
}
|
||||
|
||||
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* t = GetTarget())
|
||||
{
|
||||
t->ApplySpellImmune(GetId(), IMMUNITY_ID, 62549, true);
|
||||
t->ApplySpellImmune(GetId(), IMMUNITY_ID, 63475, true);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* t = GetTarget())
|
||||
{
|
||||
t->ApplySpellImmune(GetId(), IMMUNITY_ID, 62549, false);
|
||||
t->ApplySpellImmune(GetId(), IMMUNITY_ID, 63475, false);
|
||||
if (t->IsAlive())
|
||||
t->CastSpell(t, (GetId() == 62717 ? 62836 : 63536), true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_ignis_slag_pot_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
OnEffectApply += AuraEffectApplyFn(spell_ignis_slag_pot_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_ignis_slag_pot_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_ignis_slag_pot_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_ignis_shattered : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_ignis_shattered() : AchievementCriteriaScript("achievement_ignis_shattered") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
if (!target || target->GetTypeId() != TYPEID_UNIT)
|
||||
return false;
|
||||
return !!target->ToCreature()->AI()->GetData(1337);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_ignis()
|
||||
{
|
||||
new boss_ignis();
|
||||
|
||||
537
src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.h
Normal file
537
src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.h
Normal file
@@ -0,0 +1,537 @@
|
||||
#ifndef BOSS_IGNIS_H_
|
||||
#define BOSS_IGNIS_H_
|
||||
|
||||
#include "AchievementCriteriaScript.h"
|
||||
#include "CreatureScript.h"
|
||||
#include "GameTime.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellScriptLoader.h"
|
||||
#include "Vehicle.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
#define SPELL_FLAME_JETS_10 62680
|
||||
#define SPELL_FLAME_JETS_25 63472
|
||||
#define S_FLAME_JETS RAID_MODE(SPELL_FLAME_JETS_10, SPELL_FLAME_JETS_25)
|
||||
#define SPELL_SCORCH_10 62546
|
||||
#define SPELL_SCORCH_25 63474
|
||||
#define S_SCORCH RAID_MODE(SPELL_SCORCH_10, SPELL_SCORCH_25)
|
||||
#define SPELL_ACTIVATE_CONSTRUCT 62488
|
||||
#define SPELL_STRENGTH_OF_THE_CREATOR 64473
|
||||
#define SPELL_SLAG_POT_10 62717
|
||||
#define SPELL_SLAG_POT_25 63477
|
||||
#define S_SLAG_POT RAID_MODE(SPELL_SLAG_POT_10, SPELL_SLAG_POT_25)
|
||||
#define SPELL_BERSERK 64238
|
||||
#define SPELL_GRAB 62707
|
||||
#define SPELL_GRAB_TRIGGERED 62708
|
||||
#define SPELL_GRAB_CONTROL_2 62711
|
||||
|
||||
#define SPELL_SCORCHED_GROUND_10 62548
|
||||
#define SPELL_SCORCHED_GROUND_25 63476
|
||||
#define S_SCORCHED_GROUND RAID_MODE(SPELL_SCORCHED_GROUND_10, SPELL_SCORCHED_GROUND_25)
|
||||
#define SPELL_HEAT_AREA 62343
|
||||
#define SPELL_HEAT_BUFF 65667
|
||||
#define SPELL_MOLTEN 62373
|
||||
#define SPELL_BRITTLE_10 62382
|
||||
#define SPELL_BRITTLE_25 67114
|
||||
#define S_BRITTLE RAID_MODE(SPELL_BRITTLE_10, SPELL_BRITTLE_25)
|
||||
#define SPELL_SHATTER 62383
|
||||
|
||||
#define BOSS_IGNIS 33118
|
||||
#define NPC_IRON_CONSTRUCT 33121
|
||||
#define NPC_SCORCHED_GROUND 33123
|
||||
#define NPC_WATER_TRIGGER 22515
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SUMMON = 1,
|
||||
SAY_SLAG_POT = 2,
|
||||
SAY_SCORCH = 3,
|
||||
SAY_SLAY = 4,
|
||||
SAY_BERSERK = 5,
|
||||
SAY_DEATH = 6,
|
||||
EMOTE_JETS = 7,
|
||||
};
|
||||
|
||||
#define ACHIEV_STOKIN_THE_FURNACE_EVENT 20951
|
||||
|
||||
enum eEvents
|
||||
{
|
||||
EVENT_NONE = 0,
|
||||
EVENT_ACTIVATE_CONSTRUCT,
|
||||
EVENT_SPELL_SCORCH,
|
||||
EVENT_ENABLE_ROTATE,
|
||||
EVENT_SPELL_FLAME_JETS,
|
||||
EVENT_GRAB,
|
||||
};
|
||||
|
||||
class npc_ulduar_iron_construct : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_ulduar_iron_construct() : CreatureScript("npc_ulduar_iron_construct") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<npc_ulduar_iron_constructAI>(pCreature);
|
||||
}
|
||||
|
||||
struct npc_ulduar_iron_constructAI : public ScriptedAI
|
||||
{
|
||||
npc_ulduar_iron_constructAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
me->CastSpell(me, 38757, true);
|
||||
}
|
||||
|
||||
uint16 timer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
timer = 1000;
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
me->CastSpell(me, 38757, true);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
|
||||
{
|
||||
if (spell->Id == SPELL_ACTIVATE_CONSTRUCT)
|
||||
{
|
||||
me->RemoveAura(38757);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (Creature* ignis = ObjectAccessor::GetCreature(*me, instance->GetGuidData(TYPE_IGNIS)))
|
||||
{
|
||||
ignis->CastSpell(ignis, SPELL_STRENGTH_OF_THE_CREATOR, true);
|
||||
AttackStart(ignis->GetVictim());
|
||||
DoZoneInCombat();
|
||||
}
|
||||
}
|
||||
else if (spell->Id == SPELL_HEAT_BUFF)
|
||||
{
|
||||
if (Aura* heat = me->GetAura(SPELL_HEAT_BUFF))
|
||||
{
|
||||
if (heat->GetStackAmount() >= 10)
|
||||
{
|
||||
if (heat->GetStackAmount() > 10)
|
||||
{
|
||||
heat->ModStackAmount(-1);
|
||||
}
|
||||
me->CastSpell(me, SPELL_MOLTEN, true);
|
||||
me->GetThreatMgr().ResetAllThreat();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if( damage >= RAID_MODE(3000U, 5000U) && me->GetAura(S_BRITTLE) )
|
||||
{
|
||||
me->CastSpell(me, SPELL_SHATTER, true);
|
||||
Unit::Kill(attacker, me);
|
||||
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (Creature* ignis = ObjectAccessor::GetCreature(*me, instance->GetGuidData(TYPE_IGNIS)))
|
||||
ignis->AI()->SetData(1337, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (Creature* ignis = ObjectAccessor::GetCreature(*me, instance->GetGuidData(TYPE_IGNIS)))
|
||||
ignis->RemoveAuraFromStack(SPELL_STRENGTH_OF_THE_CREATOR);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (timer <= diff)
|
||||
{
|
||||
timer = 1000;
|
||||
if (Aura* a = me->GetAura(SPELL_MOLTEN))
|
||||
if (me->FindNearestCreature(NPC_WATER_TRIGGER, 18.0f, true))
|
||||
{
|
||||
me->RemoveAura(a);
|
||||
me->CastSpell(me, S_BRITTLE, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override {}
|
||||
};
|
||||
};
|
||||
|
||||
class boss_ignis : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_ignis() : CreatureScript("boss_ignis") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<boss_ignisAI>(pCreature);
|
||||
}
|
||||
|
||||
struct boss_ignisAI : public ScriptedAI
|
||||
{
|
||||
boss_ignisAI(Creature* pCreature) : ScriptedAI(pCreature) { }
|
||||
|
||||
EventMap events;
|
||||
uint8 counter;
|
||||
bool bShattered;
|
||||
uint32 lastShatterMSTime;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
counter = 0;
|
||||
bShattered = false;
|
||||
lastShatterMSTime = 0;
|
||||
|
||||
if( InstanceScript* m_pInstance = me->GetInstanceScript() )
|
||||
{
|
||||
m_pInstance->SetData(TYPE_IGNIS, NOT_STARTED);
|
||||
m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_STOKIN_THE_FURNACE_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
me->setActive(true);
|
||||
|
||||
std::list<Creature*> icl;
|
||||
me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT);
|
||||
for( std::list<Creature*>::iterator itr = icl.begin(); itr != icl.end(); ++itr )
|
||||
{
|
||||
if (!(*itr)->IsAlive())
|
||||
{
|
||||
(*itr)->Respawn();
|
||||
(*itr)->UpdatePosition((*itr)->GetHomePosition(), true);
|
||||
(*itr)->StopMovingOnCurrentPos();
|
||||
}
|
||||
(*itr)->AI()->Reset();
|
||||
if (!(*itr)->HasAura(38757))
|
||||
(*itr)->CastSpell((*itr), 38757, true);
|
||||
}
|
||||
|
||||
bShattered = false;
|
||||
lastShatterMSTime = 0;
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_ACTIVATE_CONSTRUCT, RAID_MODE(40000, 30000));
|
||||
events.ScheduleEvent(EVENT_SPELL_SCORCH, 10s);
|
||||
events.ScheduleEvent(EVENT_SPELL_FLAME_JETS, 32s);
|
||||
events.ScheduleEvent(EVENT_GRAB, 25s);
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
DoZoneInCombat();
|
||||
|
||||
if( InstanceScript* m_pInstance = me->GetInstanceScript() )
|
||||
{
|
||||
m_pInstance->SetData(TYPE_IGNIS, IN_PROGRESS);
|
||||
m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_STOKIN_THE_FURNACE_EVENT);
|
||||
m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_STOKIN_THE_FURNACE_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 id, uint32 /*value*/) override
|
||||
{
|
||||
if (id == 1337)
|
||||
{
|
||||
if (lastShatterMSTime)
|
||||
if (getMSTimeDiff(lastShatterMSTime, GameTime::GetGameTimeMS().count()) <= 5000)
|
||||
bShattered = true;
|
||||
|
||||
lastShatterMSTime = GameTime::GetGameTimeMS().count();
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 id) const override
|
||||
{
|
||||
if (id == 1337)
|
||||
return (bShattered ? 1 : 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
me->setActive(false);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if( me->GetInstanceScript() )
|
||||
me->GetInstanceScript()->SetData(TYPE_IGNIS, DONE);
|
||||
|
||||
std::list<Creature*> icl;
|
||||
me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT);
|
||||
for( std::list<Creature*>::iterator itr = icl.begin(); itr != icl.end(); ++itr )
|
||||
if ((*itr)->IsAlive() && (*itr)->IsInCombat())
|
||||
Unit::Kill(*itr, *itr);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, SpellInfo const* spell) override
|
||||
{
|
||||
if (caster && spell->Id == SPELL_GRAB_CONTROL_2)
|
||||
{
|
||||
//caster->ClearUnitState(UNIT_STATE_ONVEHICLE);
|
||||
me->CastSpell(caster, S_SLAG_POT, true);
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override {}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if( me->GetPositionX() < 490.0f || me->GetPositionX() > 690.0f || me->GetPositionY() < 130.0f || me->GetPositionY() > 410.0f )
|
||||
{
|
||||
EnterEvadeMode(EVADE_REASON_OTHER);
|
||||
return;
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_ACTIVATE_CONSTRUCT:
|
||||
Talk(SAY_SUMMON);
|
||||
me->CastCustomSpell(SPELL_ACTIVATE_CONSTRUCT, SPELLVALUE_MAX_TARGETS, 1, (Unit*)nullptr, false);
|
||||
if (++counter >= 20)
|
||||
{
|
||||
Talk(SAY_BERSERK);
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
break;
|
||||
}
|
||||
events.RepeatEvent(RAID_MODE(40000, 30000));
|
||||
break;
|
||||
case EVENT_SPELL_SCORCH:
|
||||
Talk(SAY_SCORCH);
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(true);
|
||||
me->SendMovementFlagUpdate();
|
||||
me->CastSpell(me->GetVictim(), S_SCORCH, false);
|
||||
events.Repeat(20s);
|
||||
events.RescheduleEvent(EVENT_ENABLE_ROTATE, 3s);
|
||||
break;
|
||||
case EVENT_ENABLE_ROTATE:
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
break;
|
||||
case EVENT_SPELL_FLAME_JETS:
|
||||
Talk(EMOTE_JETS);
|
||||
me->CastSpell(me->GetVictim(), S_FLAME_JETS, false);
|
||||
events.Repeat(25s);
|
||||
break;
|
||||
case EVENT_GRAB:
|
||||
{
|
||||
std::list<Creature*> icl;
|
||||
me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT);
|
||||
|
||||
GuidVector playerGUIDs;
|
||||
Map::PlayerList const& pl = me->GetMap()->GetPlayers();
|
||||
Player* temp = nullptr;
|
||||
|
||||
for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
|
||||
{
|
||||
temp = itr->GetSource();
|
||||
if( !temp->IsAlive() || temp->GetExactDist2d(me) > 90.0f )
|
||||
continue;
|
||||
if( me->GetVictim() && temp->GetGUID() == me->GetVictim()->GetGUID() )
|
||||
continue;
|
||||
bool found = false;
|
||||
for (std::list<Creature*>::iterator iterator = icl.begin(); iterator != icl.end(); ++iterator)
|
||||
{
|
||||
if ((*iterator)->GetVictim() && (*iterator)->GetVictim()->GetGUID() == temp->GetGUID())
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !found )
|
||||
playerGUIDs.push_back(temp->GetGUID());
|
||||
}
|
||||
|
||||
if( !playerGUIDs.empty() )
|
||||
{
|
||||
int8 pos = urand(0, playerGUIDs.size() - 1);
|
||||
if( Player* pTarget = ObjectAccessor::GetPlayer(*me, playerGUIDs.at(pos)) )
|
||||
{
|
||||
Talk(SAY_SLAG_POT);
|
||||
me->CastSpell(pTarget, SPELL_GRAB, false);
|
||||
}
|
||||
}
|
||||
|
||||
events.Repeat(24s);
|
||||
events.DelayEvents(6s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
ScriptedAI::EnterEvadeMode(why);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_ignis_scorch : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ignis_scorch() : SpellScriptLoader("spell_ignis_scorch") { }
|
||||
|
||||
class spell_ignis_scorch_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_ignis_scorch_AuraScript)
|
||||
|
||||
void HandleEffectPeriodic(AuraEffect const* aurEff)
|
||||
{
|
||||
if (aurEff->GetTotalTicks() >= 0 && aurEff->GetTickNumber() == uint32(aurEff->GetTotalTicks()))
|
||||
if (Unit* c = GetCaster())
|
||||
if (Creature* s = c->SummonCreature(NPC_SCORCHED_GROUND, c->GetPositionX() + 20.0f * cos(c->GetOrientation()), c->GetPositionY() + 20.0f * std::sin(c->GetOrientation()), 361.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 30000))
|
||||
{
|
||||
if (!s->FindNearestCreature(NPC_WATER_TRIGGER, 25.0f, true)) // must be away from the water
|
||||
s->CastSpell(s, (aurEff->GetId() == 62546 ? SPELL_SCORCHED_GROUND_10 : SPELL_SCORCHED_GROUND_25), true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_ignis_scorch_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_ignis_scorch_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_ignis_grab_initial : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ignis_grab_initial() : SpellScriptLoader("spell_ignis_grab_initial") { }
|
||||
|
||||
class spell_ignis_grab_initial_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_ignis_grab_initial_SpellScript);
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Unit* t = GetHitUnit())
|
||||
t->CastSpell(t, SPELL_GRAB_TRIGGERED, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_ignis_grab_initial_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_ignis_grab_initial_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_ignis_slag_pot : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ignis_slag_pot() : SpellScriptLoader("spell_ignis_slag_pot") { }
|
||||
|
||||
class spell_ignis_slag_pot_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_ignis_slag_pot_AuraScript)
|
||||
|
||||
void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
if (Unit* c = GetCaster())
|
||||
if (Unit* t = GetTarget())
|
||||
c->CastSpell(t, (GetId() == 62717 ? 65722 : 65723), true);
|
||||
}
|
||||
|
||||
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* t = GetTarget())
|
||||
{
|
||||
t->ApplySpellImmune(GetId(), IMMUNITY_ID, 62549, true);
|
||||
t->ApplySpellImmune(GetId(), IMMUNITY_ID, 63475, true);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* t = GetTarget())
|
||||
{
|
||||
t->ApplySpellImmune(GetId(), IMMUNITY_ID, 62549, false);
|
||||
t->ApplySpellImmune(GetId(), IMMUNITY_ID, 63475, false);
|
||||
if (t->IsAlive())
|
||||
t->CastSpell(t, (GetId() == 62717 ? 62836 : 63536), true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_ignis_slag_pot_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
OnEffectApply += AuraEffectApplyFn(spell_ignis_slag_pot_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_ignis_slag_pot_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_ignis_slag_pot_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_ignis_shattered : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_ignis_shattered() : AchievementCriteriaScript("achievement_ignis_shattered") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
if (!target || target->GetTypeId() != TYPEID_UNIT)
|
||||
return false;
|
||||
return !!target->ToCreature()->AI()->GetData(1337);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -15,6 +15,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "boss_kologarn.h"
|
||||
#include "AchievementCriteriaScript.h"
|
||||
#include "CreatureScript.h"
|
||||
#include "PassiveAI.h"
|
||||
@@ -26,867 +27,6 @@
|
||||
#include "Vehicle.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
enum KologarnSays
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_LEFT_ARM_GONE = 2,
|
||||
SAY_RIGHT_ARM_GONE = 3,
|
||||
SAY_SHOCKWAVE = 4,
|
||||
SAY_GRAB_PLAYER = 5,
|
||||
SAY_DEATH = 6,
|
||||
SAY_BERSERK = 7,
|
||||
EMOTE_STONE_GRIP = 8,
|
||||
EMOTE_EYES = 9
|
||||
};
|
||||
|
||||
enum KologarnSpells
|
||||
{
|
||||
SPELL_KOLOGARN_REDUCE_PARRY = 64651,
|
||||
|
||||
// BASIC
|
||||
SPELL_OVERHEAD_SMASH_10 = 63356,
|
||||
SPELL_OVERHEAD_SMASH_25 = 64003,
|
||||
SPELL_ONEARMED_OVERHEAD_SMASH_10 = 63573,
|
||||
SPELL_ONEARMED_OVERHEAD_SMASH_25 = 64006,
|
||||
SPELL_PETRIFYING_BREATH_10 = 62030,
|
||||
SPELL_PETRIFYING_BREATH_25 = 63980,
|
||||
SPELL_STONE_SHOUT_10 = 63716,
|
||||
SPELL_STONE_SHOUT_25 = 64005,
|
||||
|
||||
// EYEBEAM
|
||||
SPELL_FOCUSED_EYEBEAM_SUMMON = 63342,
|
||||
SPELL_FOCUSED_EYEBEAM_10 = 63347,
|
||||
SPELL_FOCUSED_EYEBEAM_25 = 63977,
|
||||
SPELL_FOCUSED_EYEBEAM_RIGHT = 63702,
|
||||
SPELL_FOCUSED_EYEBEAM_LEFT = 63676,
|
||||
|
||||
// ARMS
|
||||
SPELL_ARM_DEAD_10 = 63629,
|
||||
SPELL_ARM_DEAD_25 = 63979,
|
||||
SPELL_RUBBLE_FALL_10 = 63821,
|
||||
SPELL_RUBBLE_FALL_25 = 64001,
|
||||
SPELL_ARM_RESPAWN_VISUAL = 64753,
|
||||
|
||||
// LEFT ARM
|
||||
SPELL_ARM_SWEEP_10 = 63766,
|
||||
SPELL_ARM_SWEEP_25 = 63983,
|
||||
|
||||
// RIGHT ARM
|
||||
SPELL_STONE_GRIP_10 = 62166,
|
||||
SPELL_STONE_GRIP_25 = 63981,
|
||||
SPELL_RIDE_RIGHT_ARM_10 = 62056,
|
||||
SPELL_RIDE_RIGHT_ARM_25 = 63985,
|
||||
|
||||
// RUBBLE TRASH
|
||||
SPELL_RUBBLE_ATTACK_10 = 63818,
|
||||
SPELL_RUBBLE_ATTACK_25 = 63978,
|
||||
};
|
||||
|
||||
#define SPELL_PETRIFYING_BREATH RAID_MODE(SPELL_PETRIFYING_BREATH_10, SPELL_PETRIFYING_BREATH_25)
|
||||
#define SPELL_OVERHEAD_SMASH RAID_MODE(SPELL_OVERHEAD_SMASH_10, SPELL_OVERHEAD_SMASH_25)
|
||||
#define SPELL_ONEARMED_OVERHEAD_SMASH RAID_MODE(SPELL_ONEARMED_OVERHEAD_SMASH_10, SPELL_ONEARMED_OVERHEAD_SMASH_25)
|
||||
#define SPELL_ARM_DEAD RAID_MODE(SPELL_ARM_DEAD_10, SPELL_ARM_DEAD_25)
|
||||
#define SPELL_ARM_SWEEP RAID_MODE(SPELL_ARM_SWEEP_10, SPELL_ARM_SWEEP_25)
|
||||
#define SPELL_STONE_GRIP RAID_MODE(SPELL_STONE_GRIP_10, SPELL_STONE_GRIP_25)
|
||||
#define SPELL_FOCUSED_EYEBEAM RAID_MODE(SPELL_FOCUSED_EYEBEAM_10, SPELL_FOCUSED_EYEBEAM_25)
|
||||
#define SPELL_RUBBLE_FALL RAID_MODE(SPELL_RUBBLE_FALL_10, SPELL_RUBBLE_FALL_25)
|
||||
#define SPELL_RUBBLE_ATTACK RAID_MODE(SPELL_RUBBLE_ATTACK_10, SPELL_RUBBLE_ATTACK_25)
|
||||
#define SPELL_RIDE_RIGHT_ARM RAID_MODE(SPELL_RIDE_RIGHT_ARM_10, SPELL_RIDE_RIGHT_ARM_25)
|
||||
#define SPELL_STONE_SHOUT RAID_MODE(SPELL_STONE_SHOUT_10, SPELL_STONE_SHOUT_25)
|
||||
|
||||
enum KologarnEvents
|
||||
{
|
||||
EVENT_SMASH = 1,
|
||||
EVENT_GRIP = 2,
|
||||
EVENT_SWEEP = 3,
|
||||
EVENT_RESTORE_ARM_LEFT = 4,
|
||||
EVENT_RESTORE_ARM_RIGHT = 5,
|
||||
EVENT_FOCUSED_EYEBEAM = 6,
|
||||
EVENT_STONE_SHOUT = 7,
|
||||
EVENT_PREPARE_BREATH = 8, // Kologarn can't cast breath on pull
|
||||
};
|
||||
|
||||
enum KologarnNPCs
|
||||
{
|
||||
NPC_LEFT_ARM = 32933,
|
||||
NPC_RIGHT_ARM = 32934,
|
||||
NPC_SWEEP_TRIGGER = 33661,
|
||||
NPC_EYE_LEFT = 33632,
|
||||
NPC_EYE_RIGHT = 33802,
|
||||
NPC_RUBBLE_TRIGGER = 33809,
|
||||
NPC_RUBBLE_SUMMON = 33768,
|
||||
};
|
||||
|
||||
enum KologarnSounds
|
||||
{
|
||||
SOUND_AGGRO = 15586,
|
||||
SOUND_SLAY1 = 15587,
|
||||
SOUND_SLAY2 = 15588,
|
||||
SOUND_LARM_GONE = 15589,
|
||||
SOUND_RARM_GONE = 15590,
|
||||
SOUND_SHOCKWAVE = 15591,
|
||||
SOUND_GRIP = 15592,
|
||||
SOUND_DEATH = 15593,
|
||||
SOUND_BERSERK = 15594,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
ACHIEVEMENT_DISARMED_CRITERIA = 21687,
|
||||
|
||||
DATA_KOLOGARN_LOOKS_ACHIEV = 55,
|
||||
DATA_KOLOGARN_RUBBLE_ACHIEV = 56,
|
||||
DATA_KOLOGARN_ARMS_ACHIEV = 57,
|
||||
};
|
||||
|
||||
class boss_kologarn : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_kologarn() : CreatureScript("boss_kologarn") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<boss_kologarnAI>(pCreature);
|
||||
}
|
||||
|
||||
struct boss_kologarnAI : public ScriptedAI
|
||||
{
|
||||
boss_kologarnAI(Creature* pCreature) : ScriptedAI(pCreature), vehicle(me->GetVehicleKit()), summons(me), breathReady(false)
|
||||
{
|
||||
m_pInstance = me->GetInstanceScript();
|
||||
eyebeamTarget = nullptr;
|
||||
assert(vehicle);
|
||||
me->SetStandState(UNIT_STAND_STATE_SUBMERGED);
|
||||
}
|
||||
|
||||
InstanceScript* m_pInstance;
|
||||
|
||||
Vehicle* vehicle;
|
||||
ObjectGuid _left, _right;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
|
||||
Unit* eyebeamTarget;
|
||||
|
||||
bool _looksAchievement, breathReady;
|
||||
uint8 _rubbleAchievement;
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && me->GetExactDist2d(who) < 45.0f && me->getStandState() == UNIT_STAND_STATE_SUBMERGED)
|
||||
{
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
if (Unit* arm = ObjectAccessor::GetCreature(*me, _left))
|
||||
arm->CastSpell(arm, SPELL_ARM_RESPAWN_VISUAL, true);
|
||||
if (Unit* arm = ObjectAccessor::GetCreature(*me, _right))
|
||||
arm->CastSpell(arm, SPELL_ARM_RESPAWN_VISUAL, true);
|
||||
}
|
||||
|
||||
if (me->GetExactDist2d(who) < 30.0f)
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
if (!_EnterEvadeMode(why))
|
||||
return;
|
||||
Reset();
|
||||
me->setActive(false);
|
||||
}
|
||||
|
||||
void AttachLeftArm()
|
||||
{
|
||||
if (Unit* arm = ObjectAccessor::GetCreature(*me, _left))
|
||||
arm->SetHealth(arm->GetMaxHealth());
|
||||
else if (Creature* accessory = me->SummonCreature(NPC_LEFT_ARM, *me, TEMPSUMMON_MANUAL_DESPAWN))
|
||||
{
|
||||
accessory->AddUnitTypeMask(UNIT_MASK_ACCESSORY);
|
||||
if (!me->HandleSpellClick(accessory, 0))
|
||||
accessory->DespawnOrUnsummon();
|
||||
else
|
||||
{
|
||||
_left = accessory->GetGUID();
|
||||
accessory->SetOrientation(M_PI);
|
||||
accessory->CastSpell(accessory, SPELL_ARM_RESPAWN_VISUAL, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AttachRightArm()
|
||||
{
|
||||
if (Unit* arm = ObjectAccessor::GetCreature(*me, _right))
|
||||
arm->SetHealth(arm->GetMaxHealth());
|
||||
else if (Creature* accessory = me->SummonCreature(NPC_RIGHT_ARM, *me, TEMPSUMMON_MANUAL_DESPAWN))
|
||||
{
|
||||
accessory->AddUnitTypeMask(UNIT_MASK_ACCESSORY);
|
||||
if (!me->HandleSpellClick(accessory, 1))
|
||||
accessory->DespawnOrUnsummon();
|
||||
else
|
||||
{
|
||||
_right = accessory->GetGUID();
|
||||
accessory->SetOrientation(M_PI);
|
||||
accessory->CastSpell(accessory, SPELL_ARM_RESPAWN_VISUAL, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_rubbleAchievement = 0;
|
||||
_looksAchievement = true;
|
||||
|
||||
me->SetDisableGravity(true);
|
||||
me->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE);
|
||||
me->DisableRotate(true);
|
||||
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
|
||||
if (m_pInstance)
|
||||
{
|
||||
m_pInstance->SetData(TYPE_KOLOGARN, NOT_STARTED);
|
||||
|
||||
// Open the door inside Kologarn chamber
|
||||
if (GameObject* door = m_pInstance->instance->GetGameObject(m_pInstance->GetGuidData(GO_KOLOGARN_DOORS)))
|
||||
door->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
|
||||
AttachLeftArm();
|
||||
AttachRightArm();
|
||||
|
||||
// Reset breath on pull
|
||||
breathReady = false;
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == DATA_KOLOGARN_LOOKS_ACHIEV)
|
||||
_looksAchievement = false;
|
||||
if (param == DATA_KOLOGARN_RUBBLE_ACHIEV)
|
||||
{
|
||||
// Means arm died
|
||||
if (m_pInstance && (!_left || !_right))
|
||||
m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_DISARMED_CRITERIA);
|
||||
|
||||
++_rubbleAchievement;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 param) const override
|
||||
{
|
||||
if (param == DATA_KOLOGARN_LOOKS_ACHIEV)
|
||||
return _looksAchievement;
|
||||
else if (param == DATA_KOLOGARN_RUBBLE_ACHIEV)
|
||||
return (_rubbleAchievement >= 5);
|
||||
else if (param == DATA_KOLOGARN_ARMS_ACHIEV)
|
||||
return !_rubbleAchievement;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
{
|
||||
me->Attack(who, true);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) override
|
||||
{
|
||||
if (cr->GetEntry() != NPC_LEFT_ARM && cr->GetEntry() != NPC_RIGHT_ARM)
|
||||
summons.Summon(cr);
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
summons.DespawnAll();
|
||||
me->StopMoving();
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_KOLOGARN, DONE);
|
||||
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if (m_pInstance)
|
||||
{
|
||||
// Open the door inside Kologarn chamber
|
||||
if (GameObject* door = m_pInstance->instance->GetGameObject(m_pInstance->GetGuidData(GO_KOLOGARN_DOORS)))
|
||||
door->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
|
||||
if (GameObject* bridge = me->FindNearestGameObject(GO_KOLOGARN_BRIDGE, 100))
|
||||
bridge->SetGoState(GO_STATE_READY);
|
||||
|
||||
// Summon Chest
|
||||
if (GameObject* go = me->SummonGameObject(RAID_MODE(GO_KOLOGARN_CHEST, GO_KOLOGARN_CHEST_HERO), 1839.62f, -35.98f, 448.81f, 3.6f, 0, 0, 0, 0, 7 * 86400))
|
||||
{
|
||||
me->RemoveGameObject(go, false);
|
||||
go->SetSpellId(1); // hack to make it despawn
|
||||
go->ReplaceAllGameObjectFlags((GameObjectFlags)0);
|
||||
go->SetLootRecipient(me);
|
||||
}
|
||||
if (Creature* arm = ObjectAccessor::GetCreature(*me, _left))
|
||||
arm->DespawnOrUnsummon(3000); // visual
|
||||
if (Creature* arm = ObjectAccessor::GetCreature(*me, _right))
|
||||
arm->DespawnOrUnsummon(3000); // visual
|
||||
}
|
||||
|
||||
void KilledUnit(Unit*) override
|
||||
{
|
||||
if (!urand(0, 2))
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void PassengerBoarded(Unit* who, int8 /*seatId*/, bool apply) override
|
||||
{
|
||||
if (!me->IsAlive())
|
||||
return;
|
||||
|
||||
if (!apply)
|
||||
{
|
||||
// left arm
|
||||
if (who->GetGUID() == _left)
|
||||
{
|
||||
_left.Clear();
|
||||
if (me->IsInCombat())
|
||||
{
|
||||
Talk(SAY_LEFT_ARM_GONE);
|
||||
events.ScheduleEvent(EVENT_RESTORE_ARM_LEFT, 50s);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_right.Clear();
|
||||
if (me->IsInCombat())
|
||||
{
|
||||
Talk(SAY_RIGHT_ARM_GONE);
|
||||
events.ScheduleEvent(EVENT_RESTORE_ARM_RIGHT, 50s);
|
||||
}
|
||||
}
|
||||
|
||||
me->CastSpell(me, SPELL_ARM_DEAD, true);
|
||||
if (!_right && !_left)
|
||||
events.ScheduleEvent(EVENT_STONE_SHOUT, 5s);
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (who && who->GetEntry() == me->GetEntry() && me->GetHealth())
|
||||
{
|
||||
damage = std::min(damage, me->GetHealth() - 1);
|
||||
me->LowerPlayerDamageReq(damage);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_KOLOGARN, IN_PROGRESS);
|
||||
|
||||
events.ScheduleEvent(EVENT_SMASH, 8s);
|
||||
events.ScheduleEvent(EVENT_SWEEP, 17s);
|
||||
events.ScheduleEvent(EVENT_GRIP, 15s);
|
||||
events.ScheduleEvent(EVENT_FOCUSED_EYEBEAM, 10s);
|
||||
events.ScheduleEvent(EVENT_PREPARE_BREATH, 3s);
|
||||
//events.ScheduleEvent(EVENT_ENRAGE, x); no info
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
me->setActive(true);
|
||||
|
||||
// Close the door inside Kologarn chamber
|
||||
if (m_pInstance)
|
||||
{
|
||||
if (GameObject* door = m_pInstance->instance->GetGameObject(m_pInstance->GetGuidData(GO_KOLOGARN_DOORS)))
|
||||
{
|
||||
door->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
EnterEvadeMode(EVADE_REASON_OTHER);
|
||||
return;
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_PREPARE_BREATH:
|
||||
breathReady = true;
|
||||
break;
|
||||
case EVENT_STONE_SHOUT:
|
||||
if (_left || _right)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
me->CastSpell(me->GetVictim(), SPELL_STONE_SHOUT, false);
|
||||
events.ScheduleEvent(EVENT_STONE_SHOUT, 2s);
|
||||
break;
|
||||
case EVENT_SMASH:
|
||||
if (_left && _right)
|
||||
me->CastSpell(me->GetVictim(), SPELL_OVERHEAD_SMASH, false);
|
||||
else if (_left || _right)
|
||||
me->CastSpell(me->GetVictim(), SPELL_ONEARMED_OVERHEAD_SMASH, false);
|
||||
|
||||
events.DelayEvents(1s);
|
||||
events.ScheduleEvent(EVENT_SMASH, 14s);
|
||||
return;
|
||||
case EVENT_SWEEP:
|
||||
if (_left)
|
||||
{
|
||||
if (Creature* cr = me->FindNearestCreature(NPC_SWEEP_TRIGGER, 300))
|
||||
cr->CastSpell(cr, SPELL_ARM_SWEEP, false);
|
||||
|
||||
if (urand(0, 1))
|
||||
Talk(SAY_SHOCKWAVE);
|
||||
}
|
||||
|
||||
events.DelayEvents(1s);
|
||||
events.ScheduleEvent(EVENT_SWEEP, 17s);
|
||||
return;
|
||||
case EVENT_GRIP:
|
||||
events.ScheduleEvent(EVENT_GRIP, 25s);
|
||||
if (!_right)
|
||||
break;
|
||||
|
||||
me->CastSpell(me, SPELL_STONE_GRIP, false);
|
||||
Talk(SAY_GRAB_PLAYER);
|
||||
Talk(EMOTE_STONE_GRIP);
|
||||
return;
|
||||
case EVENT_FOCUSED_EYEBEAM:
|
||||
{
|
||||
events.ScheduleEvent(EVENT_FOCUSED_EYEBEAM, 20s);
|
||||
|
||||
if ((eyebeamTarget = SelectTarget(SelectTargetMethod::MinDistance, 0, 0, true)))
|
||||
{
|
||||
me->CastSpell(eyebeamTarget, SPELL_FOCUSED_EYEBEAM_SUMMON, false);
|
||||
}
|
||||
|
||||
Talk(EMOTE_EYES);
|
||||
return;
|
||||
}
|
||||
case EVENT_RESTORE_ARM_LEFT:
|
||||
// shouldn't happen
|
||||
AttachLeftArm();
|
||||
return;
|
||||
case EVENT_RESTORE_ARM_RIGHT:
|
||||
// shouldn't happen
|
||||
AttachRightArm();
|
||||
return;
|
||||
}
|
||||
|
||||
//Make sure our attack is ready and we aren't currently casting before checking distance
|
||||
if (me->isAttackReady() && me->GetVictim()) // victim could die by a spell (IMPORTANT!!!) and kologarn entered evade mode
|
||||
{
|
||||
//If we are within range melee the target
|
||||
if (me->IsWithinMeleeRange(me->GetVictim()))
|
||||
{
|
||||
me->AttackerStateUpdate(me->GetVictim());
|
||||
me->resetAttackTimer();
|
||||
return;
|
||||
}
|
||||
else if (Unit* tgt = me->SelectNearbyTarget())
|
||||
{
|
||||
me->AttackerStateUpdate(tgt);
|
||||
me->resetAttackTimer();
|
||||
return;
|
||||
}
|
||||
|
||||
if (breathReady)
|
||||
me->CastSpell(me->GetVictim(), SPELL_PETRIFYING_BREATH, false);
|
||||
me->resetAttackTimer();
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// also used for left arm, all functions except JustDied wont be used by left arm
|
||||
class boss_kologarn_arms : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_kologarn_arms() : CreatureScript("boss_kologarn_arms") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<boss_kologarn_armsAI>(pCreature);
|
||||
}
|
||||
|
||||
struct boss_kologarn_armsAI : public ScriptedAI
|
||||
{
|
||||
boss_kologarn_armsAI(Creature* c) : ScriptedAI(c) { }
|
||||
|
||||
int32 _damageDone;
|
||||
bool _combatStarted;
|
||||
|
||||
void EnterEvadeMode(EvadeReason /*why*/ = EVADE_REASON_OTHER) override {}
|
||||
void MoveInLineOfSight(Unit*) override {}
|
||||
void AttackStart(Unit*) override {}
|
||||
void UpdateAI(uint32 /*diff*/) override {}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_combatStarted = false;
|
||||
_damageDone = 0;
|
||||
}
|
||||
|
||||
void PassengerBoarded(Unit* /*who*/, int8 /*seatId*/, bool apply) override
|
||||
{
|
||||
if (!apply)
|
||||
_damageDone = 0;
|
||||
else
|
||||
{
|
||||
//who->ClearUnitState(UNIT_STATE_ONVEHICLE);
|
||||
if (!_damageDone)
|
||||
_damageDone = RAID_MODE(80000, 380000);
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (!_combatStarted)
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, instance->GetGuidData(TYPE_KOLOGARN)))
|
||||
{
|
||||
_combatStarted = true;
|
||||
if (!cr->IsInCombat() && who)
|
||||
cr->AI()->AttackStart(who);
|
||||
}
|
||||
|
||||
if (_damageDone > 0)
|
||||
{
|
||||
_damageDone -= damage;
|
||||
if (_damageDone <= 0 || damage >= me->GetHealth())
|
||||
me->RemoveAurasByType(SPELL_AURA_CONTROL_VEHICLE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
float x, y, z;
|
||||
// left arm
|
||||
if( me->GetEntry() == NPC_LEFT_ARM )
|
||||
{
|
||||
x = 1776.97f;
|
||||
y = -44.8396f;
|
||||
z = 448.888f;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = 1777.82f;
|
||||
y = -3.50803f;
|
||||
z = 448.888f;
|
||||
}
|
||||
|
||||
if (Creature* cr = me->SummonTrigger(x, y, z, 0, 5000))
|
||||
{
|
||||
cr->CastSpell(cr, SPELL_RUBBLE_FALL, true);
|
||||
|
||||
if (me->GetInstanceScript())
|
||||
if (Creature* kologarn = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_KOLOGARN)))
|
||||
for (uint8 i = 0; i < 5; ++i)
|
||||
if (Creature* cr2 = kologarn->SummonCreature(NPC_RUBBLE_SUMMON, cr->GetPositionX() + irand(-5, 5), cr->GetPositionY() + irand(-5, 5), cr->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000))
|
||||
{
|
||||
cr2->SetInCombatWithZone();
|
||||
if (Unit* target = SelectTargetFromPlayerList(100))
|
||||
cr2->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
|
||||
if (me->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_KOLOGARN)))
|
||||
cr->AI()->DoAction(DATA_KOLOGARN_RUBBLE_ACHIEV);
|
||||
|
||||
me->ExitVehicle();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class boss_kologarn_eyebeam : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_kologarn_eyebeam() : CreatureScript("boss_kologarn_eyebeam") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<boss_kologarn_eyebeamAI>(pCreature);
|
||||
}
|
||||
struct boss_kologarn_eyebeamAI : public ScriptedAI
|
||||
{
|
||||
boss_kologarn_eyebeamAI(Creature* c) : ScriptedAI(c), _timer(1), _damaged(false), justSpawned(true)
|
||||
{
|
||||
m_pInstance = (InstanceScript*)c->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* m_pInstance;
|
||||
uint32 _timer;
|
||||
bool _damaged, justSpawned;
|
||||
|
||||
void DamageDealt(Unit* /*victim*/, uint32& damage, DamageEffectType /*damageType*/) override
|
||||
{
|
||||
if (damage > 0 && !_damaged && me->GetInstanceScript())
|
||||
{
|
||||
_damaged = true;
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_KOLOGARN)))
|
||||
cr->AI()->DoAction(DATA_KOLOGARN_LOOKS_ACHIEV);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (justSpawned)
|
||||
{
|
||||
me->DespawnOrUnsummon(10000);
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, m_pInstance->GetGuidData(TYPE_KOLOGARN)))
|
||||
{
|
||||
me->CastSpell(cr, me->GetEntry() == NPC_EYE_LEFT ? SPELL_FOCUSED_EYEBEAM_LEFT : SPELL_FOCUSED_EYEBEAM_RIGHT, true);
|
||||
}
|
||||
me->CastSpell(me, SPELL_FOCUSED_EYEBEAM, true);
|
||||
justSpawned = false;
|
||||
}
|
||||
if (_timer)
|
||||
{
|
||||
_timer += diff;
|
||||
if (_timer >= 2000)
|
||||
{
|
||||
me->CastSpell(me, (me->GetMap()->Is25ManRaid() ? SPELL_FOCUSED_EYEBEAM_25 : SPELL_FOCUSED_EYEBEAM_10), true);
|
||||
_timer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// predicate function to select non main tank target
|
||||
class StoneGripTargetSelector
|
||||
{
|
||||
public:
|
||||
StoneGripTargetSelector(Creature* me, Unit const* victim) : _me(me), _victim(victim) {}
|
||||
|
||||
bool operator() (WorldObject* target) const
|
||||
{
|
||||
if (target == _victim && _me->GetThreatMgr().GetThreatListSize() > 1)
|
||||
return true;
|
||||
|
||||
if (target->GetTypeId() != TYPEID_PLAYER)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
Creature* _me;
|
||||
Unit const* _victim;
|
||||
};
|
||||
|
||||
class spell_ulduar_stone_grip_cast_target : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ulduar_stone_grip_cast_target() : SpellScriptLoader("spell_ulduar_stone_grip_cast_target") { }
|
||||
|
||||
class spell_ulduar_stone_grip_cast_target_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_ulduar_stone_grip_cast_target_SpellScript);
|
||||
|
||||
bool Load() override
|
||||
{
|
||||
if (GetCaster()->GetTypeId() != TYPEID_UNIT)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FilterTargetsInitial(std::list<WorldObject*>& targets)
|
||||
{
|
||||
// Remove "main tank" and non-player targets
|
||||
targets.remove_if (StoneGripTargetSelector(GetCaster()->ToCreature(), GetCaster()->GetVictim()));
|
||||
// Maximum affected targets per difficulty mode
|
||||
uint32 maxTargets = 1;
|
||||
if (GetSpellInfo()->Id == 63981)
|
||||
maxTargets = 3;
|
||||
|
||||
// Return a random amount of targets based on maxTargets
|
||||
while (maxTargets < targets.size())
|
||||
{
|
||||
std::list<WorldObject*>::iterator itr = targets.begin();
|
||||
advance(itr, urand(0, targets.size() - 1));
|
||||
targets.erase(itr);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_ulduar_stone_grip_cast_target_SpellScript::FilterTargetsInitial, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_ulduar_stone_grip_cast_target_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_ulduar_stone_grip : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ulduar_stone_grip() : SpellScriptLoader("spell_ulduar_stone_grip") { }
|
||||
|
||||
class spell_ulduar_stone_grip_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_ulduar_stone_grip_AuraScript);
|
||||
|
||||
void OnRemoveStun(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Player* owner = GetOwner()->ToPlayer())
|
||||
owner->RemoveAurasDueToSpell(aurEff->GetAmount());
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectRemove += AuraEffectRemoveFn(spell_ulduar_stone_grip_AuraScript::OnRemoveStun, EFFECT_2, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_ulduar_stone_grip_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_ulduar_squeezed_lifeless : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ulduar_squeezed_lifeless() : SpellScriptLoader("spell_ulduar_squeezed_lifeless") { }
|
||||
|
||||
class spell_ulduar_squeezed_lifeless_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_ulduar_squeezed_lifeless_SpellScript);
|
||||
|
||||
void HandleInstaKill(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (!GetHitPlayer() || !GetHitPlayer()->GetVehicle())
|
||||
return;
|
||||
|
||||
// Hack to set correct position is in _ExitVehicle()
|
||||
GetHitPlayer()->ExitVehicle();
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_ulduar_squeezed_lifeless_SpellScript::HandleInstaKill, EFFECT_1, SPELL_EFFECT_INSTAKILL);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_ulduar_squeezed_lifeless_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_kologarn_stone_shout : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_kologarn_stone_shout() : SpellScriptLoader("spell_kologarn_stone_shout") { }
|
||||
|
||||
class spell_kologarn_stone_shout_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_kologarn_stone_shout_AuraScript);
|
||||
|
||||
void OnPeriodic(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
uint32 triggerSpellId = GetSpellInfo()->Effects[EFFECT_0].TriggerSpell;
|
||||
if (Unit* caster = GetCaster())
|
||||
caster->CastSpell(caster, triggerSpellId, false);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
if (m_scriptSpellId == SPELL_STONE_SHOUT_10 || m_scriptSpellId == SPELL_STONE_SHOUT_25)
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_kologarn_stone_shout_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_kologarn_stone_shout_AuraScript();
|
||||
}
|
||||
|
||||
class spell_kologarn_stone_shout_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_kologarn_stone_shout_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.remove_if (PlayerOrPetCheck());
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
if (m_scriptSpellId != SPELL_STONE_SHOUT_10 && m_scriptSpellId != SPELL_STONE_SHOUT_25)
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kologarn_stone_shout_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_kologarn_stone_shout_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_kologarn_looks_could_kill : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_kologarn_looks_could_kill() : AchievementCriteriaScript("achievement_kologarn_looks_could_kill") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
if (target)
|
||||
if (InstanceScript* instance = target->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_KOLOGARN)))
|
||||
return cr->AI()->GetData(DATA_KOLOGARN_LOOKS_ACHIEV);
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_kologarn_rubble_and_roll : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_kologarn_rubble_and_roll() : AchievementCriteriaScript("achievement_kologarn_rubble_and_roll") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
if (target)
|
||||
if (InstanceScript* instance = target->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_KOLOGARN)))
|
||||
return cr->AI()->GetData(DATA_KOLOGARN_RUBBLE_ACHIEV);
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_kologarn_with_open_arms : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_kologarn_with_open_arms() : AchievementCriteriaScript("achievement_kologarn_with_open_arms") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
if (target)
|
||||
if (InstanceScript* instance = target->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_KOLOGARN)))
|
||||
return cr->AI()->GetData(DATA_KOLOGARN_ARMS_ACHIEV);
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_kologarn()
|
||||
{
|
||||
// Npcs
|
||||
|
||||
876
src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.h
Normal file
876
src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.h
Normal file
@@ -0,0 +1,876 @@
|
||||
#ifndef BOSS_KOLOGARN_H_
|
||||
#define BOSS_KOLOGARN_H_
|
||||
|
||||
#include "AchievementCriteriaScript.h"
|
||||
#include "CreatureScript.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellScriptLoader.h"
|
||||
#include "Vehicle.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
enum KologarnSays
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_LEFT_ARM_GONE = 2,
|
||||
SAY_RIGHT_ARM_GONE = 3,
|
||||
SAY_SHOCKWAVE = 4,
|
||||
SAY_GRAB_PLAYER = 5,
|
||||
SAY_DEATH = 6,
|
||||
SAY_BERSERK = 7,
|
||||
EMOTE_STONE_GRIP = 8,
|
||||
EMOTE_EYES = 9
|
||||
};
|
||||
|
||||
enum KologarnSpells
|
||||
{
|
||||
SPELL_KOLOGARN_REDUCE_PARRY = 64651,
|
||||
|
||||
// BASIC
|
||||
SPELL_OVERHEAD_SMASH_10 = 63356,
|
||||
SPELL_OVERHEAD_SMASH_25 = 64003,
|
||||
SPELL_ONEARMED_OVERHEAD_SMASH_10 = 63573,
|
||||
SPELL_ONEARMED_OVERHEAD_SMASH_25 = 64006,
|
||||
SPELL_PETRIFYING_BREATH_10 = 62030,
|
||||
SPELL_PETRIFYING_BREATH_25 = 63980,
|
||||
SPELL_STONE_SHOUT_10 = 63716,
|
||||
SPELL_STONE_SHOUT_25 = 64005,
|
||||
|
||||
// EYEBEAM
|
||||
SPELL_FOCUSED_EYEBEAM_SUMMON = 63342,
|
||||
SPELL_FOCUSED_EYEBEAM_10 = 63347,
|
||||
SPELL_FOCUSED_EYEBEAM_25 = 63977,
|
||||
SPELL_FOCUSED_EYEBEAM_RIGHT = 63702,
|
||||
SPELL_FOCUSED_EYEBEAM_LEFT = 63676,
|
||||
|
||||
// ARMS
|
||||
SPELL_ARM_DEAD_10 = 63629,
|
||||
SPELL_ARM_DEAD_25 = 63979,
|
||||
SPELL_RUBBLE_FALL_10 = 63821,
|
||||
SPELL_RUBBLE_FALL_25 = 64001,
|
||||
SPELL_ARM_RESPAWN_VISUAL = 64753,
|
||||
|
||||
// LEFT ARM
|
||||
SPELL_ARM_SWEEP_10 = 63766,
|
||||
SPELL_ARM_SWEEP_25 = 63983,
|
||||
|
||||
// RIGHT ARM
|
||||
SPELL_STONE_GRIP_10 = 62166,
|
||||
SPELL_STONE_GRIP_25 = 63981,
|
||||
SPELL_RIDE_RIGHT_ARM_10 = 62056,
|
||||
SPELL_RIDE_RIGHT_ARM_25 = 63985,
|
||||
|
||||
// RUBBLE TRASH
|
||||
SPELL_RUBBLE_ATTACK_10 = 63818,
|
||||
SPELL_RUBBLE_ATTACK_25 = 63978,
|
||||
};
|
||||
|
||||
#define SPELL_PETRIFYING_BREATH RAID_MODE(SPELL_PETRIFYING_BREATH_10, SPELL_PETRIFYING_BREATH_25)
|
||||
#define SPELL_OVERHEAD_SMASH RAID_MODE(SPELL_OVERHEAD_SMASH_10, SPELL_OVERHEAD_SMASH_25)
|
||||
#define SPELL_ONEARMED_OVERHEAD_SMASH RAID_MODE(SPELL_ONEARMED_OVERHEAD_SMASH_10, SPELL_ONEARMED_OVERHEAD_SMASH_25)
|
||||
#define SPELL_ARM_DEAD RAID_MODE(SPELL_ARM_DEAD_10, SPELL_ARM_DEAD_25)
|
||||
#define SPELL_ARM_SWEEP RAID_MODE(SPELL_ARM_SWEEP_10, SPELL_ARM_SWEEP_25)
|
||||
#define SPELL_STONE_GRIP RAID_MODE(SPELL_STONE_GRIP_10, SPELL_STONE_GRIP_25)
|
||||
#define SPELL_FOCUSED_EYEBEAM RAID_MODE(SPELL_FOCUSED_EYEBEAM_10, SPELL_FOCUSED_EYEBEAM_25)
|
||||
#define SPELL_RUBBLE_FALL RAID_MODE(SPELL_RUBBLE_FALL_10, SPELL_RUBBLE_FALL_25)
|
||||
#define SPELL_RUBBLE_ATTACK RAID_MODE(SPELL_RUBBLE_ATTACK_10, SPELL_RUBBLE_ATTACK_25)
|
||||
#define SPELL_RIDE_RIGHT_ARM RAID_MODE(SPELL_RIDE_RIGHT_ARM_10, SPELL_RIDE_RIGHT_ARM_25)
|
||||
#define SPELL_STONE_SHOUT RAID_MODE(SPELL_STONE_SHOUT_10, SPELL_STONE_SHOUT_25)
|
||||
|
||||
enum KologarnEvents
|
||||
{
|
||||
EVENT_SMASH = 1,
|
||||
EVENT_GRIP = 2,
|
||||
EVENT_SWEEP = 3,
|
||||
EVENT_RESTORE_ARM_LEFT = 4,
|
||||
EVENT_RESTORE_ARM_RIGHT = 5,
|
||||
EVENT_FOCUSED_EYEBEAM = 6,
|
||||
EVENT_STONE_SHOUT = 7,
|
||||
EVENT_PREPARE_BREATH = 8, // Kologarn can't cast breath on pull
|
||||
};
|
||||
|
||||
enum KologarnNPCs
|
||||
{
|
||||
NPC_LEFT_ARM = 32933,
|
||||
NPC_RIGHT_ARM = 32934,
|
||||
NPC_SWEEP_TRIGGER = 33661,
|
||||
NPC_EYE_LEFT = 33632,
|
||||
NPC_EYE_RIGHT = 33802,
|
||||
NPC_RUBBLE_TRIGGER = 33809,
|
||||
NPC_RUBBLE_SUMMON = 33768,
|
||||
};
|
||||
|
||||
enum KologarnSounds
|
||||
{
|
||||
SOUND_AGGRO = 15586,
|
||||
SOUND_SLAY1 = 15587,
|
||||
SOUND_SLAY2 = 15588,
|
||||
SOUND_LARM_GONE = 15589,
|
||||
SOUND_RARM_GONE = 15590,
|
||||
SOUND_SHOCKWAVE = 15591,
|
||||
SOUND_GRIP = 15592,
|
||||
SOUND_DEATH = 15593,
|
||||
SOUND_BERSERK = 15594,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
ACHIEVEMENT_DISARMED_CRITERIA = 21687,
|
||||
|
||||
DATA_KOLOGARN_LOOKS_ACHIEV = 55,
|
||||
DATA_KOLOGARN_RUBBLE_ACHIEV = 56,
|
||||
DATA_KOLOGARN_ARMS_ACHIEV = 57,
|
||||
};
|
||||
|
||||
class boss_kologarn : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_kologarn() : CreatureScript("boss_kologarn") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<boss_kologarnAI>(pCreature);
|
||||
}
|
||||
|
||||
struct boss_kologarnAI : public ScriptedAI
|
||||
{
|
||||
boss_kologarnAI(Creature* pCreature) : ScriptedAI(pCreature), vehicle(me->GetVehicleKit()), summons(me), breathReady(false)
|
||||
{
|
||||
m_pInstance = me->GetInstanceScript();
|
||||
eyebeamTarget = nullptr;
|
||||
assert(vehicle);
|
||||
me->SetStandState(UNIT_STAND_STATE_SUBMERGED);
|
||||
}
|
||||
|
||||
InstanceScript* m_pInstance;
|
||||
|
||||
Vehicle* vehicle;
|
||||
ObjectGuid _left, _right;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
|
||||
Unit* eyebeamTarget;
|
||||
|
||||
bool _looksAchievement, breathReady;
|
||||
uint8 _rubbleAchievement;
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && me->GetExactDist2d(who) < 45.0f && me->getStandState() == UNIT_STAND_STATE_SUBMERGED)
|
||||
{
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
if (Unit* arm = ObjectAccessor::GetCreature(*me, _left))
|
||||
arm->CastSpell(arm, SPELL_ARM_RESPAWN_VISUAL, true);
|
||||
if (Unit* arm = ObjectAccessor::GetCreature(*me, _right))
|
||||
arm->CastSpell(arm, SPELL_ARM_RESPAWN_VISUAL, true);
|
||||
}
|
||||
|
||||
if (me->GetExactDist2d(who) < 30.0f)
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
if (!_EnterEvadeMode(why))
|
||||
return;
|
||||
Reset();
|
||||
me->setActive(false);
|
||||
}
|
||||
|
||||
void AttachLeftArm()
|
||||
{
|
||||
if (Unit* arm = ObjectAccessor::GetCreature(*me, _left))
|
||||
arm->SetHealth(arm->GetMaxHealth());
|
||||
else if (Creature* accessory = me->SummonCreature(NPC_LEFT_ARM, *me, TEMPSUMMON_MANUAL_DESPAWN))
|
||||
{
|
||||
accessory->AddUnitTypeMask(UNIT_MASK_ACCESSORY);
|
||||
if (!me->HandleSpellClick(accessory, 0))
|
||||
accessory->DespawnOrUnsummon();
|
||||
else
|
||||
{
|
||||
_left = accessory->GetGUID();
|
||||
accessory->SetOrientation(M_PI);
|
||||
accessory->CastSpell(accessory, SPELL_ARM_RESPAWN_VISUAL, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AttachRightArm()
|
||||
{
|
||||
if (Unit* arm = ObjectAccessor::GetCreature(*me, _right))
|
||||
arm->SetHealth(arm->GetMaxHealth());
|
||||
else if (Creature* accessory = me->SummonCreature(NPC_RIGHT_ARM, *me, TEMPSUMMON_MANUAL_DESPAWN))
|
||||
{
|
||||
accessory->AddUnitTypeMask(UNIT_MASK_ACCESSORY);
|
||||
if (!me->HandleSpellClick(accessory, 1))
|
||||
accessory->DespawnOrUnsummon();
|
||||
else
|
||||
{
|
||||
_right = accessory->GetGUID();
|
||||
accessory->SetOrientation(M_PI);
|
||||
accessory->CastSpell(accessory, SPELL_ARM_RESPAWN_VISUAL, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_rubbleAchievement = 0;
|
||||
_looksAchievement = true;
|
||||
|
||||
me->SetDisableGravity(true);
|
||||
me->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE);
|
||||
me->DisableRotate(true);
|
||||
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
|
||||
if (m_pInstance)
|
||||
{
|
||||
m_pInstance->SetData(TYPE_KOLOGARN, NOT_STARTED);
|
||||
|
||||
// Open the door inside Kologarn chamber
|
||||
if (GameObject* door = m_pInstance->instance->GetGameObject(m_pInstance->GetGuidData(GO_KOLOGARN_DOORS)))
|
||||
door->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
|
||||
AttachLeftArm();
|
||||
AttachRightArm();
|
||||
|
||||
// Reset breath on pull
|
||||
breathReady = false;
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == DATA_KOLOGARN_LOOKS_ACHIEV)
|
||||
_looksAchievement = false;
|
||||
if (param == DATA_KOLOGARN_RUBBLE_ACHIEV)
|
||||
{
|
||||
// Means arm died
|
||||
if (m_pInstance && (!_left || !_right))
|
||||
m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_DISARMED_CRITERIA);
|
||||
|
||||
++_rubbleAchievement;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 param) const override
|
||||
{
|
||||
if (param == DATA_KOLOGARN_LOOKS_ACHIEV)
|
||||
return _looksAchievement;
|
||||
else if (param == DATA_KOLOGARN_RUBBLE_ACHIEV)
|
||||
return (_rubbleAchievement >= 5);
|
||||
else if (param == DATA_KOLOGARN_ARMS_ACHIEV)
|
||||
return !_rubbleAchievement;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
{
|
||||
me->Attack(who, true);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) override
|
||||
{
|
||||
if (cr->GetEntry() != NPC_LEFT_ARM && cr->GetEntry() != NPC_RIGHT_ARM)
|
||||
summons.Summon(cr);
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
summons.DespawnAll();
|
||||
me->StopMoving();
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_KOLOGARN, DONE);
|
||||
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if (m_pInstance)
|
||||
{
|
||||
// Open the door inside Kologarn chamber
|
||||
if (GameObject* door = m_pInstance->instance->GetGameObject(m_pInstance->GetGuidData(GO_KOLOGARN_DOORS)))
|
||||
door->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
|
||||
if (GameObject* bridge = me->FindNearestGameObject(GO_KOLOGARN_BRIDGE, 100))
|
||||
bridge->SetGoState(GO_STATE_READY);
|
||||
|
||||
// Summon Chest
|
||||
if (GameObject* go = me->SummonGameObject(RAID_MODE(GO_KOLOGARN_CHEST, GO_KOLOGARN_CHEST_HERO), 1839.62f, -35.98f, 448.81f, 3.6f, 0, 0, 0, 0, 7 * 86400))
|
||||
{
|
||||
me->RemoveGameObject(go, false);
|
||||
go->SetSpellId(1); // hack to make it despawn
|
||||
go->ReplaceAllGameObjectFlags((GameObjectFlags)0);
|
||||
go->SetLootRecipient(me);
|
||||
}
|
||||
if (Creature* arm = ObjectAccessor::GetCreature(*me, _left))
|
||||
arm->DespawnOrUnsummon(3000); // visual
|
||||
if (Creature* arm = ObjectAccessor::GetCreature(*me, _right))
|
||||
arm->DespawnOrUnsummon(3000); // visual
|
||||
}
|
||||
|
||||
void KilledUnit(Unit*) override
|
||||
{
|
||||
if (!urand(0, 2))
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void PassengerBoarded(Unit* who, int8 /*seatId*/, bool apply) override
|
||||
{
|
||||
if (!me->IsAlive())
|
||||
return;
|
||||
|
||||
if (!apply)
|
||||
{
|
||||
// left arm
|
||||
if (who->GetGUID() == _left)
|
||||
{
|
||||
_left.Clear();
|
||||
if (me->IsInCombat())
|
||||
{
|
||||
Talk(SAY_LEFT_ARM_GONE);
|
||||
events.ScheduleEvent(EVENT_RESTORE_ARM_LEFT, 50s);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_right.Clear();
|
||||
if (me->IsInCombat())
|
||||
{
|
||||
Talk(SAY_RIGHT_ARM_GONE);
|
||||
events.ScheduleEvent(EVENT_RESTORE_ARM_RIGHT, 50s);
|
||||
}
|
||||
}
|
||||
|
||||
me->CastSpell(me, SPELL_ARM_DEAD, true);
|
||||
if (!_right && !_left)
|
||||
events.ScheduleEvent(EVENT_STONE_SHOUT, 5s);
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (who && who->GetEntry() == me->GetEntry() && me->GetHealth())
|
||||
{
|
||||
damage = std::min(damage, me->GetHealth() - 1);
|
||||
me->LowerPlayerDamageReq(damage);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_KOLOGARN, IN_PROGRESS);
|
||||
|
||||
events.ScheduleEvent(EVENT_SMASH, 8s);
|
||||
events.ScheduleEvent(EVENT_SWEEP, 17s);
|
||||
events.ScheduleEvent(EVENT_GRIP, 15s);
|
||||
events.ScheduleEvent(EVENT_FOCUSED_EYEBEAM, 10s);
|
||||
events.ScheduleEvent(EVENT_PREPARE_BREATH, 3s);
|
||||
//events.ScheduleEvent(EVENT_ENRAGE, x); no info
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
me->setActive(true);
|
||||
|
||||
// Close the door inside Kologarn chamber
|
||||
if (m_pInstance)
|
||||
{
|
||||
if (GameObject* door = m_pInstance->instance->GetGameObject(m_pInstance->GetGuidData(GO_KOLOGARN_DOORS)))
|
||||
{
|
||||
door->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
EnterEvadeMode(EVADE_REASON_OTHER);
|
||||
return;
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_PREPARE_BREATH:
|
||||
breathReady = true;
|
||||
break;
|
||||
case EVENT_STONE_SHOUT:
|
||||
if (_left || _right)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
me->CastSpell(me->GetVictim(), SPELL_STONE_SHOUT, false);
|
||||
events.ScheduleEvent(EVENT_STONE_SHOUT, 2s);
|
||||
break;
|
||||
case EVENT_SMASH:
|
||||
if (_left && _right)
|
||||
me->CastSpell(me->GetVictim(), SPELL_OVERHEAD_SMASH, false);
|
||||
else if (_left || _right)
|
||||
me->CastSpell(me->GetVictim(), SPELL_ONEARMED_OVERHEAD_SMASH, false);
|
||||
|
||||
events.DelayEvents(1s);
|
||||
events.ScheduleEvent(EVENT_SMASH, 14s);
|
||||
return;
|
||||
case EVENT_SWEEP:
|
||||
if (_left)
|
||||
{
|
||||
if (Creature* cr = me->FindNearestCreature(NPC_SWEEP_TRIGGER, 300))
|
||||
cr->CastSpell(cr, SPELL_ARM_SWEEP, false);
|
||||
|
||||
if (urand(0, 1))
|
||||
Talk(SAY_SHOCKWAVE);
|
||||
}
|
||||
|
||||
events.DelayEvents(1s);
|
||||
events.ScheduleEvent(EVENT_SWEEP, 17s);
|
||||
return;
|
||||
case EVENT_GRIP:
|
||||
events.ScheduleEvent(EVENT_GRIP, 25s);
|
||||
if (!_right)
|
||||
break;
|
||||
|
||||
me->CastSpell(me, SPELL_STONE_GRIP, false);
|
||||
Talk(SAY_GRAB_PLAYER);
|
||||
Talk(EMOTE_STONE_GRIP);
|
||||
return;
|
||||
case EVENT_FOCUSED_EYEBEAM:
|
||||
{
|
||||
events.ScheduleEvent(EVENT_FOCUSED_EYEBEAM, 20s);
|
||||
|
||||
if ((eyebeamTarget = SelectTarget(SelectTargetMethod::MinDistance, 0, 0, true)))
|
||||
{
|
||||
me->CastSpell(eyebeamTarget, SPELL_FOCUSED_EYEBEAM_SUMMON, false);
|
||||
}
|
||||
|
||||
Talk(EMOTE_EYES);
|
||||
return;
|
||||
}
|
||||
case EVENT_RESTORE_ARM_LEFT:
|
||||
// shouldn't happen
|
||||
AttachLeftArm();
|
||||
return;
|
||||
case EVENT_RESTORE_ARM_RIGHT:
|
||||
// shouldn't happen
|
||||
AttachRightArm();
|
||||
return;
|
||||
}
|
||||
|
||||
//Make sure our attack is ready and we aren't currently casting before checking distance
|
||||
if (me->isAttackReady() && me->GetVictim()) // victim could die by a spell (IMPORTANT!!!) and kologarn entered evade mode
|
||||
{
|
||||
//If we are within range melee the target
|
||||
if (me->IsWithinMeleeRange(me->GetVictim()))
|
||||
{
|
||||
me->AttackerStateUpdate(me->GetVictim());
|
||||
me->resetAttackTimer();
|
||||
return;
|
||||
}
|
||||
else if (Unit* tgt = me->SelectNearbyTarget())
|
||||
{
|
||||
me->AttackerStateUpdate(tgt);
|
||||
me->resetAttackTimer();
|
||||
return;
|
||||
}
|
||||
|
||||
if (breathReady)
|
||||
me->CastSpell(me->GetVictim(), SPELL_PETRIFYING_BREATH, false);
|
||||
me->resetAttackTimer();
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// also used for left arm, all functions except JustDied wont be used by left arm
|
||||
class boss_kologarn_arms : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_kologarn_arms() : CreatureScript("boss_kologarn_arms") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<boss_kologarn_armsAI>(pCreature);
|
||||
}
|
||||
|
||||
struct boss_kologarn_armsAI : public ScriptedAI
|
||||
{
|
||||
boss_kologarn_armsAI(Creature* c) : ScriptedAI(c) { }
|
||||
|
||||
int32 _damageDone;
|
||||
bool _combatStarted;
|
||||
|
||||
void EnterEvadeMode(EvadeReason /*why*/ = EVADE_REASON_OTHER) override {}
|
||||
void MoveInLineOfSight(Unit*) override {}
|
||||
void AttackStart(Unit*) override {}
|
||||
void UpdateAI(uint32 /*diff*/) override {}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_combatStarted = false;
|
||||
_damageDone = 0;
|
||||
}
|
||||
|
||||
void PassengerBoarded(Unit* /*who*/, int8 /*seatId*/, bool apply) override
|
||||
{
|
||||
if (!apply)
|
||||
_damageDone = 0;
|
||||
else
|
||||
{
|
||||
//who->ClearUnitState(UNIT_STATE_ONVEHICLE);
|
||||
if (!_damageDone)
|
||||
_damageDone = RAID_MODE(80000, 380000);
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (!_combatStarted)
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, instance->GetGuidData(TYPE_KOLOGARN)))
|
||||
{
|
||||
_combatStarted = true;
|
||||
if (!cr->IsInCombat() && who)
|
||||
cr->AI()->AttackStart(who);
|
||||
}
|
||||
|
||||
if (_damageDone > 0)
|
||||
{
|
||||
_damageDone -= damage;
|
||||
if (_damageDone <= 0 || damage >= me->GetHealth())
|
||||
me->RemoveAurasByType(SPELL_AURA_CONTROL_VEHICLE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
float x, y, z;
|
||||
// left arm
|
||||
if( me->GetEntry() == NPC_LEFT_ARM )
|
||||
{
|
||||
x = 1776.97f;
|
||||
y = -44.8396f;
|
||||
z = 448.888f;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = 1777.82f;
|
||||
y = -3.50803f;
|
||||
z = 448.888f;
|
||||
}
|
||||
|
||||
if (Creature* cr = me->SummonTrigger(x, y, z, 0, 5000))
|
||||
{
|
||||
cr->CastSpell(cr, SPELL_RUBBLE_FALL, true);
|
||||
|
||||
if (me->GetInstanceScript())
|
||||
if (Creature* kologarn = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_KOLOGARN)))
|
||||
for (uint8 i = 0; i < 5; ++i)
|
||||
if (Creature* cr2 = kologarn->SummonCreature(NPC_RUBBLE_SUMMON, cr->GetPositionX() + irand(-5, 5), cr->GetPositionY() + irand(-5, 5), cr->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000))
|
||||
{
|
||||
cr2->SetInCombatWithZone();
|
||||
if (Unit* target = SelectTargetFromPlayerList(100))
|
||||
cr2->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
|
||||
if (me->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_KOLOGARN)))
|
||||
cr->AI()->DoAction(DATA_KOLOGARN_RUBBLE_ACHIEV);
|
||||
|
||||
me->ExitVehicle();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class boss_kologarn_eyebeam : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_kologarn_eyebeam() : CreatureScript("boss_kologarn_eyebeam") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<boss_kologarn_eyebeamAI>(pCreature);
|
||||
}
|
||||
struct boss_kologarn_eyebeamAI : public ScriptedAI
|
||||
{
|
||||
boss_kologarn_eyebeamAI(Creature* c) : ScriptedAI(c), _timer(1), _damaged(false), justSpawned(true)
|
||||
{
|
||||
m_pInstance = (InstanceScript*)c->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* m_pInstance;
|
||||
uint32 _timer;
|
||||
bool _damaged, justSpawned;
|
||||
|
||||
void DamageDealt(Unit* /*victim*/, uint32& damage, DamageEffectType /*damageType*/) override
|
||||
{
|
||||
if (damage > 0 && !_damaged && me->GetInstanceScript())
|
||||
{
|
||||
_damaged = true;
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_KOLOGARN)))
|
||||
cr->AI()->DoAction(DATA_KOLOGARN_LOOKS_ACHIEV);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (justSpawned)
|
||||
{
|
||||
me->DespawnOrUnsummon(10000);
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, m_pInstance->GetGuidData(TYPE_KOLOGARN)))
|
||||
{
|
||||
me->CastSpell(cr, me->GetEntry() == NPC_EYE_LEFT ? SPELL_FOCUSED_EYEBEAM_LEFT : SPELL_FOCUSED_EYEBEAM_RIGHT, true);
|
||||
}
|
||||
me->CastSpell(me, SPELL_FOCUSED_EYEBEAM, true);
|
||||
justSpawned = false;
|
||||
}
|
||||
if (_timer)
|
||||
{
|
||||
_timer += diff;
|
||||
if (_timer >= 2000)
|
||||
{
|
||||
me->CastSpell(me, (me->GetMap()->Is25ManRaid() ? SPELL_FOCUSED_EYEBEAM_25 : SPELL_FOCUSED_EYEBEAM_10), true);
|
||||
_timer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// predicate function to select non main tank target
|
||||
class StoneGripTargetSelector
|
||||
{
|
||||
public:
|
||||
StoneGripTargetSelector(Creature* me, Unit const* victim) : _me(me), _victim(victim) {}
|
||||
|
||||
bool operator() (WorldObject* target) const
|
||||
{
|
||||
if (target == _victim && _me->GetThreatMgr().GetThreatListSize() > 1)
|
||||
return true;
|
||||
|
||||
if (target->GetTypeId() != TYPEID_PLAYER)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
Creature* _me;
|
||||
Unit const* _victim;
|
||||
};
|
||||
|
||||
class spell_ulduar_stone_grip_cast_target : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ulduar_stone_grip_cast_target() : SpellScriptLoader("spell_ulduar_stone_grip_cast_target") { }
|
||||
|
||||
class spell_ulduar_stone_grip_cast_target_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_ulduar_stone_grip_cast_target_SpellScript);
|
||||
|
||||
bool Load() override
|
||||
{
|
||||
if (GetCaster()->GetTypeId() != TYPEID_UNIT)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FilterTargetsInitial(std::list<WorldObject*>& targets)
|
||||
{
|
||||
// Remove "main tank" and non-player targets
|
||||
targets.remove_if (StoneGripTargetSelector(GetCaster()->ToCreature(), GetCaster()->GetVictim()));
|
||||
// Maximum affected targets per difficulty mode
|
||||
uint32 maxTargets = 1;
|
||||
if (GetSpellInfo()->Id == 63981)
|
||||
maxTargets = 3;
|
||||
|
||||
// Return a random amount of targets based on maxTargets
|
||||
while (maxTargets < targets.size())
|
||||
{
|
||||
std::list<WorldObject*>::iterator itr = targets.begin();
|
||||
advance(itr, urand(0, targets.size() - 1));
|
||||
targets.erase(itr);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_ulduar_stone_grip_cast_target_SpellScript::FilterTargetsInitial, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_ulduar_stone_grip_cast_target_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_ulduar_stone_grip : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ulduar_stone_grip() : SpellScriptLoader("spell_ulduar_stone_grip") { }
|
||||
|
||||
class spell_ulduar_stone_grip_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_ulduar_stone_grip_AuraScript);
|
||||
|
||||
void OnRemoveStun(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Player* owner = GetOwner()->ToPlayer())
|
||||
owner->RemoveAurasDueToSpell(aurEff->GetAmount());
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectRemove += AuraEffectRemoveFn(spell_ulduar_stone_grip_AuraScript::OnRemoveStun, EFFECT_2, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_ulduar_stone_grip_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_ulduar_squeezed_lifeless : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ulduar_squeezed_lifeless() : SpellScriptLoader("spell_ulduar_squeezed_lifeless") { }
|
||||
|
||||
class spell_ulduar_squeezed_lifeless_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_ulduar_squeezed_lifeless_SpellScript);
|
||||
|
||||
void HandleInstaKill(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (!GetHitPlayer() || !GetHitPlayer()->GetVehicle())
|
||||
return;
|
||||
|
||||
// Hack to set correct position is in _ExitVehicle()
|
||||
GetHitPlayer()->ExitVehicle();
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_ulduar_squeezed_lifeless_SpellScript::HandleInstaKill, EFFECT_1, SPELL_EFFECT_INSTAKILL);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_ulduar_squeezed_lifeless_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_kologarn_stone_shout : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_kologarn_stone_shout() : SpellScriptLoader("spell_kologarn_stone_shout") { }
|
||||
|
||||
class spell_kologarn_stone_shout_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_kologarn_stone_shout_AuraScript);
|
||||
|
||||
void OnPeriodic(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
uint32 triggerSpellId = GetSpellInfo()->Effects[EFFECT_0].TriggerSpell;
|
||||
if (Unit* caster = GetCaster())
|
||||
caster->CastSpell(caster, triggerSpellId, false);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
if (m_scriptSpellId == SPELL_STONE_SHOUT_10 || m_scriptSpellId == SPELL_STONE_SHOUT_25)
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_kologarn_stone_shout_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_kologarn_stone_shout_AuraScript();
|
||||
}
|
||||
|
||||
class spell_kologarn_stone_shout_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_kologarn_stone_shout_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.remove_if (PlayerOrPetCheck());
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
if (m_scriptSpellId != SPELL_STONE_SHOUT_10 && m_scriptSpellId != SPELL_STONE_SHOUT_25)
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kologarn_stone_shout_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_kologarn_stone_shout_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_kologarn_looks_could_kill : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_kologarn_looks_could_kill() : AchievementCriteriaScript("achievement_kologarn_looks_could_kill") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
if (target)
|
||||
if (InstanceScript* instance = target->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_KOLOGARN)))
|
||||
return cr->AI()->GetData(DATA_KOLOGARN_LOOKS_ACHIEV);
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_kologarn_rubble_and_roll : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_kologarn_rubble_and_roll() : AchievementCriteriaScript("achievement_kologarn_rubble_and_roll") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
if (target)
|
||||
if (InstanceScript* instance = target->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_KOLOGARN)))
|
||||
return cr->AI()->GetData(DATA_KOLOGARN_RUBBLE_ACHIEV);
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_kologarn_with_open_arms : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_kologarn_with_open_arms() : AchievementCriteriaScript("achievement_kologarn_with_open_arms") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
if (target)
|
||||
if (InstanceScript* instance = target->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_KOLOGARN)))
|
||||
return cr->AI()->GetData(DATA_KOLOGARN_ARMS_ACHIEV);
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
2475
src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.h
Normal file
2475
src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.h
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1157
src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.h
Normal file
1157
src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.h
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1797
src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.h
Normal file
1797
src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.h
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1066
src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.h
Normal file
1066
src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.h
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
3010
src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.h
Normal file
3010
src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.h
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user