mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 01:08:35 +00:00
Revert "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,7 +15,6 @@
|
||||
* 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"
|
||||
@@ -25,6 +24,123 @@
|
||||
#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)
|
||||
@@ -77,6 +193,783 @@ 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()
|
||||
{
|
||||
|
||||
@@ -1,908 +0,0 @@
|
||||
#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,7 +15,6 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "boss_auriaya.h"
|
||||
#include "AchievementCriteriaScript.h"
|
||||
#include "CreatureScript.h"
|
||||
#include "Player.h"
|
||||
@@ -25,6 +24,472 @@
|
||||
#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();
|
||||
|
||||
@@ -1,479 +0,0 @@
|
||||
#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
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,6 @@
|
||||
* 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"
|
||||
@@ -29,6 +28,665 @@
|
||||
#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();
|
||||
|
||||
@@ -1,676 +0,0 @@
|
||||
#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
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,6 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "boss_ignis.h"
|
||||
#include "AchievementCriteriaScript.h"
|
||||
#include "CreatureScript.h"
|
||||
#include "GameTime.h"
|
||||
@@ -28,6 +27,527 @@
|
||||
#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();
|
||||
|
||||
@@ -1,537 +0,0 @@
|
||||
#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,7 +15,6 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "boss_kologarn.h"
|
||||
#include "AchievementCriteriaScript.h"
|
||||
#include "CreatureScript.h"
|
||||
#include "PassiveAI.h"
|
||||
@@ -27,6 +26,867 @@
|
||||
#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
|
||||
|
||||
@@ -1,876 +0,0 @@
|
||||
#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
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user