Merge branch 'master' into Playerbot

This commit is contained in:
Yunfan Li
2023-06-09 23:40:54 +08:00
18 changed files with 937 additions and 929 deletions

View File

@@ -27,7 +27,7 @@ for i in `find data/sql/updates/pending* -name "*sql" -type f`; do
echo "> broadcast_text check - Failed"
echo " - DON'T EDIT broadcast_text TABLE UNLESS YOU KNOW WHAT YOU ARE DOING!"
echo " - This error can safely be ignored if the changes are approved to be sniffed."
# exit 1
exit 1
else
echo "> broadcast_text check - OK"
fi

View File

@@ -0,0 +1,12 @@
-- DB update 2023_06_07_04 -> 2023_06_08_00
--
DELETE FROM `spelldifficulty_dbc` WHERE `ID` IN (8374,15039,33534,12548,33620,15659,38795);
INSERT INTO `spelldifficulty_dbc` (`ID`, `DifficultySpellID_1`, `DifficultySpellID_2`) VALUES
(8374, 8374, 38761),
(15039, 15039, 15616),
(33534, 33534, 38135),
(12548, 12548, 21401),
(33620, 33620, 38137),
(15659, 15659, 15305),
(38795, 38795, 33666);

View File

@@ -0,0 +1,12 @@
-- DB update 2023_06_08_00 -> 2023_06_09_00
--
DELETE FROM `creature_template_movement` WHERE (`CreatureId` IN (18176,18177,18178,18179,19897,19898,19899,19900));
INSERT INTO `creature_template_movement` (`CreatureId`, `Flight`, `Rooted`) VALUES
(18176, 1, 1),
(18177, 1, 1),
(18178, 1, 1),
(18179, 1, 1),
(19897, 1, 1),
(19898, 1, 1),
(19899, 1, 1),
(19900, 1, 1);

View File

@@ -1297,18 +1297,6 @@ AllowTickets = 1
DeletedCharacterTicketTrace = 0
#
# DungeonFinder.OptionsMask
# Description: Dungeon and raid finder system.
# Value is a bitmask consisting of:
# LFG_OPTION_ENABLE_DUNGEON_FINDER = 1, Enable the dungeon finder browser
# LFG_OPTION_ENABLE_RAID_BROWSER = 2, Enable the raid browser
# LFG_OPTION_ENABLE_SEASONAL_BOSSES = 4, Enable seasonal bosses
# Default: 5
DungeonFinder.OptionsMask = 5
#
# DBC.EnforceItemAttributes
# Disallow overriding item attributes stored in DBC files with values from the database
@@ -3682,6 +3670,17 @@ Calculate.Gameoject.Zone.Area.Data = 0
Group.Raid.LevelRestriction = 10
#
# DungeonFinder.OptionsMask
# Description: Dungeon and raid finder system.
# Value is a bitmask consisting of:
# LFG_OPTION_ENABLE_DUNGEON_FINDER = 1, Enable the dungeon finder browser
# LFG_OPTION_ENABLE_RAID_BROWSER = 2, Enable the raid browser
# LFG_OPTION_ENABLE_SEASONAL_BOSSES = 4, Enable seasonal bosses
# Default: 5
DungeonFinder.OptionsMask = 5
#
# LFG.Location.All
#

View File

@@ -5043,11 +5043,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
if (caster && target->CanHaveThreatList())
target->AddThreat(caster, 10.0f);
break;
case 13139: // net-o-matic
// root to self part of (root_target->charge->root_self sequence
if (caster)
caster->CastSpell(caster, 13138, true, nullptr, this);
break;
case 34026: // kill command
{
Unit* pet = target->GetGuardianPet();

View File

@@ -126,17 +126,19 @@ public:
{
boss_dorotheeAI(Creature* creature) : ScriptedAI(creature)
{
SetCombatMovement(false);
//this is kinda a big no-no. but it will prevent her from moving to chase targets. she should just cast her spells. in this case, since there is not really something to LOS her with or get out of range this would work. but a more elegant solution would be better
Initialize();
instance = creature->GetInstanceScript();
}
void Initialize()
{
AggroTimer = 500;
AggroTimer = 12000;
WaterBoltTimer = 5000;
WaterBoltTimer = 0;
FearTimer = 15000;
SummonTitoTimer = 47500;
SummonTitoTimer = 41000;
SummonedTito = false;
TitoDied = false;
@@ -152,6 +154,7 @@ public:
bool SummonedTito;
bool TitoDied;
bool IntroDone = false;
void Reset() override
{
@@ -160,8 +163,7 @@ public:
void JustEngagedWith(Unit* /*who*/) override
{
Talk(SAY_DOROTHEE_AGGRO);
DoZoneInCombat();
me->SetInCombatWithZone();
}
void JustReachedHome() override
@@ -175,6 +177,7 @@ public:
{
Talk(SAY_DOROTHEE_DEATH);
SummonCroneIfReady(instance, me);
me->DespawnOrUnsummon();
}
void AttackStart(Unit* who) override
@@ -186,7 +189,6 @@ public:
}
void MoveInLineOfSight(Unit* who) override
{
if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
return;
@@ -194,14 +196,35 @@ public:
ScriptedAI::MoveInLineOfSight(who);
}
void EnterEvadeMode(EvadeReason reason) override
{
ScriptedAI::EnterEvadeMode(reason);
if(!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
{
instance->SetBossState(DATA_OPERA_PERFORMANCE, FAIL);
me->DespawnOrUnsummon();
}
}
void UpdateAI(uint32 diff) override
{
if(!IntroDone)
{
if(!me->IsInEvadeMode())
{
Talk(SAY_DOROTHEE_AGGRO);
IntroDone = true;
}
}
if (AggroTimer)
{
if (AggroTimer <= diff)
{
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetImmuneToPC(false);
me->SetInCombatWithZone();
AggroTimer = 0;
}
else
@@ -214,7 +237,7 @@ public:
if (WaterBoltTimer <= diff)
{
DoCast(SelectTarget(SelectTargetMethod::Random, 0), SPELL_WATERBOLT);
WaterBoltTimer = TitoDied ? 1500 : 5000;
WaterBoltTimer = 1500;
}
else
WaterBoltTimer -= diff;
@@ -279,6 +302,7 @@ public:
Talk(SAY_DOROTHEE_TITO_DEATH, Dorothee);
}
}
me->DespawnOrUnsummon();
}
void UpdateAI(uint32 diff) override
@@ -311,6 +335,136 @@ void boss_dorothee::boss_dorotheeAI::SummonTito()
}
}
class boss_roar : public CreatureScript
{
public:
boss_roar() : CreatureScript("boss_roar") { }
CreatureAI* GetAI(Creature* creature) const override
{
return GetKarazhanAI<boss_roarAI>(creature);
}
struct boss_roarAI : public ScriptedAI
{
boss_roarAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
}
InstanceScript* instance;
uint32 AggroTimer;
uint32 MangleTimer;
uint32 ShredTimer;
uint32 ScreamTimer;
void Reset() override
{
AggroTimer = 16670;
MangleTimer = 5000;
ShredTimer = 10000;
ScreamTimer = 15000;
}
void MoveInLineOfSight(Unit* who) override
{
if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
return;
ScriptedAI::MoveInLineOfSight(who);
}
void EnterEvadeMode(EvadeReason reason) override
{
ScriptedAI::EnterEvadeMode(reason);
if(!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
{
instance->SetBossState(DATA_OPERA_PERFORMANCE, FAIL);
me->DespawnOrUnsummon();
}
}
void AttackStart(Unit* who) override
{
if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
return;
ScriptedAI::AttackStart(who);
}
void JustEngagedWith(Unit* /*who*/) override
{
Talk(SAY_ROAR_AGGRO);
DoZoneInCombat();
}
void JustReachedHome() override
{
me->DespawnOrUnsummon();
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_ROAR_DEATH);
SummonCroneIfReady(instance, me);
me->DespawnOrUnsummon();
}
void KilledUnit(Unit* /*victim*/) override
{
Talk(SAY_ROAR_SLAY);
}
void UpdateAI(uint32 diff) override
{
if (AggroTimer)
{
if (AggroTimer <= diff)
{
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetImmuneToPC(false);
me->SetInCombatWithZone();
AggroTimer = 0;
}
else
AggroTimer -= diff;
}
if (!UpdateVictim())
return;
if (MangleTimer <= diff)
{
DoCastVictim(SPELL_MANGLE);
MangleTimer = urand(5000, 8000);
}
else
MangleTimer -= diff;
if (ShredTimer <= diff)
{
DoCastVictim(SPELL_SHRED);
ShredTimer = urand(10000, 15000);
}
else
ShredTimer -= diff;
if (ScreamTimer <= diff)
{
DoCastVictim(SPELL_FRIGHTENED_SCREAM);
ScreamTimer = urand(20000, 30000);
}
else
ScreamTimer -= diff;
DoMeleeAttackIfReady();
}
};
};
class boss_strawman : public CreatureScript
{
public:
@@ -336,7 +490,7 @@ public:
void Reset() override
{
AggroTimer = 11000;
AggroTimer = 26300;
BrainBashTimer = 5000;
BrainWipeTimer = 7000;
}
@@ -350,7 +504,6 @@ public:
}
void MoveInLineOfSight(Unit* who) override
{
if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
return;
@@ -358,6 +511,16 @@ public:
ScriptedAI::MoveInLineOfSight(who);
}
void EnterEvadeMode(EvadeReason reason) override
{
ScriptedAI::EnterEvadeMode(reason);
if(!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
{
instance->SetBossState(DATA_OPERA_PERFORMANCE, FAIL);
me->DespawnOrUnsummon();
}
}
void JustEngagedWith(Unit* /*who*/) override
{
Talk(SAY_STRAWMAN_AGGRO);
@@ -385,8 +548,8 @@ public:
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_STRAWMAN_DEATH);
SummonCroneIfReady(instance, me);
me->DespawnOrUnsummon();
}
void KilledUnit(Unit* /*victim*/) override
@@ -402,6 +565,7 @@ public:
{
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetImmuneToPC(false);
me->SetInCombatWithZone();
AggroTimer = 0;
}
else
@@ -460,7 +624,7 @@ public:
void Reset() override
{
AggroTimer = 15000;
AggroTimer = 34470;
CleaveTimer = 5000;
RustTimer = 15000;
@@ -487,7 +651,6 @@ public:
}
void MoveInLineOfSight(Unit* who) override
{
if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
return;
@@ -495,11 +658,22 @@ public:
ScriptedAI::MoveInLineOfSight(who);
}
void EnterEvadeMode(EvadeReason reason) override
{
ScriptedAI::EnterEvadeMode(reason);
if(!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
{
instance->SetBossState(DATA_OPERA_PERFORMANCE, FAIL);
me->DespawnOrUnsummon();
}
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_TINHEAD_DEATH);
SummonCroneIfReady(instance, me);
me->DespawnOrUnsummon();
}
void KilledUnit(Unit* /*victim*/) override
@@ -515,6 +689,7 @@ public:
{
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetImmuneToPC(false);
me->SetInCombatWithZone();
AggroTimer = 0;
}
else
@@ -550,124 +725,6 @@ public:
};
};
class boss_roar : public CreatureScript
{
public:
boss_roar() : CreatureScript("boss_roar") { }
CreatureAI* GetAI(Creature* creature) const override
{
return GetKarazhanAI<boss_roarAI>(creature);
}
struct boss_roarAI : public ScriptedAI
{
boss_roarAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
}
InstanceScript* instance;
uint32 AggroTimer;
uint32 MangleTimer;
uint32 ShredTimer;
uint32 ScreamTimer;
void Reset() override
{
AggroTimer = 20000;
MangleTimer = 5000;
ShredTimer = 10000;
ScreamTimer = 15000;
}
void MoveInLineOfSight(Unit* who) override
{
if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
return;
ScriptedAI::MoveInLineOfSight(who);
}
void AttackStart(Unit* who) override
{
if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
return;
ScriptedAI::AttackStart(who);
}
void JustEngagedWith(Unit* /*who*/) override
{
Talk(SAY_ROAR_AGGRO);
DoZoneInCombat();
}
void JustReachedHome() override
{
me->DespawnOrUnsummon();
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_ROAR_DEATH);
SummonCroneIfReady(instance, me);
}
void KilledUnit(Unit* /*victim*/) override
{
Talk(SAY_ROAR_SLAY);
}
void UpdateAI(uint32 diff) override
{
if (AggroTimer)
{
if (AggroTimer <= diff)
{
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetImmuneToPC(false);
AggroTimer = 0;
}
else
AggroTimer -= diff;
}
if (!UpdateVictim())
return;
if (MangleTimer <= diff)
{
DoCastVictim(SPELL_MANGLE);
MangleTimer = urand(5000, 8000);
}
else
MangleTimer -= diff;
if (ShredTimer <= diff)
{
DoCastVictim(SPELL_SHRED);
ShredTimer = urand(10000, 15000);
}
else
ShredTimer -= diff;
if (ScreamTimer <= diff)
{
DoCastVictim(SPELL_FRIGHTENED_SCREAM);
ScreamTimer = urand(20000, 30000);
}
else
ScreamTimer -= diff;
DoMeleeAttackIfReady();
}
};
};
class boss_crone : public CreatureScript
{
public:

View File

@@ -38,4 +38,6 @@ inline AI* GetAuchenaiCryptsAI(T* obj)
return GetInstanceAI<AI>(obj, ACScriptName);
}
#define RegisterAuchenaiCryptsCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetAuchenaiCryptsAI)
#endif // AUCHENAI_CRYPTS_H_

View File

@@ -19,142 +19,26 @@
#include "ScriptedCreature.h"
#include "auchenai_crypts.h"
enum ExarchMaladaar
enum Text
{
SAY_INTRO = 0,
SAY_SUMMON = 1,
SAY_AGGRO = 2,
SAY_ROAR = 3,
SAY_SLAY = 4,
SAY_DEATH = 5,
SAY_DEATH = 5
};
enum Spells
{
// Exarch Maladaar
SPELL_RIBBON_OF_SOULS = 32422,
SPELL_SOUL_SCREAM = 32421,
SPELL_STOLEN_SOUL = 32346,
SPELL_STOLEN_SOUL_VISUAL = 32395,
SPELL_SUMMON_AVATAR = 32424,
ENTRY_STOLEN_SOUL = 18441,
EVENT_SPELL_FEAR = 1,
EVENT_SPELL_RIBBON = 2,
EVENT_SPELL_SOUL = 3,
EVENT_CHECK_HEALTH = 4
};
class boss_exarch_maladaar : public CreatureScript
{
public:
boss_exarch_maladaar() : CreatureScript("boss_exarch_maladaar") { }
CreatureAI* GetAI(Creature* creature) const override
{
return GetAuchenaiCryptsAI<boss_exarch_maladaarAI>(creature);
}
struct boss_exarch_maladaarAI : public ScriptedAI
{
boss_exarch_maladaarAI(Creature* creature) : ScriptedAI(creature)
{
_talked = false;
}
bool _talked;
EventMap events;
void Reset() override
{
events.Reset();
}
void MoveInLineOfSight(Unit* who) override
{
if (!_talked && who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 150.0f))
{
Talk(SAY_INTRO);
_talked = true;
}
ScriptedAI::MoveInLineOfSight(who);
}
void JustEngagedWith(Unit*) override
{
Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_SPELL_FEAR, 15000);
events.ScheduleEvent(EVENT_SPELL_RIBBON, 5000);
events.ScheduleEvent(EVENT_SPELL_SOUL, 25000);
events.ScheduleEvent(EVENT_CHECK_HEALTH, 5000);
}
void KilledUnit(Unit*) override
{
if (urand(0, 1))
Talk(SAY_SLAY);
}
void JustDied(Unit*) override
{
Talk(SAY_DEATH);
//When Exarch Maladar is defeated D'ore appear.
me->SummonCreature(19412, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 600000);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_CHECK_HEALTH:
if (HealthBelowPct(25))
{
Talk(SAY_SUMMON);
me->CastSpell(me, SPELL_SUMMON_AVATAR, false);
return;
}
events.RepeatEvent(2000);
break;
case EVENT_SPELL_SOUL:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
{
Talk(SAY_ROAR);
me->CastSpell(target, SPELL_STOLEN_SOUL, false);
if (Creature* summon = me->SummonCreature(ENTRY_STOLEN_SOUL, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000))
{
summon->CastSpell(summon, SPELL_STOLEN_SOUL_VISUAL, false);
summon->SetDisplayId(target->GetDisplayId());
summon->AI()->DoAction(target->getClass());
summon->AI()->AttackStart(target);
}
}
events.RepeatEvent(urand(25000, 30000));
break;
case EVENT_SPELL_RIBBON:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
me->CastSpell(target, SPELL_RIBBON_OF_SOULS, false);
events.RepeatEvent(urand(10000, 20000));
break;
case EVENT_SPELL_FEAR:
me->CastSpell(me, SPELL_SOUL_SCREAM, false);
events.RepeatEvent(urand(15000, 25000));
break;
}
DoMeleeAttackIfReady();
}
};
};
enum stolenSoul
{
// Stolen Soul
SPELL_MOONFIRE = 37328,
SPELL_FIREBALL = 37329,
SPELL_MIND_FLAY = 37330,
@@ -164,99 +48,211 @@ enum stolenSoul
SPELL_MORTAL_STRIKE = 37335,
SPELL_FREEZING_TRAP = 37368,
SPELL_HAMMER_OF_JUSTICE = 37369,
SPELL_PLAGUE_STRIKE = 58839,
EVENT_STOLEN_SOUL_SPELL = 1,
SPELL_PLAGUE_STRIKE = 58839
};
class npc_stolen_soul : public CreatureScript
enum Npc
{
public:
npc_stolen_soul() : CreatureScript("npc_stolen_soul") { }
ENTRY_STOLEN_SOUL = 18441
};
CreatureAI* GetAI(Creature* creature) const override
struct boss_exarch_maladaar : public BossAI
{
boss_exarch_maladaar(Creature* creature) : BossAI(creature, DATA_EXARCH_MALADAAR)
{
return GetAuchenaiCryptsAI<npc_stolen_soulAI>(creature);
_talked = false;
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
struct npc_stolen_soulAI : public ScriptedAI
bool _talked;
void Reset() override
{
npc_stolen_soulAI(Creature* creature) : ScriptedAI(creature) {}
_Reset();
ScheduleHealthCheckEvent(25, [&] {
Talk(SAY_SUMMON);
DoCastSelf(SPELL_SUMMON_AVATAR);
});
}
uint8 myClass;
EventMap events;
void Reset() override
void MoveInLineOfSight(Unit* who) override
{
if (!_talked && who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 150.0f))
{
myClass = CLASS_WARRIOR;
events.ScheduleEvent(EVENT_STOLEN_SOUL_SPELL, 1000);
_talked = true;
Talk(SAY_INTRO);
}
ScriptedAI::MoveInLineOfSight(who);
}
void DoAction(int32 pClass) override
void JustEngagedWith(Unit*) override
{
_JustEngagedWith();
Talk(SAY_AGGRO);
scheduler.Schedule(15s, [this] (TaskContext context)
{
myClass = pClass;
}
void UpdateAI(uint32 diff) override
DoCastSelf(SPELL_SOUL_SCREAM);
context.Repeat(15s, 25s);
}).Schedule(5s, [this](TaskContext context)
{
if (!UpdateVictim())
return;
events.Update(diff);
if (events.ExecuteEvent() == EVENT_STOLEN_SOUL_SPELL)
DoCastRandomTarget(SPELL_RIBBON_OF_SOULS);
context.Repeat(10s, 20s);
}).Schedule(25s, [this](TaskContext context)
{
if (Unit * target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
{
switch (myClass)
Talk(SAY_ROAR);
DoCast(target, SPELL_STOLEN_SOUL);
if (Creature* summon = me->SummonCreature(ENTRY_STOLEN_SOUL, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000))
{
case CLASS_WARRIOR:
me->CastSpell(me->GetVictim(), SPELL_MORTAL_STRIKE, false);
events.RepeatEvent(6000);
break;
case CLASS_PALADIN:
me->CastSpell(me->GetVictim(), SPELL_HAMMER_OF_JUSTICE, false);
events.RepeatEvent(6000);
break;
case CLASS_HUNTER:
me->CastSpell(me->GetVictim(), SPELL_FREEZING_TRAP, false);
events.RepeatEvent(20000);
break;
case CLASS_ROGUE:
me->CastSpell(me->GetVictim(), SPELL_HEMORRHAGE, false);
events.RepeatEvent(10000);
break;
case CLASS_PRIEST:
me->CastSpell(me->GetVictim(), SPELL_MIND_FLAY, false);
events.RepeatEvent(5000);
break;
case CLASS_SHAMAN:
me->CastSpell(me->GetVictim(), SPELL_FROSTSHOCK, false);
events.RepeatEvent(8000);
break;
case CLASS_MAGE:
me->CastSpell(me->GetVictim(), SPELL_FIREBALL, false);
events.RepeatEvent(5000);
break;
case CLASS_WARLOCK:
me->CastSpell(me->GetVictim(), SPELL_CURSE_OF_AGONY, false);
events.RepeatEvent(20000);
break;
case CLASS_DRUID:
me->CastSpell(me->GetVictim(), SPELL_MOONFIRE, false);
events.RepeatEvent(10000);
break;
case CLASS_DEATH_KNIGHT:
me->CastSpell(me->GetVictim(), SPELL_PLAGUE_STRIKE, false);
events.RepeatEvent(6000);
break;
summon->CastSpell(summon, SPELL_STOLEN_SOUL_VISUAL, false);
summon->SetDisplayId(target->GetDisplayId());
summon->AI()->DoAction(target->getClass());
summon->AI()->AttackStart(target);
}
}
context.Repeat(25s, 30s);
});
}
DoMeleeAttackIfReady();
void KilledUnit(Unit* victim) override
{
if (victim->IsPlayer() && urand(0, 1))
{
Talk(SAY_SLAY);
}
};
}
void JustDied(Unit*) override
{
Talk(SAY_DEATH);
me->SummonCreature(19412, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 600000);
_JustDied();
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
scheduler.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
DoMeleeAttackIfReady();
}
};
struct npc_stolen_soul : public ScriptedAI
{
npc_stolen_soul(Creature* creature) : ScriptedAI(creature) {}
uint8 myClass;
void Reset() override
{
myClass = CLASS_WARRIOR;
_scheduler.Schedule(1s, [this] (TaskContext /*context*/)
{
switch (myClass)
{
case CLASS_WARRIOR:
_scheduler.Schedule(0ms, [this](TaskContext context)
{
DoCastVictim(SPELL_MORTAL_STRIKE);
context.Repeat(6s);
});
break;
case CLASS_PALADIN:
_scheduler.Schedule(0ms, [this](TaskContext context)
{
DoCastVictim(SPELL_HAMMER_OF_JUSTICE);
context.Repeat(6s);
});
break;
case CLASS_HUNTER:
_scheduler.Schedule(0ms, [this](TaskContext context)
{
DoCastVictim(SPELL_FREEZING_TRAP);
context.Repeat(20s);
});
break;
case CLASS_ROGUE:
_scheduler.Schedule(0ms, [this](TaskContext context)
{
DoCastVictim(SPELL_HEMORRHAGE);
context.Repeat(10s);
});
break;
case CLASS_PRIEST:
_scheduler.Schedule(0ms, [this](TaskContext context)
{
DoCastVictim(SPELL_MIND_FLAY);
context.Repeat(5s);
});
break;
case CLASS_SHAMAN:
_scheduler.Schedule(0ms, [this](TaskContext context)
{
DoCastVictim(SPELL_FROSTSHOCK);
context.Repeat(8s);
});
break;
case CLASS_MAGE:
_scheduler.Schedule(0ms, [this](TaskContext context)
{
DoCastVictim(SPELL_FIREBALL);
context.Repeat(5s);
});
break;
case CLASS_WARLOCK:
_scheduler.Schedule(0ms, [this](TaskContext context)
{
DoCastVictim(SPELL_CURSE_OF_AGONY);
context.Repeat(20s);
});
break;
case CLASS_DRUID:
_scheduler.Schedule(0ms, [this](TaskContext context)
{
DoCastVictim(SPELL_MOONFIRE);
context.Repeat(10s);
});
break;
case CLASS_DEATH_KNIGHT:
_scheduler.Schedule(0ms, [this](TaskContext context)
{
DoCastVictim(SPELL_PLAGUE_STRIKE);
context.Repeat(6s);
});
break;
}
});
}
void DoAction(int32 pClass) override
{
myClass = pClass;
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
private:
TaskScheduler _scheduler;
};
void AddSC_boss_exarch_maladaar()
{
new boss_exarch_maladaar();
new npc_stolen_soul();
RegisterAuchenaiCryptsCreatureAI(boss_exarch_maladaar);
RegisterAuchenaiCryptsCreatureAI(npc_stolen_soul);
}

View File

@@ -22,220 +22,222 @@
#include "SpellScript.h"
#include "auchenai_crypts.h"
enum eShirrak
enum Spells
{
SPELL_INHIBIT_MAGIC = 32264,
SPELL_ATTRACT_MAGIC = 32265,
SPELL_CARNIVOROUS_BITE_N = 36383,
SPELL_CARNIVOROUS_BITE_H = 39382,
SPELL_INHIBIT_MAGIC = 32264,
SPELL_ATTRACT_MAGIC = 32265,
SPELL_CARNIVOROUS_BITE = 36383,
SPELL_FIERY_BLAST = 32302,
SPELL_FOCUS_FIRE_VISUAL = 32286,
SPELL_FOCUS_CAST = 32300,
SPELL_FIERY_BLAST_N = 32302,
SPELL_FIERY_BLAST_H = 38382,
SPELL_FOCUS_FIRE_VISUAL = 32286,
SPELL_FOCUS_CAST = 32300,
EVENT_SPELL_INHIBIT_MAGIC = 1,
EVENT_SPELL_ATTRACT_MAGIC = 2,
EVENT_SPELL_CARNIVOROUS = 3,
EVENT_SPELL_FOCUS_FIRE = 4,
EVENT_SPELL_FOCUS_FIRE_2 = 5,
EVENT_SPELL_FOCUS_FIRE_3 = 6,
ENTRY_FOCUS_FIRE = 18374,
EMOTE_FOCUSED = 0
SPELL_POSSESS_INSTANT = 32830,
SPELL_POSSESS_CHANNELED = 33401
};
class boss_shirrak_the_dead_watcher : public CreatureScript
enum Misc
{
public:
boss_shirrak_the_dead_watcher() : CreatureScript("boss_shirrak_the_dead_watcher") { }
ENTRY_FOCUS_FIRE = 18374,
EMOTE_FOCUSED = 0
};
CreatureAI* GetAI(Creature* creature) const override
struct boss_shirrak_the_dead_watcher : public BossAI
{
boss_shirrak_the_dead_watcher(Creature* creature) : BossAI(creature, DATA_SHIRRAK_THE_DEAD_WATCHER)
{
return GetAuchenaiCryptsAI<boss_shirrak_the_dead_watcherAI>(creature);
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
struct boss_shirrak_the_dead_watcherAI : public ScriptedAI
ObjectGuid focusGUID;
void EnterEvadeMode(EvadeReason why) override
{
boss_shirrak_the_dead_watcherAI(Creature* creature) : ScriptedAI(creature)
me->SetControlled(false, UNIT_STATE_ROOT);
CreatureAI::EnterEvadeMode(why);
}
void Reset() override
{
_Reset();
focusGUID.Clear();
me->SetControlled(false, UNIT_STATE_ROOT);
}
void JustEngagedWith(Unit*) override
{
_JustEngagedWith();
scheduler.Schedule(1ms, [this] (TaskContext context)
{
}
EventMap events;
ObjectGuid focusGUID;
void EnterEvadeMode(EvadeReason why) override
{
me->SetControlled(false, UNIT_STATE_ROOT);
ScriptedAI::EnterEvadeMode(why);
}
void Reset() override
{
events.Reset();
focusGUID.Clear();
me->SetControlled(false, UNIT_STATE_ROOT);
}
void JustEngagedWith(Unit*) override
{
events.ScheduleEvent(EVENT_SPELL_INHIBIT_MAGIC, 0);
events.ScheduleEvent(EVENT_SPELL_ATTRACT_MAGIC, 28000);
events.ScheduleEvent(EVENT_SPELL_CARNIVOROUS, 10000);
events.ScheduleEvent(EVENT_SPELL_FOCUS_FIRE, 17000);
}
void JustSummoned(Creature* summon) override
{
summon->CastSpell(summon, SPELL_FOCUS_FIRE_VISUAL, true);
}
void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_FOCUS_CAST)
target->CastSpell(target, DUNGEON_MODE(SPELL_FIERY_BLAST_N, SPELL_FIERY_BLAST_H), false);
}
uint8 getStackCount(float dist)
{
if (dist < 15)
return 4;
if (dist < 25)
return 3;
if (dist < 35)
return 2;
return 1;
}
void UpdateAI(uint32 diff) override
{
events.Update(diff);
uint32 eventId = events.ExecuteEvent();
if (eventId == EVENT_SPELL_INHIBIT_MAGIC)
Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers();
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
{
Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers();
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
if (Player* player = i->GetSource())
if (Player* player = i->GetSource())
{
float dist = me->GetDistance(player);
if (player->IsAlive() && dist < 45.0f)
{
float dist = me->GetDistance(player);
if (player->IsAlive() && dist < 45.0f)
Aura* aura = player->GetAura(SPELL_INHIBIT_MAGIC);
if (!aura)
{
Aura* aura = player->GetAura(SPELL_INHIBIT_MAGIC);
if (!aura)
aura = me->AddAura(SPELL_INHIBIT_MAGIC, player);
else
aura->RefreshDuration();
if (aura)
aura->SetStackAmount(getStackCount(dist));
aura = me->AddAura(SPELL_INHIBIT_MAGIC, player);
}
else
player->RemoveAurasDueToSpell(SPELL_INHIBIT_MAGIC);
{
aura->RefreshDuration();
}
if (aura)
{
aura->SetStackAmount(getStackCount(dist));
}
}
events.RepeatEvent(3000);
return;
}
if (!UpdateVictim())
return;
switch (eventId)
{
case EVENT_SPELL_ATTRACT_MAGIC:
me->CastSpell(me, SPELL_ATTRACT_MAGIC, false);
events.RepeatEvent(30000);
events.RescheduleEvent(EVENT_SPELL_CARNIVOROUS, 1500);
break;
case EVENT_SPELL_CARNIVOROUS:
me->CastSpell(me, DUNGEON_MODE(SPELL_CARNIVOROUS_BITE_N, SPELL_CARNIVOROUS_BITE_H), false);
events.RepeatEvent(10000);
break;
case EVENT_SPELL_FOCUS_FIRE:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 60.0f, true))
else
{
if (Creature* cr = me->SummonCreature(ENTRY_FOCUS_FIRE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 7000))
focusGUID = cr->GetGUID();
Talk(EMOTE_FOCUSED, target);
player->RemoveAurasDueToSpell(SPELL_INHIBIT_MAGIC);
}
events.RepeatEvent(urand(15000, 20000));
events.ScheduleEvent(EVENT_SPELL_FOCUS_FIRE_2, 3000);
events.ScheduleEvent(EVENT_SPELL_FOCUS_FIRE_2, 3500);
events.ScheduleEvent(EVENT_SPELL_FOCUS_FIRE_2, 4000);
events.ScheduleEvent(EVENT_SPELL_FOCUS_FIRE_3, 5000);
me->SetControlled(true, UNIT_STATE_ROOT);
break;
case EVENT_SPELL_FOCUS_FIRE_2:
if (Unit* flare = ObjectAccessor::GetCreature(*me, focusGUID))
me->CastSpell(flare, SPELL_FOCUS_CAST, true);
break;
case EVENT_SPELL_FOCUS_FIRE_3:
me->SetControlled(false, UNIT_STATE_ROOT);
break;
}
}
context.Repeat(3s);
}).Schedule(28s, [this](TaskContext context)
{
DoCastSelf(SPELL_ATTRACT_MAGIC);
context.Repeat(30s);
scheduler.Schedule(1500ms, [this](TaskContext context)
{
DoCastSelf(SPELL_CARNIVOROUS_BITE);
context.Repeat(10s);
});
}).Schedule(10s, [this](TaskContext context)
{
DoCastSelf(SPELL_CARNIVOROUS_BITE);
context.Repeat(10s);
}).Schedule(17s, [this](TaskContext context)
{
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 60.0f, true))
{
if (Creature* cr = me->SummonCreature(ENTRY_FOCUS_FIRE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 7000))
{
focusGUID = cr->GetGUID();
}
Talk(EMOTE_FOCUSED, target);
}
context.Repeat(15s, 20s);
scheduler.Schedule(3s, [this](TaskContext /*context*/)
{
if (Unit* flare = ObjectAccessor::GetCreature(*me, focusGUID))
{
me->CastSpell(flare, SPELL_FOCUS_CAST, true);
}
}).Schedule(3500ms, [this](TaskContext /*context*/)
{
if (Unit* flare = ObjectAccessor::GetCreature(*me, focusGUID))
{
me->CastSpell(flare, SPELL_FOCUS_CAST, true);
}
}).Schedule(4s, [this](TaskContext /*context*/)
{
if (Unit* flare = ObjectAccessor::GetCreature(*me, focusGUID))
{
me->CastSpell(flare, SPELL_FOCUS_CAST, true);
}
}).Schedule(5s, [this](TaskContext /*context*/)
{
me->SetControlled(false, UNIT_STATE_ROOT);
});
me->SetControlled(true, UNIT_STATE_ROOT);
});
}
DoMeleeAttackIfReady();
void JustSummoned(Creature* summon) override
{
summon->CastSpell(summon, SPELL_FOCUS_FIRE_VISUAL, true);
}
void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_FOCUS_CAST)
{
target->CastSpell(target, SPELL_FIERY_BLAST, false);
}
};
}
uint8 getStackCount(float dist)
{
if (dist < 15)
return 4;
if (dist < 25)
return 3;
if (dist < 35)
return 2;
return 1;
}
void UpdateAI(uint32 diff) override
{
scheduler.Update(diff);
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
};
class spell_auchenai_possess : public SpellScriptLoader
class spell_auchenai_possess : public AuraScript
{
public:
spell_auchenai_possess() : SpellScriptLoader("spell_auchenai_possess") { }
PrepareAuraScript(spell_auchenai_possess);
class spell_auchenai_possess_AuraScript : public AuraScript
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
PrepareAuraScript(spell_auchenai_possess_AuraScript);
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
{
if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
return;
}
if (Unit* caster = GetCaster())
{
if (Unit* target = GetTarget())
{
return;
}
if (Unit* caster = GetCaster())
if (Unit* target = GetTarget())
caster->CastSpell(target, 32830 /*POSSESS*/, true);
}
void CalcPeriodic(AuraEffect const* /*effect*/, bool& isPeriodic, int32& amplitude)
{
isPeriodic = true;
amplitude = 2000;
}
void Update(AuraEffect* /*effect*/)
{
// Xinef: Charm is removed when target is at or below 50%hp
if (Unit* owner = GetUnitOwner())
if (owner->GetHealthPct() <= 50)
SetDuration(0);
}
void Register() override
{
// Base channel
if (m_scriptSpellId == 33401)
OnEffectRemove += AuraEffectRemoveFn(spell_auchenai_possess_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
else
{
DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_auchenai_possess_AuraScript::CalcPeriodic, EFFECT_0, SPELL_AURA_MOD_CHARM);
OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_auchenai_possess_AuraScript::Update, EFFECT_0, SPELL_AURA_MOD_CHARM);
caster->CastSpell(target, SPELL_POSSESS_INSTANT, true);
}
}
};
}
AuraScript* GetAuraScript() const override
void CalcPeriodic(AuraEffect const* /*effect*/, bool& isPeriodic, int32& amplitude)
{
return new spell_auchenai_possess_AuraScript();
isPeriodic = true;
amplitude = 2000;
}
void Update(AuraEffect* /*effect*/)
{
if (Unit* owner = GetUnitOwner())
{
if (owner->GetHealthPct() <= 50)
{
SetDuration(0);
}
}
}
void Register() override
{
if (m_scriptSpellId == SPELL_POSSESS_CHANNELED)
{
OnEffectRemove += AuraEffectRemoveFn(spell_auchenai_possess::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
}
else
{
DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_auchenai_possess::CalcPeriodic, EFFECT_0, SPELL_AURA_MOD_CHARM);
OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_auchenai_possess::Update, EFFECT_0, SPELL_AURA_MOD_CHARM);
}
}
};
void AddSC_boss_shirrak_the_dead_watcher()
{
new boss_shirrak_the_dead_watcher();
new spell_auchenai_possess();
RegisterAuchenaiCryptsCreatureAI(boss_shirrak_the_dead_watcher);
RegisterSpellScript(spell_auchenai_possess);
}

View File

@@ -20,220 +20,185 @@
#include "ScriptedCreature.h"
#include "mana_tombs.h"
enum ePrince
enum Text
{
SAY_INTRO = 0,
SAY_AGGRO = 1,
SAY_SLAY = 2,
SAY_SUMMON = 3,
SAY_DEAD = 4,
SAY_DEAD = 4
};
enum Spells
{
// Shaffar
SPELL_BLINK = 34605,
SPELL_FROSTBOLT = 32364,
SPELL_FIREBALL = 32363,
SPELL_FROSTNOVA = 32365,
SPELL_ETHEREAL_BEACON = 32371, // Summons NPC_BEACON
SPELL_ETHEREAL_BEACON = 32371, // Summons NPC_BEACON
SPELL_ETHEREAL_BEACON_VISUAL = 32368,
NPC_BEACON = 18431,
NPC_SHAFFAR = 18344,
EVENT_SPELL_BEACON = 1,
EVENT_SPELL_FR_FI = 2,
EVENT_SPELL_FROST_NOVA = 3,
EVENT_SPELL_BLINK = 4,
// Yor
SPELL_DOUBLE_BREATH = 38361,
SPELL_STOMP = 36405
};
class boss_nexusprince_shaffar : public CreatureScript
enum Npc
{
public:
boss_nexusprince_shaffar() : CreatureScript("boss_nexusprince_shaffar") { }
NPC_BEACON = 18431
};
CreatureAI* GetAI(Creature* creature) const override
struct boss_nexusprince_shaffar : public BossAI
{
boss_nexusprince_shaffar(Creature* creature) : BossAI(creature, DATA_NEXUSPRINCE_SHAFFAR), summons(me)
{
return GetManaTombsAI<boss_nexusprince_shaffarAI>(creature);
HasTaunted = false;
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
struct boss_nexusprince_shaffarAI : public ScriptedAI
SummonList summons;
bool HasTaunted;
void Reset() override
{
boss_nexusprince_shaffarAI(Creature* creature) : ScriptedAI(creature), summons(me)
{
HasTaunted = false;
}
EventMap events;
SummonList summons;
bool HasTaunted;
void Reset() override
{
float dist = 8.0f;
float posX, posY, posZ, angle;
me->GetHomePosition(posX, posY, posZ, angle);
summons.DespawnAll();
events.Reset();
me->SummonCreature(NPC_BEACON, posX - dist, posY - dist, posZ, angle, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 7200000);
me->SummonCreature(NPC_BEACON, posX - dist, posY + dist, posZ, angle, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 7200000);
me->SummonCreature(NPC_BEACON, posX + dist, posY, posZ, angle, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 7200000);
}
void MoveInLineOfSight(Unit* who) override
{
if (!HasTaunted && who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 100.0f))
{
Talk(SAY_INTRO);
HasTaunted = true;
}
}
void JustEngagedWith(Unit*) override
{
Talk(SAY_AGGRO);
me->SetInCombatWithZone();
summons.DoZoneInCombat();
events.ScheduleEvent(EVENT_SPELL_BEACON, 10000);
events.ScheduleEvent(EVENT_SPELL_FR_FI, 4000);
events.ScheduleEvent(EVENT_SPELL_FROST_NOVA, 15000);
}
void JustSummoned(Creature* summon) override
{
if (me->IsInCombat() && summon->GetEntry() == NPC_BEACON)
{
summon->CastSpell(summon, SPELL_ETHEREAL_BEACON_VISUAL, false);
if (Unit* target = SelectTargetFromPlayerList(50.0f))
summon->AI()->AttackStart(target);
}
summons.Summon(summon);
}
void SummonedCreatureDespawn(Creature* summon) override
{
summons.Despawn(summon);
}
void KilledUnit(Unit* victim) override
{
if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_SLAY);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEAD);
summons.DespawnAll();
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_SPELL_FROST_NOVA:
me->CastSpell(me, SPELL_FROSTNOVA, false);
events.RepeatEvent(urand(16000, 23000));
events.DelayEvents(1500);
events.ScheduleEvent(EVENT_SPELL_BLINK, 1500);
break;
case EVENT_SPELL_FR_FI:
me->CastSpell(me->GetVictim(), RAND(SPELL_FROSTBOLT, SPELL_FIREBALL), false);
events.RepeatEvent(urand(3000, 4000));
break;
case EVENT_SPELL_BLINK:
me->CastSpell(me, SPELL_BLINK, false);
events.RescheduleEvent(EVENT_SPELL_FR_FI, 0);
break;
case EVENT_SPELL_BEACON:
if (!urand(0, 3))
Talk(SAY_SUMMON);
me->CastSpell(me, SPELL_ETHEREAL_BEACON, true);
events.RepeatEvent(10000);
break;
}
DoMeleeAttackIfReady();
}
};
};
enum Yor
{
SPELL_DOUBLE_BREATH = 38361,
SPELL_STOMP = 36405,
EVENT_DOUBLE_BREATH = 1,
EVENT_STOMP = 2
};
class npc_yor : public CreatureScript
{
public:
npc_yor() : CreatureScript("npc_yor") { }
CreatureAI* GetAI(Creature* creature) const override
{
return GetManaTombsAI<npc_yorAI>(creature);
_Reset();
float dist = 8.0f;
float posX, posY, posZ, angle;
me->GetHomePosition(posX, posY, posZ, angle);
summons.DespawnAll();
me->SummonCreature(NPC_BEACON, posX - dist, posY - dist, posZ, angle, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 7200000);
me->SummonCreature(NPC_BEACON, posX - dist, posY + dist, posZ, angle, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 7200000);
me->SummonCreature(NPC_BEACON, posX + dist, posY, posZ, angle, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 7200000);
}
struct npc_yorAI : public ScriptedAI
void MoveInLineOfSight(Unit* who) override
{
npc_yorAI(Creature* creature) : ScriptedAI(creature) { }
void Reset() override { }
void JustEngagedWith(Unit* /*who*/) override
if (!HasTaunted && who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 100.0f))
{
events.ScheduleEvent(EVENT_DOUBLE_BREATH, urand(26500, 30500));
events.ScheduleEvent(EVENT_STOMP, urand(12000, 18000));
HasTaunted = true;
Talk(SAY_INTRO);
}
}
void UpdateAI(uint32 diff) override
void JustEngagedWith(Unit*) override
{
_JustEngagedWith();
Talk(SAY_AGGRO);
summons.DoZoneInCombat();
scheduler.Schedule(10s, [this](TaskContext context)
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
if (!urand(0, 3))
{
return;
Talk(SAY_SUMMON);
}
while (uint32 eventId = events.ExecuteEvent())
DoCastSelf(SPELL_ETHEREAL_BEACON, true);
context.Repeat(10s);
}).Schedule(4s, [this](TaskContext context)
{
DoCastVictim(RAND(SPELL_FROSTBOLT, SPELL_FIREBALL));
context.Repeat(3s, 4s);
}).Schedule(15s, [this](TaskContext context)
{
DoCastSelf(SPELL_FROSTNOVA);
context.Repeat(16s, 23s);
scheduler.DelayAll(1500ms);
scheduler.Schedule(1500ms, [this](TaskContext /*context*/)
{
switch (eventId)
{
case EVENT_DOUBLE_BREATH:
if (me->IsWithinDist(me->GetVictim(), ATTACK_DISTANCE))
DoCastVictim(SPELL_DOUBLE_BREATH);
events.ScheduleEvent(EVENT_DOUBLE_BREATH, urand(10000, 20000));
break;
case EVENT_STOMP:
DoCastAOE(SPELL_STOMP);
events.ScheduleEvent(EVENT_STOMP, urand(14000, 24000));
break;
}
DoCastSelf(SPELL_BLINK);
});
});
}
void JustSummoned(Creature* summon) override
{
if (me->IsInCombat() && summon->GetEntry() == NPC_BEACON)
{
summon->CastSpell(summon, SPELL_ETHEREAL_BEACON_VISUAL, false);
if (Unit* target = SelectTargetFromPlayerList(50.0f))
{
summon->AI()->AttackStart(target);
}
DoMeleeAttackIfReady();
}
private:
EventMap events;
};
summons.Summon(summon);
}
void SummonedCreatureDespawn(Creature* summon) override
{
summons.Despawn(summon);
}
void KilledUnit(Unit* victim) override
{
if (victim->GetTypeId() == TYPEID_PLAYER)
{
Talk(SAY_SLAY);
}
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(SAY_DEAD);
summons.DespawnAll();
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
scheduler.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
DoMeleeAttackIfReady();
}
};
struct npc_yor : public ScriptedAI
{
npc_yor(Creature* creature) : ScriptedAI(creature) { }
void Reset() override { }
void JustEngagedWith(Unit* /*who*/) override
{
_scheduler.Schedule(25500ms, 30500ms, [this](TaskContext context)
{
if (me->IsWithinDist(me->GetVictim(), ATTACK_DISTANCE))
{
DoCastVictim(SPELL_DOUBLE_BREATH);
}
context.Repeat(10s, 20s);
}).Schedule(12s, 18s, [this](TaskContext context)
{
DoCastAOE(SPELL_STOMP);
context.Repeat(14s, 24s);
});
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
DoMeleeAttackIfReady();
}
private:
TaskScheduler _scheduler;
};
void AddSC_boss_nexusprince_shaffar()
{
new boss_nexusprince_shaffar();
new npc_yor();
RegisterManaTombsCreatureAI(boss_nexusprince_shaffar);
RegisterManaTombsCreatureAI(npc_yor);
}

View File

@@ -23,8 +23,7 @@ enum Spells
{
SPELL_EARTHQUAKE = 33919,
SPELL_CRYSTAL_PRISON = 32361,
SPELL_ARCING_SMASH_N = 8374,
SPELL_ARCING_SMASH_H = 38761
SPELL_ARCING_SMASH = 8374
};
struct boss_tavarok : public BossAI
@@ -45,7 +44,6 @@ struct boss_tavarok : public BossAI
void JustEngagedWith(Unit* /*who*/) override
{
_JustEngagedWith();
scheduler.Schedule(10s, 14200ms, [this](TaskContext context)
{
DoCastSelf(SPELL_EARTHQUAKE);
@@ -56,7 +54,7 @@ struct boss_tavarok : public BossAI
context.Repeat(15s, 22s);
}).Schedule(5900ms, [this](TaskContext context)
{
DoCastVictim(DUNGEON_MODE(SPELL_ARCING_SMASH_N, SPELL_ARCING_SMASH_H));
DoCastVictim(SPELL_ARCING_SMASH);
context.Repeat(8s, 12s);
});
}
@@ -66,12 +64,10 @@ struct boss_tavarok : public BossAI
_JustDied();
}
void KilledUnit(Unit* /*victim*/) override
{
}
void KilledUnit(Unit* /*victim*/) override {}
};
void AddSC_boss_tavarok()
{
RegisterManaTombsCreatureAI(boss_tavarok);
}
}

View File

@@ -20,23 +20,25 @@
#include "SpellScript.h"
#include "sethekk_halls.h"
enum Anzu
enum Text
{
SAY_ANZU_INTRO1 = 0,
SAY_ANZU_INTRO2 = 1,
SAY_SUMMON = 2,
SAY_SUMMON = 2
};
enum Spells
{
SPELL_PARALYZING_SCREECH = 40184,
SPELL_SPELL_BOMB = 40303,
SPELL_CYCLONE = 40321,
SPELL_BANISH_SELF = 42354,
SPELL_SHADOWFORM = 40973,
SPELL_SHADOWFORM = 40973
};
EVENT_SPELL_SCREECH = 1,
EVENT_SPELL_BOMB = 2,
EVENT_SPELL_CYCLONE = 3,
EVENT_ANZU_HEALTH1 = 4,
EVENT_ANZU_HEALTH2 = 5
enum Npc
{
NPC_BROOD_OF_ANZU = 23132
};
struct boss_anzu : public BossAI
@@ -46,6 +48,10 @@ struct boss_anzu : public BossAI
talkTimer = 1;
me->ReplaceAllUnitFlags(UNIT_FLAG_NON_ATTACKABLE);
me->AddAura(SPELL_SHADOWFORM, me);
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
uint32 talkTimer;
@@ -55,18 +61,45 @@ struct boss_anzu : public BossAI
summons.Despawn(summon);
summons.RemoveNotExisting();
if (summons.empty())
{
me->RemoveAurasDueToSpell(SPELL_BANISH_SELF);
}
}
void Reset() override
{
_Reset();
ScheduleHealthCheckEvent({ 66, 33 }, [&] {
SummonBroods();
scheduler.DelayAll(10s);
});
}
void JustEngagedWith(Unit* /*who*/) override
{
_JustEngagedWith();
events.Reset();
events.ScheduleEvent(EVENT_SPELL_SCREECH, 14000);
events.ScheduleEvent(EVENT_SPELL_BOMB, 5000);
events.ScheduleEvent(EVENT_SPELL_CYCLONE, 8000);
events.ScheduleEvent(EVENT_ANZU_HEALTH1, 2000);
events.ScheduleEvent(EVENT_ANZU_HEALTH2, 2001);
scheduler.Schedule(14s, [this](TaskContext context)
{
DoCastSelf(SPELL_PARALYZING_SCREECH);
context.Repeat(23s);
scheduler.DelayAll(3s);
}).Schedule(5s, [this](TaskContext context)
{
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true))
{
DoCast(target, SPELL_SPELL_BOMB);
}
context.Repeat(16s, 24500ms);
scheduler.DelayAll(3s);
}).Schedule(8s, [this](TaskContext context)
{
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 45.0f, true))
{
DoCast(target, SPELL_CYCLONE);
}
context.Repeat(22s, 27s);
scheduler.DelayAll(3s);
});
}
void SummonBroods()
@@ -74,7 +107,9 @@ struct boss_anzu : public BossAI
Talk(SAY_SUMMON);
me->CastSpell(me, SPELL_BANISH_SELF, true);
for (uint8 i = 0; i < 5; ++i)
me->SummonCreature(23132 /*NPC_BROOD_OF_ANZU*/, me->GetPositionX() + 20 * cos((float)i), me->GetPositionY() + 20 * std::sin((float)i), me->GetPositionZ() + 25.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
{
me->SummonCreature(NPC_BROOD_OF_ANZU, me->GetPositionX() + 20 * cos((float)i), me->GetPositionY() + 20 * std::sin((float)i), me->GetPositionZ() + 25.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
}
}
void UpdateAI(uint32 diff) override
@@ -99,49 +134,10 @@ struct boss_anzu : public BossAI
if (!UpdateVictim())
return;
events.Update(diff);
scheduler.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING | UNIT_STATE_STUNNED))
return;
switch (events.ExecuteEvent())
{
case EVENT_SPELL_SCREECH:
me->CastSpell(me, SPELL_PARALYZING_SCREECH, false);
events.RepeatEvent(23000);
events.DelayEvents(3000);
break;
case EVENT_SPELL_BOMB:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true))
me->CastSpell(target, SPELL_SPELL_BOMB, false);
events.RepeatEvent(urand(16000, 24500));
events.DelayEvents(3000);
break;
case EVENT_SPELL_CYCLONE:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 45.0f, true))
me->CastSpell(target, SPELL_CYCLONE, false);
events.RepeatEvent(urand(22000, 27000));
events.DelayEvents(3000);
break;
case EVENT_ANZU_HEALTH1:
if (me->HealthBelowPct(66))
{
SummonBroods();
events.DelayEvents(10000);
return;
}
events.RepeatEvent(1000);
break;
case EVENT_ANZU_HEALTH2:
if (me->HealthBelowPct(33))
{
SummonBroods();
events.DelayEvents(10000);
return;
}
events.RepeatEvent(1000);
break;
}
DoMeleeAttackIfReady();
}
};

View File

@@ -19,24 +19,6 @@
#include "ScriptedCreature.h"
#include "sethekk_halls.h"
enum Spells
{
SPELL_FLAME_SHOCK_N = 15039,
SPELL_FLAME_SHOCK_H = 15616,
SPELL_ARCANE_SHOCK_N = 33534,
SPELL_ARCANE_SHOCK_H = 38135,
SPELL_FROST_SHOCK_N = 12548,
SPELL_FROST_SHOCK_H = 21401,
SPELL_SHADOW_SHOCK_N = 33620,
SPELL_SHADOW_SHOCK_H = 38137,
SPELL_CHAIN_LIGHTNING_N = 15659,
SPELL_CHAIN_LIGHTNING_H = 15305,
SPELL_SUMMON_ARC_ELE = 33538,
SPELL_SUMMON_FIRE_ELE = 33537,
SPELL_SUMMON_FROST_ELE = 33539,
SPELL_SUMMON_SHADOW_ELE = 33540
};
enum Text
{
SAY_SUMMON = 0,
@@ -45,6 +27,19 @@ enum Text
SAY_DEATH = 3
};
enum Spells
{
SPELL_FLAME_SHOCK = 15039,
SPELL_ARCANE_SHOCK = 33534,
SPELL_FROST_SHOCK = 12548,
SPELL_SHADOW_SHOCK = 33620,
SPELL_CHAIN_LIGHTNING = 15659,
SPELL_SUMMON_ARC_ELE = 33538,
SPELL_SUMMON_FIRE_ELE = 33537,
SPELL_SUMMON_FROST_ELE = 33539,
SPELL_SUMMON_SHADOW_ELE = 33540
};
struct boss_darkweaver_syth : public BossAI
{
boss_darkweaver_syth(Creature* creature) : BossAI(creature, DATA_DARKWEAVER_SYTH)
@@ -58,7 +53,6 @@ struct boss_darkweaver_syth : public BossAI
void Reset() override
{
_Reset();
ScheduleHealthCheckEvent({90, 50, 10}, [&] {
Talk(SAY_SUMMON);
DoCastSelf(SPELL_SUMMON_ARC_ELE);
@@ -72,26 +66,25 @@ struct boss_darkweaver_syth : public BossAI
{
_JustEngagedWith();
Talk(SAY_AGGRO);
scheduler.Schedule(2s, [this](TaskContext context)
{
DoCastRandomTarget(DUNGEON_MODE(SPELL_FLAME_SHOCK_N, SPELL_FLAME_SHOCK_H));
DoCastRandomTarget(SPELL_FLAME_SHOCK);
context.Repeat(10s, 15s);
}).Schedule(4s, [this](TaskContext context)
{
DoCastRandomTarget(DUNGEON_MODE(SPELL_ARCANE_SHOCK_N, SPELL_ARCANE_SHOCK_H));
DoCastRandomTarget(SPELL_ARCANE_SHOCK);
context.Repeat(10s, 15s);
}).Schedule(6s, [this](TaskContext context)
{
DoCastRandomTarget(DUNGEON_MODE(SPELL_FROST_SHOCK_N, SPELL_FROST_SHOCK_H));
DoCastRandomTarget(SPELL_FROST_SHOCK);
context.Repeat(10s, 15s);
}).Schedule(8s, [this](TaskContext context)
{
DoCastRandomTarget(DUNGEON_MODE(SPELL_SHADOW_SHOCK_N, SPELL_SHADOW_SHOCK_H));
DoCastRandomTarget(SPELL_SHADOW_SHOCK);
context.Repeat(10s, 15s);
}).Schedule(15s, [this](TaskContext context)
{
DoCastRandomTarget(DUNGEON_MODE(SPELL_CHAIN_LIGHTNING_N, SPELL_CHAIN_LIGHTNING_H));
DoCastRandomTarget(SPELL_CHAIN_LIGHTNING);
context.Repeat(10s, 15s);
});
}
@@ -99,17 +92,19 @@ struct boss_darkweaver_syth : public BossAI
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(SAY_DEATH);
}
void KilledUnit(Unit* /*victim*/) override
void KilledUnit(Unit* victim) override
{
Talk(SAY_SLAY);
if (victim->GetTypeId() == TYPEID_PLAYER)
{
Talk(SAY_SLAY);
}
}
};
void AddSC_boss_darkweaver_syth()
{
RegisterSethekkHallsCreatureAI(boss_darkweaver_syth);
}
}

View File

@@ -20,13 +20,13 @@
#include "SpellScript.h"
#include "sethekk_halls.h"
enum TailonkingIkiss
enum Text
{
SAY_INTRO = 0,
SAY_AGGRO = 1,
SAY_SLAY = 2,
SAY_DEATH = 3,
EMOTE_ARCANE_EXP = 4,
EMOTE_ARCANE_EXP = 4
};
enum Spells
@@ -38,7 +38,7 @@ enum Spells
SPELL_SLOW = 35032,
SPELL_POLYMORPH = 38245,
SPELL_ARCANE_VOLLEY = 35059,
SPELL_ARCANE_EXPLOSION = 38197,
SPELL_ARCANE_EXPLOSION = 38197
};
struct boss_talon_king_ikiss : public BossAI
@@ -55,14 +55,12 @@ struct boss_talon_king_ikiss : public BossAI
{
_Reset();
_spoken = false;
ScheduleHealthCheckEvent({ 80, 50, 25 }, [&] {
me->InterruptNonMeleeSpells(false);
DoCastAOE(SPELL_BLINK);
DoCastSelf(SPELL_ARCANE_BUBBLE, true);
Talk(EMOTE_ARCANE_EXP);
scheduler.Schedule(1s, [this](TaskContext)
scheduler.Schedule(1s, [this](TaskContext /*context*/)
{
DoCastAOE(SPELL_ARCANE_EXPLOSION);
}).Schedule(6500ms, [this](TaskContext /*context*/)
@@ -72,7 +70,7 @@ struct boss_talon_king_ikiss : public BossAI
});
ScheduleHealthCheckEvent(20, [&] {
DoCast(me, SPELL_MANA_SHIELD);
DoCastSelf(SPELL_MANA_SHIELD);
});
}
@@ -89,7 +87,6 @@ struct boss_talon_king_ikiss : public BossAI
Talk(SAY_INTRO);
_spoken = true;
}
ScriptedAI::MoveInLineOfSight(who);
}
@@ -97,7 +94,6 @@ struct boss_talon_king_ikiss : public BossAI
{
_JustEngagedWith();
Talk(SAY_AGGRO);
scheduler.Schedule(5s, [this](TaskContext context)
{
DoCastAOE(SPELL_ARCANE_VOLLEY);
@@ -114,7 +110,6 @@ struct boss_talon_king_ikiss : public BossAI
}
context.Repeat(15s, 17500ms);
});
if (IsHeroic())
{
scheduler.Schedule(15s, 25s, [this](TaskContext context)
@@ -129,17 +124,18 @@ struct boss_talon_king_ikiss : public BossAI
{
_JustDied();
Talk(SAY_DEATH);
if (GameObject* coffer = instance->GetGameObject(DATA_GO_TALON_KING_COFFER))
{
coffer->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE | GO_FLAG_INTERACT_COND);
}
}
void KilledUnit(Unit* /*victim*/) override
void KilledUnit(Unit* victim) override
{
if (urand(0, 1))
if (victim->IsPlayer() && urand(0, 1))
{
Talk(SAY_SLAY);
}
}
private:

View File

@@ -19,23 +19,25 @@
#include "ScriptedCreature.h"
#include "shadow_labyrinth.h"
enum eEnums
enum Text
{
SAY_INTRO = 0,
SAY_AGGRO = 1,
SAY_HELP = 2,
SAY_SLAY = 3,
SAY_DEATH = 4,
SAY_DEATH = 4
};
enum Spells
{
SPELL_BANISH = 30231,
SPELL_CORROSIVE_ACID = 33551,
SPELL_FEAR = 33547,
SPELL_ENRAGE = 34970,
EVENT_SPELL_CORROSIVE = 1,
EVENT_SPELL_FEAR = 2,
EVENT_SPELL_ENRAGE = 3,
SPELL_ENRAGE = 34970
};
enum Misc
{
PATH_ID_START = 1873100,
PATH_ID_PATHING = 1873101,
@@ -81,7 +83,6 @@ struct boss_ambassador_hellmaw : public BossAI
{
return;
}
me->RemoveAurasDueToSpell(SPELL_BANISH);
Talk(SAY_INTRO);
DoPlaySoundToSet(me, SOUND_INTRO);
@@ -96,9 +97,7 @@ struct boss_ambassador_hellmaw : public BossAI
{
return;
}
Talk(SAY_AGGRO);
scheduler.Schedule(23050ms, 30350ms, [this](TaskContext context)
{
DoCastVictim(SPELL_CORROSIVE_ACID);
@@ -111,12 +110,11 @@ struct boss_ambassador_hellmaw : public BossAI
if (IsHeroic())
{
scheduler.Schedule(3min, [this](TaskContext)
scheduler.Schedule(3min, [this](TaskContext /*context*/)
{
DoCastSelf(SPELL_ENRAGE, true);
});
}
_JustEngagedWith();
}
@@ -126,7 +124,6 @@ struct boss_ambassador_hellmaw : public BossAI
{
return;
}
ScriptedAI::MoveInLineOfSight(who);
}
@@ -136,7 +133,6 @@ struct boss_ambassador_hellmaw : public BossAI
{
return;
}
ScriptedAI::AttackStart(who);
}
@@ -188,7 +184,7 @@ struct boss_ambassador_hellmaw : public BossAI
return;
}
//Make sure our attack is ready and we aren't currently casting before checking distance
// Make sure our attack is ready and we aren't currently casting before checking distance
if (me->isAttackReady())
{
// xinef: prevent base and off attack in same time, delay attack at 0.2 sec
@@ -199,7 +195,6 @@ struct boss_ambassador_hellmaw : public BossAI
me->setAttackTimer(OFF_ATTACK, ATTACK_DISPLAY_DELAY);
}
}
me->AttackerStateUpdate(victim, BASE_ATTACK, false, ignoreCasting);
me->resetAttackTimer();
}
@@ -211,7 +206,6 @@ struct boss_ambassador_hellmaw : public BossAI
{
me->setAttackTimer(BASE_ATTACK, ATTACK_DISPLAY_DELAY);
}
me->AttackerStateUpdate(victim, OFF_ATTACK, false, ignoreCasting);
me->resetAttackTimer(OFF_ATTACK);
}

View File

@@ -19,32 +19,38 @@
#include "ScriptedCreature.h"
#include "shadow_labyrinth.h"
enum BlackheartTheInciter
enum Text
{
SPELL_INCITE_CHAOS = 33676,
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,
SAY_SLAY = 2,
SAY_HELP = 3,
SAY_DEATH = 4,
SAY_DEATH = 4
};
EVENT_SPELL_INCITE = 1,
EVENT_INCITE_WAIT = 2,
EVENT_SPELL_CHARGE = 3,
EVENT_SPELL_KNOCKBACK = 4,
EVENT_SPELL_WAR_STOMP = 5,
enum Spells
{
SPELL_INCITE_CHAOS = 33676,
SPELL_INCITE_CHAOS_B = 33684, // debuff applied to each player
SPELL_CHARGE = 33709,
SPELL_WAR_STOMP = 33707,
SPELL_LAUGHTER = 33722
};
NPC_INCITE_TRIGGER = 19300
enum Npc
{
NPC_INCITE_TRIGGER = 19300
};
struct boss_blackheart_the_inciter : public BossAI
{
boss_blackheart_the_inciter(Creature* creature) : BossAI(creature, DATA_BLACKHEARTTHEINCITEREVENT) { }
boss_blackheart_the_inciter(Creature* creature) : BossAI(creature, DATA_BLACKHEARTTHEINCITEREVENT)
{
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
bool InciteChaos;
@@ -72,12 +78,48 @@ struct boss_blackheart_the_inciter : public BossAI
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();
me->CallForHelp(100.0f);
scheduler.Schedule(24s, [this](TaskContext context)
{
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)
{
Unit* target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid());
if (target && target->IsPlayer())
{
if (Creature* inciteTrigger = me->SummonCreature(inciteTriggerID++, *target, TEMPSUMMON_TIMED_DESPAWN, 15 * IN_MILLISECONDS))
{
inciteTrigger->CastSpell(target, SPELL_INCITE_CHAOS_B, true);
}
}
}
DoResetThreatList();
me->SetImmuneToPC(true);
InciteChaos = true;
scheduler.DelayAll(15s);
context.Repeat(50s, 70s);
scheduler.Schedule(15s, [this](TaskContext /*context*/)
{
me->SetImmuneToPC(false);
InciteChaos = false;
});
}).Schedule(15s, [this](TaskContext /*context*/)
{
me->SetImmuneToPC(false);
InciteChaos = false;
}).Schedule(30s, 50s, [this](TaskContext context)
{
DoCastRandomTarget(SPELL_CHARGE);
context.Repeat(30s, 50s);
}).Schedule(16950ms, 26350ms, [this](TaskContext context)
{
DoCastAOE(SPELL_WAR_STOMP);
context.Repeat(16950ms, 26350ms);
});
}
void EnterEvadeMode(EvadeReason why) override
@@ -91,55 +133,9 @@ struct boss_blackheart_the_inciter : public BossAI
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim() && !InciteChaos)
{
return;
}
events.Update(diff);
switch (events.ExecuteEvent())
{
case EVENT_INCITE_WAIT:
me->SetImmuneToPC(false);
InciteChaos = false;
break;
case EVENT_SPELL_INCITE:
{
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)
{
Unit* target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid());
if (target && target->IsPlayer())
{
if (Creature* inciteTrigger = me->SummonCreature(inciteTriggerID++, *target, TEMPSUMMON_TIMED_DESPAWN, 15 * IN_MILLISECONDS))
{
inciteTrigger->CastSpell(target, SPELL_INCITE_CHAOS_B, true);
}
}
}
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;
}
scheduler.Update(diff);
if (InciteChaos)
return;

View File

@@ -20,47 +20,52 @@
#include "ScriptedCreature.h"
#include "shadow_labyrinth.h"
enum GrandmasterVorpil
enum Text
{
SAY_INTRO = 0,
SAY_AGGRO = 1,
SAY_HELP = 2,
SAY_SLAY = 3,
SAY_DEATH = 4,
SAY_DEATH = 4
};
enum Spells
{
// Vorpil
SPELL_RAIN_OF_FIRE = 33617,
SPELL_DRAW_SHADOWS = 33563,
SPELL_SHADOWBOLT_VOLLEY = 33841,
SPELL_BANISH = 38791,
NPC_VOID_TRAVELER = 19226,
// Void Traveler
SPELL_SACRIFICE = 33587,
SPELL_SHADOW_NOVA = 33846,
SPELL_EMPOWERING_SHADOWS = 33783,
NPC_VOID_PORTAL = 19224,
SPELL_VOID_PORTAL_VISUAL = 33569,
SPELL_VOID_PORTAL_VISUAL = 33569
};
enum Npc
{
NPC_VOID_TRAVELER = 19226,
NPC_VOID_PORTAL = 19224
};
float VorpilPosition[3] = {-253.548f, -263.646f, 17.0864f};
//x, y, z, and orientation
// x, y, z, and orientation
float VoidPortalCoords[5][4] =
{
{-208.411f, -263.652f, 17.086313f, 3.121870040893554687f}, //portal A 33566
{-261.676f, -297.69f, 17.087011f, 1.360249996185302734f}, //portal B 33614
{-282.272f, -240.432f, 12.683899f, 5.580170154571533203f}, //portal C 33615
{-291.833f, -268.595f, 12.682545f, 0.047733999788761138f}, //portal D 33567
{-303.966f, -255.759f, 12.683404f, 6.012829780578613281f} //portal E 33616
{-208.411f, -263.652f, 17.086313f, 3.121870040893554687f}, // portal A 33566
{-261.676f, -297.69f, 17.087011f, 1.360249996185302734f}, // portal B 33614
{-282.272f, -240.432f, 12.683899f, 5.580170154571533203f}, // portal C 33615
{-291.833f, -268.595f, 12.682545f, 0.047733999788761138f}, // portal D 33567
{-303.966f, -255.759f, 12.683404f, 6.012829780578613281f} // portal E 33616
};
struct boss_grandmaster_vorpil : public BossAI
{
boss_grandmaster_vorpil(Creature* creature) : BossAI(creature, DATA_GRANDMASTER_VORPIL)
{
sayIntro = false;
}
boss_grandmaster_vorpil(Creature* creature) : BossAI(creature, DATA_GRANDMASTER_VORPIL), sayIntro(false) {}
bool sayIntro, sayHelp;
@@ -111,7 +116,6 @@ struct boss_grandmaster_vorpil : public BossAI
default:
return 4800ms;
}
return 1s;
}
@@ -146,7 +150,6 @@ struct boss_grandmaster_vorpil : public BossAI
{
Talk(SAY_AGGRO);
summonPortals();
scheduler.Schedule(9700ms, 20s, [this](TaskContext context)
{
DoCastAOE(SPELL_SHADOWBOLT_VOLLEY);

View File

@@ -20,10 +20,8 @@
#include "SpellInfo.h"
#include "shadow_labyrinth.h"
enum Murmur
enum Spells
{
EMOTE_SONIC_BOOM = 0,
SPELL_SUPPRESSION = 33332,
SPELL_SHOCKWAVE = 33686,
SPELL_SHOCKWAVE_SERVERSIDE = 33673,
@@ -34,12 +32,14 @@ enum Murmur
SPELL_MURMUR_WRATH_AOE = 33329,
SPELL_MURMUR_WRATH = 33331,
SPELL_SONIC_BOOM_CAST_N = 33923,
SPELL_SONIC_BOOM_CAST_H = 38796,
SPELL_SONIC_BOOM_EFFECT_N = 38795,
SPELL_SONIC_BOOM_EFFECT_H = 33666,
SPELL_MURMURS_TOUCH_N = 33711,
SPELL_MURMURS_TOUCH_H = 38794,
SPELL_SONIC_BOOM_CAST = 33923,
SPELL_SONIC_BOOM_EFFECT = 38795,
SPELL_MURMURS_TOUCH = 33711
};
enum Misc
{
EMOTE_SONIC_BOOM = 0,
GROUP_RESONANCE = 1,
GROUP_OOC_CAST = 2,
@@ -47,7 +47,7 @@ enum Murmur
GUID_MURMUR_NPCS = 1
};
enum Creatures
enum Npc
{
NPC_CABAL_SPELLBINDER = 18639
};
@@ -57,7 +57,6 @@ struct boss_murmur : public BossAI
boss_murmur(Creature* creature) : BossAI(creature, DATA_MURMUR)
{
SetCombatMovement(false);
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
@@ -75,7 +74,6 @@ struct boss_murmur : public BossAI
void CastSupressionOOC()
{
me->m_Events.CancelEventGroup(GROUP_OOC_CAST);
me->m_Events.AddEventAtOffset([this] {
if (me->FindNearestCreature(NPC_CABAL_SPELLBINDER, 35.0f))
{
@@ -106,13 +104,11 @@ struct boss_murmur : public BossAI
{
return true;
}
if (Unit* victimTarget = victim->GetVictim())
{
return victimTarget != me;
}
}
return true;
}
@@ -133,23 +129,21 @@ struct boss_murmur : public BossAI
{
return;
}
_JustEngagedWith();
scheduler.Schedule(28s, [this](TaskContext context)
{
Talk(EMOTE_SONIC_BOOM);
DoCastAOE(DUNGEON_MODE(SPELL_SONIC_BOOM_CAST_N, SPELL_SONIC_BOOM_CAST_H));
DoCastAOE(SPELL_SONIC_BOOM_CAST);
scheduler.Schedule(1500ms, [this](TaskContext)
{
DoCastAOE(DUNGEON_MODE(SPELL_SONIC_BOOM_EFFECT_N, SPELL_SONIC_BOOM_EFFECT_H), true);
DoCastAOE(SPELL_SONIC_BOOM_EFFECT, true);
});
context.Repeat(34s, 40s);
}).Schedule(14600ms, 25500ms, [this](TaskContext context)
{
DoCastRandomTarget(DUNGEON_MODE(SPELL_MURMURS_TOUCH_N, SPELL_MURMURS_TOUCH_H));
DoCastRandomTarget(SPELL_MURMURS_TOUCH);
context.Repeat(14600ms, 25500ms);
}).Schedule(15s, 30s, [this](TaskContext context)
{
@@ -177,7 +171,6 @@ struct boss_murmur : public BossAI
});
}
}
context.Repeat();
});
@@ -193,7 +186,6 @@ struct boss_murmur : public BossAI
context.Repeat(3650ms, 9150ms);
});
}
me->m_Events.CancelEventGroup(GROUP_OOC_CAST);
}
};