mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 01:08:35 +00:00
Merge branch 'master' into Playerbot
This commit is contained in:
@@ -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
|
||||
|
||||
12
data/sql/updates/db_world/2023_06_08_00.sql
Normal file
12
data/sql/updates/db_world/2023_06_08_00.sql
Normal 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);
|
||||
|
||||
12
data/sql/updates/db_world/2023_06_09_00.sql
Normal file
12
data/sql/updates/db_world/2023_06_09_00.sql
Normal 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);
|
||||
@@ -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
|
||||
#
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user