diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp | 100 |
1 files changed, 76 insertions, 24 deletions
diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp index a7305c6528c..cf2946faf50 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp @@ -15,6 +15,7 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "PassiveAI.h" #include "ObjectAccessor.h" #include "Player.h" #include "PlayerAI.h" @@ -25,6 +26,7 @@ enum BlackheartTheInciter { + NPC_BLACKHEART = 18667, SPELL_INCITE_CHAOS = 33676, SPELL_INCITE_CHAOS_B = 33684, //debuff applied to each member of party SPELL_CHARGE = 33709, @@ -58,29 +60,30 @@ class BlackheartCharmedPlayerAI : public SimpleCharmedPlayerAI { if (Unit* charmer = me->GetCharmer()) { - if (charmer->m_Controlled.size() <= 1) - return nullptr; - Unit* target = nullptr; - do + std::list<Player*> targets; + for (ThreatReference const* ref : charmer->GetThreatManager().GetUnsortedThreatList()) { - auto it = charmer->m_Controlled.begin(); - std::advance(it, urand(0, charmer->m_Controlled.size() - 1)); - target = *it; - } while (target == me); - return target; + if (Player* victim = ref->GetVictim()->ToPlayer()) + if (me->IsValidAttackTarget(victim)) + targets.push_back(victim); + } + if (targets.empty()) + return nullptr; + + auto it = targets.begin(); + std::advance(it, urand(0, targets.size() - 1)); + return *it; } return nullptr; } void OnCharmed(bool apply) override { SimpleCharmedPlayerAI::OnCharmed(apply); - if (apply) - if (Unit* charmer = GetCharmer()) - { - // @todo hack to be removed in new combat system - charmer->SetInCombatState(false); - me->SetInCombatState(false); - } + if (Creature* blackheart = me->FindNearestCreature(NPC_BLACKHEART, 50000.0f)) + { + blackheart->AI()->SetData(0, apply); + blackheart->GetThreatManager().AddThreat(me, 0.0f); + } } }; @@ -116,16 +119,29 @@ struct boss_blackheart_the_inciter : public BossAI Talk(SAY_DEATH); } - void UpdateAI(uint32 diff) override + uint8 charmCount = 0; + void SetData(uint32 /*index*/, uint32 data) override { - if (me->HasReactState(REACT_PASSIVE) && me->m_Controlled.empty()) + if (data) + ++charmCount; + else + { + if (!charmCount) + EnterEvadeMode(EVADE_REASON_OTHER); // sanity check + --charmCount; + } + if (charmCount) + me->SetReactState(REACT_PASSIVE); + else me->SetReactState(REACT_AGGRESSIVE); + } + void UpdateAI(uint32 diff) override + { + events.Update(diff); if (me->HasReactState(REACT_PASSIVE) || !UpdateVictim()) return; - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) return; @@ -137,7 +153,7 @@ struct boss_blackheart_the_inciter : public BossAI { if (me->GetThreatManager().GetThreatListSize() > 1) { - me->SetReactState(REACT_PASSIVE); + ResetThreatList(); DoCast(me, SPELL_INCITE_CHAOS); } events.ScheduleEvent(EVENT_INCITE_CHAOS, 40000); @@ -160,7 +176,36 @@ struct boss_blackheart_the_inciter : public BossAI DoMeleeAttackIfReady(); } +}; + +struct boss_blackheart_the_inciter_mc_dummy : public NullCreatureAI +{ + using NullCreatureAI::NullCreatureAI; + void InitializeAI() override { me->SetReactState(REACT_PASSIVE); } + static const uint32 FIRST_DUMMY = 19300, LAST_DUMMY = 19304; + void IsSummonedBy(Unit* who) override + { + me->CastSpell(who, SPELL_INCITE_CHAOS_B, true); + // ensure everyone is in combat with everyone + for (uint32 entry = FIRST_DUMMY; entry <= LAST_DUMMY; ++entry) + if (entry != me->GetEntry()) + if (Creature* trigger = me->FindNearestCreature(entry, 50000.0f)) + { + me->GetThreatManager().AddThreat(trigger, 0.0f); + trigger->GetThreatManager().AddThreat(who, 0.0f); + for (Unit* other : trigger->m_Controlled) + { + me->GetThreatManager().AddThreat(other, 0.0f); + other->GetThreatManager().AddThreat(who, 0.0f); + } + } + } + void UpdateAI(uint32 /*diff*/) override + { + if (me->m_Controlled.empty()) + me->DespawnOrUnsummon(); + } PlayerAI* GetAIForCharmedPlayer(Player* player) override { return new BlackheartCharmedPlayerAI(player); @@ -175,11 +220,16 @@ class spell_blackheart_incite_chaos : public SpellScript return ValidateSpellInfo({ SPELL_INCITE_CHAOS_B }); } + static const uint8 NUM_INCITE_SPELLS = 5; + static const uint32 INCITE_SPELLS[NUM_INCITE_SPELLS]; + uint8 i=0; void HandleDummy(SpellEffIndex /*effIndex*/) { - if (Unit* caster = GetCaster()) - if (Unit* target = GetHitUnit()) - caster->CastSpell(target, SPELL_INCITE_CHAOS_B, true); + if (Unit* target = GetHitUnit()) + { + target->CastSpell(nullptr, INCITE_SPELLS[i], true); + i = (i + 1) % NUM_INCITE_SPELLS; + } } void Register() override @@ -187,9 +237,11 @@ class spell_blackheart_incite_chaos : public SpellScript OnEffectHitTarget += SpellEffectFn(spell_blackheart_incite_chaos::HandleDummy, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; +const uint32 spell_blackheart_incite_chaos::INCITE_SPELLS[spell_blackheart_incite_chaos::NUM_INCITE_SPELLS] = { 33677,33680,33681,33682,33683 }; void AddSC_boss_blackheart_the_inciter() { RegisterCreatureAIWithFactory(boss_blackheart_the_inciter, GetShadowLabyrinthAI); + RegisterCreatureAIWithFactory(boss_blackheart_the_inciter_mc_dummy, GetShadowLabyrinthAI); RegisterSpellScript(spell_blackheart_incite_chaos); } |