aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp1907
1 files changed, 882 insertions, 1025 deletions
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
index 472b9651d3e..3a7c929eb55 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
@@ -246,1141 +246,993 @@ Position const chokePos[6] =
Position const finalPos = {-563.7552f, 2211.328f, 538.7848f, 0.0f};
-class boss_deathbringer_saurfang : public CreatureScript
+struct boss_deathbringer_saurfang : public BossAI
{
- public:
- boss_deathbringer_saurfang() : CreatureScript("boss_deathbringer_saurfang") { }
-
- struct boss_deathbringer_saurfangAI : public BossAI
+ boss_deathbringer_saurfang(Creature* creature) : BossAI(creature, DATA_DEATHBRINGER_SAURFANG), _introDone(false), _frenzied(false), _dead(false)
+ {
+ ASSERT(creature->GetVehicleKit()); // we dont actually use it, just check if exists
+ _fallenChampionCastCount = 0;
+ }
+
+ void Reset() override
+ {
+ if (_dead)
+ return;
+ _Reset();
+ events.SetPhase(PHASE_COMBAT);
+ _frenzied = false;
+ _dead = false;
+ me->SetPower(POWER_ENERGY, 0);
+ DoCastSelf(SPELL_ZERO_POWER, true);
+ DoCastSelf(SPELL_BLOOD_LINK, true);
+ DoCastSelf(SPELL_BLOOD_POWER, true);
+ DoCastSelf(SPELL_MARK_OF_THE_FALLEN_CHAMPION_S, true);
+ DoCastSelf(SPELL_RUNE_OF_BLOOD_S, true);
+ me->RemoveAurasDueToSpell(SPELL_BERSERK);
+ me->RemoveAurasDueToSpell(SPELL_FRENZY);
+ }
+
+ void JustEngagedWith(Unit* who) override
+ {
+ if (_dead)
+ return;
+
+ if (!instance->CheckRequiredBosses(DATA_DEATHBRINGER_SAURFANG, who->ToPlayer()))
{
- boss_deathbringer_saurfangAI(Creature* creature) : BossAI(creature, DATA_DEATHBRINGER_SAURFANG), _introDone(false), _frenzied(false), _dead(false)
- {
- ASSERT(creature->GetVehicleKit()); // we dont actually use it, just check if exists
- _fallenChampionCastCount = 0;
- }
-
- void Reset() override
- {
- if (_dead)
- return;
- _Reset();
- events.SetPhase(PHASE_COMBAT);
- _frenzied = false;
- _dead = false;
- me->SetPower(POWER_ENERGY, 0);
- DoCastSelf(SPELL_ZERO_POWER, true);
- DoCastSelf(SPELL_BLOOD_LINK, true);
- DoCastSelf(SPELL_BLOOD_POWER, true);
- DoCastSelf(SPELL_MARK_OF_THE_FALLEN_CHAMPION_S, true);
- DoCastSelf(SPELL_RUNE_OF_BLOOD_S, true);
- me->RemoveAurasDueToSpell(SPELL_BERSERK);
- me->RemoveAurasDueToSpell(SPELL_FRENZY);
- }
-
- void JustEngagedWith(Unit* who) override
- {
- if (_dead)
- return;
-
- if (!instance->CheckRequiredBosses(DATA_DEATHBRINGER_SAURFANG, who->ToPlayer()))
- {
- EnterEvadeMode(EVADE_REASON_OTHER);
- instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
- return;
- }
-
- // oh just screw intro, enter combat - no exploits please
- me->setActive(true);
- DoZoneInCombat();
+ EnterEvadeMode(EVADE_REASON_OTHER);
+ instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
+ return;
+ }
- events.Reset();
- events.SetPhase(PHASE_COMBAT);
- me->SetImmuneToPC(false);
- if (!_introDone)
- {
- DoCastSelf(SPELL_GRIP_OF_AGONY);
- if (Creature* creature = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SAURFANG_EVENT_NPC)))
- creature->AI()->DoAction(ACTION_INTERRUPT_INTRO);
- }
+ // oh just screw intro, enter combat - no exploits please
+ me->setActive(true);
+ DoZoneInCombat();
- _introDone = true;
+ events.Reset();
+ events.SetPhase(PHASE_COMBAT);
+ me->SetImmuneToPC(false);
+ if (!_introDone)
+ {
+ DoCastSelf(SPELL_GRIP_OF_AGONY);
+ if (Creature* creature = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SAURFANG_EVENT_NPC)))
+ creature->AI()->DoAction(ACTION_INTERRUPT_INTRO);
+ }
- Talk(SAY_AGGRO);
- events.ScheduleEvent(EVENT_SUMMON_BLOOD_BEAST, 30s, 0, PHASE_COMBAT);
- events.ScheduleEvent(EVENT_BERSERK, IsHeroic() ? 360s : 480s, 0, PHASE_COMBAT);
- events.ScheduleEvent(EVENT_BOILING_BLOOD, 15500ms, 0, PHASE_COMBAT);
- events.ScheduleEvent(EVENT_BLOOD_NOVA, 17s, 0, PHASE_COMBAT);
- events.ScheduleEvent(EVENT_RUNE_OF_BLOOD, 20s, 0, PHASE_COMBAT);
+ _introDone = true;
+
+ Talk(SAY_AGGRO);
+ events.ScheduleEvent(EVENT_SUMMON_BLOOD_BEAST, 30s, 0, PHASE_COMBAT);
+ events.ScheduleEvent(EVENT_BERSERK, IsHeroic() ? 360s : 480s, 0, PHASE_COMBAT);
+ events.ScheduleEvent(EVENT_BOILING_BLOOD, 15500ms, 0, PHASE_COMBAT);
+ events.ScheduleEvent(EVENT_BLOOD_NOVA, 17s, 0, PHASE_COMBAT);
+ events.ScheduleEvent(EVENT_RUNE_OF_BLOOD, 20s, 0, PHASE_COMBAT);
+
+ _fallenChampionCastCount = 0;
+ instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MARK_OF_THE_FALLEN_CHAMPION);
+ instance->SetBossState(DATA_DEATHBRINGER_SAURFANG, IN_PROGRESS);
+ }
+
+ void JustDied(Unit* /*killer*/) override
+ {
+ }
+
+ void AttackStart(Unit* victim) override
+ {
+ if (me->IsImmuneToPC())
+ return;
+
+ ScriptedAI::AttackStart(victim);
+ }
+
+ void EnterEvadeMode(EvadeReason why) override
+ {
+ ScriptedAI::EnterEvadeMode(why);
+ if (_introDone)
+ me->SetImmuneToPC(false);
+ }
+
+ void JustReachedHome() override
+ {
+ if (_dead)
+ return;
+ _JustReachedHome();
+ Reset();
+ instance->SetBossState(DATA_DEATHBRINGER_SAURFANG, FAIL);
+ instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MARK_OF_THE_FALLEN_CHAMPION);
+ }
+
+ void KilledUnit(Unit* victim) override
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_KILL);
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) override
+ {
+ if (damage >= me->GetHealth())
+ damage = me->GetHealth() - 1;
+
+ if (!_frenzied && HealthBelowPct(31)) // AT 30%, not below
+ {
+ _frenzied = true;
+ DoCastSelf(SPELL_FRENZY, true);
+ Talk(SAY_FRENZY);
+ }
- _fallenChampionCastCount = 0;
- instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MARK_OF_THE_FALLEN_CHAMPION);
- instance->SetBossState(DATA_DEATHBRINGER_SAURFANG, IN_PROGRESS);
- }
+ if (!_dead && me->GetHealth()-damage < FightWonValue)
+ {
+ _dead = true;
+ _JustDied();
+ _EnterEvadeMode();
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetImmuneToPC(true);
+ me->RemoveAurasOnEvade();
+ DoCastAOE(SPELL_REMOVE_MARKS_OF_THE_FALLEN_CHAMPION);
+ DoCastSelf(SPELL_ACHIEVEMENT, true);
+ Talk(SAY_DEATH);
+ DoCastSelf(SPELL_REPUTATION_BOSS_KILL, true);
+ DoCastSelf(SPELL_PERMANENT_FEIGN_DEATH);
+ if (Creature* creature = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SAURFANG_EVENT_NPC)))
+ creature->AI()->DoAction(ACTION_START_OUTRO);
+ }
+ }
- void JustDied(Unit* /*killer*/) override
+ void JustSummoned(Creature* summon) override
+ {
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true))
+ {
+ if (target->GetTransport())
{
+ summon->DespawnOrUnsummon(1ms);
+ EnterEvadeMode(EVADE_REASON_OTHER);
+ return;
}
- void AttackStart(Unit* victim) override
- {
- if (me->IsImmuneToPC())
- return;
+ summon->AI()->AttackStart(target);
+ }
- ScriptedAI::AttackStart(victim);
- }
+ summon->CastSpell(summon, SPELL_BLOOD_LINK_BEAST, true);
+ summon->CastSpell(summon, SPELL_RESISTANT_SKIN, true);
+ summons.Summon(summon);
+ DoZoneInCombat(summon);
+ }
- void EnterEvadeMode(EvadeReason why) override
- {
- ScriptedAI::EnterEvadeMode(why);
- if (_introDone)
- me->SetImmuneToPC(false);
- }
+ void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
+ {
+ summons.Despawn(summon);
+ }
- void JustReachedHome() override
- {
- if (_dead)
- return;
- _JustReachedHome();
- Reset();
- instance->SetBossState(DATA_DEATHBRINGER_SAURFANG, FAIL);
- instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MARK_OF_THE_FALLEN_CHAMPION);
- }
+ void MovementInform(uint32 type, uint32 id) override
+ {
+ if (type != POINT_MOTION_TYPE && id != POINT_SAURFANG)
+ return;
- void KilledUnit(Unit* victim) override
- {
- if (victim->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_KILL);
- }
+ instance->HandleGameObject(instance->GetGuidData(GO_SAURFANG_S_DOOR), false);
+ }
- void DamageTaken(Unit* /*attacker*/, uint32& damage) override
- {
- if (damage >= me->GetHealth())
- damage = me->GetHealth() - 1;
+ void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
+ {
+ if (target->GetTransport())
+ {
+ EnterEvadeMode(EVADE_REASON_OTHER);
+ return;
+ }
- if (!_frenzied && HealthBelowPct(31)) // AT 30%, not below
+ switch (spellInfo->Id)
+ {
+ case SPELL_MARK_OF_THE_FALLEN_CHAMPION:
+ Talk(SAY_MARK_OF_THE_FALLEN_CHAMPION);
+ break;
+ case 72255: // Mark of the Fallen Champion, triggered id
+ case 72444:
+ case 72445:
+ case 72446:
+ if (me->GetPower(POWER_ENERGY) != me->GetMaxPower(POWER_ENERGY))
{
- _frenzied = true;
- DoCastSelf(SPELL_FRENZY, true);
- Talk(SAY_FRENZY);
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.AddSpellBP0(1);
+ target->CastSpell(nullptr, SPELL_BLOOD_LINK_DUMMY, args);
}
+ break;
+ default:
+ break;
+ }
+ }
- if (!_dead && me->GetHealth()-damage < FightWonValue)
- {
- _dead = true;
- _JustDied();
- _EnterEvadeMode();
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->SetImmuneToPC(true);
- me->RemoveAurasOnEvade();
- DoCastAOE(SPELL_REMOVE_MARKS_OF_THE_FALLEN_CHAMPION);
- DoCastSelf(SPELL_ACHIEVEMENT, true);
- Talk(SAY_DEATH);
- DoCastSelf(SPELL_REPUTATION_BOSS_KILL, true);
- DoCastSelf(SPELL_PERMANENT_FEIGN_DEATH);
- if (Creature* creature = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SAURFANG_EVENT_NPC)))
- creature->AI()->DoAction(ACTION_START_OUTRO);
- }
- }
+ void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
+ {
+ if (spellInfo->Id == SPELL_BLOOD_LINK_POWER)
+ if (Aura* bloodPower = me->GetAura(SPELL_BLOOD_POWER))
+ bloodPower->RecalculateAmountOfEffects();
+ }
- void JustSummoned(Creature* summon) override
- {
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true))
- {
- if (target->GetTransport())
- {
- summon->DespawnOrUnsummon(1ms);
- EnterEvadeMode(EVADE_REASON_OTHER);
- return;
- }
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim() && !(events.IsInPhase(PHASE_INTRO_A) || events.IsInPhase(PHASE_INTRO_H)))
+ return;
- summon->AI()->AttackStart(target);
- }
+ events.Update(diff);
- summon->CastSpell(summon, SPELL_BLOOD_LINK_BEAST, true);
- summon->CastSpell(summon, SPELL_RESISTANT_SKIN, true);
- summons.Summon(summon);
- DoZoneInCombat(summon);
- }
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
- {
- summons.Despawn(summon);
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_INTRO_ALLIANCE_2:
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetFaction(FACTION_UNDEAD_SCOURGE);
+ Talk(SAY_INTRO_ALLIANCE_2);
+ break;
+ case EVENT_INTRO_ALLIANCE_3:
+ Talk(SAY_INTRO_ALLIANCE_3);
+ break;
+ case EVENT_INTRO_ALLIANCE_6:
+ Talk(SAY_INTRO_ALLIANCE_6);
+ Talk(SAY_INTRO_ALLIANCE_7);
+ DoCastSelf(SPELL_GRIP_OF_AGONY);
+ break;
+ case EVENT_INTRO_HORDE_2:
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetFaction(FACTION_UNDEAD_SCOURGE);
+ Talk(SAY_INTRO_HORDE_2);
+ break;
+ case EVENT_INTRO_HORDE_4:
+ Talk(SAY_INTRO_HORDE_4);
+ break;
+ case EVENT_INTRO_HORDE_9:
+ DoCastSelf(SPELL_GRIP_OF_AGONY);
+ Talk(SAY_INTRO_HORDE_9);
+ break;
+ case EVENT_INTRO_FINISH:
+ events.SetPhase(PHASE_COMBAT);
+ _introDone = true;
+ me->SetImmuneToPC(false);
+ break;
+ case EVENT_SUMMON_BLOOD_BEAST:
+ for (uint32 i10 = 0; i10 < 2; ++i10)
+ DoCastSelf(SPELL_SUMMON_BLOOD_BEAST+i10);
+ if (Is25ManRaid())
+ for (uint32 i25 = 0; i25 < 3; ++i25)
+ DoCastSelf(SPELL_SUMMON_BLOOD_BEAST_25_MAN+i25);
+ Talk(SAY_BLOOD_BEASTS);
+ events.ScheduleEvent(EVENT_SUMMON_BLOOD_BEAST, 40s, 0, PHASE_COMBAT);
+ if (IsHeroic())
+ events.ScheduleEvent(EVENT_SCENT_OF_BLOOD, 10s, 0, PHASE_COMBAT);
+ break;
+ case EVENT_BLOOD_NOVA:
+ DoCastAOE(SPELL_BLOOD_NOVA_TRIGGER);
+ events.ScheduleEvent(EVENT_BLOOD_NOVA, 20s, 25s, 0, PHASE_COMBAT);
+ break;
+ case EVENT_RUNE_OF_BLOOD:
+ DoCastVictim(SPELL_RUNE_OF_BLOOD);
+ events.ScheduleEvent(EVENT_RUNE_OF_BLOOD, 20s, 25s, 0, PHASE_COMBAT);
+ break;
+ case EVENT_BOILING_BLOOD:
+ DoCastSelf(SPELL_BOILING_BLOOD);
+ events.ScheduleEvent(EVENT_BOILING_BLOOD, 15s, 20s, 0, PHASE_COMBAT);
+ break;
+ case EVENT_BERSERK:
+ DoCastSelf(SPELL_BERSERK);
+ Talk(SAY_BERSERK);
+ break;
+ case EVENT_SCENT_OF_BLOOD:
+ if (!summons.empty())
+ {
+ Talk(EMOTE_SCENT_OF_BLOOD);
+ DoCastAOE(SPELL_SCENT_OF_BLOOD);
+ }
+ break;
+ default:
+ break;
}
- void MovementInform(uint32 type, uint32 id) override
- {
- if (type != POINT_MOTION_TYPE && id != POINT_SAURFANG)
- return;
-
- instance->HandleGameObject(instance->GetGuidData(GO_SAURFANG_S_DOOR), false);
- }
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+ }
- void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
- {
- if (target->GetTransport())
- {
- EnterEvadeMode(EVADE_REASON_OTHER);
- return;
- }
+ DoMeleeAttackIfReady();
+ }
- switch (spellInfo->Id)
- {
- case SPELL_MARK_OF_THE_FALLEN_CHAMPION:
- Talk(SAY_MARK_OF_THE_FALLEN_CHAMPION);
- break;
- case 72255: // Mark of the Fallen Champion, triggered id
- case 72444:
- case 72445:
- case 72446:
- if (me->GetPower(POWER_ENERGY) != me->GetMaxPower(POWER_ENERGY))
- {
- CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
- args.AddSpellBP0(1);
- target->CastSpell(nullptr, SPELL_BLOOD_LINK_DUMMY, args);
- }
- break;
- default:
- break;
- }
- }
+ uint32 GetData(uint32 type) const override
+ {
+ if (type == DATA_MADE_A_MESS)
+ if (_fallenChampionCastCount < RAID_MODE<uint32>(3, 5, 3, 5))
+ return 1;
- void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
- {
- if (spellInfo->Id == SPELL_BLOOD_LINK_POWER)
- if (Aura* bloodPower = me->GetAura(SPELL_BLOOD_POWER))
- bloodPower->RecalculateAmountOfEffects();
- }
+ return 0;
+ }
- void UpdateAI(uint32 diff) override
+ // intro setup
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case PHASE_INTRO_A:
+ case PHASE_INTRO_H:
{
- if (!UpdateVictim() && !(events.IsInPhase(PHASE_INTRO_A) || events.IsInPhase(PHASE_INTRO_H)))
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ // controls what events will execute
+ events.SetPhase(uint32(action));
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_INTRO_ALLIANCE_2:
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->SetFaction(FACTION_UNDEAD_SCOURGE);
- Talk(SAY_INTRO_ALLIANCE_2);
- break;
- case EVENT_INTRO_ALLIANCE_3:
- Talk(SAY_INTRO_ALLIANCE_3);
- break;
- case EVENT_INTRO_ALLIANCE_6:
- Talk(SAY_INTRO_ALLIANCE_6);
- Talk(SAY_INTRO_ALLIANCE_7);
- DoCastSelf(SPELL_GRIP_OF_AGONY);
- break;
- case EVENT_INTRO_HORDE_2:
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->SetFaction(FACTION_UNDEAD_SCOURGE);
- Talk(SAY_INTRO_HORDE_2);
- break;
- case EVENT_INTRO_HORDE_4:
- Talk(SAY_INTRO_HORDE_4);
- break;
- case EVENT_INTRO_HORDE_9:
- DoCastSelf(SPELL_GRIP_OF_AGONY);
- Talk(SAY_INTRO_HORDE_9);
- break;
- case EVENT_INTRO_FINISH:
- events.SetPhase(PHASE_COMBAT);
- _introDone = true;
- me->SetImmuneToPC(false);
- break;
- case EVENT_SUMMON_BLOOD_BEAST:
- for (uint32 i10 = 0; i10 < 2; ++i10)
- DoCastSelf(SPELL_SUMMON_BLOOD_BEAST+i10);
- if (Is25ManRaid())
- for (uint32 i25 = 0; i25 < 3; ++i25)
- DoCastSelf(SPELL_SUMMON_BLOOD_BEAST_25_MAN+i25);
- Talk(SAY_BLOOD_BEASTS);
- events.ScheduleEvent(EVENT_SUMMON_BLOOD_BEAST, 40s, 0, PHASE_COMBAT);
- if (IsHeroic())
- events.ScheduleEvent(EVENT_SCENT_OF_BLOOD, 10s, 0, PHASE_COMBAT);
- break;
- case EVENT_BLOOD_NOVA:
- DoCastAOE(SPELL_BLOOD_NOVA_TRIGGER);
- events.ScheduleEvent(EVENT_BLOOD_NOVA, 20s, 25s, 0, PHASE_COMBAT);
- break;
- case EVENT_RUNE_OF_BLOOD:
- DoCastVictim(SPELL_RUNE_OF_BLOOD);
- events.ScheduleEvent(EVENT_RUNE_OF_BLOOD, 20s, 25s, 0, PHASE_COMBAT);
- break;
- case EVENT_BOILING_BLOOD:
- DoCastSelf(SPELL_BOILING_BLOOD);
- events.ScheduleEvent(EVENT_BOILING_BLOOD, 15s, 20s, 0, PHASE_COMBAT);
- break;
- case EVENT_BERSERK:
- DoCastSelf(SPELL_BERSERK);
- Talk(SAY_BERSERK);
- break;
- case EVENT_SCENT_OF_BLOOD:
- if (!summons.empty())
- {
- Talk(EMOTE_SCENT_OF_BLOOD);
- DoCastAOE(SPELL_SCENT_OF_BLOOD);
- }
- break;
- default:
- break;
- }
+ me->SetHomePosition(deathbringerPos.GetPositionX(), deathbringerPos.GetPositionY(), deathbringerPos.GetPositionZ(), me->GetOrientation());
+ me->GetMotionMaster()->MovePoint(POINT_SAURFANG, deathbringerPos.GetPositionX(), deathbringerPos.GetPositionY(), deathbringerPos.GetPositionZ());
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
- }
+ events.ScheduleEvent(EVENT_INTRO_ALLIANCE_2, 2500ms, 0, PHASE_INTRO_A);
+ events.ScheduleEvent(EVENT_INTRO_ALLIANCE_3, 20s, 0, PHASE_INTRO_A);
- DoMeleeAttackIfReady();
+ events.ScheduleEvent(EVENT_INTRO_HORDE_2, 5s, 0, PHASE_INTRO_H);
+ break;
}
-
- uint32 GetData(uint32 type) const override
+ case ACTION_CONTINUE_INTRO:
{
- if (type == DATA_MADE_A_MESS)
- if (_fallenChampionCastCount < RAID_MODE<uint32>(3, 5, 3, 5))
- return 1;
+ if (_introDone)
+ return;
- return 0;
- }
+ events.ScheduleEvent(EVENT_INTRO_ALLIANCE_6, 7s, 0, PHASE_INTRO_A);
+ events.ScheduleEvent(EVENT_INTRO_FINISH, 8s, 0, PHASE_INTRO_A);
- // intro setup
- void DoAction(int32 action) override
+ events.ScheduleEvent(EVENT_INTRO_HORDE_4, 6500ms, 0, PHASE_INTRO_H);
+ events.ScheduleEvent(EVENT_INTRO_HORDE_9, 48200ms, 0, PHASE_INTRO_H);
+ events.ScheduleEvent(EVENT_INTRO_FINISH, 55700ms, 0, PHASE_INTRO_H);
+ break;
+ }
+ case ACTION_MARK_OF_THE_FALLEN_CHAMPION:
{
- switch (action)
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, true, -SPELL_MARK_OF_THE_FALLEN_CHAMPION))
{
- case PHASE_INTRO_A:
- case PHASE_INTRO_H:
- {
- // controls what events will execute
- events.SetPhase(uint32(action));
-
- me->SetHomePosition(deathbringerPos.GetPositionX(), deathbringerPos.GetPositionY(), deathbringerPos.GetPositionZ(), me->GetOrientation());
- me->GetMotionMaster()->MovePoint(POINT_SAURFANG, deathbringerPos.GetPositionX(), deathbringerPos.GetPositionY(), deathbringerPos.GetPositionZ());
-
- events.ScheduleEvent(EVENT_INTRO_ALLIANCE_2, 2500ms, 0, PHASE_INTRO_A);
- events.ScheduleEvent(EVENT_INTRO_ALLIANCE_3, 20s, 0, PHASE_INTRO_A);
-
- events.ScheduleEvent(EVENT_INTRO_HORDE_2, 5s, 0, PHASE_INTRO_H);
- break;
- }
- case ACTION_CONTINUE_INTRO:
- {
- if (_introDone)
- return;
-
- events.ScheduleEvent(EVENT_INTRO_ALLIANCE_6, 7s, 0, PHASE_INTRO_A);
- events.ScheduleEvent(EVENT_INTRO_FINISH, 8s, 0, PHASE_INTRO_A);
-
- events.ScheduleEvent(EVENT_INTRO_HORDE_4, 6500ms, 0, PHASE_INTRO_H);
- events.ScheduleEvent(EVENT_INTRO_HORDE_9, 48200ms, 0, PHASE_INTRO_H);
- events.ScheduleEvent(EVENT_INTRO_FINISH, 55700ms, 0, PHASE_INTRO_H);
- break;
- }
- case ACTION_MARK_OF_THE_FALLEN_CHAMPION:
- {
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, true, -SPELL_MARK_OF_THE_FALLEN_CHAMPION))
- {
- ++_fallenChampionCastCount;
- DoCast(target, SPELL_MARK_OF_THE_FALLEN_CHAMPION);
- me->SetPower(POWER_ENERGY, 0);
- if (Aura* bloodPower = me->GetAura(SPELL_BLOOD_POWER))
- bloodPower->RecalculateAmountOfEffects();
- }
- break;
- }
- default:
- break;
+ ++_fallenChampionCastCount;
+ DoCast(target, SPELL_MARK_OF_THE_FALLEN_CHAMPION);
+ me->SetPower(POWER_ENERGY, 0);
+ if (Aura* bloodPower = me->GetAura(SPELL_BLOOD_POWER))
+ bloodPower->RecalculateAmountOfEffects();
}
+ break;
}
+ default:
+ break;
+ }
+ }
- bool CanAIAttack(Unit const* target) const override
- {
- if (target->GetTransport())
- return false;
-
- return BossAI::CanAIAttack(target);
- }
+ bool CanAIAttack(Unit const* target) const override
+ {
+ if (target->GetTransport())
+ return false;
- static uint32 const FightWonValue;
+ return BossAI::CanAIAttack(target);
+ }
- private:
- uint32 _fallenChampionCastCount;
- bool _introDone;
- bool _frenzied; // faster than iterating all auras to find Frenzy
- bool _dead;
- };
+ static uint32 const FightWonValue;
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetIcecrownCitadelAI<boss_deathbringer_saurfangAI>(creature);
- }
+private:
+ uint32 _fallenChampionCastCount;
+ bool _introDone;
+ bool _frenzied; // faster than iterating all auras to find Frenzy
+ bool _dead;
};
-uint32 const boss_deathbringer_saurfang::boss_deathbringer_saurfangAI::FightWonValue = 100000;
+uint32 const boss_deathbringer_saurfang::FightWonValue = 100000;
-class npc_high_overlord_saurfang_icc : public CreatureScript
+struct npc_high_overlord_saurfang_icc : public ScriptedAI
{
- public:
- npc_high_overlord_saurfang_icc() : CreatureScript("npc_high_overlord_saurfang_icc") { }
-
- struct npc_high_overlord_saurfangAI : public ScriptedAI
+ npc_high_overlord_saurfang_icc(Creature* creature) : ScriptedAI(creature)
+ {
+ ASSERT(creature->GetVehicleKit());
+ _instance = me->GetInstanceScript();
+ }
+
+ void Reset() override
+ {
+ _events.Reset();
+ }
+
+ bool OnGossipSelect(Player* player, uint32 menuId, uint32 /*gossipListId*/) override
+ {
+ if (menuId == GOSSIP_MENU_HIGH_OVERLORD_SAURFANG)
{
- npc_high_overlord_saurfangAI(Creature* creature) : ScriptedAI(creature)
- {
- ASSERT(creature->GetVehicleKit());
- _instance = me->GetInstanceScript();
- }
-
- void Reset() override
+ CloseGossipMenuFor(player);
+ DoAction(ACTION_START_EVENT);
+ }
+ return false;
+ }
+
+ void GuardBroadcast(std::function<void(Creature*)>&& action) const
+ {
+ std::vector<Creature*> guardList;
+ GetCreatureListWithEntryInGrid(guardList, me, NPC_SE_KOR_KRON_REAVER, 100.0f);
+ for (Creature* guard : guardList)
+ action(guard);
+ }
+
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case ACTION_START_EVENT:
{
- _events.Reset();
- }
+ // Prevent crashes
+ if (_events.IsInPhase(PHASE_INTRO_A) || _events.IsInPhase(PHASE_INTRO_H))
+ return;
- bool OnGossipSelect(Player* player, uint32 menuId, uint32 /*gossipListId*/) override
- {
- if (menuId == GOSSIP_MENU_HIGH_OVERLORD_SAURFANG)
+ std::list<Creature*> guardList;
+ GetCreatureListWithEntryInGrid(guardList, me, NPC_SE_KOR_KRON_REAVER, 20.0f);
+ guardList.sort(Trinity::ObjectDistanceOrderPred(me));
+ uint32 x = 1;
+ for (auto itr = guardList.begin(); itr != guardList.end(); ++x, ++itr)
+ (*itr)->AI()->SetData(0, x);
+
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ Talk(SAY_INTRO_HORDE_1);
+ _events.SetPhase(PHASE_INTRO_H);
+ _events.ScheduleEvent(EVENT_INTRO_HORDE_3, 18500ms, 0, PHASE_INTRO_H);
+ _instance->HandleGameObject(_instance->GetGuidData(GO_SAURFANG_S_DOOR), true);
+ if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_DEATHBRINGER_SAURFANG)))
+ deathbringer->AI()->DoAction(PHASE_INTRO_H);
+ break;
+ }
+ case ACTION_START_OUTRO:
+ {
+ me->RemoveAurasDueToSpell(SPELL_GRIP_OF_AGONY);
+ Talk(SAY_OUTRO_HORDE_1);
+ _events.ScheduleEvent(EVENT_OUTRO_HORDE_2, 10s); // say
+ _events.ScheduleEvent(EVENT_OUTRO_HORDE_3, 18s); // say
+ _events.ScheduleEvent(EVENT_OUTRO_HORDE_4, 24s); // cast
+ _events.ScheduleEvent(EVENT_OUTRO_HORDE_5, 30s); // move
+ me->SetDisableGravity(false);
+ me->GetMotionMaster()->MoveFall();
+ GuardBroadcast([](Creature* guard)
{
- CloseGossipMenuFor(player);
- DoAction(ACTION_START_EVENT);
- }
- return false;
- }
-
- void GuardBroadcast(std::function<void(Creature*)>&& action) const
- {
- std::vector<Creature*> guardList;
- GetCreatureListWithEntryInGrid(guardList, me, NPC_SE_KOR_KRON_REAVER, 100.0f);
- for (Creature* guard : guardList)
- action(guard);
+ guard->AI()->DoAction(ACTION_DESPAWN);
+ });
+ break;
}
-
- void DoAction(int32 action) override
+ case ACTION_INTERRUPT_INTRO:
{
- switch (action)
+ _events.Reset();
+ GuardBroadcast([](Creature* guard)
{
- case ACTION_START_EVENT:
- {
- // Prevent crashes
- if (_events.IsInPhase(PHASE_INTRO_A) || _events.IsInPhase(PHASE_INTRO_H))
- return;
-
- std::list<Creature*> guardList;
- GetCreatureListWithEntryInGrid(guardList, me, NPC_SE_KOR_KRON_REAVER, 20.0f);
- guardList.sort(Trinity::ObjectDistanceOrderPred(me));
- uint32 x = 1;
- for (auto itr = guardList.begin(); itr != guardList.end(); ++x, ++itr)
- (*itr)->AI()->SetData(0, x);
-
- me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- Talk(SAY_INTRO_HORDE_1);
- _events.SetPhase(PHASE_INTRO_H);
- _events.ScheduleEvent(EVENT_INTRO_HORDE_3, 18500ms, 0, PHASE_INTRO_H);
- _instance->HandleGameObject(_instance->GetGuidData(GO_SAURFANG_S_DOOR), true);
- if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_DEATHBRINGER_SAURFANG)))
- deathbringer->AI()->DoAction(PHASE_INTRO_H);
- break;
- }
- case ACTION_START_OUTRO:
- {
- me->RemoveAurasDueToSpell(SPELL_GRIP_OF_AGONY);
- Talk(SAY_OUTRO_HORDE_1);
- _events.ScheduleEvent(EVENT_OUTRO_HORDE_2, 10s); // say
- _events.ScheduleEvent(EVENT_OUTRO_HORDE_3, 18s); // say
- _events.ScheduleEvent(EVENT_OUTRO_HORDE_4, 24s); // cast
- _events.ScheduleEvent(EVENT_OUTRO_HORDE_5, 30s); // move
- me->SetDisableGravity(false);
- me->GetMotionMaster()->MoveFall();
- GuardBroadcast([](Creature* guard)
- {
- guard->AI()->DoAction(ACTION_DESPAWN);
- });
- break;
- }
- case ACTION_INTERRUPT_INTRO:
- {
- _events.Reset();
- GuardBroadcast([](Creature* guard)
- {
- guard->AI()->DoAction(ACTION_DESPAWN);
- });
- break;
- }
- default:
- break;
- }
+ guard->AI()->DoAction(ACTION_DESPAWN);
+ });
+ break;
}
+ default:
+ break;
+ }
+ }
- void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
- {
- if (spellInfo->Id == SPELL_GRIP_OF_AGONY)
- {
- me->SetDisableGravity(true);
- me->GetMotionMaster()->MovePoint(POINT_CHOKE, chokePos[0]);
- }
- }
+ void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
+ {
+ if (spellInfo->Id == SPELL_GRIP_OF_AGONY)
+ {
+ me->SetDisableGravity(true);
+ me->GetMotionMaster()->MovePoint(POINT_CHOKE, chokePos[0]);
+ }
+ }
- void MovementInform(uint32 type, uint32 id) override
+ void MovementInform(uint32 type, uint32 id) override
+ {
+ if (type == POINT_MOTION_TYPE)
+ {
+ switch (id)
{
- if (type == POINT_MOTION_TYPE)
- {
- switch (id)
+ case POINT_FIRST_STEP:
+ me->SetWalk(false);
+ Talk(SAY_INTRO_HORDE_3);
+ _events.ScheduleEvent(EVENT_INTRO_HORDE_5, 15500ms, 0, PHASE_INTRO_H);
+ _events.ScheduleEvent(EVENT_INTRO_HORDE_6, 29500ms, 0, PHASE_INTRO_H);
+ _events.ScheduleEvent(EVENT_INTRO_HORDE_7, 43800ms, 0, PHASE_INTRO_H);
+ _events.ScheduleEvent(EVENT_INTRO_HORDE_8, 47000ms, 0, PHASE_INTRO_H);
+ if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_DEATHBRINGER_SAURFANG)))
+ deathbringer->AI()->DoAction(ACTION_CONTINUE_INTRO);
+ break;
+ case POINT_CORPSE:
+ if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_DEATHBRINGER_SAURFANG)))
{
- case POINT_FIRST_STEP:
- me->SetWalk(false);
- Talk(SAY_INTRO_HORDE_3);
- _events.ScheduleEvent(EVENT_INTRO_HORDE_5, 15500ms, 0, PHASE_INTRO_H);
- _events.ScheduleEvent(EVENT_INTRO_HORDE_6, 29500ms, 0, PHASE_INTRO_H);
- _events.ScheduleEvent(EVENT_INTRO_HORDE_7, 43800ms, 0, PHASE_INTRO_H);
- _events.ScheduleEvent(EVENT_INTRO_HORDE_8, 47000ms, 0, PHASE_INTRO_H);
- if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_DEATHBRINGER_SAURFANG)))
- deathbringer->AI()->DoAction(ACTION_CONTINUE_INTRO);
- break;
- case POINT_CORPSE:
- if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_DEATHBRINGER_SAURFANG)))
- {
- deathbringer->CastSpell(me, SPELL_RIDE_VEHICLE, true); // for the packet logs.
- deathbringer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- deathbringer->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_DROWNED);
- }
- _events.ScheduleEvent(EVENT_OUTRO_HORDE_5, 1s); // move
- _events.ScheduleEvent(EVENT_OUTRO_HORDE_6, 4s); // say
- break;
- case POINT_FINAL:
- if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_DEATHBRINGER_SAURFANG)))
- deathbringer->DespawnOrUnsummon();
- me->DespawnOrUnsummon();
- break;
- default:
- break;
+ deathbringer->CastSpell(me, SPELL_RIDE_VEHICLE, true); // for the packet logs.
+ deathbringer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ deathbringer->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_DROWNED);
}
- }
- else if (type == WAYPOINT_MOTION_TYPE && id == POINT_EXIT)
- {
- std::list<Creature*> guards;
- GetCreatureListWithEntryInGrid(guards, me, NPC_KOR_KRON_GENERAL, 50.0f);
- for (std::list<Creature*>::iterator itr = guards.begin(); itr != guards.end(); ++itr)
- (*itr)->DespawnOrUnsummon();
+ _events.ScheduleEvent(EVENT_OUTRO_HORDE_5, 1s); // move
+ _events.ScheduleEvent(EVENT_OUTRO_HORDE_6, 4s); // say
+ break;
+ case POINT_FINAL:
+ if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_DEATHBRINGER_SAURFANG)))
+ deathbringer->DespawnOrUnsummon();
me->DespawnOrUnsummon();
- }
- }
-
- void UpdateAI(uint32 diff) override
- {
- _events.Update(diff);
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_INTRO_HORDE_3:
- me->SetWalk(true);
- me->GetMotionMaster()->MovePoint(POINT_FIRST_STEP, firstStepPos.GetPositionX(), firstStepPos.GetPositionY(), firstStepPos.GetPositionZ());
- break;
- case EVENT_INTRO_HORDE_5:
- Talk(SAY_INTRO_HORDE_5);
- break;
- case EVENT_INTRO_HORDE_6:
- Talk(SAY_INTRO_HORDE_6);
- break;
- case EVENT_INTRO_HORDE_7:
- Talk(SAY_INTRO_HORDE_7);
- break;
- case EVENT_INTRO_HORDE_8:
- Talk(SAY_INTRO_HORDE_8);
- GuardBroadcast([](Creature* guard)
- {
- guard->AI()->DoAction(ACTION_CHARGE);
- });
- me->GetMotionMaster()->MoveCharge(chargePos[0].GetPositionX(), chargePos[0].GetPositionY(), chargePos[0].GetPositionZ(), 8.5f, POINT_CHARGE);
- break;
- case EVENT_OUTRO_HORDE_2: // say
- if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_DEATHBRINGER_SAURFANG)))
- me->SetFacingToObject(deathbringer);
- Talk(SAY_OUTRO_HORDE_2);
- break;
- case EVENT_OUTRO_HORDE_3: // say
- Talk(SAY_OUTRO_HORDE_3);
- break;
- case EVENT_OUTRO_HORDE_4: // move
- if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_DEATHBRINGER_SAURFANG)))
- {
- float x, y, z;
- deathbringer->GetClosePoint(x, y, z, deathbringer->GetCombatReach());
- me->SetWalk(true);
- me->GetMotionMaster()->MovePoint(POINT_CORPSE, x, y, z);
- }
- break;
- case EVENT_OUTRO_HORDE_5: // move
- me->GetMotionMaster()->MovePoint(POINT_FINAL, finalPos);
- break;
- case EVENT_OUTRO_HORDE_6: // say
- Talk(SAY_OUTRO_HORDE_4);
- break;
- }
- }
+ break;
+ default:
+ break;
}
-
- private:
- EventMap _events;
- InstanceScript* _instance;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
+ }
+ else if (type == WAYPOINT_MOTION_TYPE && id == POINT_EXIT)
{
- return GetIcecrownCitadelAI<npc_high_overlord_saurfangAI>(creature);
+ std::list<Creature*> guards;
+ GetCreatureListWithEntryInGrid(guards, me, NPC_KOR_KRON_GENERAL, 50.0f);
+ for (std::list<Creature*>::iterator itr = guards.begin(); itr != guards.end(); ++itr)
+ (*itr)->DespawnOrUnsummon();
+ me->DespawnOrUnsummon();
}
-};
-
-class npc_muradin_bronzebeard_icc : public CreatureScript
-{
- public:
- npc_muradin_bronzebeard_icc() : CreatureScript("npc_muradin_bronzebeard_icc") { }
+ }
- struct npc_muradin_bronzebeard_iccAI : public ScriptedAI
+ void UpdateAI(uint32 diff) override
+ {
+ _events.Update(diff);
+ while (uint32 eventId = _events.ExecuteEvent())
{
- npc_muradin_bronzebeard_iccAI(Creature* creature) : ScriptedAI(creature)
- {
- _instance = me->GetInstanceScript();
- }
-
- void Reset() override
- {
- _events.Reset();
- }
-
- bool OnGossipSelect(Player* player, uint32 menuId, uint32 /*gossipListId*/) override
- {
- if (menuId == GOSSIP_MENU_MURADIN_BRONZEBEARD)
- {
- CloseGossipMenuFor(player);
- DoAction(ACTION_START_EVENT);
- }
- return false;
- }
-
- void GuardBroadcast(std::function<void(Creature*)>&& action) const
- {
- std::vector<Creature*> guardList;
- GetCreatureListWithEntryInGrid(guardList, me, NPC_SE_SKYBREAKER_MARINE, 100.0f);
- for (Creature* guard : guardList)
- action(guard);
- }
-
- void DoAction(int32 action) override
- {
- switch (action)
- {
- case ACTION_START_EVENT:
+ switch (eventId)
+ {
+ case EVENT_INTRO_HORDE_3:
+ me->SetWalk(true);
+ me->GetMotionMaster()->MovePoint(POINT_FIRST_STEP, firstStepPos.GetPositionX(), firstStepPos.GetPositionY(), firstStepPos.GetPositionZ());
+ break;
+ case EVENT_INTRO_HORDE_5:
+ Talk(SAY_INTRO_HORDE_5);
+ break;
+ case EVENT_INTRO_HORDE_6:
+ Talk(SAY_INTRO_HORDE_6);
+ break;
+ case EVENT_INTRO_HORDE_7:
+ Talk(SAY_INTRO_HORDE_7);
+ break;
+ case EVENT_INTRO_HORDE_8:
+ Talk(SAY_INTRO_HORDE_8);
+ GuardBroadcast([](Creature* guard)
{
- // Prevent crashes
- if (_events.IsInPhase(PHASE_INTRO_A) || _events.IsInPhase(PHASE_INTRO_H))
- return;
-
- _events.SetPhase(PHASE_INTRO_A);
- std::list<Creature*> guardList;
- GetCreatureListWithEntryInGrid(guardList, me, NPC_SE_SKYBREAKER_MARINE, 20.0f);
- guardList.sort(Trinity::ObjectDistanceOrderPred(me));
- uint32 x = 1;
- for (auto itr = guardList.begin(); itr != guardList.end(); ++x, ++itr)
- (*itr)->AI()->SetData(0, x);
-
- me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- Talk(SAY_INTRO_ALLIANCE_1);
- _events.ScheduleEvent(EVENT_INTRO_ALLIANCE_4, 29500ms, 0, PHASE_INTRO_A);
- _instance->HandleGameObject(_instance->GetGuidData(GO_SAURFANG_S_DOOR), true);
- if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_DEATHBRINGER_SAURFANG)))
- deathbringer->AI()->DoAction(PHASE_INTRO_A);
- break;
- }
- case ACTION_START_OUTRO:
- {
- me->RemoveAurasDueToSpell(SPELL_GRIP_OF_AGONY);
- Talk(SAY_OUTRO_ALLIANCE_1);
- me->SetDisableGravity(false);
- me->GetMotionMaster()->MoveFall();
- GuardBroadcast([](Creature* guard)
- {
- guard->AI()->DoAction(ACTION_DESPAWN);
- });
-
- // temp until outro fully done - to put deathbringer on respawn timer (until next reset)
- if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_DEATHBRINGER_SAURFANG)))
- deathbringer->DespawnOrUnsummon(5s);
- break;
- }
- case ACTION_INTERRUPT_INTRO:
- _events.Reset();
- GuardBroadcast([](Creature* guard)
- {
- guard->AI()->DoAction(ACTION_DESPAWN);
- });
- break;
- }
- }
-
- void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
- {
- if (spellInfo->Id == SPELL_GRIP_OF_AGONY)
- {
- me->SetDisableGravity(true);
- me->GetMotionMaster()->MovePoint(POINT_CHOKE, chokePos[0]);
- }
- }
-
- void MovementInform(uint32 type, uint32 id) override
- {
- if (type == POINT_MOTION_TYPE && id == POINT_FIRST_STEP)
- {
- me->SetWalk(false);
- Talk(SAY_INTRO_ALLIANCE_4);
- _events.ScheduleEvent(EVENT_INTRO_ALLIANCE_5, 5s, 0, PHASE_INTRO_A);
+ guard->AI()->DoAction(ACTION_CHARGE);
+ });
+ me->GetMotionMaster()->MoveCharge(chargePos[0].GetPositionX(), chargePos[0].GetPositionY(), chargePos[0].GetPositionZ(), 8.5f, POINT_CHARGE);
+ break;
+ case EVENT_OUTRO_HORDE_2: // say
+ if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_DEATHBRINGER_SAURFANG)))
+ me->SetFacingToObject(deathbringer);
+ Talk(SAY_OUTRO_HORDE_2);
+ break;
+ case EVENT_OUTRO_HORDE_3: // say
+ Talk(SAY_OUTRO_HORDE_3);
+ break;
+ case EVENT_OUTRO_HORDE_4: // move
if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_DEATHBRINGER_SAURFANG)))
- deathbringer->AI()->DoAction(ACTION_CONTINUE_INTRO);
- }
- else if (type == WAYPOINT_MOTION_TYPE && id == POINT_EXIT)
- {
- std::list<Creature*> guards;
- GetCreatureListWithEntryInGrid(guards, me, NPC_ALLIANCE_COMMANDER, 50.0f);
- for (std::list<Creature*>::iterator itr = guards.begin(); itr != guards.end(); ++itr)
- (*itr)->DespawnOrUnsummon();
- me->DespawnOrUnsummon();
- }
- }
-
- void UpdateAI(uint32 diff) override
- {
- _events.Update(diff);
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
{
- case EVENT_INTRO_ALLIANCE_4:
- me->SetWalk(true);
- me->GetMotionMaster()->MovePoint(POINT_FIRST_STEP, firstStepPos.GetPositionX(), firstStepPos.GetPositionY(), firstStepPos.GetPositionZ());
- break;
- case EVENT_INTRO_ALLIANCE_5:
- Talk(SAY_INTRO_ALLIANCE_5);
- GuardBroadcast([](Creature* guard)
- {
- guard->AI()->DoAction(ACTION_CHARGE);
- });
- me->GetMotionMaster()->MoveCharge(chargePos[0].GetPositionX(), chargePos[0].GetPositionY(), chargePos[0].GetPositionZ(), 8.5f, POINT_CHARGE);
- break;
+ float x, y, z;
+ deathbringer->GetClosePoint(x, y, z, deathbringer->GetCombatReach());
+ me->SetWalk(true);
+ me->GetMotionMaster()->MovePoint(POINT_CORPSE, x, y, z);
}
- }
+ break;
+ case EVENT_OUTRO_HORDE_5: // move
+ me->GetMotionMaster()->MovePoint(POINT_FINAL, finalPos);
+ break;
+ case EVENT_OUTRO_HORDE_6: // say
+ Talk(SAY_OUTRO_HORDE_4);
+ break;
}
-
- private:
- EventMap _events;
- InstanceScript* _instance;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetIcecrownCitadelAI<npc_muradin_bronzebeard_iccAI>(creature);
}
+ }
+
+private:
+ EventMap _events;
+ InstanceScript* _instance;
};
-class npc_saurfang_event : public CreatureScript
+struct npc_muradin_bronzebeard_icc : public ScriptedAI
{
- public:
- npc_saurfang_event() : CreatureScript("npc_saurfang_event") { }
-
- struct npc_saurfang_eventAI : public ScriptedAI
+ npc_muradin_bronzebeard_icc(Creature* creature) : ScriptedAI(creature)
+ {
+ _instance = me->GetInstanceScript();
+ }
+
+ void Reset() override
+ {
+ _events.Reset();
+ }
+
+ bool OnGossipSelect(Player* player, uint32 menuId, uint32 /*gossipListId*/) override
+ {
+ if (menuId == GOSSIP_MENU_MURADIN_BRONZEBEARD)
{
- npc_saurfang_eventAI(Creature* creature) : ScriptedAI(creature)
- {
- _index = 0;
- }
-
- void SetData(uint32 type, uint32 data) override
+ CloseGossipMenuFor(player);
+ DoAction(ACTION_START_EVENT);
+ }
+ return false;
+ }
+
+ void GuardBroadcast(std::function<void(Creature*)>&& action) const
+ {
+ std::vector<Creature*> guardList;
+ GetCreatureListWithEntryInGrid(guardList, me, NPC_SE_SKYBREAKER_MARINE, 100.0f);
+ for (Creature* guard : guardList)
+ action(guard);
+ }
+
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case ACTION_START_EVENT:
{
- if (!(!type && data && data < 6))
+ // Prevent crashes
+ if (_events.IsInPhase(PHASE_INTRO_A) || _events.IsInPhase(PHASE_INTRO_H))
return;
- _index = data;
- }
- void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
- {
- if (spellInfo->Id == SPELL_GRIP_OF_AGONY)
+ _events.SetPhase(PHASE_INTRO_A);
+ std::list<Creature*> guardList;
+ GetCreatureListWithEntryInGrid(guardList, me, NPC_SE_SKYBREAKER_MARINE, 20.0f);
+ guardList.sort(Trinity::ObjectDistanceOrderPred(me));
+ uint32 x = 1;
+ for (auto itr = guardList.begin(); itr != guardList.end(); ++x, ++itr)
+ (*itr)->AI()->SetData(0, x);
+
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ Talk(SAY_INTRO_ALLIANCE_1);
+ _events.ScheduleEvent(EVENT_INTRO_ALLIANCE_4, 29500ms, 0, PHASE_INTRO_A);
+ _instance->HandleGameObject(_instance->GetGuidData(GO_SAURFANG_S_DOOR), true);
+ if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_DEATHBRINGER_SAURFANG)))
+ deathbringer->AI()->DoAction(PHASE_INTRO_A);
+ break;
+ }
+ case ACTION_START_OUTRO:
+ {
+ me->RemoveAurasDueToSpell(SPELL_GRIP_OF_AGONY);
+ Talk(SAY_OUTRO_ALLIANCE_1);
+ me->SetDisableGravity(false);
+ me->GetMotionMaster()->MoveFall();
+ GuardBroadcast([](Creature* guard)
{
- me->SetDisableGravity(true);
- me->GetMotionMaster()->MovePoint(POINT_CHOKE, chokePos[_index]);
- }
- }
+ guard->AI()->DoAction(ACTION_DESPAWN);
+ });
- void DoAction(int32 action) override
- {
- if (action == ACTION_CHARGE && _index)
- me->GetMotionMaster()->MoveCharge(chargePos[_index].GetPositionX(), chargePos[_index].GetPositionY(), chargePos[_index].GetPositionZ(), 13.0f, POINT_CHARGE);
- else if (action == ACTION_DESPAWN)
- me->DespawnOrUnsummon();
+ // temp until outro fully done - to put deathbringer on respawn timer (until next reset)
+ if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_DEATHBRINGER_SAURFANG)))
+ deathbringer->DespawnOrUnsummon(5s);
+ break;
}
+ case ACTION_INTERRUPT_INTRO:
+ _events.Reset();
+ GuardBroadcast([](Creature* guard)
+ {
+ guard->AI()->DoAction(ACTION_DESPAWN);
+ });
+ break;
+ }
+ }
- private:
- uint32 _index;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
+ void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
+ {
+ if (spellInfo->Id == SPELL_GRIP_OF_AGONY)
{
- return GetIcecrownCitadelAI<npc_saurfang_eventAI>(creature);
+ me->SetDisableGravity(true);
+ me->GetMotionMaster()->MovePoint(POINT_CHOKE, chokePos[0]);
}
-};
-
-class spell_deathbringer_blood_link : public SpellScriptLoader
-{
- public:
- spell_deathbringer_blood_link() : SpellScriptLoader("spell_deathbringer_blood_link") { }
+ }
- class spell_deathbringer_blood_link_SpellScript : public SpellScript
+ void MovementInform(uint32 type, uint32 id) override
+ {
+ if (type == POINT_MOTION_TYPE && id == POINT_FIRST_STEP)
{
- PrepareSpellScript(spell_deathbringer_blood_link_SpellScript);
-
- bool Validate(SpellInfo const* /*spellInfo*/) override
- {
- return ValidateSpellInfo({ SPELL_BLOOD_LINK_POWER, SPELL_BLOOD_POWER });
- }
-
- void HandleDummy(SpellEffIndex /*effIndex*/)
- {
- CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
- args.AddSpellBP0(GetEffectValue());
- GetHitUnit()->CastSpell(GetHitUnit(), SPELL_BLOOD_LINK_POWER, args);
- PreventHitDefaultEffect(EFFECT_0);
- }
-
- void Register() override
- {
- OnEffectHitTarget += SpellEffectFn(spell_deathbringer_blood_link_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
- }
- };
-
- SpellScript* GetSpellScript() const override
+ me->SetWalk(false);
+ Talk(SAY_INTRO_ALLIANCE_4);
+ _events.ScheduleEvent(EVENT_INTRO_ALLIANCE_5, 5s, 0, PHASE_INTRO_A);
+ if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_DEATHBRINGER_SAURFANG)))
+ deathbringer->AI()->DoAction(ACTION_CONTINUE_INTRO);
+ }
+ else if (type == WAYPOINT_MOTION_TYPE && id == POINT_EXIT)
{
- return new spell_deathbringer_blood_link_SpellScript();
+ std::list<Creature*> guards;
+ GetCreatureListWithEntryInGrid(guards, me, NPC_ALLIANCE_COMMANDER, 50.0f);
+ for (std::list<Creature*>::iterator itr = guards.begin(); itr != guards.end(); ++itr)
+ (*itr)->DespawnOrUnsummon();
+ me->DespawnOrUnsummon();
}
-};
-
-class spell_deathbringer_blood_link_aura : public SpellScriptLoader
-{
- public:
- spell_deathbringer_blood_link_aura() : SpellScriptLoader("spell_deathbringer_blood_link_aura") { }
+ }
- class spell_deathbringer_blood_link_AuraScript : public AuraScript
+ void UpdateAI(uint32 diff) override
+ {
+ _events.Update(diff);
+ while (uint32 eventId = _events.ExecuteEvent())
{
- PrepareAuraScript(spell_deathbringer_blood_link_AuraScript);
-
- bool Validate(SpellInfo const* /*spellInfo*/) override
- {
- return ValidateSpellInfo({ SPELL_MARK_OF_THE_FALLEN_CHAMPION });
- }
-
- void HandlePeriodicTick(AuraEffect const* /*aurEff*/)
- {
- PreventDefaultAction();
- if (GetUnitOwner()->GetPowerType() == POWER_ENERGY && GetUnitOwner()->GetPower(POWER_ENERGY) == GetUnitOwner()->GetMaxPower(POWER_ENERGY))
- if (Creature* saurfang = GetUnitOwner()->ToCreature())
- saurfang->AI()->DoAction(ACTION_MARK_OF_THE_FALLEN_CHAMPION);
- }
-
- void Register() override
- {
- OnEffectPeriodic += AuraEffectPeriodicFn(spell_deathbringer_blood_link_AuraScript::HandlePeriodicTick, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY);
+ switch (eventId)
+ {
+ case EVENT_INTRO_ALLIANCE_4:
+ me->SetWalk(true);
+ me->GetMotionMaster()->MovePoint(POINT_FIRST_STEP, firstStepPos.GetPositionX(), firstStepPos.GetPositionY(), firstStepPos.GetPositionZ());
+ break;
+ case EVENT_INTRO_ALLIANCE_5:
+ Talk(SAY_INTRO_ALLIANCE_5);
+ GuardBroadcast([](Creature* guard)
+ {
+ guard->AI()->DoAction(ACTION_CHARGE);
+ });
+ me->GetMotionMaster()->MoveCharge(chargePos[0].GetPositionX(), chargePos[0].GetPositionY(), chargePos[0].GetPositionZ(), 8.5f, POINT_CHARGE);
+ break;
}
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_deathbringer_blood_link_AuraScript();
}
+ }
+
+private:
+ EventMap _events;
+ InstanceScript* _instance;
};
-class spell_deathbringer_blood_power : public SpellScriptLoader
+struct npc_saurfang_event : public ScriptedAI
{
- public:
- spell_deathbringer_blood_power() : SpellScriptLoader("spell_deathbringer_blood_power") { }
-
- class spell_deathbringer_blood_power_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_deathbringer_blood_power_SpellScript);
-
- void ModAuraValue()
- {
- if (Aura* aura = GetHitAura())
- aura->RecalculateAmountOfEffects();
- }
-
- void Register() override
- {
- AfterHit += SpellHitFn(spell_deathbringer_blood_power_SpellScript::ModAuraValue);
- }
- };
-
- class spell_deathbringer_blood_power_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_deathbringer_blood_power_AuraScript);
-
- void RecalculateHook(AuraEffect const* /*aurEffect*/, int32& amount, bool& canBeRecalculated)
- {
- amount = int32(GetUnitOwner()->GetPower(POWER_ENERGY));
- canBeRecalculated = true;
- }
-
- void Register() override
- {
- DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_deathbringer_blood_power_AuraScript::RecalculateHook, EFFECT_0, SPELL_AURA_MOD_SCALE);
- DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_deathbringer_blood_power_AuraScript::RecalculateHook, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
- }
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_deathbringer_blood_power_SpellScript();
- }
-
- AuraScript* GetAuraScript() const override
+ npc_saurfang_event(Creature* creature) : ScriptedAI(creature)
+ {
+ _index = 0;
+ }
+
+ void SetData(uint32 type, uint32 data) override
+ {
+ if (!(!type && data && data < 6))
+ return;
+ _index = data;
+ }
+
+ void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
+ {
+ if (spellInfo->Id == SPELL_GRIP_OF_AGONY)
{
- return new spell_deathbringer_blood_power_AuraScript();
+ me->SetDisableGravity(true);
+ me->GetMotionMaster()->MovePoint(POINT_CHOKE, chokePos[_index]);
}
+ }
+
+ void DoAction(int32 action) override
+ {
+ if (action == ACTION_CHARGE && _index)
+ me->GetMotionMaster()->MoveCharge(chargePos[_index].GetPositionX(), chargePos[_index].GetPositionY(), chargePos[_index].GetPositionZ(), 13.0f, POINT_CHARGE);
+ else if (action == ACTION_DESPAWN)
+ me->DespawnOrUnsummon();
+ }
+
+private:
+ uint32 _index;
};
-class spell_deathbringer_rune_of_blood : public SpellScriptLoader
+class spell_deathbringer_blood_link : public SpellScript
{
- public:
- spell_deathbringer_rune_of_blood() : SpellScriptLoader("spell_deathbringer_rune_of_blood") { }
-
- class spell_deathbringer_rune_of_blood_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_deathbringer_rune_of_blood_SpellScript);
+ PrepareSpellScript(spell_deathbringer_blood_link);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_BLOOD_LINK_POWER, SPELL_BLOOD_POWER });
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.AddSpellBP0(GetEffectValue());
+ GetHitUnit()->CastSpell(GetHitUnit(), SPELL_BLOOD_LINK_POWER, args);
+ PreventHitDefaultEffect(EFFECT_0);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_deathbringer_blood_link::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+};
- bool Validate(SpellInfo const* /*spellInfo*/) override
- {
- return ValidateSpellInfo({ SPELL_BLOOD_LINK_DUMMY });
- }
+class spell_deathbringer_blood_link_aura : public AuraScript
+{
+ PrepareAuraScript(spell_deathbringer_blood_link_aura);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_MARK_OF_THE_FALLEN_CHAMPION });
+ }
+
+ void HandlePeriodicTick(AuraEffect const* /*aurEff*/)
+ {
+ PreventDefaultAction();
+ if (GetUnitOwner()->GetPowerType() == POWER_ENERGY && GetUnitOwner()->GetPower(POWER_ENERGY) == GetUnitOwner()->GetMaxPower(POWER_ENERGY))
+ if (Creature* saurfang = GetUnitOwner()->ToCreature())
+ saurfang->AI()->DoAction(ACTION_MARK_OF_THE_FALLEN_CHAMPION);
+ }
+
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_deathbringer_blood_link_aura::HandlePeriodicTick, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY);
+ }
+};
- void HandleScript(SpellEffIndex effIndex)
- {
- PreventHitDefaultEffect(effIndex); // make this the default handler
- GetHitUnit()->CastSpell(nullptr, SPELL_BLOOD_LINK_DUMMY, CastSpellExtraArgs(TRIGGERED_FULL_MASK).AddSpellBP0(1));
- }
+class spell_deathbringer_blood_power : public SpellScript
+{
+ PrepareSpellScript(spell_deathbringer_blood_power);
+
+ void ModAuraValue()
+ {
+ if (Aura* aura = GetHitAura())
+ aura->RecalculateAmountOfEffects();
+ }
+
+ void Register() override
+ {
+ AfterHit += SpellHitFn(spell_deathbringer_blood_power::ModAuraValue);
+ }
+};
- void Register() override
- {
- OnEffectHitTarget += SpellEffectFn(spell_deathbringer_rune_of_blood_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
- }
- };
+class spell_deathbringer_blood_power_aura : public AuraScript
+{
+ PrepareAuraScript(spell_deathbringer_blood_power_aura);
+
+ void RecalculateHook(AuraEffect const* /*aurEffect*/, int32& amount, bool& canBeRecalculated)
+ {
+ amount = int32(GetUnitOwner()->GetPower(POWER_ENERGY));
+ canBeRecalculated = true;
+ }
+
+ void Register() override
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_deathbringer_blood_power_aura::RecalculateHook, EFFECT_0, SPELL_AURA_MOD_SCALE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_deathbringer_blood_power_aura::RecalculateHook, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+ }
+};
- SpellScript* GetSpellScript() const override
- {
- return new spell_deathbringer_rune_of_blood_SpellScript();
- }
+class spell_deathbringer_rune_of_blood : public SpellScript
+{
+ PrepareSpellScript(spell_deathbringer_rune_of_blood);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_BLOOD_LINK_DUMMY });
+ }
+
+ void HandleScript(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex); // make this the default handler
+ GetHitUnit()->CastSpell(nullptr, SPELL_BLOOD_LINK_DUMMY, CastSpellExtraArgs(TRIGGERED_FULL_MASK).AddSpellBP0(1));
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_deathbringer_rune_of_blood::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
};
// 72176 - Blood Beast's Blood Link
-class spell_deathbringer_blood_beast_blood_link : public SpellScriptLoader
+class spell_deathbringer_blood_beast_blood_link : public AuraScript
{
- public:
- spell_deathbringer_blood_beast_blood_link() : SpellScriptLoader("spell_deathbringer_blood_beast_blood_link") { }
-
- class spell_deathbringer_blood_beast_blood_link_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_deathbringer_blood_beast_blood_link_AuraScript);
-
- bool Validate(SpellInfo const* /*spellInfo*/) override
- {
- return ValidateSpellInfo({ SPELL_BLOOD_LINK_DUMMY });
- }
-
- void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
- {
- PreventDefaultAction();
- eventInfo.GetProcTarget()->CastSpell(nullptr, SPELL_BLOOD_LINK_DUMMY, CastSpellExtraArgs(aurEff).AddSpellBP0(3));
- }
-
- void Register() override
- {
- OnEffectProc += AuraEffectProcFn(spell_deathbringer_blood_beast_blood_link_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
- }
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_deathbringer_blood_beast_blood_link_AuraScript();
- }
+ PrepareAuraScript(spell_deathbringer_blood_beast_blood_link);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_BLOOD_LINK_DUMMY });
+ }
+
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ eventInfo.GetProcTarget()->CastSpell(nullptr, SPELL_BLOOD_LINK_DUMMY, CastSpellExtraArgs(aurEff).AddSpellBP0(3));
+ }
+
+ void Register() override
+ {
+ OnEffectProc += AuraEffectProcFn(spell_deathbringer_blood_beast_blood_link::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
+ }
};
-class spell_deathbringer_blood_nova : public SpellScriptLoader
+class spell_deathbringer_blood_nova : public SpellScript
{
- public:
- spell_deathbringer_blood_nova() : SpellScriptLoader("spell_deathbringer_blood_nova") { }
-
- class spell_deathbringer_blood_nova_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_deathbringer_blood_nova_SpellScript);
-
- bool Validate(SpellInfo const* /*spellInfo*/) override
- {
- return ValidateSpellInfo({ SPELL_BLOOD_LINK_DUMMY });
- }
-
- void HandleScript(SpellEffIndex effIndex)
- {
- PreventHitDefaultEffect(effIndex); // make this the default handler
- GetHitUnit()->CastSpell(nullptr, SPELL_BLOOD_LINK_DUMMY, CastSpellExtraArgs(TRIGGERED_FULL_MASK).AddSpellBP0(2));
- }
-
- void Register() override
- {
- OnEffectHitTarget += SpellEffectFn(spell_deathbringer_blood_nova_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
- }
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_deathbringer_blood_nova_SpellScript();
- }
+ PrepareSpellScript(spell_deathbringer_blood_nova);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_BLOOD_LINK_DUMMY });
+ }
+
+ void HandleScript(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex); // make this the default handler
+ GetHitUnit()->CastSpell(nullptr, SPELL_BLOOD_LINK_DUMMY, CastSpellExtraArgs(TRIGGERED_FULL_MASK).AddSpellBP0(2));
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_deathbringer_blood_nova::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
};
-class spell_deathbringer_blood_nova_targeting : public SpellScriptLoader
+class spell_deathbringer_blood_nova_targeting : public SpellScript
{
- public:
- spell_deathbringer_blood_nova_targeting() : SpellScriptLoader("spell_deathbringer_blood_nova_targeting") { }
-
- class spell_deathbringer_blood_nova_targeting_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_deathbringer_blood_nova_targeting_SpellScript);
-
- public:
- spell_deathbringer_blood_nova_targeting_SpellScript()
- {
- target = nullptr;
- }
-
- private:
- void FilterTargetsInitial(std::list<WorldObject*>& targets)
- {
- if (targets.empty())
- return;
-
- // select one random target, preferring ranged targets
- uint32 targetsAtRange = 0;
- uint32 const minTargets = uint32(GetCaster()->GetMap()->Is25ManRaid() ? 10 : 4);
- targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster(), false));
-
- // get target count at range
- for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr, ++targetsAtRange)
- if ((*itr)->GetDistance(GetCaster()) < 12.0f)
- break;
-
- // If not enough ranged targets are present just select anyone
- if (targetsAtRange < minTargets)
- targetsAtRange = uint32(targets.size());
-
- std::list<WorldObject*>::const_iterator itr = targets.begin();
- std::advance(itr, urand(0, targetsAtRange - 1));
- target = *itr;
- targets.clear();
- targets.push_back(target);
- }
-
- // use the same target for first and second effect
- void FilterTargetsSubsequent(std::list<WorldObject*>& unitList)
- {
- unitList.clear();
- if (!target)
- return;
-
- unitList.push_back(target);
- }
-
- void HandleForceCast(SpellEffIndex /*effIndex*/)
- {
- GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), TRIGGERED_FULL_MASK);
- }
-
- void Register() override
- {
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_deathbringer_blood_nova_targeting_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_deathbringer_blood_nova_targeting_SpellScript::FilterTargetsSubsequent, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
- OnEffectHitTarget += SpellEffectFn(spell_deathbringer_blood_nova_targeting_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST);
- }
-
- WorldObject* target;
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_deathbringer_blood_nova_targeting_SpellScript();
- }
+ PrepareSpellScript(spell_deathbringer_blood_nova_targeting);
+
+public:
+ spell_deathbringer_blood_nova_targeting()
+ {
+ target = nullptr;
+ }
+
+private:
+ void FilterTargetsInitial(std::list<WorldObject*>& targets)
+ {
+ if (targets.empty())
+ return;
+
+ // select one random target, preferring ranged targets
+ uint32 targetsAtRange = 0;
+ uint32 const minTargets = uint32(GetCaster()->GetMap()->Is25ManRaid() ? 10 : 4);
+ targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster(), false));
+
+ // get target count at range
+ for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr, ++targetsAtRange)
+ if ((*itr)->GetDistance(GetCaster()) < 12.0f)
+ break;
+
+ // If not enough ranged targets are present just select anyone
+ if (targetsAtRange < minTargets)
+ targetsAtRange = uint32(targets.size());
+
+ std::list<WorldObject*>::const_iterator itr = targets.begin();
+ std::advance(itr, urand(0, targetsAtRange - 1));
+ target = *itr;
+ targets.clear();
+ targets.push_back(target);
+ }
+
+ // use the same target for first and second effect
+ void FilterTargetsSubsequent(std::list<WorldObject*>& unitList)
+ {
+ unitList.clear();
+ if (!target)
+ return;
+
+ unitList.push_back(target);
+ }
+
+ void HandleForceCast(SpellEffIndex /*effIndex*/)
+ {
+ GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), TRIGGERED_FULL_MASK);
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_deathbringer_blood_nova_targeting::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_deathbringer_blood_nova_targeting::FilterTargetsSubsequent, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnEffectHitTarget += SpellEffectFn(spell_deathbringer_blood_nova_targeting::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST);
+ }
+
+ WorldObject* target;
};
-class spell_deathbringer_boiling_blood : public SpellScriptLoader
+class spell_deathbringer_boiling_blood : public SpellScript
{
- public:
- spell_deathbringer_boiling_blood() : SpellScriptLoader("spell_deathbringer_boiling_blood") { }
-
- class spell_deathbringer_boiling_blood_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_deathbringer_boiling_blood_SpellScript);
-
- bool Load() override
- {
- return GetCaster()->GetTypeId() == TYPEID_UNIT;
- }
-
- void FilterTargets(std::list<WorldObject*>& targets)
- {
- targets.remove(GetCaster()->GetVictim());
- if (targets.empty())
- return;
-
- WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
- targets.clear();
- targets.push_back(target);
- }
-
- void Register() override
- {
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_deathbringer_boiling_blood_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- }
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_deathbringer_boiling_blood_SpellScript();
- }
+ PrepareSpellScript(spell_deathbringer_boiling_blood);
+
+ bool Load() override
+ {
+ return GetCaster()->GetTypeId() == TYPEID_UNIT;
+ }
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ targets.remove(GetCaster()->GetVictim());
+ if (targets.empty())
+ return;
+
+ WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
+ targets.clear();
+ targets.push_back(target);
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_deathbringer_boiling_blood::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
};
-class spell_deathbringer_remove_marks : public SpellScriptLoader
+class spell_deathbringer_remove_marks : public SpellScript
{
- public:
- spell_deathbringer_remove_marks() : SpellScriptLoader("spell_deathbringer_remove_marks") { }
-
- class spell_deathbringer_remove_marks_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_deathbringer_remove_marks_SpellScript);
-
- void HandleScript(SpellEffIndex effIndex)
- {
- PreventHitDefaultEffect(effIndex);
- GetHitUnit()->RemoveAurasDueToSpell(uint32(GetEffectValue()));
- }
-
- void Register() override
- {
- OnEffectHitTarget += SpellEffectFn(spell_deathbringer_remove_marks_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
- }
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_deathbringer_remove_marks_SpellScript();
- }
+ PrepareSpellScript(spell_deathbringer_remove_marks);
+
+ void HandleScript(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ GetHitUnit()->RemoveAurasDueToSpell(uint32(GetEffectValue()));
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_deathbringer_remove_marks::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
};
class achievement_ive_gone_and_made_a_mess : public AchievementCriteriaScript
@@ -1401,18 +1253,23 @@ class achievement_ive_gone_and_made_a_mess : public AchievementCriteriaScript
void AddSC_boss_deathbringer_saurfang()
{
- new boss_deathbringer_saurfang();
- new npc_high_overlord_saurfang_icc();
- new npc_muradin_bronzebeard_icc();
- new npc_saurfang_event();
- new spell_deathbringer_blood_link();
- new spell_deathbringer_blood_link_aura();
- new spell_deathbringer_blood_power();
- new spell_deathbringer_rune_of_blood();
- new spell_deathbringer_blood_beast_blood_link();
- new spell_deathbringer_blood_nova();
- new spell_deathbringer_blood_nova_targeting();
- new spell_deathbringer_boiling_blood();
- new spell_deathbringer_remove_marks();
+ // Creatures
+ RegisterIcecrownCitadelCreatureAI(boss_deathbringer_saurfang);
+ RegisterIcecrownCitadelCreatureAI(npc_high_overlord_saurfang_icc);
+ RegisterIcecrownCitadelCreatureAI(npc_muradin_bronzebeard_icc);
+ RegisterIcecrownCitadelCreatureAI(npc_saurfang_event);
+
+ // Spells
+ RegisterSpellScript(spell_deathbringer_blood_link);
+ RegisterSpellScript(spell_deathbringer_blood_link_aura);
+ RegisterSpellAndAuraScriptPair(spell_deathbringer_blood_power, spell_deathbringer_blood_power_aura);
+ RegisterSpellScript(spell_deathbringer_rune_of_blood);
+ RegisterSpellScript(spell_deathbringer_blood_beast_blood_link);
+ RegisterSpellScript(spell_deathbringer_blood_nova);
+ RegisterSpellScript(spell_deathbringer_blood_nova_targeting);
+ RegisterSpellScript(spell_deathbringer_boiling_blood);
+ RegisterSpellScript(spell_deathbringer_remove_marks);
+
+ // Achievements
new achievement_ive_gone_and_made_a_mess();
}