diff --git a/BossMod/BossModule/ArenaBounds.cs b/BossMod/BossModule/ArenaBounds.cs index d7714b6fb8..ae345efb8a 100644 --- a/BossMod/BossModule/ArenaBounds.cs +++ b/BossMod/BossModule/ArenaBounds.cs @@ -116,17 +116,18 @@ public override WDir ClampToBounds(WDir offset) private Pathfinding.Map BuildMap() { - // circle is convex, and pathfinding always aims to cell centers, so we can only block pixels which centers are out of bounds var map = new Pathfinding.Map(MapResolution, default, Radius, Radius); int iCell = 0; var threshold = Radius * Radius / (MapResolution * MapResolution); // square of bounds radius, in grid coordinates var dy = -map.Height / 2 + 0.5f; for (int y = 0; y < map.Height; ++y, ++dy) { + var cy = Math.Abs(dy) + 0.5f; // farthest corner var dx = -map.Width / 2 + 0.5f; for (int x = 0; x < map.Width; ++x, ++dx) { - if (dx * dx + dy * dy > threshold) + var cx = Math.Abs(dx) + 0.5f; + if (cx * cx + cy * cy > threshold) { map.PixelMaxG[iCell] = -1000; } diff --git a/BossMod/Modules/Dawntrail/Ultimate/FRU/FRU.cs b/BossMod/Modules/Dawntrail/Ultimate/FRU/FRU.cs index 22d8f9a5ff..8f250a8177 100644 --- a/BossMod/Modules/Dawntrail/Ultimate/FRU/FRU.cs +++ b/BossMod/Modules/Dawntrail/Ultimate/FRU/FRU.cs @@ -10,6 +10,8 @@ class P5ParadiseLost(BossModule module) : Components.CastCounter(module, ActionI [ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.BossP1, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 1006, NameID = 9707, PlanLevel = 100)] public class FRU(WorldState ws, Actor primary) : BossModule(ws, primary, new(100, 100), new ArenaBoundsCircle(20)) { + public static readonly ArenaBoundsSquare PathfindHugBorderBounds = new(20); // this is a hack to allow precise positioning near border by some mechanics, TODO reconsider + private Actor? _bossP2; private Actor? _iceVeil; private Actor? _bossP3; diff --git a/BossMod/Modules/Dawntrail/Ultimate/FRU/P1UtopianSky.cs b/BossMod/Modules/Dawntrail/Ultimate/FRU/P1UtopianSky.cs index 45bc972a3c..143cc15c3b 100644 --- a/BossMod/Modules/Dawntrail/Ultimate/FRU/P1UtopianSky.cs +++ b/BossMod/Modules/Dawntrail/Ultimate/FRU/P1UtopianSky.cs @@ -181,6 +181,7 @@ public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignme _ => default }; var range = spreadSpot == 0 ? 13 : 19; + hints.PathfindMapBounds = FRU.PathfindHugBorderBounds; hints.AddForbiddenZone(ShapeDistance.PrecisePosition(Module.Center + range * direction.ToDirection(), new(0, 1), Module.Bounds.MapResolution, actor.Position, 0.1f), _aoes.Activation); } } diff --git a/BossMod/Modules/Dawntrail/Ultimate/FRU/P2DiamondDust.cs b/BossMod/Modules/Dawntrail/Ultimate/FRU/P2DiamondDust.cs index 31bea6949b..99e8912b3b 100644 --- a/BossMod/Modules/Dawntrail/Ultimate/FRU/P2DiamondDust.cs +++ b/BossMod/Modules/Dawntrail/Ultimate/FRU/P2DiamondDust.cs @@ -126,7 +126,10 @@ class P2DiamondDustSafespots(BossModule module) : BossComponent(module) public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { if (_safeOffs[slot] != default) + { + hints.PathfindMapBounds = FRU.PathfindHugBorderBounds; hints.AddForbiddenZone(ShapeDistance.PrecisePosition(Module.Center + _safeOffs[slot], new WDir(0, 1), Module.Bounds.MapResolution, actor.Position, 0.1f)); + } } public override void DrawArenaForeground(int pcSlot, Actor pc) @@ -299,7 +302,7 @@ public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignme // non-healers should just stack with whatever closest healer is // before first cast, ignore master's movements var moveDir = NumCasts > 0 ? master.LastFrameMovement.Normalized() : default; - var capsule = ShapeDistance.Capsule(master.Position + 2 * moveDir, moveDir, 4, 1); + var capsule = ShapeDistance.Capsule(master.Position + 2 * moveDir, moveDir, 4, 1.5f); hints.AddForbiddenZone(p => -capsule(p), DateTime.MaxValue); } diff --git a/BossMod/Modules/Dawntrail/Ultimate/FRU/P2MirrorMirror.cs b/BossMod/Modules/Dawntrail/Ultimate/FRU/P2MirrorMirror.cs index bfbbf77b6b..b44dc3c85e 100644 --- a/BossMod/Modules/Dawntrail/Ultimate/FRU/P2MirrorMirror.cs +++ b/BossMod/Modules/Dawntrail/Ultimate/FRU/P2MirrorMirror.cs @@ -100,8 +100,8 @@ public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignme { 0 => -135.Degrees(), 1 => 135.Degrees(), - 2 => -90.Degrees(), - 3 => 90.Degrees(), + 2 => -95.Degrees(), + 3 => 95.Degrees(), _ => default }; } @@ -109,12 +109,12 @@ public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignme { dir = Angle.FromDirection(origin.Actor.Position - Module.Center) + group switch { - 0 => (RedRangedLeftOfMelee ? -90 : 90).Degrees(), - 1 => (RedRangedLeftOfMelee ? 90 : -90).Degrees(), + 0 => (RedRangedLeftOfMelee ? -95 : 95).Degrees(), + 1 => (RedRangedLeftOfMelee ? 95 : -95).Degrees(), 2 => 180.Degrees(), 3 => (RedRangedLeftOfMelee ? -135 : 135).Degrees(), - 4 => -90.Degrees(), - 5 => 90.Degrees(), + 4 => -95.Degrees(), + 5 => 95.Degrees(), 6 => (RedRangedLeftOfMelee ? 180 : -135).Degrees(), 7 => (RedRangedLeftOfMelee ? 135 : 180).Degrees(), _ => default diff --git a/BossMod/Modules/Dawntrail/Ultimate/FRU/P3Apocalypse.cs b/BossMod/Modules/Dawntrail/Ultimate/FRU/P3Apocalypse.cs index a97e3aadf5..ec15a29833 100644 --- a/BossMod/Modules/Dawntrail/Ultimate/FRU/P3Apocalypse.cs +++ b/BossMod/Modules/Dawntrail/Ultimate/FRU/P3Apocalypse.cs @@ -1,6 +1,4 @@ -using System.ComponentModel; - -namespace BossMod.Dawntrail.Ultimate.FRU; +namespace BossMod.Dawntrail.Ultimate.FRU; class P3Apocalypse(BossModule module) : Components.GenericAOEs(module) { @@ -268,7 +266,10 @@ public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignme { var safeSpot = SafeOffset(slot, out _); if (safeSpot != default) + { + hints.PathfindMapBounds = FRU.PathfindHugBorderBounds; hints.AddForbiddenZone(ShapeDistance.PrecisePosition(Module.Center + safeSpot, new(0, 1), Module.Bounds.MapResolution, actor.Position, 0.1f), Spreads.Count > 0 ? Spreads[0].Activation : DateTime.MaxValue); + } } public override void DrawArenaForeground(int pcSlot, Actor pc) diff --git a/BossMod/Modules/Dawntrail/Ultimate/FRU/P4CrystallizeTime.cs b/BossMod/Modules/Dawntrail/Ultimate/FRU/P4CrystallizeTime.cs index aeff488d05..6917cbeb2a 100644 --- a/BossMod/Modules/Dawntrail/Ultimate/FRU/P4CrystallizeTime.cs +++ b/BossMod/Modules/Dawntrail/Ultimate/FRU/P4CrystallizeTime.cs @@ -412,6 +412,7 @@ public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignme } if (hint.hint.HasFlag(Hint.SafespotPrecise)) { + hints.PathfindMapBounds = FRU.PathfindHugBorderBounds; hints.AddForbiddenZone(ShapeDistance.PrecisePosition(Module.Center + hint.offset, new(0, 1), Module.Bounds.MapResolution, actor.Position, 0.1f)); } if (hint.hint.HasFlag(Hint.Maelstrom) && _hourglass != null) diff --git a/TODO b/TODO index ecd93ad617..6a1ebbf242 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,4 @@ immediate plans -- proper circle bounds -> revise everything in fru - ai refactoring -- high-level ai modules --- ordered before standard rotation modules