awgil / ffxiv_bossmod

BossMod FFXIV dalamud plugin
BSD 3-Clause "New" or "Revised" License
262 stars 110 forks source link

Waypoint Manager #505

Closed CarnifexOptimus closed 1 month ago

CarnifexOptimus commented 2 months ago

a waypoint manager, for example for 3rd boss in dohn mheg to traverse the chasm. it got the ability to also generate random points between the waypoints to disguise botting behaviour if needed. There might be more elegant solutions to solve this like making pathfinding more accurate, but this works well enough.

example on how to use from one of my modules:

class FunambulistsFantasia(BossModule module) : BossComponent(module) { private bool WaypointsAdded; private static readonly WPos[] waypoints = [new(-142.88f, -233.2f), new(-140.89f, -246.16f), new(-129.9f, -242.38f), new(-114.19f, -244.35f), new(-125.81f, -249.33f), new(-123.5f, -256.17f)];

public override void OnCastFinished(Actor caster, ActorCastInfo spell)
{
    if ((AID)spell.Action.ID == AID.FunambulistsFantasia)
        Arena.Bounds = D033AencThon.chasmArena;
    else if ((AID)spell.Action.ID == AID.Finale)
        Arena.Bounds = D033AencThon.arena;
}

public override void OnStatusGain(Actor actor, ActorStatus status)
{
    if ((SID)status.ID == SID.FoolsTumble && actor == Module.Raid.Player())
        WaypointsAdded = false;
}

public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints)
{
    var lyre = Module.Enemies(OID.LiarsLyre).FirstOrDefault();
    hints.WaypointManager.module = Module;
    hints.WaypointManager.UpdateCurrentWaypoint(actor.Position);
    if (hints.WaypointManager.HasWaypoints)
    {
        var currentWaypoint = hints.WaypointManager.CurrentWaypoint;
        if (currentWaypoint.HasValue)
        {
            hints.ForcedMovement = (currentWaypoint.Value - actor.Position).ToVec3();
        }
    }
    if (Arena.Bounds == D033AencThon.chasmArena && lyre != null)
    {
        hints.ActionsToExecute.Push(ActionID.MakeSpell(ClassShared.AID.Sprint), actor, ActionQueue.Priority.High);
        hints.AddForbiddenZone(ShapeDistance.InvertedCircle(lyre.Position, 3));
        if (!WaypointsAdded)
        {
            hints.WaypointManager.ClearWaypoints();
            hints.WaypointManager.WaypointTimeLimit = 10;
            WaypointsAdded = true;
            hints.WaypointManager.AddWaypointsWithRandomization(waypoints, 0.1f, 10);
        }
    }
    else if (Arena.Bounds == D033AencThon.arena)
        hints.WaypointManager.ClearWaypoints();
}

}