From 46514d71ab2e4f29adf3d125a7787b42827d8c4f Mon Sep 17 00:00:00 2001 From: CarnifexOptimus <156172553+CarnifexOptimus@users.noreply.github.com> Date: Sun, 16 Feb 2025 23:25:23 +0100 Subject: [PATCH] setting to disable obstacle maps --- BossMod/AI/AIConfig.cs | 4 +-- BossMod/AI/AIManagementWindow.cs | 2 +- BossMod/AI/AIManager.cs | 20 ++++++------ BossMod/BossModule/AIHints.cs | 3 +- BossMod/Config/ConfigUI.cs | 4 +-- BossMod/Pathfinding/NavigationDecision.cs | 37 +---------------------- 6 files changed, 18 insertions(+), 52 deletions(-) diff --git a/BossMod/AI/AIConfig.cs b/BossMod/AI/AIConfig.cs index 4654b175a2..f2632bfd7a 100644 --- a/BossMod/AI/AIConfig.cs +++ b/BossMod/AI/AIConfig.cs @@ -55,8 +55,8 @@ sealed class AIConfig : ConfigNode [PropertyDisplay("Auto AFK timer", tooltip: "Time in seconds out of combat until AFK mode enables. Any movement will reset timer or disable AFK mode if already active.")] public float AFKModeTimer = 10; - [PropertyDisplay("Allow AI to be out of pathfinding map bounds")] - public bool AllowAIToBeOutsideBounds = false; + [PropertyDisplay("Disable loading obstacle maps", tooltip: "Might be required to be enabled for some some content such as deep dungeons.")] + public bool DisableObstacleMaps = false; [PropertyDisplay("Movement decision delay", tooltip: "Only change this at your own risk and keep this value low! Too high and it won't move in time for some mechanics. Make sure to readjust the value for different content.")] public double MoveDelay = 0; diff --git a/BossMod/AI/AIManagementWindow.cs b/BossMod/AI/AIManagementWindow.cs index 29f26c4941..b5bf24045c 100644 --- a/BossMod/AI/AIManagementWindow.cs +++ b/BossMod/AI/AIManagementWindow.cs @@ -60,7 +60,7 @@ public override void Draw() ImGui.Spacing(); configModified |= ImGui.Checkbox("Manual targeting", ref _config.ManualTarget); ImGui.SameLine(); - configModified |= ImGui.Checkbox("Allow outside bounds", ref _config.AllowAIToBeOutsideBounds); + configModified |= ImGui.Checkbox("Disable loading obstacle maps", ref _config.DisableObstacleMaps); ImGui.Text("Follow party slot"); ImGui.SameLine(); diff --git a/BossMod/AI/AIManager.cs b/BossMod/AI/AIManager.cs index 8c3c99f272..bf6d480f12 100644 --- a/BossMod/AI/AIManager.cs +++ b/BossMod/AI/AIManager.cs @@ -159,10 +159,10 @@ private void OnCommand(string cmd, string message) ToggleFollowTarget(messageData); configModified = cfgFollowT != _config.FollowTarget; break; - case "OUTOFBOUNDS": - var cfgOOB = _config.AllowAIToBeOutsideBounds; - ToggleOutOfBounds(messageData); - configModified = cfgOOB != _config.AllowAIToBeOutsideBounds; + case "OBSTACLEMAPS": + var cfgOM = _config.DisableObstacleMaps; + ToggleObstacleMaps(messageData); + configModified = cfgOM != _config.DisableObstacleMaps; break; case "POSITIONAL": @@ -229,26 +229,26 @@ private bool ToggleFocusTargetMaster() return true; } - private void ToggleOutOfBounds(string[] messageData) + private void ToggleObstacleMaps(string[] messageData) { if (messageData.Length == 1) - _config.AllowAIToBeOutsideBounds = !_config.AllowAIToBeOutsideBounds; + _config.DisableObstacleMaps = !_config.DisableObstacleMaps; else { switch (messageData[1].ToUpperInvariant()) { case "ON": - _config.AllowAIToBeOutsideBounds = true; + _config.DisableObstacleMaps = false; break; case "OFF": - _config.AllowAIToBeOutsideBounds = false; + _config.DisableObstacleMaps = true; break; default: - Service.ChatGui.Print($"[AI] Unknown follow target command: {messageData[1]}"); + Service.ChatGui.Print($"[AI] Unknown obstacle map command: {messageData[1]}"); return; } } - Service.Log($"[AI] Following targets is now {(_config.AllowAIToBeOutsideBounds ? "enabled" : "disabled")}"); + Service.Log($"[AI] Obstacle maps are now {(_config.DisableObstacleMaps ? "disabled" : "enabled")}"); } private void ToggleIdleWhileMounted(string[] messageData) diff --git a/BossMod/BossModule/AIHints.cs b/BossMod/BossModule/AIHints.cs index 683a150176..ef04ae2d9b 100644 --- a/BossMod/BossModule/AIHints.cs +++ b/BossMod/BossModule/AIHints.cs @@ -41,6 +41,7 @@ public enum SpecialMode public WPos PathfindMapCenter; public ArenaBounds PathfindMapBounds = DefaultBounds; public Bitmap.Region PathfindMapObstacles; + private static readonly AI.AIConfig _config = Service.Config.Get(); // list of potential targets public readonly Enemy?[] Enemies = new Enemy?[100]; @@ -200,7 +201,7 @@ public void Normalize() public void InitPathfindMap(Pathfinding.Map map) { PathfindMapBounds.PathfindMap(map, PathfindMapCenter); - if (PathfindMapObstacles.Bitmap != null) + if (PathfindMapObstacles.Bitmap != null && !_config.DisableObstacleMaps) { var offX = -PathfindMapObstacles.Rect.Left; var offY = -PathfindMapObstacles.Rect.Top; diff --git a/BossMod/Config/ConfigUI.cs b/BossMod/Config/ConfigUI.cs index 9bbc1d6b0e..80eb89be9c 100644 --- a/BossMod/Config/ConfigUI.cs +++ b/BossMod/Config/ConfigUI.cs @@ -102,8 +102,8 @@ public void Draw() { "maxdistancetarget X", "Sets max distance to target. (default = 2.6)" }, { "maxdistanceslot X", "Sets max distance to slot. (default = 1)" }, { "movedelay X", "Sets AI movement decision delay. (default = 0)" }, - { "outofbounds", "Toggles the allow AI to be out of arena bounds setting." }, - { "outofbounds on/off", "Sets the allow AI to be out of arena bounds setting to on or off." }, + { "obstaclemaps", "Toggles loading obstacle maps." }, + { "obstaclemaps on/off", "Sets the loading of obstacle maps to on or off." }, { "setpresetname X", "Sets an autorotation preset for the AI, eg. setpresetname vbm default." } }; diff --git a/BossMod/Pathfinding/NavigationDecision.cs b/BossMod/Pathfinding/NavigationDecision.cs index 83d89213d2..792d6fa140 100644 --- a/BossMod/Pathfinding/NavigationDecision.cs +++ b/BossMod/Pathfinding/NavigationDecision.cs @@ -22,7 +22,6 @@ public class Context public WPos? NextWaypoint; public float LeewaySeconds; // can be used for finishing casts / slidecasting etc. public float TimeToGoal; - private static readonly AI.AIConfig _config = Service.Config.Get(); public const float ActivationTimeCushion = 1f; // reduce time between now and activation by this value in seconds; increase for more conservativeness @@ -39,10 +38,7 @@ public static NavigationDecision Build(Context ctx, WorldState ws, AIHints hints RasterizeGoalZones(ctx.Map, localGoalZones); // execute pathfinding - if (!_config.AllowAIToBeOutsideBounds && IsOutsideBounds(player.Position, ctx)) - return FindPathFromOutsideBounds(ctx, player.Position, playerSpeed); - else - ctx.ThetaStar.Start(ctx.Map, player.Position, 1.0f / playerSpeed); + ctx.ThetaStar.Start(ctx.Map, player.Position, 1.0f / playerSpeed); var bestNodeIndex = ctx.ThetaStar.Execute(); ref var bestNode = ref ctx.ThetaStar.NodeByIndex(bestNodeIndex); var waypoints = GetFirstWaypoints(ctx.ThetaStar, ctx.Map, bestNodeIndex, player.Position); @@ -396,35 +392,4 @@ private static (WPos? first, WPos? second) GetFirstWaypoints(ThetaStar pf, Map m } while (true); } - - public static bool IsOutsideBounds(WPos position, Context ctx) - { - var map = ctx.Map; - var (x, y) = map.WorldToGrid(position); - if (x < 0 || x >= map.Width || y < 0 || y >= map.Height) - return true; // outside current pathfinding map - return map.PixelMaxG[y * map.Width + x] == -1; // inside pathfinding map, but outside actual walkable bounds - } - - public static NavigationDecision FindPathFromOutsideBounds(Context ctx, WPos startPos, float speed = 6) - { - WPos? closest = null; - var closestDistance = float.MaxValue; - var pixels = ctx.Map.EnumeratePixels(); - var len = pixels.Length; - for (var i = 0; i < len; ++i) - { - ref var p = ref pixels[i]; - if (ctx.Map.PixelMaxG[p.y * ctx.Map.Width + p.x] > 0f) // assume any pixel not marked as blocked is better than being outside of bounds - { - var distance = (p.center - startPos).LengthSq(); - if (distance < closestDistance) - { - closest = p.center; - closestDistance = distance; - } - } - } - return new() { Destination = closest, LeewaySeconds = 0f, TimeToGoal = MathF.Sqrt(closestDistance) / speed }; - } }