Merge branch 'azerothcore:master' into Playerbot

This commit is contained in:
ZhengPeiRu21
2023-04-21 22:17:38 -06:00
committed by GitHub
8 changed files with 333 additions and 144 deletions

View File

@@ -0,0 +1,41 @@
-- DB update 2023_04_20_00 -> 2023_04_21_00
-- Trigger SAI Areatrigger 173 if no Ravenclaw Apparition within 30 yards.
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceEntry` = 173 AND `SourceId` = 2;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(22, 1, 173, 2, 0, 29, 0, 2056, 30, 0, 1, 0, 0, '', 'Trigger Areatrigger 173 if no Ravenclaw Apparition within 30 yards');
-- Areatrigger - On Trigger - Summon Creature 'Ravenclaw Apparition' (The Dead Fields) for 5 minutes.
DELETE FROM `areatrigger_scripts` WHERE `entry` = 173;
INSERT INTO `areatrigger_scripts` (`entry`, `ScriptName`) VALUES (173, 'SmartTrigger');
DELETE FROM `smart_scripts` WHERE (`source_type` = 2 AND `entryorguid` = 173);
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
(173, 2, 0, 0, 46, 0, 100, 0, 0, 0, 0, 0, 0, 12, 2056, 3, 300000, 0, 0, 0, 8, 0, 0, 0, 0, 1077, 1539, 28.89, 0, 'Areatrigger - On Trigger - Summon Creature \'Ravenclaw Apparition\' (The Dead Fields)');
-- Move creature_text from Thule Ravencla to Ravenclaw Apparition
DELETE FROM `creature_text` WHERE `CreatureID` IN (1947, 2056);
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(2056, 0, 0, 'My minions...', 14, 0, 100, 0, 0, 0, 518, 0, 'Ravenclaw Apparition - Intro'),
(2056, 1, 0, 'The time for conquest approaches quickly.', 14, 0, 100, 0, 0, 0, 519, 0, 'Ravenclaw Apparition'),
(2056, 2, 0, 'Soon, your thirst for destruction will be quenched.', 14, 0, 100, 0, 0, 0, 520, 0, 'Ravenclaw Apparition'),
(2056, 3, 0, 'The rage burning within you will soon find fuel in our enemies.', 14, 0, 100, 0, 0, 0, 521, 0, 'Ravenclaw Apparition'),
(2056, 4, 0, 'I come with news of our conflict with the Rogue Undead.', 14, 0, 100, 0, 0, 0, 522, 0, 'Ravenclaw Apparition'),
(2056, 5, 0, 'The rebels of Lordaeron are small and weak, and know not the joy of serving our Lich King.', 14, 0, 100, 0, 0, 0, 523, 0, 'Ravenclaw Apparition'),
(2056, 6, 0, 'The Dark Lady\'s followers are blind to think they can stand against our might.', 14, 0, 100, 0, 0, 0, 525, 0, 'Ravenclaw Apparition'),
(2056, 7, 0, 'We grow strong, while our foes are surrounded by foes, and weakened by constant attacks.', 14, 0, 100, 0, 0, 0, 526, 0, 'Ravenclaw Apparition'),
(2056, 8, 0, 'Our Lord commands us to make ready for war!', 14, 0, 100, 0, 0, 0, 527, 0, 'Ravenclaw Apparition'),
(2056, 9, 0, 'Prepare yourselves, for we will soon launch an assault against they who called themselves "The Forsaken."', 14, 0, 100, 0, 0, 0, 528, 0, 'Ravenclaw Apparition'),
(2056, 10, 0, 'Make ready for battle, my creations.', 14, 0, 100, 0, 0, 0, 529, 0, 'Ravenclaw Apparition'),
(2056, 11, 0, 'We are the arm of His will. And we will crush His foes into grave dust!', 14, 0, 100, 0, 0, 0, 530, 0, 'Ravenclaw Apparition'),
(2056, 12, 0, 'These undead rabble, and their dead-elf queen, will fall!', 14, 0, 100, 0, 0, 0, 531, 0, 'Ravenclaw Apparition'),
(2056, 13, 0, 'We will drive our foes from Silverpine, then bring the tides of war to their very capital!', 14, 0, 100, 0, 0, 0, 532, 0, 'Ravenclaw Apparition'),
(2056, 14, 0, 'Death and Praise for the Lich King!', 14, 0, 100, 0, 0, 0, 533, 0, 'Ravenclaw Apparition - Outro');
-- Ravenclaw Apparition
UPDATE `creature_template` SET `AIName` = 'NullCreatureAI', `ScriptName` = 'npc_ravenclaw_apparition' WHERE `entry` = 2056;
-- Rot Hide Gladerunner & Rot Hide Mystic - Add cheer emote (They share creature_text), this is probably better than a hardcode.
DELETE FROM `creature_text` WHERE `CreatureID` IN (1772,1773) AND `GroupID`=1;
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(1772, 1, 0, '%s cheers!', 16, 0, 100, 4, 0, 0, 3928, 0, 'Rot Hide Gladerunner - Cheer (Apparition event)'),
(1773, 1, 0, '%s cheers!', 16, 0, 100, 4, 0, 0, 3928, 0, 'Rot Hide Mystic - Cheer (Apparition event)');

View File

@@ -1985,19 +1985,26 @@ void Player::RegenerateHealth()
else if (!IsInCombat() || HasAuraType(SPELL_AURA_MOD_REGEN_DURING_COMBAT))
{
addvalue = OCTRegenHPPerSpirit() * HealthIncreaseRate;
if (!IsStandState())
{
addvalue *= 1.33f;
}
AuraEffectList const& mModHealthRegenPct = GetAuraEffectsByType(SPELL_AURA_MOD_HEALTH_REGEN_PERCENT);
for (AuraEffectList::const_iterator i = mModHealthRegenPct.begin(); i != mModHealthRegenPct.end(); ++i)
{
AddPct(addvalue, (*i)->GetAmount());
}
if (!IsInCombat())
{
AuraEffectList const& mModHealthRegenPct = GetAuraEffectsByType(SPELL_AURA_MOD_HEALTH_REGEN_PERCENT);
for (AuraEffectList::const_iterator i = mModHealthRegenPct.begin(); i != mModHealthRegenPct.end(); ++i)
AddPct(addvalue, (*i)->GetAmount());
addvalue += GetTotalAuraModifier(SPELL_AURA_MOD_REGEN) * 2 * IN_MILLISECONDS / (5 * IN_MILLISECONDS);
}
else if (HasAuraType(SPELL_AURA_MOD_REGEN_DURING_COMBAT))
{
ApplyPct(addvalue, GetTotalAuraModifier(SPELL_AURA_MOD_REGEN_DURING_COMBAT));
if (!IsStandState())
addvalue *= 1.5f;
}
}
// always regeneration bonus (including combat)

View File

@@ -1979,7 +1979,7 @@ void Player::UpdateCharmedAI()
if (!target || !IsValidAttackTarget(target))
{
target = SelectNearbyTarget(nullptr, 30);
target = SelectNearbyTarget(nullptr, GetMap()->IsDungeon() ? 100.f : 30.f);
if (!target)
{
if (!HasUnitState(UNIT_STATE_FOLLOW))

View File

@@ -2704,11 +2704,8 @@ void Spell::EffectDistract(SpellEffIndex /*effIndex*/)
if (unitTarget->HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING))
return;
unitTarget->SetFacingTo(unitTarget->GetAngle(destTarget));
unitTarget->ClearUnitState(UNIT_STATE_MOVING);
if (unitTarget->GetTypeId() == TYPEID_UNIT)
unitTarget->GetMotionMaster()->MoveDistract(damage * IN_MILLISECONDS);
unitTarget->SetFacingTo(unitTarget->GetAngle(destTarget)); /// @BUG Causes the player to stop moving + interrupts spellcast.
unitTarget->GetMotionMaster()->MoveDistract(damage * IN_MILLISECONDS);
}
void Spell::EffectPickPocket(SpellEffIndex /*effIndex*/)

View File

@@ -713,8 +713,7 @@ void SpellMgr::LoadSpellInfoCorrections()
ApplySpellFix({
5171, // Slice and Dice
6774, // Slice and Dice
1725 // Distract
6774 // Slice and Dice
}, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_TARGET_PROCS;

View File

@@ -27,6 +27,7 @@ npc_deathstalker_erland
pyrewood_ambush
EndContentData */
#include "PassiveAI.h"
#include "Player.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
@@ -325,12 +326,165 @@ public:
};
};
/*######
## AddSC
######*/
/**
*
* @todo: Actual emote and BroadcastTextId need to be sniffed. Probably the entire event to begin with....
* There is a possibility that the unused texts are chosen by random for specific parts of the speech. (making it look like they are preset, when in fact, they are not)
*
*/
enum ApparitionMisc
{
// Crowd
NPC_GNOLL_RUNNER = 1772,
NPC_GNOLL_MYSTIC = 1773,
EMOTE_CHEER = 71,
EMOTE_GNOLL_CHEER = 1,
// Apparition
SAY_APPA_INTRO = 0,
SAY_APPA_OUTRO = 14,
// Variation 1
SAY_APPA_OPTION_1_1 = 1,
SAY_APPA_OPTION_1_2 = 5,
SAY_APPA_OPTION_1_3 = 10,
SAY_APPA_OPTION_1_4 = 13,
// Variation 2
SAY_APPA_OPTION_2_1 = 2,
SAY_APPA_OPTION_2_2 = 5,
SAY_APPA_OPTION_2_3 = 9,
SAY_APPA_OPTION_2_4 = 12,
};
enum ApparitionEvents
{
EVENT_APPA_INTRO = 1,
EVENT_APPA_SAY_1 = 2,
EVENT_APPA_SAY_2 = 3,
EVENT_APPA_SAY_3 = 4,
EVENT_APPA_SAY_4 = 5,
EVENT_APPA_OUTRO = 6,
EVENT_APPA_OUTRO_CROWD = 7,
EVENT_APPA_OUTRO_END = 8,
};
class npc_ravenclaw_apparition : public CreatureScript
{
public:
npc_ravenclaw_apparition() : CreatureScript("npc_ravenclaw_apparition") { }
CreatureAI* GetAI(Creature* creature) const override
{
return new npc_ravenclaw_apparitionAI(creature);
}
struct npc_ravenclaw_apparitionAI : public NullCreatureAI
{
npc_ravenclaw_apparitionAI(Creature* creature) : NullCreatureAI(creature), summons(me)
{
HasEnded = false;
TalkRNG = urand(0,1);
events.ScheduleEvent(EVENT_APPA_INTRO, 2000);
summons.DespawnAll();
}
EventMap events;
SummonList summons;
bool HasEnded;
bool TalkRNG;
void SummonCrowd()
{
for (uint8 i = 0; i < urand(3, 5); ++i)
{
float o = i * 10;
me->SummonCreature(urand(NPC_GNOLL_RUNNER,NPC_GNOLL_MYSTIC), me->GetPositionX() + urand(3,5) * cos(o) , me->GetPositionY() + urand(3,5) * sin(o), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 35000);
}
}
void EmoteCrowd()
{
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
{
if (Creature* c = ObjectAccessor::GetCreature(*me, *itr))
{
if (urand(0,1))
{
c->HandleEmoteCommand(EMOTE_CHEER);
c->AI()->Talk(EMOTE_GNOLL_CHEER);
}
}
}
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
summon->SetUnitFlag(UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_PACIFIED);
summon->SetFacingToObject(me);
}
// Should never die, just in case.
void JustDied(Unit* /*killer*/) override
{
summons.DespawnAll();
events.Reset();
}
void UpdateAI(uint32 diff) override
{
if (HasEnded || !me->IsVisible())
return;
events.Update(diff);
switch (events.ExecuteEvent())
{
case EVENT_APPA_INTRO:
Talk(SAY_APPA_INTRO);
SummonCrowd();
events.ScheduleEvent(EVENT_APPA_SAY_1, 3000);
break;
case EVENT_APPA_SAY_1:
Talk(TalkRNG ? SAY_APPA_OPTION_1_1 : SAY_APPA_OPTION_2_1);
events.ScheduleEvent(EVENT_APPA_SAY_2, 5000);
break;
case EVENT_APPA_SAY_2:
Talk(TalkRNG ? SAY_APPA_OPTION_1_2 : SAY_APPA_OPTION_2_2);
events.ScheduleEvent(EVENT_APPA_SAY_3, 5000);
break;
case EVENT_APPA_SAY_3:
Talk(TalkRNG ? SAY_APPA_OPTION_1_3 : SAY_APPA_OPTION_2_3);
events.ScheduleEvent(EVENT_APPA_SAY_4, 5000);
break;
case EVENT_APPA_SAY_4:
Talk(TalkRNG ? SAY_APPA_OPTION_1_4 : SAY_APPA_OPTION_2_4);
events.ScheduleEvent(EVENT_APPA_OUTRO, 5000);
break;
case EVENT_APPA_OUTRO:
Talk(SAY_APPA_OUTRO);
events.ScheduleEvent(EVENT_APPA_OUTRO_CROWD, 3000);
break;
case EVENT_APPA_OUTRO_CROWD:
EmoteCrowd();
events.ScheduleEvent(EVENT_APPA_OUTRO_END, 5000);
break;
case EVENT_APPA_OUTRO_END: // Despawn for Apparition is handled via Areatrigger SAI (5m)
summons.DespawnAll();
me->SetVisible(false);
HasEnded = true;
events.Reset();
break;
}
}
};
};
void AddSC_silverpine_forest()
{
new npc_deathstalker_erland();
new pyrewood_ambush();
new npc_ravenclaw_apparition();
}

View File

@@ -276,14 +276,32 @@ public:
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
if (gateOpened)
if (Unit* target = SelectTarget(SelectTargetMethod::MinDistance, 0, 200.0f))
{
summons.DoZoneInCombat();
}
else if (Unit* target = me->SelectNearestTarget(50.0f))
{
AttackStart(target);
DoZoneInCombat();
if (gateOpened)
{
summon->AI()->AttackStart(target);
summon->CallForHelp(40.0f);
}
else
{
if (summon->GetEntry() == NPC_LIVING_TRAINEE ||
summon->GetEntry() == NPC_LIVING_KNIGHT ||
summon->GetEntry() == NPC_LIVING_RIDER )
{
if (IN_LIVE_SIDE(target))
{
summon->AI()->AttackStart(target);
}
}
else
{
if (!IN_LIVE_SIDE(target))
{
summon->AI()->AttackStart(target);
}
}
}
}
}
@@ -489,7 +507,6 @@ public:
me->RemoveUnitFlag(UNIT_FLAG_DISABLE_MOVE);
me->SetImmuneToPC(false);
me->RemoveAllAuras();
summons.DoZoneInCombat();
events.ScheduleEvent(EVENT_SHADOW_BOLT, 1s);
events.ScheduleEvent(EVENT_HARVEST_SOUL, 5s, 15s);
events.ScheduleEvent(EVENT_TELEPORT, 20s);
@@ -504,7 +521,6 @@ public:
{
go->SetGoState(GO_STATE_ACTIVE);
}
summons.DoZoneInCombat();
gateOpened = true;
Talk(EMOTE_GATE_OPENED);
}
@@ -571,20 +587,6 @@ public:
}
}
void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
if (!attacker || !IsOnSameSide(attacker))
{
damage = 0;
}
if (!me->IsInCombat())
{
me->CallForHelp(25.0f);
AttackStart(attacker);
}
}
void JustDied(Unit*) override
{
switch (me->GetEntry())
@@ -634,9 +636,9 @@ public:
case EVENT_SHADOW_MARK:
if (Unit* victim = me->GetVictim())
{
if (!victim->HasAura(SPELL_SHADOW_MARK))
if (victim->IsWithinDist(me, 10))
{
me->CastSpell(me->GetVictim(), SPELL_SHADOW_MARK, false);
me->CastSpell(victim, SPELL_SHADOW_MARK, false);
}
}
events.Repeat(5s, 7s);

View File

@@ -25,6 +25,7 @@ enum BlackheartTheInciter
SPELL_INCITE_CHAOS_B = 33684, //debuff applied to each member of party
SPELL_CHARGE = 33709,
SPELL_WAR_STOMP = 33707,
SPELL_LAUGHTER = 33722,
SAY_INTRO = 0,
SAY_AGGRO = 1,
@@ -35,130 +36,118 @@ enum BlackheartTheInciter
EVENT_SPELL_INCITE = 1,
EVENT_INCITE_WAIT = 2,
EVENT_SPELL_CHARGE = 3,
EVENT_SPELL_WAR_STOMP = 4
EVENT_SPELL_KNOCKBACK = 4,
EVENT_SPELL_WAR_STOMP = 5,
NPC_INCITE_TRIGGER = 19300
};
class boss_blackheart_the_inciter : public CreatureScript
struct boss_blackheart_the_inciter : public BossAI
{
public:
boss_blackheart_the_inciter() : CreatureScript("boss_blackheart_the_inciter") { }
boss_blackheart_the_inciter(Creature* creature) : BossAI(creature, DATA_BLACKHEARTTHEINCITEREVENT) { }
CreatureAI* GetAI(Creature* creature) const override
bool InciteChaos;
void Reset() override
{
return GetShadowLabyrinthAI<boss_blackheart_the_inciterAI>(creature);
_Reset();
me->SetImmuneToPC(false);
InciteChaos = false;
}
struct boss_blackheart_the_inciterAI : public ScriptedAI
void KilledUnit(Unit* victim) override
{
boss_blackheart_the_inciterAI(Creature* creature) : ScriptedAI(creature)
if (victim->IsPlayer() && urand(0, 1))
{
instance = creature->GetInstanceScript();
Talk(SAY_SLAY);
}
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
_JustDied();
}
void JustEngagedWith(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
me->CallForHelp(100.0f);
events.ScheduleEvent(EVENT_SPELL_INCITE, 24000);
events.ScheduleEvent(EVENT_INCITE_WAIT, 15000);
events.ScheduleEvent(EVENT_SPELL_CHARGE, urand(30000, 50000));
events.ScheduleEvent(EVENT_SPELL_WAR_STOMP, urand(16950, 26350));
_JustEngagedWith();
}
void EnterEvadeMode(EvadeReason why) override
{
if (InciteChaos && SelectTargetFromPlayerList(100.0f))
return;
CreatureAI::EnterEvadeMode(why);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim() && !InciteChaos)
{
return;
}
InstanceScript* instance;
EventMap events;
bool InciteChaos;
void Reset() override
events.Update(diff);
switch (events.ExecuteEvent())
{
case EVENT_INCITE_WAIT:
me->SetImmuneToPC(false);
InciteChaos = false;
events.Reset();
if (instance)
{
instance->SetData(DATA_BLACKHEARTTHEINCITEREVENT, NOT_STARTED);
}
}
void KilledUnit(Unit* victim) override
break;
case EVENT_SPELL_INCITE:
{
if (victim->GetTypeId() == TYPEID_PLAYER && urand(0, 1))
DoCastAOE(SPELL_INCITE_CHAOS);
DoCastSelf(SPELL_LAUGHTER, true);
uint32 inciteTriggerID = NPC_INCITE_TRIGGER;
std::list<HostileReference*> t_list = me->GetThreatMgr().GetThreatList();
for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr != t_list.end(); ++itr)
{
Talk(SAY_SLAY);
}
}
Unit* target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid());
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
if (instance)
{
instance->SetData(DATA_BLACKHEARTTHEINCITEREVENT, DONE);
}
}
void JustEngagedWith(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
me->CallForHelp(100.0f);
events.ScheduleEvent(EVENT_SPELL_INCITE, 24000);
events.ScheduleEvent(EVENT_INCITE_WAIT, 15000);
events.ScheduleEvent(EVENT_SPELL_CHARGE, urand(30000, 50000));
events.ScheduleEvent(EVENT_SPELL_WAR_STOMP, urand(16950, 26350));
if (instance)
{
instance->SetData(DATA_BLACKHEARTTHEINCITEREVENT, IN_PROGRESS);
}
}
void EnterEvadeMode(EvadeReason why) override
{
if (InciteChaos && SelectTargetFromPlayerList(100.0f))
return;
CreatureAI::EnterEvadeMode(why);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
switch (events.ExecuteEvent())
{
case EVENT_INCITE_WAIT:
InciteChaos = false;
break;
case EVENT_SPELL_INCITE:
if (target && target->IsPlayer())
{
if (Creature* inciteTrigger = me->SummonCreature(inciteTriggerID++, *target, TEMPSUMMON_TIMED_DESPAWN, 15 * IN_MILLISECONDS))
{
DoCastAOE(SPELL_INCITE_CHAOS);
std::list<HostileReference*> t_list = me->GetThreatMgr().GetThreatList();
for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr != t_list.end(); ++itr)
{
Unit* target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid());
if (target && target->GetTypeId() == TYPEID_PLAYER)
{
me->CastSpell(target, SPELL_INCITE_CHAOS_B, true);
}
}
DoResetThreatList();
InciteChaos = true;
events.DelayEvents(15000);
events.RepeatEvent(urand(50000, 70000));
events.ScheduleEvent(EVENT_INCITE_WAIT, 15000);
break;
inciteTrigger->CastSpell(target, SPELL_INCITE_CHAOS_B, true);
}
case EVENT_SPELL_CHARGE:
DoCastRandomTarget(SPELL_CHARGE);
events.RepeatEvent(urand(30000, 50000));
break;
case EVENT_SPELL_WAR_STOMP:
DoCastAOE(SPELL_WAR_STOMP);
events.RepeatEvent(urand(16950, 26350));
break;
}
}
if (InciteChaos)
return;
DoMeleeAttackIfReady();
DoResetThreatList();
me->SetImmuneToPC(true);
InciteChaos = true;
events.DelayEvents(15000);
events.RepeatEvent(urand(50000, 70000));
events.ScheduleEvent(EVENT_INCITE_WAIT, 15000);
break;
}
};
case EVENT_SPELL_CHARGE:
DoCastRandomTarget(SPELL_CHARGE);
events.RepeatEvent(urand(30000, 50000));
break;
case EVENT_SPELL_WAR_STOMP:
DoCastAOE(SPELL_WAR_STOMP);
events.RepeatEvent(urand(16950, 26350));
break;
}
if (InciteChaos)
return;
DoMeleeAttackIfReady();
}
};
void AddSC_boss_blackheart_the_inciter()
{
new boss_blackheart_the_inciter();
RegisterShadowLabyrinthCreatureAI(boss_blackheart_the_inciter);
}