From dba72cbd693929b196c03adf39c4044ba49f70a9 Mon Sep 17 00:00:00 2001 From: CarnifexOptimus <156172553+CarnifexOptimus@users.noreply.github.com> Date: Sun, 8 Dec 2024 22:50:54 +0100 Subject: [PATCH] clarified out of bounds method --- .../Dungeon/D04KtisisHyperboreia/D041Lyssa.cs | 6 ++--- .../D04KtisisHyperboreia/D043Hermes.cs | 7 ++--- BossMod/Pathfinding/NavigationDecision.cs | 26 ++++++++++--------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/BossMod/Modules/Endwalker/Dungeon/D04KtisisHyperboreia/D041Lyssa.cs b/BossMod/Modules/Endwalker/Dungeon/D04KtisisHyperboreia/D041Lyssa.cs index 3c2242e23d..3ab0c5f097 100644 --- a/BossMod/Modules/Endwalker/Dungeon/D04KtisisHyperboreia/D041Lyssa.cs +++ b/BossMod/Modules/Endwalker/Dungeon/D04KtisisHyperboreia/D041Lyssa.cs @@ -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 @@ -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)]); } diff --git a/BossMod/Modules/Endwalker/Dungeon/D04KtisisHyperboreia/D043Hermes.cs b/BossMod/Modules/Endwalker/Dungeon/D04KtisisHyperboreia/D043Hermes.cs index e0c6a6b480..606192ffd3 100644 --- a/BossMod/Modules/Endwalker/Dungeon/D04KtisisHyperboreia/D043Hermes.cs +++ b/BossMod/Modules/Endwalker/Dungeon/D04KtisisHyperboreia/D043Hermes.cs @@ -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)]); } diff --git a/BossMod/Pathfinding/NavigationDecision.cs b/BossMod/Pathfinding/NavigationDecision.cs index 08b8c0e0b0..5abf22e3a3 100644 --- a/BossMod/Pathfinding/NavigationDecision.cs +++ b/BossMod/Pathfinding/NavigationDecision.cs @@ -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().AllowAIToBeOutsideBounds && IsInBlockedPixel(player.Position, ctx)) + + if (!Service.Config.Get().AllowAIToBeOutsideBounds && IsOutsideBounds(player.Position, ctx)) { return FindPathFromOutsideBounds(ctx, player.Position, playerSpeed); } + (Func shapeDistance, DateTime activation)[] localForbiddenZones = [.. hints.ForbiddenZones]; var imminent = ImminentExplosionTime(ws.CurrentTime); var len = localForbiddenZones.Length; @@ -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]; @@ -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) { @@ -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 + } }