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();
}
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)
{
if (!target)

View File

@@ -205,6 +205,7 @@ public:
void MoveChase(Unit* target, float dist) { MoveChase(target, ChaseRange(dist)); }
void MoveCircleTarget(Unit* target);
void MoveBackwards(Unit* target, float dist);
void MoveForwards(Unit* target, float dist);
void MoveConfused();
void MoveFleeing(Unit* enemy, uint32 time = 0);
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_ENRAGE = 15716,
EVENT_ACID_BREATH = 1,
EVENT_ACID_SPIT = 2,
EVENT_TAIL_SWEEP = 3,
ACTION_MOVE_TO_PLATFORM = 1
};
@@ -39,6 +35,10 @@ struct boss_ghazan : public BossAI
{
boss_ghazan(Creature* creature) : BossAI(creature, DATA_GHAZAN)
{
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
void InitializeAI() override
@@ -50,31 +50,34 @@ struct boss_ghazan : public BossAI
void Reset() override
{
_enraged = false;
_Reset();
if (!_reachedPlatform)
{
_movedToPlatform = false;
}
BossAI::Reset();
}
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;
ScheduleHealthCheckEvent(20, [&] {
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
@@ -110,7 +113,7 @@ struct boss_ghazan : public BossAI
me->GetMotionMaster()->MoveRandom(12.f);
}
BossAI::JustReachedHome();
_JustReachedHome();
}
void UpdateAI(uint32 diff) override
@@ -120,42 +123,12 @@ struct boss_ghazan : public BossAI
return;
}
events.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;
}
}
scheduler.Update(diff);
DoMeleeAttackIfReady();
}
private:
bool _enraged;
bool _movedToPlatform;
bool _reachedPlatform;
};

View File

@@ -44,35 +44,29 @@ enum Misc
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)
{
_foul_spores = true;
_Reset();
_scheduler.CancelAll();
DoCastAOE(SPELL_DESPAWN_MUSHROOMS, true);
ScheduleHealthCheckEvent(20, [&] {
me->AddUnitState(UNIT_STATE_ROOT);
Talk(EMOTE_ROARS);
DoCastSelf(SPELL_FOUL_SPORES);
_scheduler.DelayAll(11s);
_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();
_foul_spores = false;
_scheduler.CancelAll();
DoCastAOE(SPELL_DESPAWN_MUSHROOMS, true);
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
_JustEngagedWith();
_scheduler.Schedule(IsHeroic() ? randtime(2400ms, 3600ms) : 10s, [this](TaskContext context)
{
@@ -107,7 +101,6 @@ struct boss_hungarfen : public BossAI
private:
TaskScheduler _scheduler;
bool _foul_spores;
};
struct npc_underbog_mushroom : public ScriptedAI

View File

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

View File

@@ -47,14 +47,6 @@ enum eBlackStalker
SPELL_SUSPENSION_PRIMER = 31720,
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
};
@@ -62,18 +54,47 @@ struct boss_the_black_stalker : public BossAI
{
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));
events.ScheduleEvent(EVENT_SPELL_CHAIN, 6000);
events.ScheduleEvent(EVENT_SPELL_STATIC, 10000);
events.ScheduleEvent(EVENT_CHECK, 5000);
if (IsHeroic())
events.ScheduleEvent(EVENT_SPELL_SPORES, urand(10000, 15000));
scheduler.Schedule(8s, 12s, [this](TaskContext context)
{
DoCastSelf(SPELL_LEVITATE);
context.Repeat(18s, 24s);
}).Schedule(6s, [this](TaskContext context)
{
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
@@ -89,8 +110,6 @@ struct boss_the_black_stalker : public BossAI
void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
{
summons.Despawn(summon);
for (uint8 i = 0; i < 3; ++i)
me->CastSpell(me, SPELL_SUMMON_SPORE_STRIDER, false);
}
void UpdateAI(uint32 diff) override
@@ -98,45 +117,7 @@ struct boss_the_black_stalker : public BossAI
if (!UpdateVictim())
return;
events.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;
scheduler.Update(diff);
DoMeleeAttackIfReady();
}