mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 01:08:35 +00:00
script zones
This commit is contained in:
@@ -37,15 +37,7 @@ enum Misc
|
||||
NPC_DRAKKARI_SCYTHECLAW = 26628,
|
||||
NPC_DRAKKARI_GUTRIPPER = 26641,
|
||||
|
||||
SAY_CLAW_EMOTE = 0,
|
||||
|
||||
EVENT_SPELL_BELLOWING_ROAR = 1,
|
||||
EVENT_SPELL_GRIEVOUS_BITE = 2,
|
||||
EVENT_SPELL_MANGLING_SLASH = 3,
|
||||
EVENT_SPELL_FEARSOME_ROAR = 4,
|
||||
EVENT_SPELL_PIERCING_SLASH = 5,
|
||||
EVENT_SPELL_RAPTOR_CALL = 6,
|
||||
EVENT_MENACING_CLAW = 7
|
||||
SAY_CLAW_EMOTE = 0
|
||||
};
|
||||
|
||||
class boss_dred : public CreatureScript
|
||||
@@ -60,14 +52,52 @@ public:
|
||||
|
||||
struct boss_dredAI : public BossAI
|
||||
{
|
||||
boss_dredAI(Creature* creature) : BossAI(creature, DATA_DRED)
|
||||
{
|
||||
}
|
||||
boss_dredAI(Creature* creature) : BossAI(creature, DATA_DRED) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
BossAI::Reset();
|
||||
_raptorCount = 0;
|
||||
|
||||
ScheduleHealthCheckEvent({ 67, 34 }, [&] {
|
||||
DoCastAOE(SPELL_BELLOWING_ROAR);
|
||||
}, false);
|
||||
}
|
||||
|
||||
void ScheduleTasks() override
|
||||
{
|
||||
ScheduleTimedEvent(20s, [&] {
|
||||
DoCastVictim(SPELL_GRIEVOUS_BITE);
|
||||
}, 20s);
|
||||
|
||||
ScheduleTimedEvent(18s + 500ms, [&] {
|
||||
DoCastVictim(SPELL_MANGLING_SLASH);
|
||||
}, 20s);
|
||||
|
||||
ScheduleTimedEvent(10s, 20s, [&] {
|
||||
DoCastAOE(SPELL_FEARSOME_ROAR);
|
||||
}, 17s);
|
||||
|
||||
ScheduleTimedEvent(17s, [&] {
|
||||
DoCastVictim(SPELL_PIERCING_SLASH);
|
||||
}, 20s);
|
||||
|
||||
if (IsHeroic())
|
||||
{
|
||||
ScheduleTimedEvent(16s, [&] {
|
||||
DoCastSelf(SPELL_RAPTOR_CALL);
|
||||
}, 30s);
|
||||
|
||||
ScheduleTimedEvent(21s, [&] {
|
||||
Talk(SAY_CLAW_EMOTE);
|
||||
me->setAttackTimer(BASE_ATTACK, 2000);
|
||||
me->AttackerStateUpdate(me->GetVictim());
|
||||
if (me->GetVictim())
|
||||
me->AttackerStateUpdate(me->GetVictim());
|
||||
if (me->GetVictim())
|
||||
me->AttackerStateUpdate(me->GetVictim());
|
||||
}, 20s);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 data) const override
|
||||
@@ -87,67 +117,6 @@ public:
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
_raptorCount = 0;
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_BELLOWING_ROAR, 33s);
|
||||
events.ScheduleEvent(EVENT_SPELL_GRIEVOUS_BITE, 20s);
|
||||
events.ScheduleEvent(EVENT_SPELL_MANGLING_SLASH, 18s + 500ms);
|
||||
events.ScheduleEvent(EVENT_SPELL_FEARSOME_ROAR, 10s, 20s);
|
||||
events.ScheduleEvent(EVENT_SPELL_PIERCING_SLASH, 17s);
|
||||
if (IsHeroic())
|
||||
{
|
||||
events.ScheduleEvent(EVENT_MENACING_CLAW, 21s);
|
||||
events.ScheduleEvent(EVENT_SPELL_RAPTOR_CALL, 20s, 25s);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_BELLOWING_ROAR:
|
||||
me->CastSpell(me, SPELL_BELLOWING_ROAR, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_BELLOWING_ROAR, 40s);
|
||||
break;
|
||||
case EVENT_SPELL_GRIEVOUS_BITE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_GRIEVOUS_BITE, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_GRIEVOUS_BITE, 20s);
|
||||
break;
|
||||
case EVENT_SPELL_MANGLING_SLASH:
|
||||
me->CastSpell(me->GetVictim(), SPELL_MANGLING_SLASH, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_MANGLING_SLASH, 20s);
|
||||
break;
|
||||
case EVENT_SPELL_FEARSOME_ROAR:
|
||||
me->CastSpell(me, SPELL_FEARSOME_ROAR, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_FEARSOME_ROAR, 17s);
|
||||
break;
|
||||
case EVENT_SPELL_PIERCING_SLASH:
|
||||
me->CastSpell(me->GetVictim(), SPELL_PIERCING_SLASH, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_PIERCING_SLASH, 20s);
|
||||
break;
|
||||
case EVENT_SPELL_RAPTOR_CALL:
|
||||
me->CastSpell(me, SPELL_RAPTOR_CALL, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_RAPTOR_CALL, 20s);
|
||||
break;
|
||||
case EVENT_MENACING_CLAW:
|
||||
Talk(SAY_CLAW_EMOTE);
|
||||
me->setAttackTimer(BASE_ATTACK, 2000);
|
||||
me->AttackerStateUpdate(me->GetVictim());
|
||||
if (me->GetVictim())
|
||||
me->AttackerStateUpdate(me->GetVictim());
|
||||
if (me->GetVictim())
|
||||
me->AttackerStateUpdate(me->GetVictim());
|
||||
events.ScheduleEvent(EVENT_MENACING_CLAW, 20s);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -181,7 +150,23 @@ class spell_dred_raptor_call : public SpellScript
|
||||
|
||||
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
GetCaster()->SummonCreature(RAND(NPC_DRAKKARI_GUTRIPPER, NPC_DRAKKARI_SCYTHECLAW), -522.02f, -718.89f, 30.26f, 2.41f);
|
||||
std::list<Creature*> raptors;
|
||||
GetCaster()->GetCreatureListWithEntryInGrid(raptors, { NPC_DRAKKARI_SCYTHECLAW, NPC_DRAKKARI_GUTRIPPER }, 100.0f);
|
||||
|
||||
raptors.remove_if([](Creature* raptor)
|
||||
{
|
||||
return !raptor->IsAlive() || raptor->IsInCombat();
|
||||
});
|
||||
|
||||
if (raptors.empty())
|
||||
return;
|
||||
|
||||
Creature* raptor = Acore::Containers::SelectRandomContainerElement(raptors);
|
||||
if (!raptor)
|
||||
return;
|
||||
|
||||
if (GetCaster()->GetVictim())
|
||||
raptor->AI()->AttackStart(GetCaster()->GetVictim());
|
||||
}
|
||||
|
||||
void Register() override
|
||||
@@ -193,16 +178,14 @@ class spell_dred_raptor_call : public SpellScript
|
||||
class achievement_better_off_dred : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_better_off_dred() : AchievementCriteriaScript("achievement_better_off_dred")
|
||||
{
|
||||
}
|
||||
achievement_better_off_dred() : AchievementCriteriaScript("achievement_better_off_dred") { }
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
return target->GetAI()->GetData(target->GetEntry());
|
||||
return target->GetAI()->GetData(target->GetEntry()) >= 6;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ enum Spells
|
||||
SPELL_COPY_OF_SUMMON_MINIONS = 59933,
|
||||
SPELL_BLIZZARD = 49034,
|
||||
SPELL_FROSTBOLT = 49037,
|
||||
SPELL_TOUCH_OF_MISERY = 50090
|
||||
SPELL_WRATH_OF_MISERY = 50089
|
||||
};
|
||||
|
||||
enum Misc
|
||||
@@ -56,14 +56,7 @@ enum Misc
|
||||
NPC_CRYSTAL_HANDLER = 26627,
|
||||
NPC_SUMMON_CRYSTAL_HANDLER_TARGET = 27583,
|
||||
|
||||
EVENT_SUMMON_FETID_TROLL = 1,
|
||||
EVENT_SUMMON_SHADOWCASTER = 2,
|
||||
EVENT_SUMMON_HULKING_CORPSE = 3,
|
||||
EVENT_SUMMON_CRYSTAL_HANDLER = 4,
|
||||
EVENT_CAST_OFFENSIVE_SPELL = 5,
|
||||
EVENT_KILL_TALK = 6,
|
||||
EVENT_CHECK_PHASE = 7,
|
||||
EVENT_SPELL_SUMMON_MINIONS = 8,
|
||||
EVENT_KILL_TALK = 1,
|
||||
|
||||
ROOM_RIGHT = 0,
|
||||
ROOM_LEFT = 1,
|
||||
@@ -77,198 +70,215 @@ std::unordered_map<uint32, std::tuple <uint32, Position>> const npcSummon =
|
||||
{ ROOM_STAIRS, { NPC_CRYSTAL_CHANNEL_TARGET, { -378.40f, -813.13f, 59.74f, 0.0f } } },
|
||||
};
|
||||
|
||||
class boss_novos : public CreatureScript
|
||||
// 26631
|
||||
struct boss_novos : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_novos() : CreatureScript("boss_novos") { }
|
||||
boss_novos(Creature* creature) : BossAI(creature, DATA_NOVOS) { }
|
||||
|
||||
struct boss_novosAI : public BossAI
|
||||
void Reset() override
|
||||
{
|
||||
boss_novosAI(Creature* creature) : BossAI(creature, DATA_NOVOS)
|
||||
{
|
||||
}
|
||||
BossAI::Reset();
|
||||
instance->SetBossState(DATA_NOVOS_CRYSTALS, IN_PROGRESS);
|
||||
instance->SetBossState(DATA_NOVOS_CRYSTALS, NOT_STARTED);
|
||||
_crystalCounter = 0;
|
||||
_summonTargetRightGUID.Clear();
|
||||
_summonTargetLeftGUID.Clear();
|
||||
_stage = 0;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
BossAI::Reset();
|
||||
instance->SetBossState(DATA_NOVOS_CRYSTALS, IN_PROGRESS);
|
||||
instance->SetBossState(DATA_NOVOS_CRYSTALS, NOT_STARTED);
|
||||
_crystalCounter = 0;
|
||||
_summonTargetRightGUID.Clear();
|
||||
_summonTargetLeftGUID.Clear();
|
||||
_stage = 0;
|
||||
me->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
|
||||
me->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
_achievement = true;
|
||||
}
|
||||
|
||||
_achievement = true;
|
||||
}
|
||||
uint32 GetData(uint32 data) const override
|
||||
{
|
||||
if (data == me->GetEntry())
|
||||
return uint32(_achievement);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 data) const override
|
||||
{
|
||||
if (data == me->GetEntry())
|
||||
return uint32(_achievement);
|
||||
return 0;
|
||||
}
|
||||
void SetData(uint32 type, uint32) override
|
||||
{
|
||||
if (type == me->GetEntry())
|
||||
_achievement = false;
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32) override
|
||||
{
|
||||
if (type == me->GetEntry())
|
||||
_achievement = false;
|
||||
}
|
||||
void MoveInLineOfSight(Unit* /*who*/) override { }
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override { }
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
BossAI::JustEngagedWith(who);
|
||||
scheduler.ClearValidator();
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
BossAI::JustEngagedWith(who);
|
||||
ScheduleTimedEvent(3s, [&] {
|
||||
if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET))
|
||||
trigger->CastSpell(trigger, SPELL_SUMMON_FETID_TROLL_CORPSE, true, nullptr, nullptr, me->GetGUID());
|
||||
}, 3s);
|
||||
|
||||
events.ScheduleEvent(EVENT_SUMMON_FETID_TROLL, 3s);
|
||||
events.ScheduleEvent(EVENT_SUMMON_SHADOWCASTER, 9s);
|
||||
events.ScheduleEvent(EVENT_SUMMON_HULKING_CORPSE, 30s);
|
||||
events.ScheduleEvent(EVENT_SUMMON_CRYSTAL_HANDLER, 20s);
|
||||
events.ScheduleEvent(EVENT_CHECK_PHASE, 80s);
|
||||
ScheduleTimedEvent(9s, [&] {
|
||||
if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET))
|
||||
trigger->CastSpell(trigger, SPELL_SUMMON_RISEN_SHADOWCASTER, true, nullptr, nullptr, me->GetGUID());
|
||||
}, 10s);
|
||||
|
||||
me->CastSpell(me, SPELL_ARCANE_BLAST, true);
|
||||
me->CastSpell(me, SPELL_ARCANE_FIELD, true);
|
||||
me->CastSpell(me, SPELL_DESPAWN_CRYSTAL_HANDLER, true);
|
||||
ScheduleTimedEvent(30s, [&] {
|
||||
if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET))
|
||||
trigger->CastSpell(trigger, SPELL_SUMMON_HULKING_CORPSE, true, nullptr, nullptr, me->GetGUID());
|
||||
}, 30s);
|
||||
|
||||
for (auto& itr : npcSummon)
|
||||
scheduler.Schedule(70s, [this](TaskContext context) {
|
||||
if (me->HasAura(SPELL_BEAM_CHANNEL))
|
||||
{
|
||||
uint32 summonEntry;
|
||||
Position summonPos;
|
||||
std::tie(summonEntry, summonPos) = itr.second;
|
||||
if (Creature* creature = me->SummonCreature(summonEntry, summonPos))
|
||||
switch (itr.first)
|
||||
{
|
||||
case ROOM_LEFT:
|
||||
_summonTargetLeftGUID = creature->GetGUID();
|
||||
break;
|
||||
case ROOM_RIGHT:
|
||||
_summonTargetRightGUID = creature->GetGUID();
|
||||
break;
|
||||
}
|
||||
context.Repeat(2s);
|
||||
return;
|
||||
}
|
||||
|
||||
me->SetGuidValue(UNIT_FIELD_TARGET, ObjectGuid::Empty);
|
||||
me->RemoveAllAuras();
|
||||
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
scheduler.CancelAll();
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
BossAI::JustDied(killer);
|
||||
instance->SetBossState(DATA_NOVOS_CRYSTALS, DONE);
|
||||
}
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
||||
scheduler.SetValidator([this] {
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||
});
|
||||
|
||||
ScheduleTimedEvent(5s, 10s, [&] {
|
||||
DoCastRandomTarget(SPELL_BLIZZARD);
|
||||
}, 12s, 25s);
|
||||
|
||||
ScheduleTimedEvent(5s, 10s, [&] {
|
||||
DoCastRandomTarget(SPELL_WRATH_OF_MISERY);
|
||||
}, 8s, 16s);
|
||||
|
||||
if (IsHeroic())
|
||||
{
|
||||
Talk(SAY_KILL);
|
||||
events.ScheduleEvent(EVENT_KILL_TALK, 6s);
|
||||
ScheduleTimedEvent(10s, [&] {
|
||||
DoCastAOE(SPELL_SUMMON_MINIONS);
|
||||
}, 37s, 55s);
|
||||
}
|
||||
});
|
||||
|
||||
for (Seconds timer : { 16s, 32s, 48s, 64s })
|
||||
{
|
||||
me->m_Events.AddEventAtOffset([&] {
|
||||
Talk(SAY_SUMMONING_ADDS);
|
||||
Talk(EMOTE_SUMMONING_ADDS);
|
||||
if (Creature* target = ObjectAccessor::GetCreature(*me, _stage ? _summonTargetLeftGUID : _summonTargetRightGUID))
|
||||
target->CastSpell(target, SPELL_SUMMON_CRYSTAL_HANDLER, true, nullptr, nullptr, me->GetGUID());
|
||||
_stage = _stage ? 0 : 1;
|
||||
}, timer);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
me->SetGuidValue(UNIT_FIELD_TARGET, ObjectGuid::Empty);
|
||||
me->RemoveAllAuras();
|
||||
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
||||
|
||||
DoCastSelf(SPELL_ARCANE_BLAST, true);
|
||||
DoCastSelf(SPELL_ARCANE_FIELD, true);
|
||||
DoCastSelf(SPELL_DESPAWN_CRYSTAL_HANDLER, true);
|
||||
|
||||
for (auto& itr : npcSummon)
|
||||
{
|
||||
summons.Summon(summon);
|
||||
if (me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) && summon->GetEntry() != NPC_CRYSTAL_CHANNEL_TARGET && summon->GetEntry() != NPC_CRYSTAL_HANDLER)
|
||||
uint32 summonEntry;
|
||||
Position summonPos;
|
||||
std::tie(summonEntry, summonPos) = itr.second;
|
||||
if (Creature* creature = me->SummonCreature(summonEntry, summonPos))
|
||||
switch (itr.first)
|
||||
{
|
||||
case ROOM_LEFT:
|
||||
_summonTargetLeftGUID = creature->GetGUID();
|
||||
break;
|
||||
case ROOM_RIGHT:
|
||||
_summonTargetRightGUID = creature->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
BossAI::JustDied(killer);
|
||||
instance->SetBossState(DATA_NOVOS_CRYSTALS, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
if (!events.HasTimeUntilEvent(EVENT_KILL_TALK))
|
||||
{
|
||||
Talk(SAY_KILL);
|
||||
events.ScheduleEvent(EVENT_KILL_TALK, 6s);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
|
||||
// Phase 1
|
||||
if (me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
|
||||
{
|
||||
if (summon->GetEntry() != NPC_CRYSTAL_CHANNEL_TARGET && summon->GetEntry() != NPC_CRYSTAL_HANDLER)
|
||||
summon->SetReactState(REACT_DEFENSIVE);
|
||||
else if (summon->GetEntry() != NPC_CRYSTAL_CHANNEL_TARGET)
|
||||
|
||||
if (summon->GetEntry() == NPC_FETID_TROLL_CORPSE)
|
||||
summon->GetMotionMaster()->MovePoint(1, -373.56f, -770.86f, 28.59f);
|
||||
|
||||
if (summon->EntryEquals(NPC_CRYSTAL_HANDLER))
|
||||
summon->SetInCombatWithZone();
|
||||
}
|
||||
// Phase 2
|
||||
else if (summon->GetEntry() != NPC_CRYSTAL_CHANNEL_TARGET)
|
||||
summon->SetInCombatWithZone();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
|
||||
{
|
||||
if (summon->GetEntry() == NPC_FETID_TROLL_CORPSE)
|
||||
summon->DespawnOrUnsummon(10s);
|
||||
}
|
||||
|
||||
void SummonMovementInform(Creature* summon, uint32 movementType, uint32 pathId) override
|
||||
{
|
||||
if (movementType == POINT_MOTION_TYPE && pathId == 1)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
switch (events.ExecuteEvent())
|
||||
if (summon->GetEntry() == NPC_FETID_TROLL_CORPSE)
|
||||
{
|
||||
case EVENT_SUMMON_FETID_TROLL:
|
||||
if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET))
|
||||
trigger->CastSpell(trigger, SPELL_SUMMON_FETID_TROLL_CORPSE, true, nullptr, nullptr, me->GetGUID());
|
||||
events.ScheduleEvent(EVENT_SUMMON_FETID_TROLL, 3s);
|
||||
break;
|
||||
case EVENT_SUMMON_HULKING_CORPSE:
|
||||
if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET))
|
||||
trigger->CastSpell(trigger, SPELL_SUMMON_HULKING_CORPSE, true, nullptr, nullptr, me->GetGUID());
|
||||
events.ScheduleEvent(EVENT_SUMMON_HULKING_CORPSE, 30s);
|
||||
break;
|
||||
case EVENT_SUMMON_SHADOWCASTER:
|
||||
if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET))
|
||||
trigger->CastSpell(trigger, SPELL_SUMMON_RISEN_SHADOWCASTER, true, nullptr, nullptr, me->GetGUID());
|
||||
events.ScheduleEvent(EVENT_SUMMON_SHADOWCASTER, 10s);
|
||||
break;
|
||||
case EVENT_SUMMON_CRYSTAL_HANDLER:
|
||||
if (_crystalCounter++ < 4)
|
||||
{
|
||||
Talk(SAY_SUMMONING_ADDS);
|
||||
Talk(EMOTE_SUMMONING_ADDS);
|
||||
if (Creature* target = ObjectAccessor::GetCreature(*me, _stage ? _summonTargetLeftGUID : _summonTargetRightGUID))
|
||||
target->CastSpell(target, SPELL_SUMMON_CRYSTAL_HANDLER, true, nullptr, nullptr, me->GetGUID());
|
||||
_stage = _stage ? 0 : 1;
|
||||
events.ScheduleEvent(EVENT_SUMMON_CRYSTAL_HANDLER, 20s);
|
||||
}
|
||||
break;
|
||||
case EVENT_CHECK_PHASE:
|
||||
if (me->HasAura(SPELL_BEAM_CHANNEL))
|
||||
{
|
||||
events.ScheduleEvent(EVENT_CHECK_PHASE, 2s);
|
||||
break;
|
||||
}
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_CAST_OFFENSIVE_SPELL, 3s);
|
||||
events.ScheduleEvent(EVENT_SPELL_SUMMON_MINIONS, 10s);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
break;
|
||||
case EVENT_CAST_OFFENSIVE_SPELL:
|
||||
if (!me->HasUnitState(UNIT_STATE_CASTING))
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true))
|
||||
me->CastSpell(target, RAND(SPELL_BLIZZARD, SPELL_FROSTBOLT, SPELL_TOUCH_OF_MISERY), false);
|
||||
|
||||
events.ScheduleEvent(EVENT_CAST_OFFENSIVE_SPELL, 500ms);
|
||||
break;
|
||||
case EVENT_SPELL_SUMMON_MINIONS:
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
{
|
||||
me->CastSpell(me, SPELL_SUMMON_MINIONS, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_SUMMON_MINIONS, 15s);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_SPELL_SUMMON_MINIONS, 500ms);
|
||||
break;
|
||||
DoZoneInCombat(summon);
|
||||
_achievement = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckEvadeIfOutOfCombatArea() const override
|
||||
{
|
||||
return !SelectTargetFromPlayerList(80.0f);
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 _crystalCounter;
|
||||
uint8 _stage;
|
||||
ObjectGuid _summonTargetRightGUID;
|
||||
ObjectGuid _summonTargetLeftGUID;
|
||||
|
||||
bool _achievement;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetDraktharonKeepAI<boss_novosAI>(creature);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
scheduler.Update(diff);
|
||||
events.Update(diff);
|
||||
|
||||
if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
|
||||
DoSpellAttackIfReady(SPELL_FROSTBOLT);
|
||||
}
|
||||
|
||||
bool CheckEvadeIfOutOfCombatArea() const override
|
||||
{
|
||||
return !SelectTargetFromPlayerList(80.0f);
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 _crystalCounter;
|
||||
uint8 _stage;
|
||||
ObjectGuid _summonTargetRightGUID;
|
||||
ObjectGuid _summonTargetLeftGUID;
|
||||
|
||||
bool _achievement;
|
||||
};
|
||||
|
||||
// 51403
|
||||
class spell_novos_despawn_crystal_handler : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_novos_despawn_crystal_handler);
|
||||
@@ -290,6 +300,7 @@ class spell_novos_despawn_crystal_handler : public SpellScript
|
||||
}
|
||||
};
|
||||
|
||||
// 47336
|
||||
class spell_novos_crystal_handler_death_aura : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_novos_crystal_handler_death_aura);
|
||||
@@ -307,6 +318,7 @@ class spell_novos_crystal_handler_death_aura : public AuraScript
|
||||
}
|
||||
};
|
||||
|
||||
// 59910
|
||||
class spell_novos_summon_minions : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_novos_summon_minions);
|
||||
@@ -328,6 +340,7 @@ class spell_novos_summon_minions : public SpellScript
|
||||
}
|
||||
};
|
||||
|
||||
// 2057
|
||||
class achievement_oh_novos : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
@@ -341,7 +354,7 @@ public:
|
||||
|
||||
void AddSC_boss_novos()
|
||||
{
|
||||
new boss_novos();
|
||||
RegisterCreatureAIWithFactory(boss_novos, GetDraktharonKeepAI);
|
||||
RegisterSpellScript(spell_novos_despawn_crystal_handler);
|
||||
RegisterSpellScript(spell_novos_crystal_handler_death_aura);
|
||||
RegisterSpellScript(spell_novos_summon_minions);
|
||||
|
||||
@@ -39,6 +39,7 @@ enum Creatures
|
||||
NPC_KURZEL = 26664,
|
||||
NPC_DRAKKARI_GUARDIAN = 26620,
|
||||
NPC_RISEN_DRAKKARI_WARRIOR = 26635,
|
||||
NPC_FETID_TROLL_CORPSE = 27598,
|
||||
};
|
||||
|
||||
enum GameObjects
|
||||
|
||||
@@ -31,50 +31,39 @@ DoorData const doorData[] =
|
||||
{ 0, 0, DOOR_TYPE_ROOM }
|
||||
};
|
||||
|
||||
class instance_drak_tharon_keep : public InstanceMapScript
|
||||
struct instance_drak_tharon_keep : public InstanceScript
|
||||
{
|
||||
public:
|
||||
instance_drak_tharon_keep() : InstanceMapScript("instance_drak_tharon_keep", MAP_DRAK_THARON_KEEP) { }
|
||||
|
||||
struct instance_drak_tharon_keep_InstanceScript : public InstanceScript
|
||||
instance_drak_tharon_keep(Map* map) : InstanceScript(map)
|
||||
{
|
||||
instance_drak_tharon_keep_InstanceScript(Map* map) : InstanceScript(map)
|
||||
{
|
||||
SetHeaders(DataHeader);
|
||||
SetBossNumber(MAX_ENCOUNTERS);
|
||||
LoadDoorData(doorData);
|
||||
}
|
||||
SetHeaders(DataHeader);
|
||||
SetBossNumber(MAX_ENCOUNTERS);
|
||||
LoadDoorData(doorData);
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go) override
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_NOVOS_CRYSTAL_1:
|
||||
case GO_NOVOS_CRYSTAL_2:
|
||||
case GO_NOVOS_CRYSTAL_3:
|
||||
case GO_NOVOS_CRYSTAL_4:
|
||||
AddDoor(go);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectRemove(GameObject* go) override
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_NOVOS_CRYSTAL_1:
|
||||
case GO_NOVOS_CRYSTAL_2:
|
||||
case GO_NOVOS_CRYSTAL_3:
|
||||
case GO_NOVOS_CRYSTAL_4:
|
||||
RemoveDoor(go);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||
void OnGameObjectCreate(GameObject* go) override
|
||||
{
|
||||
return new instance_drak_tharon_keep_InstanceScript(map);
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_NOVOS_CRYSTAL_1:
|
||||
case GO_NOVOS_CRYSTAL_2:
|
||||
case GO_NOVOS_CRYSTAL_3:
|
||||
case GO_NOVOS_CRYSTAL_4:
|
||||
AddDoor(go);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectRemove(GameObject* go) override
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_NOVOS_CRYSTAL_1:
|
||||
case GO_NOVOS_CRYSTAL_2:
|
||||
case GO_NOVOS_CRYSTAL_3:
|
||||
case GO_NOVOS_CRYSTAL_4:
|
||||
RemoveDoor(go);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -121,7 +110,7 @@ class spell_dtk_summon_random_drakkari : public SpellScript
|
||||
|
||||
void AddSC_instance_drak_tharon_keep()
|
||||
{
|
||||
new instance_drak_tharon_keep();
|
||||
RegisterInstanceScript(instance_drak_tharon_keep, MAP_DRAK_THARON_KEEP);
|
||||
RegisterSpellScript(spell_dtk_raise_dead_aura);
|
||||
RegisterSpellScript(spell_dtk_summon_random_drakkari);
|
||||
}
|
||||
|
||||
@@ -63,23 +63,27 @@ public:
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* pCreature) override
|
||||
void OnCreatureCreate(Creature* creature) override
|
||||
{
|
||||
switch (pCreature->GetEntry())
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_DRAKOS:
|
||||
uiDrakosGUID = pCreature->GetGUID();
|
||||
uiDrakosGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_VAROS:
|
||||
uiVarosGUID = pCreature->GetGUID();
|
||||
uiVarosGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_UROM:
|
||||
uiUromGUID = pCreature->GetGUID();
|
||||
uiUromGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_EREGOS:
|
||||
uiEregosGUID = pCreature->GetGUID();
|
||||
uiEregosGUID = creature->GetGUID();
|
||||
break;
|
||||
}
|
||||
|
||||
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
|
||||
if (creature->EntryEquals(NPC_AMBER_DRAKE, NPC_EMERALD_DRAKE, NPC_RUBY_DRAKE))
|
||||
creature->SetFaction(FACTION_FRIENDLY); // Friendly faction to allow interaction from both factions
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* pGo) override
|
||||
|
||||
@@ -30,6 +30,7 @@ enum LokenSpells
|
||||
SPELL_LIGHTNING_NOVA_THUNDERS = 52663,
|
||||
|
||||
SPELL_PULSING_SHOCKWAVE = 52961,
|
||||
SPELL_PULSING_SHOCKWAVE_AURA = 59414,
|
||||
|
||||
// Achievement
|
||||
ACHIEVEMENT_TIMELY_DEATH = 20384
|
||||
@@ -49,15 +50,6 @@ enum Yells
|
||||
EMOTE_NOVA = 9
|
||||
};
|
||||
|
||||
enum LokenEvents
|
||||
{
|
||||
EVENT_LIGHTNING_NOVA = 1,
|
||||
EVENT_SHOCKWAVE = 2,
|
||||
EVENT_ARC_LIGHTNING = 3,
|
||||
EVENT_CHECK_HEALTH = 4,
|
||||
EVENT_AURA_REMOVE = 5
|
||||
};
|
||||
|
||||
struct boss_loken : public BossAI
|
||||
{
|
||||
boss_loken(Creature* creature) : BossAI(creature, DATA_LOKEN), _introDone(false) { }
|
||||
@@ -94,18 +86,49 @@ struct boss_loken : public BossAI
|
||||
_introDone = true;
|
||||
}
|
||||
|
||||
void OnAuraRemove(AuraApplication* auraApp, AuraRemoveMode /*mode*/) override
|
||||
{
|
||||
if (auraApp->GetBase()->GetId() == SPELL_LIGHTNING_NOVA_VISUAL)
|
||||
{
|
||||
me->RemoveAura(SPELL_LIGHTNING_NOVA_THUNDERS);
|
||||
me->ClearUnitState(UNIT_STATE_CASTING);
|
||||
me->ResumeChasingVictim();
|
||||
}
|
||||
}
|
||||
|
||||
void ScheduleTasks() override
|
||||
{
|
||||
me->m_Events.AddEventAtOffset([&] {
|
||||
DoCastAOE(SPELL_PULSING_SHOCKWAVE_AURA, true);
|
||||
me->ClearUnitState(UNIT_STATE_CASTING); // the aura above is a channeled spell, so we need this
|
||||
DoCastSelf(SPELL_PULSING_SHOCKWAVE);
|
||||
}, 3s);
|
||||
|
||||
ScheduleTimedEvent(15s, [&] {
|
||||
Talk(SAY_NOVA);
|
||||
Talk(EMOTE_NOVA);
|
||||
DoCastSelf(SPELL_LIGHTNING_NOVA_VISUAL, true);
|
||||
DoCastSelf(SPELL_LIGHTNING_NOVA_THUNDERS, true);
|
||||
DoCastAOE(SPELL_LIGHTNING_NOVA);
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
}, 15s);
|
||||
|
||||
if (IsHeroic())
|
||||
{
|
||||
ScheduleTimedEvent(10s, [&] {
|
||||
DoCastRandomTarget(SPELL_ARC_LIGHTNING, 0, 100.0f, false);
|
||||
}, 12s);
|
||||
|
||||
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_TIMELY_DEATH);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
me->m_Events.KillAllEvents(false);
|
||||
_JustEngagedWith();
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
events.ScheduleEvent(EVENT_ARC_LIGHTNING, 10s);
|
||||
events.ScheduleEvent(EVENT_SHOCKWAVE, 3s);
|
||||
events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 15s);
|
||||
|
||||
if (IsHeroic())
|
||||
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_TIMELY_DEATH);
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
@@ -122,46 +145,6 @@ struct boss_loken : public BossAI
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_LIGHTNING_NOVA:
|
||||
Talk(SAY_NOVA);
|
||||
events.Repeat(15s);
|
||||
me->CastSpell(me, SPELL_LIGHTNING_NOVA_VISUAL, true);
|
||||
me->CastSpell(me, SPELL_LIGHTNING_NOVA_THUNDERS, true);
|
||||
|
||||
events.DelayEvents(5s);
|
||||
events.ScheduleEvent(EVENT_AURA_REMOVE, me->GetMap()->IsHeroic() ? 4s : 5s);
|
||||
|
||||
me->CastSpell(me, SPELL_LIGHTNING_NOVA, false);
|
||||
break;
|
||||
case EVENT_SHOCKWAVE:
|
||||
me->CastSpell(me, SPELL_PULSING_SHOCKWAVE, false);
|
||||
break;
|
||||
case EVENT_ARC_LIGHTNING:
|
||||
if (Unit* target = SelectTargetFromPlayerList(100, SPELL_ARC_LIGHTNING))
|
||||
me->CastSpell(target, SPELL_ARC_LIGHTNING, false);
|
||||
|
||||
events.Repeat(12s);
|
||||
break;
|
||||
case EVENT_AURA_REMOVE:
|
||||
me->RemoveAura(SPELL_LIGHTNING_NOVA_THUNDERS);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
bool _introDone;
|
||||
};
|
||||
|
||||
@@ -334,7 +334,6 @@ public:
|
||||
SetDespawnAtEnd(false);
|
||||
ResetEvent();
|
||||
|
||||
me->SetFaction(FACTION_FRIENDLY);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER);
|
||||
|
||||
@@ -366,21 +365,12 @@ public:
|
||||
case ACTION_START_ESCORT_EVENT:
|
||||
Start(false, ObjectGuid::Empty, 0, true, false);
|
||||
Talk(SAY_BRANN_ESCORT_START);
|
||||
me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->SetRegeneratingHealth(true);
|
||||
break;
|
||||
case ACTION_START_TRIBUNAL:
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers();
|
||||
if (!PlayerList.IsEmpty())
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
{
|
||||
me->SetFaction(i->GetSource()->GetFaction());
|
||||
break;
|
||||
}
|
||||
|
||||
SetEscortPaused(false);
|
||||
InitializeEvent();
|
||||
me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE);
|
||||
@@ -394,7 +384,6 @@ public:
|
||||
break;
|
||||
case ACTION_GO_TO_SJONNIR:
|
||||
Talk(SAY_BRANN_ENTRANCE_MEET);
|
||||
me->SetFaction(FACTION_FRIENDLY);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetRegeneratingHealth(true);
|
||||
SetEscortPaused(false);
|
||||
@@ -406,7 +395,6 @@ public:
|
||||
me->SetImmuneToAll(true);
|
||||
break;
|
||||
case ACTION_START_SJONNIR_FIGHT:
|
||||
me->SetFaction(FACTION_FRIENDLY);
|
||||
SetEscortPaused(false);
|
||||
break;
|
||||
case ACTION_SJONNIR_DEAD:
|
||||
|
||||
@@ -209,14 +209,14 @@ public:
|
||||
enum BossIoCEvents
|
||||
{
|
||||
EVENT_CHECK_RAGE = 1,
|
||||
EVENT_BRUTAL_STRIKE = 2,
|
||||
EVENT_MORTAL_STRIKE = 2,
|
||||
EVENT_CRUSHING_LEAP = 3,
|
||||
EVENT_DAGGER_THROW = 4,
|
||||
};
|
||||
|
||||
enum BossIoCSpells
|
||||
{
|
||||
SPELL_IOCBOSS_BRUTAL_STRIKE = 58460,
|
||||
SPELL_IOCBOSS_MORTAL_STRIKE = 39171,
|
||||
SPELL_IOCBOSS_CRUSHING_LEAP = 68506,
|
||||
SPELL_IOCBOSS_DAGGER_THROW = 67280,
|
||||
SPELL_IOCBOSS_RAGE = 66776,
|
||||
@@ -262,7 +262,7 @@ public:
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
events.ScheduleEvent(EVENT_CHECK_RAGE, 2s);
|
||||
events.ScheduleEvent(EVENT_BRUTAL_STRIKE, 6s);
|
||||
events.ScheduleEvent(EVENT_MORTAL_STRIKE, 6s);
|
||||
events.ScheduleEvent(EVENT_CRUSHING_LEAP, 22s);
|
||||
events.ScheduleEvent(EVENT_DAGGER_THROW, 10s);
|
||||
}
|
||||
@@ -282,8 +282,8 @@ public:
|
||||
CheckRageBuff();
|
||||
events.Repeat(2s);
|
||||
break;
|
||||
case EVENT_BRUTAL_STRIKE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_IOCBOSS_BRUTAL_STRIKE, false);
|
||||
case EVENT_MORTAL_STRIKE:
|
||||
DoCastVictim(SPELL_IOCBOSS_MORTAL_STRIKE);
|
||||
events.Repeat(6s);
|
||||
break;
|
||||
case EVENT_CRUSHING_LEAP:
|
||||
|
||||
@@ -1989,6 +1989,40 @@ class spell_soul_deflection : public AuraScript
|
||||
}
|
||||
};
|
||||
|
||||
enum SpellBloodHaze
|
||||
{
|
||||
SPELL_BLOODSPORE_HAZE = 50380,
|
||||
SPELL_PSYCHOSIS = 50396
|
||||
};
|
||||
|
||||
// 50380 - Bloodspore Haze
|
||||
class spell_bloodspore_haze : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_bloodspore_haze);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_PSYCHOSIS });
|
||||
}
|
||||
|
||||
void HandleEffectHit(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (!GetHitUnit())
|
||||
return;
|
||||
|
||||
if (GetHitUnit()->GetAuraCount(SPELL_BLOODSPORE_HAZE) >= 5)
|
||||
{
|
||||
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_PSYCHOSIS, true);
|
||||
GetHitUnit()->RemoveAura(SPELL_BLOODSPORE_HAZE);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_bloodspore_haze::HandleEffectHit, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_borean_tundra()
|
||||
{
|
||||
RegisterSpellScript(spell_q11919_q11940_drake_hunt_aura);
|
||||
@@ -2013,4 +2047,5 @@ void AddSC_borean_tundra()
|
||||
RegisterCreatureAI(npc_jenny);
|
||||
RegisterSpellScript(spell_necropolis_beam);
|
||||
RegisterSpellScript(spell_soul_deflection);
|
||||
RegisterSpellScript(spell_bloodspore_haze);
|
||||
}
|
||||
|
||||
@@ -390,116 +390,6 @@ class spell_q12227_camera_shake : public SpellScript
|
||||
OnEffectHitTarget += SpellEffectFn(spell_q12227_camera_shake::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
// Tallhorn Stage
|
||||
|
||||
enum TallhornStage
|
||||
{
|
||||
//Gameobject
|
||||
OBJECT_HAUNCH = 188665
|
||||
};
|
||||
|
||||
class npc_tallhorn_stag : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_tallhorn_stag() : CreatureScript("npc_tallhorn_stag") { }
|
||||
|
||||
struct npc_tallhorn_stagAI : public ScriptedAI
|
||||
{
|
||||
npc_tallhorn_stagAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_phase = 1;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 /*diff*/) override
|
||||
{
|
||||
if (_phase == 1)
|
||||
{
|
||||
if (me->FindNearestGameObject(OBJECT_HAUNCH, 2.0f))
|
||||
{
|
||||
me->SetStandState(UNIT_STAND_STATE_DEAD);
|
||||
me->SetImmuneToPC(true);
|
||||
me->ReplaceAllDynamicFlags(UNIT_DYNFLAG_DEAD);
|
||||
}
|
||||
_phase = 0;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
uint8 _phase;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new npc_tallhorn_stagAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// Amberpine Woodsman
|
||||
|
||||
enum AmberpineWoodsman
|
||||
{
|
||||
// Creature
|
||||
NPC_TALLHORN_STAG = 26363
|
||||
};
|
||||
|
||||
enum AmberpineWoodsmanEvents
|
||||
{
|
||||
EVENT_WOODSMAN_1 = 1,
|
||||
EVENT_WOODSMAN_2 = 2
|
||||
};
|
||||
|
||||
class npc_amberpine_woodsman : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_amberpine_woodsman() : CreatureScript("npc_amberpine_woodsman") { }
|
||||
|
||||
struct npc_amberpine_woodsmanAI : public ScriptedAI
|
||||
{
|
||||
npc_amberpine_woodsmanAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
if (me->FindNearestCreature(NPC_TALLHORN_STAG, 0.2f))
|
||||
{
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING);
|
||||
}
|
||||
else
|
||||
_events.ScheduleEvent(EVENT_WOODSMAN_1, 0ms);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
while (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_WOODSMAN_1:
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_LOOT);
|
||||
_events.ScheduleEvent(EVENT_WOODSMAN_2, 3s);
|
||||
break;
|
||||
case EVENT_WOODSMAN_2:
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_ATTACK1H);
|
||||
_events.ScheduleEvent(EVENT_WOODSMAN_1, 4s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
UpdateVictim();
|
||||
}
|
||||
private:
|
||||
EventMap _events;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new npc_amberpine_woodsmanAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## Quest 12288: Overwhelmed!
|
||||
@@ -1178,8 +1068,6 @@ void AddSC_grizzly_hills()
|
||||
new npc_emily();
|
||||
new npc_mrfloppy();
|
||||
new npc_ravenous_worg();
|
||||
new npc_tallhorn_stag();
|
||||
new npc_amberpine_woodsman();
|
||||
RegisterCreatureAI(npc_wounded_skirmisher);
|
||||
RegisterSpellScript(spell_renew_skirmisher);
|
||||
new npc_venture_co_straggler();
|
||||
|
||||
@@ -49,7 +49,6 @@ class spell_q12726_song_of_wind_and_water : public SpellScript
|
||||
cr->SetDisplayId(cr->GetDisplayId() == NPC_SOWAW_WATER_MODEL ? NPC_SOWAW_WIND_MODEL : NPC_SOWAW_WATER_MODEL);
|
||||
if (Player* player = cr->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
{
|
||||
player->KilledMonsterCredit(cr->GetDisplayId() == NPC_SOWAW_WATER_MODEL ? 29008 : 29009);
|
||||
CreatureTemplate const* ct = sObjectMgr->GetCreatureTemplate(cr->GetDisplayId() == NPC_SOWAW_WIND_MODEL ? NPC_SOWAW_WIND_ELEMENTAL : NPC_SOWAW_WATER_ELEMENTAL);
|
||||
for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i)
|
||||
cr->m_spells[i] = ct->spells[i];
|
||||
@@ -1107,108 +1106,6 @@ class spell_q12589_shoot_rjr : public SpellScript
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## Quest: Reconnaissance Flight (12671)
|
||||
######*/
|
||||
enum ReconnaissanceFlight
|
||||
{
|
||||
NPC_PLANE = 28710, // Vic's Flying Machine
|
||||
NPC_PILOT = 28646,
|
||||
|
||||
VIC_SAY_0 = 0,
|
||||
VIC_SAY_1 = 1,
|
||||
VIC_SAY_2 = 2,
|
||||
VIC_SAY_3 = 3,
|
||||
VIC_SAY_4 = 4,
|
||||
VIC_SAY_5 = 5,
|
||||
VIC_SAY_6 = 6,
|
||||
PLANE_EMOTE = 0,
|
||||
|
||||
AURA_ENGINE = 52255, // Engine on Fire
|
||||
|
||||
SPELL_LAND = 52226, // Land Flying Machine
|
||||
SPELL_CREDIT = 53328 // Land Flying Machine Credit
|
||||
};
|
||||
|
||||
class npc_vics_flying_machine : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_vics_flying_machine() : CreatureScript("npc_vics_flying_machine") { }
|
||||
|
||||
struct npc_vics_flying_machineAI : public VehicleAI
|
||||
{
|
||||
npc_vics_flying_machineAI(Creature* creature) : VehicleAI(creature)
|
||||
{
|
||||
pointId = 0;
|
||||
}
|
||||
|
||||
uint8 pointId;
|
||||
|
||||
void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply) override
|
||||
{
|
||||
if (apply && passenger->IsPlayer())
|
||||
{
|
||||
me->GetMotionMaster()->MovePath(NPC_PLANE, FORCED_MOVEMENT_NONE, PathSource::WAYPOINT_MGR);
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 /*id*/) override
|
||||
{
|
||||
if (type != ESCORT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
if (Vehicle* veh = me->GetVehicleKit())
|
||||
if (Unit* pilot = veh->GetPassenger(0))
|
||||
switch (pointId)
|
||||
{
|
||||
case 5:
|
||||
pilot->ToCreature()->AI()->Talk(VIC_SAY_0);
|
||||
break;
|
||||
case 11:
|
||||
pilot->ToCreature()->AI()->Talk(VIC_SAY_1);
|
||||
break;
|
||||
case 12:
|
||||
pilot->ToCreature()->AI()->Talk(VIC_SAY_2);
|
||||
break;
|
||||
case 14:
|
||||
pilot->ToCreature()->AI()->Talk(VIC_SAY_3);
|
||||
break;
|
||||
case 15:
|
||||
pilot->ToCreature()->ToCreature()->AI()->Talk(VIC_SAY_4);
|
||||
break;
|
||||
case 17:
|
||||
pilot->ToCreature()->AI()->Talk(VIC_SAY_5);
|
||||
break;
|
||||
case 21:
|
||||
pilot->ToCreature()->AI()->Talk(VIC_SAY_6);
|
||||
break;
|
||||
case 25:
|
||||
Talk(PLANE_EMOTE);
|
||||
DoCastSelf(AURA_ENGINE);
|
||||
break;
|
||||
}
|
||||
pointId++;
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
|
||||
{
|
||||
if (spell->Id == SPELL_LAND)
|
||||
{
|
||||
Unit* passenger = me->GetVehicleKit()->GetPassenger(1); // player should be on seat 1
|
||||
if (passenger && passenger->IsPlayer())
|
||||
passenger->CastSpell(passenger, SPELL_CREDIT, true);
|
||||
|
||||
me->DespawnOrUnsummon();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new npc_vics_flying_machineAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## Quest Dreadsaber Mastery: Stalking the Prey (12550)
|
||||
######*/
|
||||
@@ -1296,7 +1193,6 @@ void AddSC_sholazar_basin()
|
||||
new npc_jungle_punch_target();
|
||||
RegisterSpellScript(spell_q12620_the_lifewarden_wrath);
|
||||
RegisterSpellScript(spell_q12589_shoot_rjr);
|
||||
new npc_vics_flying_machine();
|
||||
RegisterSpellScript(spell_shango_tracks);
|
||||
|
||||
RegisterSpellScript(spell_q12611_deathbolt);
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
enum qSniffingOutThePerpetrator
|
||||
{
|
||||
NPC_FROSTHOUND = 29677,
|
||||
NPC_FROSTBITE = 29903,
|
||||
SPELL_SUMMON_PURSUERS_PERIODIC = 54993,
|
||||
SPELL_SNIFFING_CREDIT = 55477,
|
||||
TALK_EMOTE_FROSTHOUND_SNIFF = 0,
|
||||
@@ -41,7 +42,7 @@ enum qSniffingOutThePerpetrator
|
||||
|
||||
struct npc_frosthound : public npc_escortAI
|
||||
{
|
||||
explicit npc_frosthound(Creature* creature) : npc_escortAI(creature), _summons(creature) {}
|
||||
explicit npc_frosthound(Creature* creature) : npc_escortAI(creature), _summons(creature), _completionWaypoint((creature->GetEntry() == NPC_FROSTBITE) ? 19 : 34) { }
|
||||
|
||||
void AttackStart(Unit* /*who*/) override {}
|
||||
void JustEngagedWith(Unit* /*who*/) override {}
|
||||
@@ -77,20 +78,15 @@ struct npc_frosthound : public npc_escortAI
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
switch (waypointId)
|
||||
if (waypointId == 0)
|
||||
Talk(TALK_SEEN, player);
|
||||
else if (waypointId == _completionWaypoint)
|
||||
{
|
||||
case 0:
|
||||
Talk(TALK_SEEN, player);
|
||||
break;
|
||||
case 34:
|
||||
Talk(TALK_EMOTE_TRACKED_COMPLETE, me);
|
||||
Talk(TALK_CONFRONT, player);
|
||||
if (Unit* summoner = me->ToTempSummon()->GetSummonerUnit())
|
||||
summoner->ToPlayer()->KilledMonsterCredit(NPC_FROSTHOUND);
|
||||
_summons.DespawnAll();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
Talk(TALK_EMOTE_TRACKED_COMPLETE, me);
|
||||
Talk(TALK_CONFRONT, player);
|
||||
if (Unit* summoner = me->ToTempSummon()->GetSummonerUnit())
|
||||
summoner->ToPlayer()->KilledMonsterCredit(NPC_FROSTHOUND); // same credit for Alliance and Horde
|
||||
_summons.DespawnAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,6 +108,7 @@ struct npc_frosthound : public npc_escortAI
|
||||
|
||||
private:
|
||||
SummonList _summons;
|
||||
uint32 _completionWaypoint;
|
||||
};
|
||||
|
||||
enum eIronWatcher
|
||||
|
||||
@@ -265,6 +265,7 @@ enum OverlordDrakuru
|
||||
NPC_TOTALLY_GENERIC_BUNNY = 29100,
|
||||
NPC_TOTALLY_GENERIC_BUNNY_JSB = 28960,
|
||||
GO_DRAKURUS_LAST_WISH = 202357,
|
||||
GO_DRAKURUS_BONE = 191458,
|
||||
|
||||
ACTION_SUMMON_DRAKURU_LAST_WISH = 1,
|
||||
ACTION_DESTROY_DRAKURU_LAST_WISH = 2,
|
||||
@@ -316,7 +317,7 @@ struct npc_overlord_drakuru_betrayal : public ScriptedAI
|
||||
{
|
||||
npc_overlord_drakuru_betrayal(Creature* creature) : ScriptedAI(creature), _summons(me), _state(BETRAYAL_NOT_STARTED)
|
||||
{
|
||||
me->SetCombatMovement(false);
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
@@ -375,7 +376,7 @@ struct npc_overlord_drakuru_betrayal : public ScriptedAI
|
||||
{
|
||||
if (Player* player = who->ToPlayer())
|
||||
{
|
||||
bool shouldStartEvent = (_state == BETRAYAL_NOT_STARTED) && IsPlayerOnQuest(player) && player->HasAura(SPELL_SCOURGE_DISGUISE) && player->IsWithinDistInMap(me, 80.0f);
|
||||
bool shouldStartEvent = (_state == BETRAYAL_NOT_STARTED) && IsPlayerOnQuest(player) && player->HasAura(SPELL_SCOURGE_DISGUISE) && player->IsWithinDistInMap(me, 80.0f) && !me->FindNearestGameObject(GO_DRAKURUS_BONE, 80.0f);
|
||||
if (shouldStartEvent)
|
||||
{
|
||||
me->SetVisible(true);
|
||||
@@ -587,6 +588,7 @@ struct npc_overlord_drakuru_betrayal : public ScriptedAI
|
||||
lich->GetMotionMaster()->MovePoint(0, 6141.2393, -2011.2728, 589.8653);
|
||||
break;
|
||||
case EVENT_BETRAYAL_EPILOGUE_10:
|
||||
_state = BETRAYAL_EVADE;
|
||||
EnterEvadeMode(EVADE_REASON_OTHER);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -141,13 +141,15 @@ public:
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (!who || me->getStandState() != UNIT_STAND_STATE_SLEEP || !who->IsPlayer() || me->GetDistance2d(who) > 90.0f || who->ToPlayer()->IsGameMaster())
|
||||
if (!who || me->getStandState() != UNIT_STAND_STATE_SLEEP || !who->IsPlayer() ||
|
||||
who->ToPlayer()->IsGameMaster() || me->GetDistance2d(who) > 90.0f ||
|
||||
!me->isInFront(who, M_PI / 4.0f) || !me->IsWithinLOSInMap(who))
|
||||
return;
|
||||
|
||||
me->SetInCombatWithZone();
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
|
||||
ScheduleUniqueTimedEvent(5s, [&] { // 15s
|
||||
ScheduleUniqueTimedEvent(5s, [&] {
|
||||
me->SetStandState(UNIT_STAND_STATE_SUBMERGED);
|
||||
DoCastSelf(SPELL_SUMMON_ESSENCE_OF_SUFFERING);
|
||||
}, EVENT_ESSENCE_OF_SUFFERING);
|
||||
|
||||
Reference in New Issue
Block a user