Skip to content

Commit

Permalink
Merge pull request #492 from FFXIV-CombatReborn/mergeWIP
Browse files Browse the repository at this point in the history
clarified out of bounds method
  • Loading branch information
CarnifexOptimus authored Dec 8, 2024
2 parents f2f2b72 + dba72cb commit 4bf9ee8
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
public enum OID : uint
{
Boss = 0x3323, // R=4.0
Helper = 0x233C,
IcePillar = 0x3324, // R2.000, x0 (spawn during fight)
IcePillar = 0x3324, // R2.0
Helper = 0x233C
}

public enum AID : uint
Expand Down Expand Up @@ -83,5 +83,5 @@ public D041LyssaStates(BossModule module) : base(module)
[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus, LTS)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 787, NameID = 10396)]
public class D041Lyssa(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena)
{
public static readonly ArenaBoundsComplex arena = new([new Circle(new(-144, 49), 19.5f)], [new Rectangle(new(-144, 28), 20, 2), new Rectangle(new(-144, 70), 20, 2)]);
public static readonly ArenaBoundsComplex arena = new([new Polygon(new(-144, 49), 19.5f, 32)], [new Rectangle(new(-144, 28), 20, 2.1f), new Rectangle(new(-144, 70), 20, 2)]);
}
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,9 @@ public D043HermesStates(BossModule module) : base(module)
}

[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus, LTS)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 787, NameID = 10363)]
public class D043Hermes(WorldState ws, Actor primary) : BossModule(ws, primary, new(0, -50), StartingBounds)
public class D043Hermes(WorldState ws, Actor primary) : BossModule(ws, primary, ArenaCenter, StartingBounds)
{
public static readonly ArenaBounds StartingBounds = new ArenaBoundsCircle(21.5f);
public static readonly ArenaBounds DefaultBounds = new ArenaBoundsCircle(20);
private static readonly WPos ArenaCenter = new(0, -50);
public static readonly ArenaBoundsComplex StartingBounds = new([new Polygon(ArenaCenter, 21.5f, 64)]);
public static readonly ArenaBoundsComplex DefaultBounds = new([new Polygon(ArenaCenter, 20, 64)]);
}
26 changes: 14 additions & 12 deletions BossMod/Pathfinding/NavigationDecision.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,18 @@ public enum Decision
public Decision DecisionType;

public const float DefaultForbiddenZoneCushion = 0.15f;
public static bool IsInBlockedPixel(WPos position, Context ctx)
{
if (ctx.Map.Pixels.Length == 0)
return false;
var gridPos = ctx.Map.WorldToGrid(position);
if (gridPos.x < 0 || gridPos.x >= ctx.Map.Width || gridPos.y < 0 || gridPos.y >= ctx.Map.Height)
return true; // Treat out-of-bounds as blocked
return ctx.Map.Pixels[gridPos.y * ctx.Map.Width + gridPos.x].MaxG < 0;
}

public static NavigationDecision Build(Context ctx, WorldState ws, AIHints hints, Actor player, WPos? targetPos, float targetRadius, Angle targetRot, Positional positional, float playerSpeed = 6, float forbiddenZoneCushion = DefaultForbiddenZoneCushion)
{
if (targetRadius < 1)
targetRadius = 1; // ensure targetRadius is at least 1 to prevent game from freezing
hints.PathfindMapBounds.PathfindMap(ctx.Map, hints.PathfindMapCenter);
if (!Service.Config.Get<AI.AIConfig>().AllowAIToBeOutsideBounds && IsInBlockedPixel(player.Position, ctx))

if (!Service.Config.Get<AI.AIConfig>().AllowAIToBeOutsideBounds && IsOutsideBounds(player.Position, ctx))
{
return FindPathFromOutsideBounds(ctx, player.Position, playerSpeed);
}

(Func<WPos, float> shapeDistance, DateTime activation)[] localForbiddenZones = [.. hints.ForbiddenZones];
var imminent = ImminentExplosionTime(ws.CurrentTime);
var len = localForbiddenZones.Length;
Expand Down Expand Up @@ -156,7 +150,6 @@ public static NavigationDecision Build(Context ctx, WorldState ws, AIHints hints
if (!player.Position.InCircle(targetPos.Value, targetRadius))
{
// we're not in uptime zone, just run to it, avoiding any aoes
hints.PathfindMapBounds.PathfindMap(ctx.Map, hints.PathfindMapCenter);
for (var i = 0; i < len; ++i)
{
var zf = localForbiddenZones[i];
Expand Down Expand Up @@ -203,7 +196,6 @@ public static NavigationDecision Build(Context ctx, WorldState ws, AIHints hints
if (!inPositional)
{
// we're in uptime zone, but not in correct quadrant - move there, avoiding all aoes and staying within uptime zone
hints.PathfindMapBounds.PathfindMap(ctx.Map, hints.PathfindMapCenter);
ctx.Map.BlockPixelsInside(ShapeDistance.InvertedCircle(targetPos.Value, targetRadius), 0, 0);
for (var i = 0; i < len; ++i)
{
Expand Down Expand Up @@ -441,4 +433,14 @@ public static NavigationDecision FindPathFromImminent(ThetaStar pathfind, Map ma
var adjDest = targetPos.Value + dir * dir.Dot(dest.Value - targetPos.Value);
return (dest.Value - adjDest).LengthSq() < 1 ? adjDest : dest;
}

public static bool IsOutsideBounds(WPos position, Context ctx)
{
if (ctx.Map.Pixels.Length == 0)
return false;
var gridPos = ctx.Map.WorldToGrid(position);
if (gridPos.x < 0 || gridPos.x >= ctx.Map.Width || gridPos.y < 0 || gridPos.y >= ctx.Map.Height)
return true; // outside current pathfinding map
return ctx.Map.Pixels[gridPos.y * ctx.Map.Width + gridPos.x].MaxG == float.NegativeInfinity; // inside pathfinding map, but outside actual walkable bounds
}
}

0 comments on commit 4bf9ee8

Please sign in to comment.