Skip to content

Commit

Permalink
setting to disable obstacle maps
Browse files Browse the repository at this point in the history
  • Loading branch information
CarnifexOptimus committed Feb 16, 2025
1 parent 3390ed2 commit 46514d7
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 52 deletions.
4 changes: 2 additions & 2 deletions BossMod/AI/AIConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion BossMod/AI/AIManagementWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
20 changes: 10 additions & 10 deletions BossMod/AI/AIManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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":
Expand Down Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion BossMod/BossModule/AIHints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<AI.AIConfig>();

// list of potential targets
public readonly Enemy?[] Enemies = new Enemy?[100];
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions BossMod/Config/ConfigUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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." }
};

Expand Down
37 changes: 1 addition & 36 deletions BossMod/Pathfinding/NavigationDecision.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<AI.AIConfig>();

public const float ActivationTimeCushion = 1f; // reduce time between now and activation by this value in seconds; increase for more conservativeness

Expand All @@ -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);
Expand Down Expand Up @@ -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 };
}
}

0 comments on commit 46514d7

Please sign in to comment.