work on pathing

This commit is contained in:
Boki 2026-02-17 13:03:12 -05:00
parent 7d10f1d2a9
commit 3bb0315912
10 changed files with 729 additions and 113 deletions

View file

@ -11,6 +11,7 @@ public class MinimapCapture : IFrameConsumer, IDisposable
private readonly MinimapConfig _config;
private readonly WallColorTracker _colorTracker;
private readonly IScreenCapture _backend; // kept for debug capture paths
private readonly IconDetector? _iconDetector;
private int _modeCheckCounter = 9; // trigger mode detection on first frame
private MinimapMode _detectedMode = MinimapMode.Overlay;
private int _pendingModeCount; // consecutive detections of a different mode
@ -21,11 +22,18 @@ public class MinimapCapture : IFrameConsumer, IDisposable
public MinimapFrame? LastFrame => _lastFrame;
public event Action<MinimapMode>? ModeChanged;
public MinimapCapture(MinimapConfig config, IScreenCapture backend)
public MinimapCapture(MinimapConfig config, IScreenCapture backend, string? assetsDir = null)
{
_config = config;
_colorTracker = new WallColorTracker(config.WallLoHSV, config.WallHiHSV);
_backend = backend;
// Load icon templates if assets directory provided and contains templates
if (assetsDir != null && File.Exists(Path.Combine(assetsDir, "door.png")))
{
try { _iconDetector = new IconDetector(assetsDir); }
catch (Exception ex) { Log.Warning(ex, "Failed to load icon templates, icon detection disabled"); }
}
}
/// <summary>
@ -115,17 +123,50 @@ public class MinimapCapture : IFrameConsumer, IDisposable
var frameSize = bgr.Width;
var classified = new Mat(frameSize, frameSize, MatType.CV_8UC1, Scalar.Black);
if (_detectedMode == MinimapMode.Corner)
{
classified.SetTo(new Scalar((byte)MapCell.Wall), wallMask);
}
else
{
using var fogMask = BuildFogMask(hsv, wallMask, playerMask);
classified.SetTo(new Scalar((byte)MapCell.Fog), fogMask);
classified.SetTo(new Scalar((byte)MapCell.Wall), wallMask);
}
// Icon detection (overlay mode only — corner has different scale)
List<Point>? checkpointsOff = null;
List<Point>? checkpointsOn = null;
if (_detectedMode == MinimapMode.Overlay && _iconDetector != null)
{
using var grayForIcons = new Mat();
Cv2.CvtColor(bgr, grayForIcons, ColorConversionCodes.BGR2GRAY);
// Doors: stamp as Wall in classified + wallMask (fills gap so BFS blocks doors)
var doors = _iconDetector.DetectDoors(grayForIcons);
if (doors.Count > 0)
{
var doorSize = _iconDetector.DoorSize;
const int pad = 2;
foreach (var d in doors)
{
var rx = Math.Max(0, d.X - doorSize.Width / 2 - pad);
var ry = Math.Max(0, d.Y - doorSize.Height / 2 - pad);
var rw = Math.Min(doorSize.Width + 2 * pad, frameSize - rx);
var rh = Math.Min(doorSize.Height + 2 * pad, frameSize - ry);
if (rw <= 0 || rh <= 0) continue;
var rect = new Rect(rx, ry, rw, rh);
using var classRoi = new Mat(classified, rect);
classRoi.SetTo(new Scalar((byte)MapCell.Wall));
using var wallRoi = new Mat(wallMask, rect);
wallRoi.SetTo(new Scalar(255));
}
Log.Debug("Icons: {Count} doors stamped as wall", doors.Count);
}
// Checkpoints: don't stamp — just pass positions into MinimapFrame
checkpointsOff = _iconDetector.DetectCheckpointsOff(grayForIcons);
checkpointsOn = _iconDetector.DetectCheckpointsOn(grayForIcons);
if (checkpointsOff.Count > 0 || checkpointsOn.Count > 0)
Log.Debug("Icons: {Off} checkpoints-off, {On} checkpoints-on", checkpointsOff.Count, checkpointsOn.Count);
}
// Gray for correlation tracking (player zeroed)
var grayForCorr = new Mat();
Cv2.CvtColor(bgr, grayForCorr, ColorConversionCodes.BGR2GRAY);
@ -159,7 +200,9 @@ public class MinimapCapture : IFrameConsumer, IDisposable
WallMask: wallMask,
ClassifiedMat: classified,
PlayerOffset: playerOffset,
Timestamp: DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
Timestamp: DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
CheckpointsOff: checkpointsOff,
CheckpointsOn: checkpointsOn
);
}
@ -374,5 +417,6 @@ public class MinimapCapture : IFrameConsumer, IDisposable
public void Dispose()
{
_lastFrame?.Dispose();
_iconDetector?.Dispose();
}
}