aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/PlayerAI/PlayerAI.cpp2
-rw-r--r--src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp207
2 files changed, 128 insertions, 81 deletions
diff --git a/src/server/game/AI/PlayerAI/PlayerAI.cpp b/src/server/game/AI/PlayerAI/PlayerAI.cpp
index 0f99211a84b..a5209c68680 100644
--- a/src/server/game/AI/PlayerAI/PlayerAI.cpp
+++ b/src/server/game/AI/PlayerAI/PlayerAI.cpp
@@ -1219,7 +1219,7 @@ void SimpleCharmedPlayerAI::UpdateAI(const uint32 diff)
if (charmer->IsEngaged())
{
Unit* target = me->GetVictim();
- if (!target || !charmer->IsValidAttackTarget(target) || target->HasBreakableByDamageCrowdControlAura())
+ if (!target || !charmer->IsValidAttackTarget(target) || !me->IsValidAttackTarget(target) || target->HasBreakableByDamageCrowdControlAura())
{
target = SelectAttackTarget();
if (!target)
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 f7ece3c01e1..a7305c6528c 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,16 +15,12 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/*
-Name: Boss_Blackheart_the_Inciter
-%Complete: 75
-Comment: Incite Chaos not functional since core lacks Mind Control support
-Category: Auchindoun, Shadow Labyrinth
-*/
-
-#include "ScriptMgr.h"
#include "ObjectAccessor.h"
+#include "Player.h"
+#include "PlayerAI.h"
+#include "ScriptMgr.h"
#include "ScriptedCreature.h"
+#include "SpellScript.h"
#include "shadow_labyrinth.h"
enum BlackheartTheInciter
@@ -55,94 +51,145 @@ enum Events
EVENT_WAR_STOMP = 3
};
-class boss_blackheart_the_inciter : public CreatureScript
+class BlackheartCharmedPlayerAI : public SimpleCharmedPlayerAI
{
- public:
- boss_blackheart_the_inciter() : CreatureScript("boss_blackheart_the_inciter") { }
-
- struct boss_blackheart_the_inciterAI : public BossAI
+ using SimpleCharmedPlayerAI::SimpleCharmedPlayerAI;
+ Unit* SelectAttackTarget() const override
+ {
+ if (Unit* charmer = me->GetCharmer())
{
- boss_blackheart_the_inciterAI(Creature* creature) : BossAI(creature, DATA_BLACKHEART_THE_INCITER) { }
-
- void Reset() override
+ if (charmer->m_Controlled.size() <= 1)
+ return nullptr;
+ Unit* target = nullptr;
+ do
{
- _Reset();
- }
-
- void EnterCombat(Unit* /*who*/) override
- {
- _EnterCombat();
- events.ScheduleEvent(EVENT_INCITE_CHAOS, 20000);
- events.ScheduleEvent(EVENT_CHARGE_ATTACK, 5000);
- events.ScheduleEvent(EVENT_WAR_STOMP, 15000);
-
- Talk(SAY_AGGRO);
- }
-
- void KilledUnit(Unit* who) override
- {
- if (who->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_SLAY);
- }
-
- void JustDied(Unit* /*killer*/) override
+ auto it = charmer->m_Controlled.begin();
+ std::advance(it, urand(0, charmer->m_Controlled.size() - 1));
+ target = *it;
+ } while (target == me);
+ return target;
+ }
+ return nullptr;
+ }
+ void OnCharmed(bool apply) override
+ {
+ SimpleCharmedPlayerAI::OnCharmed(apply);
+ if (apply)
+ if (Unit* charmer = GetCharmer())
{
- _JustDied();
- Talk(SAY_DEATH);
+ // @todo hack to be removed in new combat system
+ charmer->SetInCombatState(false);
+ me->SetInCombatState(false);
}
+ }
+};
- void UpdateAI(uint32 diff) override
+struct boss_blackheart_the_inciter : public BossAI
+{
+ boss_blackheart_the_inciter(Creature* creature) : BossAI(creature, DATA_BLACKHEART_THE_INCITER) { }
+
+ void Reset() override
+ {
+ me->SetReactState(REACT_AGGRESSIVE);
+ _Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/) override
+ {
+ _EnterCombat();
+ events.ScheduleEvent(EVENT_INCITE_CHAOS, 20000);
+ events.ScheduleEvent(EVENT_CHARGE_ATTACK, 5000);
+ events.ScheduleEvent(EVENT_WAR_STOMP, 15000);
+
+ Talk(SAY_AGGRO);
+ }
+
+ void KilledUnit(Unit* who) override
+ {
+ if (who->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_SLAY);
+ }
+
+ void JustDied(Unit* /*killer*/) override
+ {
+ _JustDied();
+ Talk(SAY_DEATH);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (me->HasReactState(REACT_PASSIVE) && me->m_Controlled.empty())
+ me->SetReactState(REACT_AGGRESSIVE);
+
+ if (me->HasReactState(REACT_PASSIVE) || !UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
{
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
+ case EVENT_INCITE_CHAOS:
{
- switch (eventId)
+ if (me->GetThreatManager().GetThreatListSize() > 1)
{
- case EVENT_INCITE_CHAOS:
- {
- DoCast(me, SPELL_INCITE_CHAOS);
-
- for (ThreatReference const* ref : me->GetThreatManager().GetUnsortedThreatList())
- if (ref->GetVictim()->GetTypeId() == TYPEID_PLAYER)
- me->CastSpell(ref->GetVictim(), SPELL_INCITE_CHAOS_B, true);
-
- ResetThreatList();
- events.ScheduleEvent(EVENT_INCITE_CHAOS, 40000);
- break;
- }
- case EVENT_CHARGE_ATTACK:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_CHARGE);
- events.ScheduleEvent(EVENT_CHARGE, urand(15000, 25000));
- break;
- case EVENT_WAR_STOMP:
- DoCast(me, SPELL_WAR_STOMP);
- events.ScheduleEvent(EVENT_WAR_STOMP, urand(18000, 24000));
- break;
+ me->SetReactState(REACT_PASSIVE);
+ DoCast(me, SPELL_INCITE_CHAOS);
}
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ events.ScheduleEvent(EVENT_INCITE_CHAOS, 40000);
+ break;
}
-
- DoMeleeAttackIfReady();
+ case EVENT_CHARGE_ATTACK:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_CHARGE);
+ events.ScheduleEvent(EVENT_CHARGE, urand(15000, 25000));
+ break;
+ case EVENT_WAR_STOMP:
+ DoCast(me, SPELL_WAR_STOMP);
+ events.ScheduleEvent(EVENT_WAR_STOMP, urand(18000, 24000));
+ break;
}
- };
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetShadowLabyrinthAI<boss_blackheart_the_inciterAI>(creature);
+ if (me->HasReactState(REACT_PASSIVE) || me->HasUnitState(UNIT_STATE_CASTING))
+ return;
}
+
+ DoMeleeAttackIfReady();
+ }
+
+ PlayerAI* GetAIForCharmedPlayer(Player* player) override
+ {
+ return new BlackheartCharmedPlayerAI(player);
+ }
+};
+
+class spell_blackheart_incite_chaos : public SpellScript
+{
+ PrepareSpellScript(spell_blackheart_incite_chaos);
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ return ValidateSpellInfo({ SPELL_INCITE_CHAOS_B });
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* caster = GetCaster())
+ if (Unit* target = GetHitUnit())
+ caster->CastSpell(target, SPELL_INCITE_CHAOS_B, true);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_blackheart_incite_chaos::HandleDummy, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
};
void AddSC_boss_blackheart_the_inciter()
{
- new boss_blackheart_the_inciter();
+ RegisterCreatureAIWithFactory(boss_blackheart_the_inciter, GetShadowLabyrinthAI);
+ RegisterSpellScript(spell_blackheart_incite_chaos);
}