fix(Scripts/Underbog): modernise boss scripts (#16149)

This commit is contained in:
Dan
2023-06-05 04:42:40 +02:00
committed by GitHub
parent 3564027f53
commit 3e19b5e637
6 changed files with 112 additions and 137 deletions

View File

@@ -344,6 +344,32 @@ void MotionMaster::MoveBackwards(Unit* target, float dist)
init.Launch(); init.Launch();
} }
void MotionMaster::MoveForwards(Unit* target, float dist)
{
//like movebackwards, but without the inversion
if (!target)
{
return;
}
Position const& pos = target->GetPosition();
float angle = target->GetAngle(_owner);
G3D::Vector3 point;
point.x = pos.m_positionX + dist * cosf(angle);
point.y = pos.m_positionY + dist * sinf(angle);
point.z = pos.m_positionZ;
if (!_owner->GetMap()->CanReachPositionAndGetValidCoords(_owner, point.x, point.y, point.z, true, true))
{
return;
}
Movement::MoveSplineInit init(_owner);
init.MoveTo(point.x, point.y, point.z, false);
init.SetFacing(target);
init.Launch();
}
void MotionMaster::MoveCircleTarget(Unit* target) void MotionMaster::MoveCircleTarget(Unit* target)
{ {
if (!target) if (!target)

View File

@@ -205,6 +205,7 @@ public:
void MoveChase(Unit* target, float dist) { MoveChase(target, ChaseRange(dist)); } void MoveChase(Unit* target, float dist) { MoveChase(target, ChaseRange(dist)); }
void MoveCircleTarget(Unit* target); void MoveCircleTarget(Unit* target);
void MoveBackwards(Unit* target, float dist); void MoveBackwards(Unit* target, float dist);
void MoveForwards(Unit* target, float dist);
void MoveConfused(); void MoveConfused();
void MoveFleeing(Unit* enemy, uint32 time = 0); void MoveFleeing(Unit* enemy, uint32 time = 0);
void MovePoint(uint32 id, const Position& pos, bool generatePath = true, bool forceDestination = true) void MovePoint(uint32 id, const Position& pos, bool generatePath = true, bool forceDestination = true)

View File

@@ -28,10 +28,6 @@ enum eBlackStalker
SPELL_TAIL_SWEEP = 34267, SPELL_TAIL_SWEEP = 34267,
SPELL_ENRAGE = 15716, SPELL_ENRAGE = 15716,
EVENT_ACID_BREATH = 1,
EVENT_ACID_SPIT = 2,
EVENT_TAIL_SWEEP = 3,
ACTION_MOVE_TO_PLATFORM = 1 ACTION_MOVE_TO_PLATFORM = 1
}; };
@@ -39,6 +35,10 @@ struct boss_ghazan : public BossAI
{ {
boss_ghazan(Creature* creature) : BossAI(creature, DATA_GHAZAN) boss_ghazan(Creature* creature) : BossAI(creature, DATA_GHAZAN)
{ {
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
} }
void InitializeAI() override void InitializeAI() override
@@ -50,31 +50,34 @@ struct boss_ghazan : public BossAI
void Reset() override void Reset() override
{ {
_enraged = false; _Reset();
if (!_reachedPlatform) if (!_reachedPlatform)
{ {
_movedToPlatform = false; _movedToPlatform = false;
} }
BossAI::Reset(); ScheduleHealthCheckEvent(20, [&] {
}
void JustEngagedWith(Unit* who) override
{
events.ScheduleEvent(EVENT_ACID_BREATH, 3s);
events.ScheduleEvent(EVENT_ACID_SPIT, 1s);
events.ScheduleEvent(EVENT_TAIL_SWEEP, DUNGEON_MODE<Milliseconds>(5900ms, 10s));
BossAI::JustEngagedWith(who);
}
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*type*/, SpellSchoolMask /*school*/) override
{
if (!_enraged && me->HealthBelowPctDamaged(20, damage))
{
_enraged = true;
DoCastSelf(SPELL_ENRAGE); DoCastSelf(SPELL_ENRAGE);
} });
}
void JustEngagedWith(Unit* /*who*/) override
{
scheduler.Schedule(3s, [this](TaskContext context)
{
DoCastVictim(SPELL_ACID_BREATH);
context.Repeat(7s, 9s);
}).Schedule(1s, [this](TaskContext context)
{
DoCastRandomTarget(SPELL_ACID_SPIT);
context.Repeat(7s, 9s);
}).Schedule(DUNGEON_MODE<Milliseconds>(5900ms, 10s), [this](TaskContext context)
{
DoCastVictim(SPELL_TAIL_SWEEP);
context.Repeat(7s, 9s);
});
_JustEngagedWith();
} }
void DoAction(int32 type) override void DoAction(int32 type) override
@@ -110,7 +113,7 @@ struct boss_ghazan : public BossAI
me->GetMotionMaster()->MoveRandom(12.f); me->GetMotionMaster()->MoveRandom(12.f);
} }
BossAI::JustReachedHome(); _JustReachedHome();
} }
void UpdateAI(uint32 diff) override void UpdateAI(uint32 diff) override
@@ -120,42 +123,12 @@ struct boss_ghazan : public BossAI
return; return;
} }
events.Update(diff); scheduler.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
{
return;
}
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_ACID_BREATH:
DoCastVictim(SPELL_ACID_BREATH);
events.Repeat(7s, 9s);
break;
case EVENT_ACID_SPIT:
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
{
DoCast(target, SPELL_ACID_SPIT);
}
events.Repeat(7s, 9s);
break;
case EVENT_TAIL_SWEEP:
DoCastVictim(SPELL_TAIL_SWEEP);
events.Repeat(7s, 9s);
break;
default:
break;
}
}
DoMeleeAttackIfReady(); DoMeleeAttackIfReady();
} }
private: private:
bool _enraged;
bool _movedToPlatform; bool _movedToPlatform;
bool _reachedPlatform; bool _reachedPlatform;
}; };

View File

@@ -44,35 +44,29 @@ enum Misc
struct boss_hungarfen : public BossAI struct boss_hungarfen : public BossAI
{ {
boss_hungarfen(Creature* creature) : BossAI(creature, DATA_HUNGARFEN), _foul_spores(false) { } boss_hungarfen(Creature* creature) : BossAI(creature, DATA_HUNGARFEN) { }
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType, SpellSchoolMask) override void Reset() override
{ {
if (me->HealthBelowPctDamaged(20, damage) && !_foul_spores) _Reset();
{ _scheduler.CancelAll();
_foul_spores = true; DoCastAOE(SPELL_DESPAWN_MUSHROOMS, true);
ScheduleHealthCheckEvent(20, [&] {
me->AddUnitState(UNIT_STATE_ROOT); me->AddUnitState(UNIT_STATE_ROOT);
Talk(EMOTE_ROARS); Talk(EMOTE_ROARS);
DoCastSelf(SPELL_FOUL_SPORES); DoCastSelf(SPELL_FOUL_SPORES);
_scheduler.DelayAll(11s); _scheduler.DelayAll(11s);
_scheduler.Schedule(11s, [this](TaskContext /*context*/) _scheduler.Schedule(11s, [this](TaskContext /*context*/)
{ {
me->ClearUnitState(UNIT_STATE_ROOT); me->ClearUnitState(UNIT_STATE_ROOT);
}); });
} });
} }
void Reset() override void JustEngagedWith(Unit* /*who*/) override
{ {
BossAI::Reset(); _JustEngagedWith();
_foul_spores = false;
_scheduler.CancelAll();
DoCastAOE(SPELL_DESPAWN_MUSHROOMS, true);
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
_scheduler.Schedule(IsHeroic() ? randtime(2400ms, 3600ms) : 10s, [this](TaskContext context) _scheduler.Schedule(IsHeroic() ? randtime(2400ms, 3600ms) : 10s, [this](TaskContext context)
{ {
@@ -107,7 +101,6 @@ struct boss_hungarfen : public BossAI
private: private:
TaskScheduler _scheduler; TaskScheduler _scheduler;
bool _foul_spores;
}; };
struct npc_underbog_mushroom : public ScriptedAI struct npc_underbog_mushroom : public ScriptedAI

View File

@@ -17,6 +17,7 @@
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "ScriptedCreature.h" #include "ScriptedCreature.h"
#include "TaskScheduler.h"
#include "the_underbog.h" #include "the_underbog.h"
enum Spells enum Spells
@@ -27,14 +28,14 @@ enum Spells
SPELL_MULTISHOT = 34974, SPELL_MULTISHOT = 34974,
SPELL_THROW_FREEZING_TRAP = 31946, SPELL_THROW_FREEZING_TRAP = 31946,
SPELL_AIMED_SHOT = 31623, SPELL_AIMED_SHOT = 31623,
SPELL_HUNTERS_MARK = 31615 SPELL_HUNTERS_MARK = 31615,
}; };
enum Text enum Text
{ {
SAY_AGGRO = 1, SAY_AGGRO = 1,
SAY_KILL = 2, SAY_KILL = 2,
SAY_JUST_DIED = 3 SAY_JUST_DIED = 3
}; };
enum Misc enum Misc
@@ -133,7 +134,7 @@ struct boss_swamplord_muselek : public BossAI
if (me->IsWithinMeleeRange(me->GetVictim())) if (me->IsWithinMeleeRange(me->GetVictim()))
{ {
me->GetMotionMaster()->Clear(); me->GetMotionMaster()->Clear();
me->GetMotionMaster()->MoveBackwards(me->GetVictim(), 10.0f); me->GetMotionMaster()->MoveForwards(me->GetVictim(), 10.0f);
} }
me->m_Events.AddEventAtOffset([this]() me->m_Events.AddEventAtOffset([this]()

View File

@@ -47,14 +47,6 @@ enum eBlackStalker
SPELL_SUSPENSION_PRIMER = 31720, SPELL_SUSPENSION_PRIMER = 31720,
SPELL_SUSPENSION = 31719, SPELL_SUSPENSION = 31719,
EVENT_LEVITATE = 1,
EVENT_SPELL_CHAIN = 2,
EVENT_SPELL_STATIC = 3,
EVENT_SPELL_SPORES = 4,
EVENT_CHECK = 5,
EVENT_LEVITATE_TARGET_1 = 6,
EVENT_LEVITATE_TARGET_2 = 7,
ENTRY_SPORE_STRIDER = 22299 ENTRY_SPORE_STRIDER = 22299
}; };
@@ -62,18 +54,47 @@ struct boss_the_black_stalker : public BossAI
{ {
boss_the_black_stalker(Creature* creature) : BossAI(creature, DATA_BLACK_STALKER) boss_the_black_stalker(Creature* creature) : BossAI(creature, DATA_BLACK_STALKER)
{ {
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
} }
void JustEngagedWith(Unit* who) override void JustEngagedWith(Unit* /*who*/) override
{ {
events.ScheduleEvent(EVENT_LEVITATE, urand(8000, 12000)); scheduler.Schedule(8s, 12s, [this](TaskContext context)
events.ScheduleEvent(EVENT_SPELL_CHAIN, 6000); {
events.ScheduleEvent(EVENT_SPELL_STATIC, 10000); DoCastSelf(SPELL_LEVITATE);
events.ScheduleEvent(EVENT_CHECK, 5000); context.Repeat(18s, 24s);
if (IsHeroic()) }).Schedule(6s, [this](TaskContext context)
events.ScheduleEvent(EVENT_SPELL_SPORES, urand(10000, 15000)); {
DoCastRandomTarget(SPELL_CHAIN_LIGHTNING, false);
context.Repeat(9s);
}).Schedule(10s, [this](TaskContext context)
{
DoCastRandomTarget(SPELL_STATIC_CHARGE, false);
context.Repeat(10s);
}).Schedule(5s, [this](TaskContext /*context*/)
{
float x, y, z, o = 0.f;
me->GetHomePosition(x, y, z, o);
if (!me->IsWithinDist3d(x, y, z, 60.0f))
{
EnterEvadeMode();
return;
}
});
BossAI::JustEngagedWith(who); if (IsHeroic())
{
scheduler.Schedule(10s, 15s, [this](TaskContext context)
{
DoCastSelf(SPELL_SUMMON_SPORE_STRIDER, false);
context.Repeat(10s, 15s);
});
}
_JustEngagedWith();
} }
void JustSummoned(Creature* summon) override void JustSummoned(Creature* summon) override
@@ -89,8 +110,6 @@ struct boss_the_black_stalker : public BossAI
void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
{ {
summons.Despawn(summon); summons.Despawn(summon);
for (uint8 i = 0; i < 3; ++i)
me->CastSpell(me, SPELL_SUMMON_SPORE_STRIDER, false);
} }
void UpdateAI(uint32 diff) override void UpdateAI(uint32 diff) override
@@ -98,45 +117,7 @@ struct boss_the_black_stalker : public BossAI
if (!UpdateVictim()) if (!UpdateVictim())
return; return;
events.Update(diff); scheduler.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_CHECK:
float x, y, z, o;
me->GetHomePosition(x, y, z, o);
if (!me->IsWithinDist3d(x, y, z, 60))
{
EnterEvadeMode();
return;
}
events.RepeatEvent(5000);
break;
case EVENT_SPELL_SPORES:
me->CastSpell(me, SPELL_SUMMON_SPORE_STRIDER, false);
events.RepeatEvent(urand(10000, 15000));
break;
case EVENT_SPELL_CHAIN:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
me->CastSpell(target, SPELL_CHAIN_LIGHTNING, false);
events.RepeatEvent(9000);
break;
case EVENT_SPELL_STATIC:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30, true))
me->CastSpell(target, SPELL_STATIC_CHARGE, false);
events.RepeatEvent(10000);
break;
case EVENT_LEVITATE:
DoCastSelf(SPELL_LEVITATE);
events.RepeatEvent(urand(18000, 24000));
break;
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
DoMeleeAttackIfReady(); DoMeleeAttackIfReady();
} }