diff options
author | ForesterDev <11771800+ForesterDev@users.noreply.github.com> | 2020-09-11 23:19:03 +0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-11 21:19:03 +0200 |
commit | def58965e8516978594a5d960c603932d34b7b2d (patch) | |
tree | 1127aeed1958534d092f45edd8f1f38226daf39b | |
parent | 02fca032e1d497be08681de0bfd7bca979f0dafd (diff) |
Scripts/ICC: update Blood Queen Lana'thel scripts to new model (#25434)
-rw-r--r-- | src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp | 1123 |
1 files changed, 520 insertions, 603 deletions
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp index edd4396c7ab..df45c82a6a2 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp @@ -140,506 +140,473 @@ bool IsVampire(Unit const* unit) return false; } -class boss_blood_queen_lana_thel : public CreatureScript +struct boss_blood_queen_lana_thel : public BossAI { - public: - boss_blood_queen_lana_thel() : CreatureScript("boss_blood_queen_lana_thel") { } + boss_blood_queen_lana_thel(Creature* creature) : BossAI(creature, DATA_BLOOD_QUEEN_LANA_THEL) + { + Initialize(); + } + + void Initialize() + { + _offtankGUID.Clear(); + _creditBloodQuickening = false; + _killMinchar = false; + } - struct boss_blood_queen_lana_thelAI : public BossAI + void Reset() override + { + _Reset(); + events.ScheduleEvent(EVENT_BERSERK, 330s); + events.ScheduleEvent(EVENT_VAMPIRIC_BITE, 15s); + events.ScheduleEvent(EVENT_BLOOD_MIRROR, 2500ms, EVENT_GROUP_CANCELLABLE); + events.ScheduleEvent(EVENT_DELIRIOUS_SLASH, 20s, 24s, EVENT_GROUP_NORMAL); + events.ScheduleEvent(EVENT_PACT_OF_THE_DARKFALLEN, 15s, EVENT_GROUP_NORMAL); + events.ScheduleEvent(EVENT_SWARMING_SHADOWS, 30500ms, EVENT_GROUP_NORMAL); + events.ScheduleEvent(EVENT_TWILIGHT_BLOODBOLT, 20s, 25s, EVENT_GROUP_NORMAL); + events.ScheduleEvent(EVENT_AIR_PHASE, 124s + (Is25ManRaid() ? 3s : 0s)); + CleanAuras(); + _vampires.clear(); + Initialize(); + } + + void JustEngagedWith(Unit* who) override + { + if (!instance->CheckRequiredBosses(DATA_BLOOD_QUEEN_LANA_THEL, who->ToPlayer())) { - boss_blood_queen_lana_thelAI(Creature* creature) : BossAI(creature, DATA_BLOOD_QUEEN_LANA_THEL) - { - Initialize(); - } + EnterEvadeMode(EVADE_REASON_OTHER); + instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT); + return; + } - void Initialize() - { - _offtankGUID.Clear(); - _creditBloodQuickening = false; - _killMinchar = false; - } + me->setActive(true); + DoZoneInCombat(); + Talk(SAY_AGGRO); + instance->SetBossState(DATA_BLOOD_QUEEN_LANA_THEL, IN_PROGRESS); + CleanAuras(); - void Reset() override - { - _Reset(); - events.ScheduleEvent(EVENT_BERSERK, 330s); - events.ScheduleEvent(EVENT_VAMPIRIC_BITE, 15s); - events.ScheduleEvent(EVENT_BLOOD_MIRROR, 2500ms, EVENT_GROUP_CANCELLABLE); - events.ScheduleEvent(EVENT_DELIRIOUS_SLASH, 20s, 24s, EVENT_GROUP_NORMAL); - events.ScheduleEvent(EVENT_PACT_OF_THE_DARKFALLEN, 15s, EVENT_GROUP_NORMAL); - events.ScheduleEvent(EVENT_SWARMING_SHADOWS, 30500ms, EVENT_GROUP_NORMAL); - events.ScheduleEvent(EVENT_TWILIGHT_BLOODBOLT, 20s, 25s, EVENT_GROUP_NORMAL); - events.ScheduleEvent(EVENT_AIR_PHASE, 124s + (Is25ManRaid() ? 3s : 0s)); - CleanAuras(); - _vampires.clear(); - Initialize(); - } + DoCast(me, SPELL_SHROUD_OF_SORROW, true); + DoCast(me, SPELL_FRENZIED_BLOODTHIRST_VISUAL, true); + DoCastSelf(SPELL_CLEAR_ALL_STATUS_AILMENTS, true); + _creditBloodQuickening = instance->GetData(DATA_BLOOD_QUICKENING_STATE) == IN_PROGRESS; + } - void JustEngagedWith(Unit* who) override - { - if (!instance->CheckRequiredBosses(DATA_BLOOD_QUEEN_LANA_THEL, who->ToPlayer())) - { - EnterEvadeMode(EVADE_REASON_OTHER); - instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT); - return; - } + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + Talk(SAY_DEATH); - me->setActive(true); - DoZoneInCombat(); - Talk(SAY_AGGRO); - instance->SetBossState(DATA_BLOOD_QUEEN_LANA_THEL, IN_PROGRESS); - CleanAuras(); + if (Is25ManRaid() && me->HasAura(SPELL_SHADOWS_FATE)) + DoCastAOE(SPELL_BLOOD_INFUSION_CREDIT, true); - DoCast(me, SPELL_SHROUD_OF_SORROW, true); - DoCast(me, SPELL_FRENZIED_BLOODTHIRST_VISUAL, true); - DoCastSelf(SPELL_CLEAR_ALL_STATUS_AILMENTS, true); - _creditBloodQuickening = instance->GetData(DATA_BLOOD_QUICKENING_STATE) == IN_PROGRESS; - } + CleanAuras(); - void JustDied(Unit* /*killer*/) override + // Blah, credit the quest + if (_creditBloodQuickening) + { + instance->SetData(DATA_BLOOD_QUICKENING_STATE, DONE); + if (Player* player = me->GetLootRecipient()) + player->RewardPlayerAndGroupAtEvent(Is25ManRaid() ? NPC_INFILTRATOR_MINCHAR_BQ_25 : NPC_INFILTRATOR_MINCHAR_BQ, player); + if (Creature* minchar = me->FindNearestCreature(NPC_INFILTRATOR_MINCHAR_BQ, 200.0f)) { - _JustDied(); - Talk(SAY_DEATH); + minchar->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); + minchar->SetAnimationTier(AnimationTier::Ground); + minchar->SetCanFly(false); + minchar->RemoveAllAuras(); + minchar->GetMotionMaster()->MoveCharge(4629.3711f, 2782.6089f, 401.5301f, SPEED_CHARGE / 3.0f); + } + } + } - if (Is25ManRaid() && me->HasAura(SPELL_SHADOWS_FATE)) - DoCastAOE(SPELL_BLOOD_INFUSION_CREDIT, true); + void CleanAuras() + { + instance->DoRemoveAurasDueToSpellOnPlayers(ESSENCE_OF_BLOOD_QUEEN); + instance->DoRemoveAurasDueToSpellOnPlayers(ESSENCE_OF_BLOOD_QUEEN_PLR); + instance->DoRemoveAurasDueToSpellOnPlayers(FRENZIED_BLOODTHIRST); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_UNCONTROLLABLE_FRENZY); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLOOD_MIRROR_DAMAGE); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLOOD_MIRROR_VISUAL); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLOOD_MIRROR_DUMMY); + instance->DoRemoveAurasDueToSpellOnPlayers(DELIRIOUS_SLASH); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_PACT_OF_THE_DARKFALLEN); + instance->DoRemoveAurasDueToSpellOnPlayers(PRESENCE_OF_THE_DARKFALLEN); + } - CleanAuras(); + void DoAction(int32 action) override + { + if (action != ACTION_KILL_MINCHAR) + return; - // Blah, credit the quest - if (_creditBloodQuickening) - { - instance->SetData(DATA_BLOOD_QUICKENING_STATE, DONE); - if (Player* player = me->GetLootRecipient()) - player->RewardPlayerAndGroupAtEvent(Is25ManRaid() ? NPC_INFILTRATOR_MINCHAR_BQ_25 : NPC_INFILTRATOR_MINCHAR_BQ, player); - if (Creature* minchar = me->FindNearestCreature(NPC_INFILTRATOR_MINCHAR_BQ, 200.0f)) - { - minchar->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); - minchar->SetAnimationTier(AnimationTier::Ground); - minchar->SetCanFly(false); - minchar->RemoveAllAuras(); - minchar->GetMotionMaster()->MoveCharge(4629.3711f, 2782.6089f, 401.5301f, SPEED_CHARGE / 3.0f); - } - } - } + if (instance->GetBossState(DATA_BLOOD_QUEEN_LANA_THEL) == IN_PROGRESS) + _killMinchar = true; + else + { + me->SetDisableGravity(true); + me->GetMotionMaster()->MovePoint(POINT_MINCHAR, mincharPos); + } + } - void CleanAuras() - { - instance->DoRemoveAurasDueToSpellOnPlayers(ESSENCE_OF_BLOOD_QUEEN); - instance->DoRemoveAurasDueToSpellOnPlayers(ESSENCE_OF_BLOOD_QUEEN_PLR); - instance->DoRemoveAurasDueToSpellOnPlayers(FRENZIED_BLOODTHIRST); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_UNCONTROLLABLE_FRENZY); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLOOD_MIRROR_DAMAGE); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLOOD_MIRROR_VISUAL); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLOOD_MIRROR_DUMMY); - instance->DoRemoveAurasDueToSpellOnPlayers(DELIRIOUS_SLASH); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_PACT_OF_THE_DARKFALLEN); - instance->DoRemoveAurasDueToSpellOnPlayers(PRESENCE_OF_THE_DARKFALLEN); - } + void EnterEvadeMode(EvadeReason why) override + { + if (!_EnterEvadeMode(why)) + return; - void DoAction(int32 action) override - { - if (action != ACTION_KILL_MINCHAR) - return; + CleanAuras(); + if (_killMinchar) + { + _killMinchar = false; + me->SetDisableGravity(true); + me->GetMotionMaster()->MovePoint(POINT_MINCHAR, mincharPos); + } + else + { + me->AddUnitState(UNIT_STATE_EVADE); + me->GetMotionMaster()->MoveTargetedHome(); + Reset(); + } + } - if (instance->GetBossState(DATA_BLOOD_QUEEN_LANA_THEL) == IN_PROGRESS) - _killMinchar = true; - else - { - me->SetDisableGravity(true); - me->GetMotionMaster()->MovePoint(POINT_MINCHAR, mincharPos); - } - } + void JustReachedHome() override + { + me->SetDisableGravity(false); + me->SetReactState(REACT_AGGRESSIVE); + _JustReachedHome(); + Talk(SAY_WIPE); + instance->SetBossState(DATA_BLOOD_QUEEN_LANA_THEL, FAIL); + } - void EnterEvadeMode(EvadeReason why) override - { - if (!_EnterEvadeMode(why)) - return; + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_KILL); + } - CleanAuras(); - if (_killMinchar) - { - _killMinchar = false; - me->SetDisableGravity(true); - me->GetMotionMaster()->MovePoint(POINT_MINCHAR, mincharPos); - } - else - { - me->AddUnitState(UNIT_STATE_EVADE); - me->GetMotionMaster()->MoveTargetedHome(); - Reset(); - } - } + void SetGUID(ObjectGuid const& guid, int32 id) override + { + switch (id) + { + case GUID_VAMPIRE: + _vampires.insert(guid); + break; + case GUID_BLOODBOLT: + _bloodboltedPlayers.insert(guid); + break; + default: + break; + } + } - void JustReachedHome() override - { + void MovementInform(uint32 type, uint32 id) override + { + if (type != POINT_MOTION_TYPE) + return; + + switch (id) + { + case POINT_CENTER: + DoCast(me, SPELL_INCITE_TERROR); + events.ScheduleEvent(EVENT_AIR_PHASE, 100s + (Is25ManRaid() ? 0s : 20s)); + events.RescheduleEvent(EVENT_SWARMING_SHADOWS, 30500ms, EVENT_GROUP_NORMAL); + events.RescheduleEvent(EVENT_PACT_OF_THE_DARKFALLEN, 25500ms, EVENT_GROUP_NORMAL); + events.ScheduleEvent(EVENT_AIR_START_FLYING, 5s); + break; + case POINT_AIR: + _bloodboltedPlayers.clear(); + DoCast(me, SPELL_BLOODBOLT_WHIRL); + Talk(SAY_AIR_PHASE); + events.ScheduleEvent(EVENT_AIR_FLY_DOWN, 10s); + break; + case POINT_GROUND: me->SetDisableGravity(false); me->SetReactState(REACT_AGGRESSIVE); - _JustReachedHome(); - Talk(SAY_WIPE); - instance->SetBossState(DATA_BLOOD_QUEEN_LANA_THEL, FAIL); - } + if (Unit* victim = me->SelectVictim()) + AttackStart(victim); + events.ScheduleEvent(EVENT_BLOOD_MIRROR, 2500ms, EVENT_GROUP_CANCELLABLE); + break; + case POINT_MINCHAR: + DoCast(me, SPELL_ANNIHILATE, true); + // already in evade mode + me->GetMotionMaster()->MoveTargetedHome(); + Reset(); + break; + default: + break; + } + } - void KilledUnit(Unit* victim) override - { - if (victim->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_KILL); - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - void SetGUID(ObjectGuid const& guid, int32 id) override - { - switch (id) - { - case GUID_VAMPIRE: - _vampires.insert(guid); - break; - case GUID_BLOODBOLT: - _bloodboltedPlayers.insert(guid); - break; - default: - break; - } - } + events.Update(diff); - void MovementInform(uint32 type, uint32 id) override - { - if (type != POINT_MOTION_TYPE) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - switch (id) + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_BERSERK: + Talk(EMOTE_BERSERK_RAID); + Talk(SAY_BERSERK); + DoCast(me, SPELL_BERSERK); + break; + case EVENT_VAMPIRIC_BITE: { - case POINT_CENTER: - DoCast(me, SPELL_INCITE_TERROR); - events.ScheduleEvent(EVENT_AIR_PHASE, 100s + (Is25ManRaid() ? 0s : 20s)); - events.RescheduleEvent(EVENT_SWARMING_SHADOWS, 30500ms, EVENT_GROUP_NORMAL); - events.RescheduleEvent(EVENT_PACT_OF_THE_DARKFALLEN, 25500ms, EVENT_GROUP_NORMAL); - events.ScheduleEvent(EVENT_AIR_START_FLYING, 5s); - break; - case POINT_AIR: - _bloodboltedPlayers.clear(); - DoCast(me, SPELL_BLOODBOLT_WHIRL); - Talk(SAY_AIR_PHASE); - events.ScheduleEvent(EVENT_AIR_FLY_DOWN, 10s); - break; - case POINT_GROUND: - me->SetDisableGravity(false); - me->SetReactState(REACT_AGGRESSIVE); - if (Unit* victim = me->SelectVictim()) - AttackStart(victim); - events.ScheduleEvent(EVENT_BLOOD_MIRROR, 2500ms, EVENT_GROUP_CANCELLABLE); - break; - case POINT_MINCHAR: - DoCast(me, SPELL_ANNIHILATE, true); - // already in evade mode - me->GetMotionMaster()->MoveTargetedHome(); - Reset(); - break; - default: - break; + std::list<Player*> targets; + SelectRandomTarget(false, &targets); + if (!targets.empty()) + { + Unit* target = targets.front(); + DoCast(target, SPELL_VAMPIRIC_BITE); + DoCastAOE(SPELL_VAMPIRIC_BITE_DUMMY, true); + Talk(SAY_VAMPIRIC_BITE); + _vampires.insert(target->GetGUID()); + target->CastSpell(target, SPELL_PRESENCE_OF_THE_DARKFALLEN, TRIGGERED_FULL_MASK); + target->CastSpell(target, SPELL_PRESENCE_OF_THE_DARKFALLEN_2, TRIGGERED_FULL_MASK); + } + break; } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) + case EVENT_BLOOD_MIRROR: { - switch (eventId) + // victim can be nullptr when this is processed in the same update tick as EVENT_AIR_PHASE + if (me->GetVictim()) { - case EVENT_BERSERK: - Talk(EMOTE_BERSERK_RAID); - Talk(SAY_BERSERK); - DoCast(me, SPELL_BERSERK); - break; - case EVENT_VAMPIRIC_BITE: - { - std::list<Player*> targets; - SelectRandomTarget(false, &targets); - if (!targets.empty()) - { - Unit* target = targets.front(); - DoCast(target, SPELL_VAMPIRIC_BITE); - DoCastAOE(SPELL_VAMPIRIC_BITE_DUMMY, true); - Talk(SAY_VAMPIRIC_BITE); - _vampires.insert(target->GetGUID()); - target->CastSpell(target, SPELL_PRESENCE_OF_THE_DARKFALLEN, TRIGGERED_FULL_MASK); - target->CastSpell(target, SPELL_PRESENCE_OF_THE_DARKFALLEN_2, TRIGGERED_FULL_MASK); - } - break; - } - case EVENT_BLOOD_MIRROR: - { - // victim can be nullptr when this is processed in the same update tick as EVENT_AIR_PHASE - if (me->GetVictim()) - { - Player* newOfftank = SelectRandomTarget(true); - if (newOfftank) - { - if (_offtankGUID != newOfftank->GetGUID()) - { - _offtankGUID = newOfftank->GetGUID(); - - // both spells have SPELL_ATTR5_SINGLE_TARGET_SPELL, no manual removal needed - newOfftank->CastSpell(me->GetVictim(), SPELL_BLOOD_MIRROR_DAMAGE, true); - me->EnsureVictim()->CastSpell(newOfftank, SPELL_BLOOD_MIRROR_DUMMY, true); - DoCastVictim(SPELL_BLOOD_MIRROR_VISUAL); - if (Is25ManRaid() && newOfftank->GetQuestStatus(QUEST_BLOOD_INFUSION) == QUEST_STATUS_INCOMPLETE && - newOfftank->HasAura(SPELL_UNSATED_CRAVING) && !newOfftank->HasAura(SPELL_THIRST_QUENCHED) && - !newOfftank->HasAura(SPELL_GUSHING_WOUND)) - newOfftank->CastSpell(newOfftank, SPELL_GUSHING_WOUND, TRIGGERED_FULL_MASK); - - } - } - else - _offtankGUID.Clear(); - } - events.ScheduleEvent(EVENT_BLOOD_MIRROR, 2500ms, EVENT_GROUP_CANCELLABLE); - break; - } - case EVENT_DELIRIOUS_SLASH: - if (_offtankGUID && me->GetAnimationTier() != AnimationTier::Fly) - if (Player* _offtank = ObjectAccessor::GetPlayer(*me, _offtankGUID)) - DoCast(_offtank, SPELL_DELIRIOUS_SLASH); - events.ScheduleEvent(EVENT_DELIRIOUS_SLASH, 20s, 24s, EVENT_GROUP_NORMAL); - break; - case EVENT_PACT_OF_THE_DARKFALLEN: + Player* newOfftank = SelectRandomTarget(true); + if (newOfftank) { - std::list<Player*> targets; - SelectRandomTarget(false, &targets); - Trinity::Containers::RandomResize(targets, Is25ManRaid() ? 3 : 2); - if (targets.size() > 1) + if (_offtankGUID != newOfftank->GetGUID()) { - Talk(SAY_PACT_OF_THE_DARKFALLEN); - for (std::list<Player*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) - DoCast(*itr, SPELL_PACT_OF_THE_DARKFALLEN); - } - events.ScheduleEvent(EVENT_PACT_OF_THE_DARKFALLEN, 30500ms, EVENT_GROUP_NORMAL); - break; - } - case EVENT_SWARMING_SHADOWS: - if (Player* target = SelectRandomTarget(false)) - { - Talk(EMOTE_SWARMING_SHADOWS, target); - Talk(SAY_SWARMING_SHADOWS); - DoCast(target, SPELL_SWARMING_SHADOWS); + _offtankGUID = newOfftank->GetGUID(); + + // both spells have SPELL_ATTR5_SINGLE_TARGET_SPELL, no manual removal needed + newOfftank->CastSpell(me->GetVictim(), SPELL_BLOOD_MIRROR_DAMAGE, true); + me->EnsureVictim()->CastSpell(newOfftank, SPELL_BLOOD_MIRROR_DUMMY, true); + DoCastVictim(SPELL_BLOOD_MIRROR_VISUAL); + if (Is25ManRaid() && newOfftank->GetQuestStatus(QUEST_BLOOD_INFUSION) == QUEST_STATUS_INCOMPLETE && + newOfftank->HasAura(SPELL_UNSATED_CRAVING) && !newOfftank->HasAura(SPELL_THIRST_QUENCHED) && + !newOfftank->HasAura(SPELL_GUSHING_WOUND)) + newOfftank->CastSpell(newOfftank, SPELL_GUSHING_WOUND, TRIGGERED_FULL_MASK); + } - events.ScheduleEvent(EVENT_SWARMING_SHADOWS, 30500ms, EVENT_GROUP_NORMAL); - break; - case EVENT_TWILIGHT_BLOODBOLT: - { - std::list<Player*> targets; - SelectRandomTarget(false, &targets); - Trinity::Containers::RandomResize(targets, uint32(Is25ManRaid() ? 4 : 2)); - for (std::list<Player*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) - DoCast(*itr, SPELL_TWILIGHT_BLOODBOLT); - DoCast(me, SPELL_TWILIGHT_BLOODBOLT_TARGET); - events.ScheduleEvent(EVENT_TWILIGHT_BLOODBOLT, 10s, 15s, EVENT_GROUP_NORMAL); - break; } - case EVENT_AIR_PHASE: - DoStopAttack(); - me->SetReactState(REACT_PASSIVE); - events.DelayEvents(10s, EVENT_GROUP_NORMAL); - events.CancelEventGroup(EVENT_GROUP_CANCELLABLE); - me->GetMotionMaster()->MovePoint(POINT_CENTER, centerPos); - break; - case EVENT_AIR_START_FLYING: - me->SetDisableGravity(true); - me->GetMotionMaster()->MovePoint(POINT_AIR, airPos); - break; - case EVENT_AIR_FLY_DOWN: - me->GetMotionMaster()->MovePoint(POINT_GROUND, centerPos); - break; - default: - break; + else + _offtankGUID.Clear(); } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + events.ScheduleEvent(EVENT_BLOOD_MIRROR, 2500ms, EVENT_GROUP_CANCELLABLE); + break; } - - DoMeleeAttackIfReady(); - } - - bool WasVampire(ObjectGuid guid) const - { - return _vampires.count(guid) != 0; + case EVENT_DELIRIOUS_SLASH: + if (_offtankGUID && me->GetAnimationTier() != AnimationTier::Fly) + if (Player* _offtank = ObjectAccessor::GetPlayer(*me, _offtankGUID)) + DoCast(_offtank, SPELL_DELIRIOUS_SLASH); + events.ScheduleEvent(EVENT_DELIRIOUS_SLASH, 20s, 24s, EVENT_GROUP_NORMAL); + break; + case EVENT_PACT_OF_THE_DARKFALLEN: + { + std::list<Player*> targets; + SelectRandomTarget(false, &targets); + Trinity::Containers::RandomResize(targets, Is25ManRaid() ? 3 : 2); + if (targets.size() > 1) + { + Talk(SAY_PACT_OF_THE_DARKFALLEN); + for (std::list<Player*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) + DoCast(*itr, SPELL_PACT_OF_THE_DARKFALLEN); + } + events.ScheduleEvent(EVENT_PACT_OF_THE_DARKFALLEN, 30500ms, EVENT_GROUP_NORMAL); + break; + } + case EVENT_SWARMING_SHADOWS: + if (Player* target = SelectRandomTarget(false)) + { + Talk(EMOTE_SWARMING_SHADOWS, target); + Talk(SAY_SWARMING_SHADOWS); + DoCast(target, SPELL_SWARMING_SHADOWS); + } + events.ScheduleEvent(EVENT_SWARMING_SHADOWS, 30500ms, EVENT_GROUP_NORMAL); + break; + case EVENT_TWILIGHT_BLOODBOLT: + { + std::list<Player*> targets; + SelectRandomTarget(false, &targets); + Trinity::Containers::RandomResize(targets, uint32(Is25ManRaid() ? 4 : 2)); + for (std::list<Player*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) + DoCast(*itr, SPELL_TWILIGHT_BLOODBOLT); + DoCast(me, SPELL_TWILIGHT_BLOODBOLT_TARGET); + events.ScheduleEvent(EVENT_TWILIGHT_BLOODBOLT, 10s, 15s, EVENT_GROUP_NORMAL); + break; + } + case EVENT_AIR_PHASE: + DoStopAttack(); + me->SetReactState(REACT_PASSIVE); + events.DelayEvents(10s, EVENT_GROUP_NORMAL); + events.CancelEventGroup(EVENT_GROUP_CANCELLABLE); + me->GetMotionMaster()->MovePoint(POINT_CENTER, centerPos); + break; + case EVENT_AIR_START_FLYING: + me->SetDisableGravity(true); + me->GetMotionMaster()->MovePoint(POINT_AIR, airPos); + break; + case EVENT_AIR_FLY_DOWN: + me->GetMotionMaster()->MovePoint(POINT_GROUND, centerPos); + break; + default: + break; } - bool WasBloodbolted(ObjectGuid guid) const - { - return _bloodboltedPlayers.count(guid) != 0; - } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } - private: - // offtank for this encounter is the player standing closest to main tank - Player* SelectRandomTarget(bool includeOfftank, std::list<Player*>* targetList = nullptr) - { - if (me->GetThreatManager().IsThreatListEmpty(true)) - return nullptr; + DoMeleeAttackIfReady(); + } - std::list<Player*> tempTargets; - Unit* maintank = me->GetThreatManager().GetCurrentVictim(); - for (ThreatReference const* ref : me->GetThreatManager().GetSortedThreatList()) - if (Player* refTarget = ref->GetVictim()->ToPlayer()) - if (refTarget != maintank && (includeOfftank || (refTarget->GetGUID() != _offtankGUID))) - tempTargets.push_back(refTarget->ToPlayer()); + bool WasVampire(ObjectGuid guid) const + { + return _vampires.count(guid) != 0; + } - if (tempTargets.empty()) - return nullptr; + bool WasBloodbolted(ObjectGuid guid) const + { + return _bloodboltedPlayers.count(guid) != 0; + } - if (targetList) - { - *targetList = std::move(tempTargets); - return nullptr; - } +private: + // offtank for this encounter is the player standing closest to main tank + Player* SelectRandomTarget(bool includeOfftank, std::list<Player*>* targetList = nullptr) + { + if (me->GetThreatManager().IsThreatListEmpty(true)) + return nullptr; - if (includeOfftank) - { - tempTargets.sort(Trinity::ObjectDistanceOrderPred(me->GetVictim())); - return tempTargets.front(); - } + std::list<Player*> tempTargets; + Unit* maintank = me->GetThreatManager().GetCurrentVictim(); + for (ThreatReference const* ref : me->GetThreatManager().GetSortedThreatList()) + if (Player* refTarget = ref->GetVictim()->ToPlayer()) + if (refTarget != maintank && (includeOfftank || (refTarget->GetGUID() != _offtankGUID))) + tempTargets.push_back(refTarget->ToPlayer()); - return Trinity::Containers::SelectRandomContainerElement(tempTargets); - } + if (tempTargets.empty()) + return nullptr; - GuidSet _vampires; - GuidSet _bloodboltedPlayers; - ObjectGuid _offtankGUID; - bool _creditBloodQuickening; - bool _killMinchar; - }; + if (targetList) + { + *targetList = std::move(tempTargets); + return nullptr; + } - CreatureAI* GetAI(Creature* creature) const override + if (includeOfftank) { - return GetIcecrownCitadelAI<boss_blood_queen_lana_thelAI>(creature); + tempTargets.sort(Trinity::ObjectDistanceOrderPred(me->GetVictim())); + return tempTargets.front(); } + + return Trinity::Containers::SelectRandomContainerElement(tempTargets); + } + + GuidSet _vampires; + GuidSet _bloodboltedPlayers; + ObjectGuid _offtankGUID; + bool _creditBloodQuickening; + bool _killMinchar; }; // helper for shortened code -typedef boss_blood_queen_lana_thel::boss_blood_queen_lana_thelAI LanaThelAI; +typedef boss_blood_queen_lana_thel LanaThelAI; -class spell_blood_queen_vampiric_bite : public SpellScriptLoader +class spell_blood_queen_vampiric_bite : public SpellScript { - public: - spell_blood_queen_vampiric_bite() : SpellScriptLoader("spell_blood_queen_vampiric_bite") { } + PrepareSpellScript(spell_blood_queen_vampiric_bite); - class spell_blood_queen_vampiric_bite_SpellScript : public SpellScript + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_PLR, SPELL_FRENZIED_BLOODTHIRST, SPELL_PRESENCE_OF_THE_DARKFALLEN }); + } + + SpellCastResult CheckTarget() + { + if (IsVampire(GetExplTargetUnit())) { - PrepareSpellScript(spell_blood_queen_vampiric_bite_SpellScript); + SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_CANT_TARGET_VAMPIRES); + return SPELL_FAILED_CUSTOM_ERROR; + } - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_PLR, SPELL_FRENZIED_BLOODTHIRST, SPELL_PRESENCE_OF_THE_DARKFALLEN }); - } + return SPELL_CAST_OK; + } - SpellCastResult CheckTarget() - { - if (IsVampire(GetExplTargetUnit())) - { - SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_CANT_TARGET_VAMPIRES); - return SPELL_FAILED_CUSTOM_ERROR; - } + void OnCast(SpellMissInfo missInfo) + { + if (GetCaster()->GetTypeId() != TYPEID_PLAYER || missInfo != SPELL_MISS_NONE) + return; - return SPELL_CAST_OK; - } + uint32 spellId = sSpellMgr->GetSpellIdForDifficulty(SPELL_FRENZIED_BLOODTHIRST, GetCaster()); + GetCaster()->RemoveAura(spellId, ObjectGuid::Empty, 0, AURA_REMOVE_BY_ENEMY_SPELL); + GetCaster()->CastSpell(GetCaster(), SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_PLR, TRIGGERED_FULL_MASK); - void OnCast(SpellMissInfo missInfo) + // Shadowmourne questline + if (Aura* aura = GetCaster()->GetAura(SPELL_GUSHING_WOUND)) + { + if (aura->GetStackAmount() == 3) { - if (GetCaster()->GetTypeId() != TYPEID_PLAYER || missInfo != SPELL_MISS_NONE) - return; - - uint32 spellId = sSpellMgr->GetSpellIdForDifficulty(SPELL_FRENZIED_BLOODTHIRST, GetCaster()); - GetCaster()->RemoveAura(spellId, ObjectGuid::Empty, 0, AURA_REMOVE_BY_ENEMY_SPELL); - GetCaster()->CastSpell(GetCaster(), SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_PLR, TRIGGERED_FULL_MASK); - - // Shadowmourne questline - if (Aura* aura = GetCaster()->GetAura(SPELL_GUSHING_WOUND)) - { - if (aura->GetStackAmount() == 3) - { - GetCaster()->CastSpell(GetCaster(), SPELL_THIRST_QUENCHED, TRIGGERED_FULL_MASK); - GetCaster()->RemoveAura(aura); - } - else - GetCaster()->CastSpell(GetCaster(), SPELL_GUSHING_WOUND, TRIGGERED_FULL_MASK); - } - - if (InstanceScript* instance = GetCaster()->GetInstanceScript()) - if (Creature* bloodQueen = ObjectAccessor::GetCreature(*GetCaster(), instance->GetGuidData(DATA_BLOOD_QUEEN_LANA_THEL))) - bloodQueen->AI()->SetGUID(GetHitUnit()->GetGUID(), GUID_VAMPIRE); + GetCaster()->CastSpell(GetCaster(), SPELL_THIRST_QUENCHED, TRIGGERED_FULL_MASK); + GetCaster()->RemoveAura(aura); } + else + GetCaster()->CastSpell(GetCaster(), SPELL_GUSHING_WOUND, TRIGGERED_FULL_MASK); + } - void HandlePresence(SpellEffIndex /*effIndex*/) - { - GetHitUnit()->CastSpell(GetHitUnit(), SPELL_PRESENCE_OF_THE_DARKFALLEN, TRIGGERED_FULL_MASK); - GetHitUnit()->CastSpell(GetHitUnit(), SPELL_PRESENCE_OF_THE_DARKFALLEN_2, TRIGGERED_FULL_MASK); - } + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + if (Creature* bloodQueen = ObjectAccessor::GetCreature(*GetCaster(), instance->GetGuidData(DATA_BLOOD_QUEEN_LANA_THEL))) + bloodQueen->AI()->SetGUID(GetHitUnit()->GetGUID(), GUID_VAMPIRE); + } - void Register() override - { - OnCheckCast += SpellCheckCastFn(spell_blood_queen_vampiric_bite_SpellScript::CheckTarget); - BeforeHit += BeforeSpellHitFn(spell_blood_queen_vampiric_bite_SpellScript::OnCast); - OnEffectHitTarget += SpellEffectFn(spell_blood_queen_vampiric_bite_SpellScript::HandlePresence, EFFECT_1, SPELL_EFFECT_TRIGGER_SPELL); - } - }; + void HandlePresence(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_PRESENCE_OF_THE_DARKFALLEN, TRIGGERED_FULL_MASK); + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_PRESENCE_OF_THE_DARKFALLEN_2, TRIGGERED_FULL_MASK); + } - SpellScript* GetSpellScript() const override - { - return new spell_blood_queen_vampiric_bite_SpellScript(); - } + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_blood_queen_vampiric_bite::CheckTarget); + BeforeHit += BeforeSpellHitFn(spell_blood_queen_vampiric_bite::OnCast); + OnEffectHitTarget += SpellEffectFn(spell_blood_queen_vampiric_bite::HandlePresence, EFFECT_1, SPELL_EFFECT_TRIGGER_SPELL); + } }; -class spell_blood_queen_frenzied_bloodthirst : public SpellScriptLoader +class spell_blood_queen_frenzied_bloodthirst : public AuraScript { - public: - spell_blood_queen_frenzied_bloodthirst() : SpellScriptLoader("spell_blood_queen_frenzied_bloodthirst") { } - - class spell_blood_queen_frenzied_bloodthirst_AuraScript : public AuraScript - { - PrepareAuraScript(spell_blood_queen_frenzied_bloodthirst_AuraScript); + PrepareAuraScript(spell_blood_queen_frenzied_bloodthirst); - void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (InstanceScript* instance = GetTarget()->GetInstanceScript()) - if (Creature* bloodQueen = ObjectAccessor::GetCreature(*GetTarget(), instance->GetGuidData(DATA_BLOOD_QUEEN_LANA_THEL))) - bloodQueen->AI()->Talk(EMOTE_BLOODTHIRST, GetTarget()); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE) - if (InstanceScript* instance = target->GetInstanceScript()) - if (Creature* bloodQueen = ObjectAccessor::GetCreature(*target, instance->GetGuidData(DATA_BLOOD_QUEEN_LANA_THEL))) - { - // this needs to be done BEFORE charm aura or we hit an assert in Unit::SetCharmedBy - if (target->GetVehicleKit()) - target->RemoveVehicleKit(); + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (InstanceScript* instance = GetTarget()->GetInstanceScript()) + if (Creature* bloodQueen = ObjectAccessor::GetCreature(*GetTarget(), instance->GetGuidData(DATA_BLOOD_QUEEN_LANA_THEL))) + bloodQueen->AI()->Talk(EMOTE_BLOODTHIRST, GetTarget()); + } - bloodQueen->AI()->Talk(SAY_MIND_CONTROL); - bloodQueen->CastSpell(target, SPELL_UNCONTROLLABLE_FRENZY, true); - } - } + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE) + if (InstanceScript* instance = target->GetInstanceScript()) + if (Creature* bloodQueen = ObjectAccessor::GetCreature(*target, instance->GetGuidData(DATA_BLOOD_QUEEN_LANA_THEL))) + { + // this needs to be done BEFORE charm aura or we hit an assert in Unit::SetCharmedBy + if (target->GetVehicleKit()) + target->RemoveVehicleKit(); - void Register() override - { - OnEffectApply += AuraEffectApplyFn(spell_blood_queen_frenzied_bloodthirst_AuraScript::OnApply, EFFECT_0, SPELL_AURA_OVERRIDE_SPELLS, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_blood_queen_frenzied_bloodthirst_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_OVERRIDE_SPELLS, AURA_EFFECT_HANDLE_REAL); - } - }; + bloodQueen->AI()->Talk(SAY_MIND_CONTROL); + bloodQueen->CastSpell(target, SPELL_UNCONTROLLABLE_FRENZY, true); + } + } - AuraScript* GetAuraScript() const override - { - return new spell_blood_queen_frenzied_bloodthirst_AuraScript(); - } + void Register() override + { + OnEffectApply += AuraEffectApplyFn(spell_blood_queen_frenzied_bloodthirst::OnApply, EFFECT_0, SPELL_AURA_OVERRIDE_SPELLS, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_blood_queen_frenzied_bloodthirst::OnRemove, EFFECT_0, SPELL_AURA_OVERRIDE_SPELLS, AURA_EFFECT_HANDLE_REAL); + } }; class BloodboltHitCheck @@ -656,205 +623,150 @@ class BloodboltHitCheck LanaThelAI* _ai; }; -class spell_blood_queen_bloodbolt : public SpellScriptLoader +class spell_blood_queen_bloodbolt : public SpellScript { - public: - spell_blood_queen_bloodbolt() : SpellScriptLoader("spell_blood_queen_bloodbolt") { } + PrepareSpellScript(spell_blood_queen_bloodbolt); - class spell_blood_queen_bloodbolt_SpellScript : public SpellScript - { - PrepareSpellScript(spell_blood_queen_bloodbolt_SpellScript); - - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_TWILIGHT_BLOODBOLT }); - } - - bool Load() override - { - return GetCaster()->GetEntry() == NPC_BLOOD_QUEEN_LANA_THEL; - } + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_TWILIGHT_BLOODBOLT }); + } - void FilterTargets(std::list<WorldObject*>& targets) - { - uint32 targetCount = (targets.size() + 2) / 3; - targets.remove_if(BloodboltHitCheck(static_cast<LanaThelAI*>(GetCaster()->GetAI()))); - Trinity::Containers::RandomResize(targets, targetCount); - // mark targets now, effect hook has missile travel time delay (might cast next in that time) - for (std::list<WorldObject*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) - GetCaster()->GetAI()->SetGUID((*itr)->GetGUID(), GUID_BLOODBOLT); - } + bool Load() override + { + return GetCaster()->GetEntry() == NPC_BLOOD_QUEEN_LANA_THEL; + } - void HandleScript(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - GetCaster()->CastSpell(GetHitUnit(), SPELL_TWILIGHT_BLOODBOLT, true); - } + void FilterTargets(std::list<WorldObject*>& targets) + { + uint32 targetCount = (targets.size() + 2) / 3; + targets.remove_if(BloodboltHitCheck(static_cast<LanaThelAI*>(GetCaster()->GetAI()))); + Trinity::Containers::RandomResize(targets, targetCount); + // mark targets now, effect hook has missile travel time delay (might cast next in that time) + for (std::list<WorldObject*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) + GetCaster()->GetAI()->SetGUID((*itr)->GetGUID(), GUID_BLOODBOLT); + } - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_blood_queen_bloodbolt_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); - OnEffectHitTarget += SpellEffectFn(spell_blood_queen_bloodbolt_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetCaster()->CastSpell(GetHitUnit(), SPELL_TWILIGHT_BLOODBOLT, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_blood_queen_bloodbolt_SpellScript(); - } + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_blood_queen_bloodbolt::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_blood_queen_bloodbolt::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } }; // 70871 - Essence of the Blood Queen -class spell_blood_queen_essence_of_the_blood_queen : public SpellScriptLoader +class spell_blood_queen_essence_of_the_blood_queen : public AuraScript { - public: - spell_blood_queen_essence_of_the_blood_queen() : SpellScriptLoader("spell_blood_queen_essence_of_the_blood_queen") { } - - class spell_blood_queen_essence_of_the_blood_queen_AuraScript : public AuraScript - { - PrepareAuraScript(spell_blood_queen_essence_of_the_blood_queen_AuraScript); + PrepareAuraScript(spell_blood_queen_essence_of_the_blood_queen); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_HEAL }); - } - - void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return; - - CastSpellExtraArgs args(aurEff); - args.AddSpellBP0(CalculatePct(damageInfo->GetDamage(), aurEff->GetAmount())); - GetTarget()->CastSpell(GetTarget(), SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_HEAL, args); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_HEAL }); + } - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_blood_queen_essence_of_the_blood_queen_AuraScript::OnProc, EFFECT_1, SPELL_AURA_DUMMY); - } - }; + void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + DamageInfo* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo || !damageInfo->GetDamage()) + return; + + CastSpellExtraArgs args(aurEff); + args.AddSpellBP0(CalculatePct(damageInfo->GetDamage(), aurEff->GetAmount())); + GetTarget()->CastSpell(GetTarget(), SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_HEAL, args); + } - AuraScript* GetAuraScript() const override - { - return new spell_blood_queen_essence_of_the_blood_queen_AuraScript(); - } + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_blood_queen_essence_of_the_blood_queen::OnProc, EFFECT_1, SPELL_AURA_DUMMY); + } }; -class spell_blood_queen_pact_of_the_darkfallen : public SpellScriptLoader +class spell_blood_queen_pact_of_the_darkfallen : public SpellScript { - public: - spell_blood_queen_pact_of_the_darkfallen() : SpellScriptLoader("spell_blood_queen_pact_of_the_darkfallen") { } - - class spell_blood_queen_pact_of_the_darkfallen_SpellScript : public SpellScript - { - PrepareSpellScript(spell_blood_queen_pact_of_the_darkfallen_SpellScript); - - void FilterTargets(std::list<WorldObject*>& targets) - { - targets.remove_if(Trinity::UnitAuraCheck(false, SPELL_PACT_OF_THE_DARKFALLEN)); + PrepareSpellScript(spell_blood_queen_pact_of_the_darkfallen); - bool remove = true; - std::list<WorldObject*>::const_iterator itrEnd = targets.end(), itr, itr2; - // we can do this, unitList is MAX 4 in size - for (itr = targets.begin(); itr != itrEnd && remove; ++itr) - { - if (!GetCaster()->IsWithinDist(*itr, 5.0f, false)) - remove = false; + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.remove_if(Trinity::UnitAuraCheck(false, SPELL_PACT_OF_THE_DARKFALLEN)); - for (itr2 = targets.begin(); itr2 != itrEnd && remove; ++itr2) - if (itr != itr2 && !(*itr2)->IsWithinDist(*itr, 5.0f, false)) - remove = false; - } + bool remove = true; + std::list<WorldObject*>::const_iterator itrEnd = targets.end(), itr, itr2; + // we can do this, unitList is MAX 4 in size + for (itr = targets.begin(); itr != itrEnd && remove; ++itr) + { + if (!GetCaster()->IsWithinDist(*itr, 5.0f, false)) + remove = false; - if (remove) - { - if (InstanceScript* instance = GetCaster()->GetInstanceScript()) - { - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_PACT_OF_THE_DARKFALLEN); - targets.clear(); - } - } - } + for (itr2 = targets.begin(); itr2 != itrEnd && remove; ++itr2) + if (itr != itr2 && !(*itr2)->IsWithinDist(*itr, 5.0f, false)) + remove = false; + } - void Register() override + if (remove) + { + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_blood_queen_pact_of_the_darkfallen_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_PACT_OF_THE_DARKFALLEN); + targets.clear(); } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_blood_queen_pact_of_the_darkfallen_SpellScript(); } + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_blood_queen_pact_of_the_darkfallen::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); + } }; -class spell_blood_queen_pact_of_the_darkfallen_dmg : public SpellScriptLoader +class spell_blood_queen_pact_of_the_darkfallen_dmg : public AuraScript { - public: - spell_blood_queen_pact_of_the_darkfallen_dmg() : SpellScriptLoader("spell_blood_queen_pact_of_the_darkfallen_dmg") { } - - class spell_blood_queen_pact_of_the_darkfallen_dmg_AuraScript : public AuraScript - { - PrepareAuraScript(spell_blood_queen_pact_of_the_darkfallen_dmg_AuraScript); + PrepareAuraScript(spell_blood_queen_pact_of_the_darkfallen_dmg); - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_PACT_OF_THE_DARKFALLEN_DAMAGE }); - } - - // this is an additional effect to be executed - void PeriodicTick(AuraEffect const* aurEff) - { - SpellInfo const* damageSpell = sSpellMgr->AssertSpellInfo(SPELL_PACT_OF_THE_DARKFALLEN_DAMAGE); - int32 damage = damageSpell->Effects[EFFECT_0].CalcValue(); - float multiplier = 0.3375f + 0.1f * uint32(aurEff->GetTickNumber()/10); // do not convert to 0.01f - we need tick number/10 as INT (damage increases every 10 ticks) - damage = int32(damage * multiplier); - - CastSpellExtraArgs args(TRIGGERED_FULL_MASK); - args.AddSpellBP0(damage); - GetTarget()->CastSpell(GetTarget(), SPELL_PACT_OF_THE_DARKFALLEN_DAMAGE, args); - } + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_PACT_OF_THE_DARKFALLEN_DAMAGE }); + } - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_blood_queen_pact_of_the_darkfallen_dmg_AuraScript::PeriodicTick, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } - }; + // this is an additional effect to be executed + void PeriodicTick(AuraEffect const* aurEff) + { + SpellInfo const* damageSpell = sSpellMgr->AssertSpellInfo(SPELL_PACT_OF_THE_DARKFALLEN_DAMAGE); + int32 damage = damageSpell->Effects[EFFECT_0].CalcValue(); + float multiplier = 0.3375f + 0.1f * uint32(aurEff->GetTickNumber()/10); // do not convert to 0.01f - we need tick number/10 as INT (damage increases every 10 ticks) + damage = int32(damage * multiplier); + + CastSpellExtraArgs args(TRIGGERED_FULL_MASK); + args.AddSpellBP0(damage); + GetTarget()->CastSpell(GetTarget(), SPELL_PACT_OF_THE_DARKFALLEN_DAMAGE, args); + } - AuraScript* GetAuraScript() const override - { - return new spell_blood_queen_pact_of_the_darkfallen_dmg_AuraScript(); - } + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_blood_queen_pact_of_the_darkfallen_dmg::PeriodicTick, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } }; -class spell_blood_queen_pact_of_the_darkfallen_dmg_target : public SpellScriptLoader +class spell_blood_queen_pact_of_the_darkfallen_dmg_target : public SpellScript { - public: - spell_blood_queen_pact_of_the_darkfallen_dmg_target() : SpellScriptLoader("spell_blood_queen_pact_of_the_darkfallen_dmg_target") { } - - class spell_blood_queen_pact_of_the_darkfallen_dmg_SpellScript : public SpellScript - { - PrepareSpellScript(spell_blood_queen_pact_of_the_darkfallen_dmg_SpellScript); + PrepareSpellScript(spell_blood_queen_pact_of_the_darkfallen_dmg_target); - void FilterTargets(std::list<WorldObject*>& unitList) - { - unitList.remove_if(Trinity::UnitAuraCheck(true, SPELL_PACT_OF_THE_DARKFALLEN)); - unitList.push_back(GetCaster()); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_blood_queen_pact_of_the_darkfallen_dmg_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); - } - }; + void FilterTargets(std::list<WorldObject*>& unitList) + { + unitList.remove_if(Trinity::UnitAuraCheck(true, SPELL_PACT_OF_THE_DARKFALLEN)); + unitList.push_back(GetCaster()); + } - SpellScript* GetSpellScript() const override - { - return new spell_blood_queen_pact_of_the_darkfallen_dmg_SpellScript(); - } + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_blood_queen_pact_of_the_darkfallen_dmg_target::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); + } }; // 71446, 71478, 71479, 71480 - Twilight Bloodbolt @@ -912,15 +824,20 @@ class achievement_once_bitten_twice_shy_v : public AchievementCriteriaScript void AddSC_boss_blood_queen_lana_thel() { - new boss_blood_queen_lana_thel(); - new spell_blood_queen_vampiric_bite(); - new spell_blood_queen_frenzied_bloodthirst(); - new spell_blood_queen_bloodbolt(); - new spell_blood_queen_essence_of_the_blood_queen(); - new spell_blood_queen_pact_of_the_darkfallen(); - new spell_blood_queen_pact_of_the_darkfallen_dmg(); - new spell_blood_queen_pact_of_the_darkfallen_dmg_target(); + // Creatures + RegisterIcecrownCitadelCreatureAI(boss_blood_queen_lana_thel); + + // Spells + RegisterSpellScript(spell_blood_queen_vampiric_bite); + RegisterSpellScript(spell_blood_queen_frenzied_bloodthirst); + RegisterSpellScript(spell_blood_queen_bloodbolt); + RegisterSpellScript(spell_blood_queen_essence_of_the_blood_queen); + RegisterSpellScript(spell_blood_queen_pact_of_the_darkfallen); + RegisterSpellScript(spell_blood_queen_pact_of_the_darkfallen_dmg); + RegisterSpellScript(spell_blood_queen_pact_of_the_darkfallen_dmg_target); RegisterSpellScript(spell_blood_queen_twilight_bloodbolt); + + // Achievements new achievement_once_bitten_twice_shy_n(); new achievement_once_bitten_twice_shy_v(); } |