mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-16 02:20:27 +00:00
fix(Scripts/HellfireRamparts): modernise boss scripts for Hellfire Ramparts (#16250)
* first two bosses * add vazruden+nazan * dumb mistake fix * remove double summon say from Omor * new attempt at scheduling talking * fix boolean condition for speaking * debug * revert debug * initial * diff comment
This commit is contained in:
@@ -34,16 +34,7 @@ enum Spells
|
||||
SPELL_SHADOW_BOLT = 30686,
|
||||
SPELL_SUMMON_FIENDISH_HOUND = 30707,
|
||||
SPELL_TREACHEROUS_AURA = 30695,
|
||||
SPELL_DEMONIC_SHIELD = 31901,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
EVENT_SUMMON1 = 1,
|
||||
EVENT_SUMMON2 = 2,
|
||||
EVENT_TREACHEROUS_AURA = 3,
|
||||
EVENT_DEMONIC_SHIELD = 4,
|
||||
EVENT_KILL_TALK = 5
|
||||
SPELL_DEMONIC_SHIELD = 31901
|
||||
};
|
||||
|
||||
class boss_omor_the_unscarred : public CreatureScript
|
||||
@@ -56,33 +47,63 @@ public:
|
||||
boss_omor_the_unscarredAI(Creature* creature) : BossAI(creature, DATA_OMOR_THE_UNSCARRED)
|
||||
{
|
||||
SetCombatMovement(false);
|
||||
|
||||
scheduler.SetValidator([this]
|
||||
{
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||
});
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Talk(SAY_WIPE);
|
||||
BossAI::Reset();
|
||||
_Reset();
|
||||
_targetGUID.Clear();
|
||||
|
||||
ScheduleHealthCheckEvent(21, [&]{
|
||||
DoCastSelf(SPELL_DEMONIC_SHIELD);
|
||||
scheduler.Schedule(15s, [this](TaskContext context)
|
||||
{
|
||||
DoCastSelf(SPELL_DEMONIC_SHIELD);
|
||||
context.Repeat(15s);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
BossAI::JustEngagedWith(who);
|
||||
_JustEngagedWith();
|
||||
|
||||
events.ScheduleEvent(EVENT_SUMMON1, 10000);
|
||||
events.ScheduleEvent(EVENT_SUMMON2, 25000);
|
||||
events.ScheduleEvent(EVENT_TREACHEROUS_AURA, 6000);
|
||||
events.ScheduleEvent(EVENT_DEMONIC_SHIELD, 1000);
|
||||
scheduler.Schedule(6s, [this](TaskContext context)
|
||||
{
|
||||
if (roll_chance_i(33))
|
||||
{
|
||||
Talk(SAY_CURSE);
|
||||
}
|
||||
DoCastRandomTarget(SPELL_TREACHEROUS_AURA);
|
||||
context.Repeat(12s, 18s);
|
||||
}).Schedule(10s, [this](TaskContext /*context*/)
|
||||
{
|
||||
DoCastSelf(SPELL_SUMMON_FIENDISH_HOUND);
|
||||
}).Schedule(25s, [this](TaskContext context)
|
||||
{
|
||||
DoCastSelf(SPELL_SUMMON_FIENDISH_HOUND);
|
||||
context.Repeat(15s);
|
||||
});
|
||||
}
|
||||
|
||||
void KilledUnit(Unit*) override
|
||||
{
|
||||
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
||||
if(!_hasSpoken)
|
||||
{
|
||||
_hasSpoken = true;
|
||||
Talk(SAY_KILL);
|
||||
events.ScheduleEvent(EVENT_KILL_TALK, 6000);
|
||||
}
|
||||
scheduler.Schedule(6s, [this](TaskContext /*context*/)
|
||||
{
|
||||
_hasSpoken = false;
|
||||
});
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
@@ -92,49 +113,20 @@ public:
|
||||
summon->SetInCombatWithZone();
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_DIE);
|
||||
BossAI::JustDied(killer);
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
void UpdateAI(uint32 /*diff*/) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SUMMON1:
|
||||
Talk(SAY_SUMMON);
|
||||
me->CastSpell(me, SPELL_SUMMON_FIENDISH_HOUND, false);
|
||||
break;
|
||||
case EVENT_SUMMON2:
|
||||
me->CastSpell(me, SPELL_SUMMON_FIENDISH_HOUND, false);
|
||||
events.ScheduleEvent(EVENT_SUMMON2, 15000);
|
||||
break;
|
||||
case EVENT_TREACHEROUS_AURA:
|
||||
if (roll_chance_i(33))
|
||||
Talk(SAY_CURSE);
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
me->CastSpell(target, SPELL_TREACHEROUS_AURA, false);
|
||||
events.ScheduleEvent(EVENT_TREACHEROUS_AURA, urand(12000, 18000));
|
||||
break;
|
||||
case EVENT_DEMONIC_SHIELD:
|
||||
if (me->HealthBelowPct(21))
|
||||
{
|
||||
me->CastSpell(me, SPELL_DEMONIC_SHIELD, false);
|
||||
events.ScheduleEvent(EVENT_DEMONIC_SHIELD, 15000);
|
||||
}
|
||||
else
|
||||
events.ScheduleEvent(EVENT_DEMONIC_SHIELD, 1000);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!me->GetVictim() || !me->isAttackReady())
|
||||
return;
|
||||
|
||||
@@ -153,6 +145,7 @@ public:
|
||||
|
||||
private:
|
||||
ObjectGuid _targetGUID;
|
||||
bool _hasSpoken;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
|
||||
@@ -43,18 +43,14 @@ enum Spells
|
||||
enum Misc
|
||||
{
|
||||
ACTION_FLY_DOWN = 0,
|
||||
|
||||
POINT_MIDDLE = 0,
|
||||
POINT_FLIGHT = 1,
|
||||
POINT_FLIGHT = 1
|
||||
};
|
||||
|
||||
EVENT_SPELL_REVENGE = 1,
|
||||
EVENT_KILL_TALK = 2,
|
||||
EVENT_AGGRO_TALK = 3,
|
||||
EVENT_SPELL_FIREBALL = 4,
|
||||
EVENT_SPELL_CONE_OF_FIRE = 5,
|
||||
EVENT_SPELL_BELLOWING_ROAR = 6,
|
||||
EVENT_CHANGE_POS = 7,
|
||||
EVENT_RESTORE_COMBAT = 8
|
||||
enum GroupPhase
|
||||
{
|
||||
GROUP_PHASE_1 = 0,
|
||||
GROUP_PHASE_2 = 1
|
||||
};
|
||||
|
||||
const Position NazanPos[3] =
|
||||
@@ -158,10 +154,14 @@ class boss_nazan : public CreatureScript
|
||||
public:
|
||||
boss_nazan() : CreatureScript("boss_nazan") { }
|
||||
|
||||
struct boss_nazanAI : public ScriptedAI
|
||||
struct boss_nazanAI : public BossAI
|
||||
{
|
||||
boss_nazanAI(Creature* creature) : ScriptedAI(creature)
|
||||
boss_nazanAI(Creature* creature) : BossAI(creature, DATA_VAZRUDEN)
|
||||
{
|
||||
scheduler.SetValidator([this]
|
||||
{
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||
});
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
@@ -178,8 +178,17 @@ public:
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
events.ScheduleEvent(EVENT_CHANGE_POS, 0);
|
||||
events.ScheduleEvent(EVENT_SPELL_FIREBALL, 5000);
|
||||
scheduler.CancelGroup(GROUP_PHASE_2);
|
||||
scheduler.Schedule(5ms, GROUP_PHASE_1, [this](TaskContext context)
|
||||
{
|
||||
me->GetMotionMaster()->MovePoint(POINT_FLIGHT, NazanPos[urand(0, 2)], false);
|
||||
scheduler.DelayAll(7s);
|
||||
context.Repeat(30s);
|
||||
}).Schedule(5s, GROUP_PHASE_1, [this](TaskContext context)
|
||||
{
|
||||
DoCastRandomTarget(SPELL_FIREBALL);
|
||||
context.Repeat(4s, 6s);
|
||||
});
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
@@ -209,48 +218,37 @@ public:
|
||||
me->SetCanFly(false);
|
||||
me->SetDisableGravity(false);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
events.ScheduleEvent(EVENT_RESTORE_COMBAT, 1);
|
||||
events.ScheduleEvent(EVENT_SPELL_CONE_OF_FIRE, 5000);
|
||||
events.ScheduleEvent(EVENT_SPELL_FIREBALL, 6000);
|
||||
scheduler.CancelGroup(GROUP_PHASE_1);
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
|
||||
scheduler.Schedule(5s, GROUP_PHASE_2, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_CONE_OF_FIRE);
|
||||
context.Repeat(12s);
|
||||
}).Schedule(6s, GROUP_PHASE_2, [this](TaskContext context)
|
||||
{
|
||||
DoCastRandomTarget(SPELL_FIREBALL);
|
||||
context.Repeat(4s, 6s);
|
||||
});
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_SPELL_BELLOWING_ROAR, 10000);
|
||||
{
|
||||
scheduler.Schedule(10s, GROUP_PHASE_2, [this](TaskContext context)
|
||||
{
|
||||
DoCastSelf(SPELL_BELLOWING_ROAR);
|
||||
context.Repeat(30s);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
void UpdateAI(uint32 /*diff*/) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_FIREBALL:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
me->CastSpell(target, SPELL_FIREBALL, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_FIREBALL, urand(4000, 6000));
|
||||
break;
|
||||
case EVENT_CHANGE_POS:
|
||||
me->GetMotionMaster()->MovePoint(POINT_FLIGHT, NazanPos[urand(0, 2)], false);
|
||||
events.DelayEvents(7000);
|
||||
events.ScheduleEvent(EVENT_CHANGE_POS, 30000);
|
||||
break;
|
||||
case EVENT_RESTORE_COMBAT:
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
break;
|
||||
case EVENT_SPELL_CONE_OF_FIRE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_CONE_OF_FIRE, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_CONE_OF_FIRE, 12000);
|
||||
break;
|
||||
case EVENT_SPELL_BELLOWING_ROAR:
|
||||
me->CastSpell(me, SPELL_BELLOWING_ROAR, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_BELLOWING_ROAR, 30000);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!me->IsLevitating())
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
@@ -270,9 +268,15 @@ class boss_vazruden : public CreatureScript
|
||||
public:
|
||||
boss_vazruden() : CreatureScript("boss_vazruden") { }
|
||||
|
||||
struct boss_vazrudenAI : public ScriptedAI
|
||||
struct boss_vazrudenAI : public BossAI
|
||||
{
|
||||
boss_vazrudenAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
boss_vazrudenAI(Creature* creature) : BossAI(creature, DATA_VAZRUDEN)
|
||||
{
|
||||
scheduler.SetValidator([this]
|
||||
{
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||
});
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
@@ -288,17 +292,27 @@ public:
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
events.ScheduleEvent(EVENT_AGGRO_TALK, 5000);
|
||||
events.ScheduleEvent(EVENT_SPELL_REVENGE, 4000);
|
||||
scheduler.Schedule(5s, [this](TaskContext /*context*/)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
}).Schedule(4s, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(DUNGEON_MODE(SPELL_REVENGE, SPELL_REVENGE_H));
|
||||
context.Repeat(6s);
|
||||
});
|
||||
}
|
||||
|
||||
void KilledUnit(Unit*) override
|
||||
{
|
||||
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
||||
if (!_hasSpoken)
|
||||
{
|
||||
_hasSpoken = true;
|
||||
Talk(SAY_KILL);
|
||||
events.ScheduleEvent(EVENT_KILL_TALK, 6000);
|
||||
}
|
||||
scheduler.Schedule(6s, [this](TaskContext /*context*/)
|
||||
{
|
||||
_hasSpoken = false;
|
||||
});
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*type*/, SpellSchoolMask /*school*/) override
|
||||
@@ -315,28 +329,17 @@ public:
|
||||
Talk(SAY_DIE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
void UpdateAI(uint32 /*diff*/) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_AGGRO_TALK:
|
||||
Talk(SAY_AGGRO);
|
||||
break;
|
||||
case EVENT_SPELL_REVENGE:
|
||||
me->CastSpell(me->GetVictim(), DUNGEON_MODE(SPELL_REVENGE, SPELL_REVENGE_H), false);
|
||||
events.ScheduleEvent(EVENT_SPELL_REVENGE, 6000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
bool _hasSpoken;
|
||||
bool _nazanCalled;
|
||||
};
|
||||
|
||||
|
||||
@@ -38,13 +38,7 @@ enum Spells
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_HELLFIRE_WATCHER = 17309,
|
||||
|
||||
EVENT_MORTAL_WOUND = 1,
|
||||
EVENT_SURGE = 2,
|
||||
EVENT_RETALIATION = 3,
|
||||
EVENT_KILL_TALK = 4,
|
||||
EVENT_CHECK_HEALTH = 5
|
||||
NPC_HELLFIRE_WATCHER = 17309
|
||||
};
|
||||
|
||||
class boss_watchkeeper_gargolmar : public CreatureScript
|
||||
@@ -57,21 +51,53 @@ public:
|
||||
boss_watchkeeper_gargolmarAI(Creature* creature) : BossAI(creature, DATA_WATCHKEEPER_GARGOLMAR)
|
||||
{
|
||||
_taunted = false;
|
||||
|
||||
scheduler.SetValidator([this]
|
||||
{
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||
});
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
BossAI::Reset();
|
||||
_Reset();
|
||||
|
||||
ScheduleHealthCheckEvent(50, [&]{
|
||||
Talk(SAY_HEAL);
|
||||
std::list<Creature*> clist;
|
||||
me->GetCreaturesWithEntryInRange(clist, 100.0f, NPC_HELLFIRE_WATCHER);
|
||||
for (std::list<Creature*>::const_iterator itr = clist.begin(); itr != clist.end(); ++itr)
|
||||
(*itr)->AI()->SetData(NPC_HELLFIRE_WATCHER, 0);
|
||||
});
|
||||
|
||||
ScheduleHealthCheckEvent(20, [&]{
|
||||
DoCastSelf(SPELL_RETALIATION);
|
||||
scheduler.Schedule(30s, [this](TaskContext context)
|
||||
{
|
||||
DoCastSelf(SPELL_RETALIATION);
|
||||
context.Repeat(30s);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
BossAI::JustEngagedWith(who);
|
||||
events.ScheduleEvent(EVENT_MORTAL_WOUND, 5000);
|
||||
events.ScheduleEvent(EVENT_SURGE, 3000);
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
|
||||
events.ScheduleEvent(EVENT_RETALIATION, 1000);
|
||||
_JustEngagedWith();
|
||||
|
||||
scheduler.Schedule(5s, [this] (TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_MORTAL_WOUND);
|
||||
context.Repeat(8s);
|
||||
}).Schedule(3s, [this](TaskContext context)
|
||||
{
|
||||
Talk(SAY_SURGE);
|
||||
if(Unit* target = SelectTarget((SelectTargetMethod::MinDistance), 0))
|
||||
{
|
||||
me->CastSpell(target, SPELL_SURGE);
|
||||
}
|
||||
context.Repeat(11s);
|
||||
});
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
@@ -90,68 +116,37 @@ public:
|
||||
|
||||
void KilledUnit(Unit*) override
|
||||
{
|
||||
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
||||
if (!_hasSpoken)
|
||||
{
|
||||
_hasSpoken = true;
|
||||
Talk(SAY_KILL);
|
||||
events.ScheduleEvent(EVENT_KILL_TALK, 6000);
|
||||
}
|
||||
scheduler.Schedule(6s, [this](TaskContext /*context*/)
|
||||
{
|
||||
_hasSpoken = false;
|
||||
});
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_DIE);
|
||||
BossAI::JustDied(killer);
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
void UpdateAI(uint32 /*diff*/) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_MORTAL_WOUND:
|
||||
me->CastSpell(me->GetVictim(), SPELL_MORTAL_WOUND, false);
|
||||
events.ScheduleEvent(EVENT_MORTAL_WOUND, 8000);
|
||||
break;
|
||||
case EVENT_SURGE:
|
||||
Talk(SAY_SURGE);
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::MinDistance, 0))
|
||||
me->CastSpell(target, SPELL_SURGE, false);
|
||||
events.ScheduleEvent(EVENT_SURGE, 11000);
|
||||
break;
|
||||
case EVENT_RETALIATION:
|
||||
if (me->HealthBelowPct(20))
|
||||
{
|
||||
me->CastSpell(me, SPELL_RETALIATION, false);
|
||||
events.ScheduleEvent(EVENT_RETALIATION, 30000);
|
||||
}
|
||||
else
|
||||
events.ScheduleEvent(EVENT_RETALIATION, 500);
|
||||
break;
|
||||
case EVENT_CHECK_HEALTH:
|
||||
if (me->HealthBelowPct(50))
|
||||
{
|
||||
Talk(SAY_HEAL);
|
||||
std::list<Creature*> clist;
|
||||
me->GetCreaturesWithEntryInRange(clist, 100.0f, NPC_HELLFIRE_WATCHER);
|
||||
for (std::list<Creature*>::const_iterator itr = clist.begin(); itr != clist.end(); ++itr)
|
||||
(*itr)->AI()->SetData(NPC_HELLFIRE_WATCHER, 0);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH, 500);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
bool _taunted;
|
||||
bool _hasSpoken;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
|
||||
Reference in New Issue
Block a user