work on well of souls and yolo detection

This commit is contained in:
Boki 2026-02-20 16:40:50 -05:00
parent 3456e0d62a
commit 40d30115bf
41 changed files with 3031 additions and 148 deletions

View file

@ -44,7 +44,9 @@ public class BotOrchestrator : IAsyncDisposable
public GameStateDetector GameState { get; }
public HudReader HudReader { get; }
public EnemyDetector EnemyDetector { get; }
public BossDetector BossDetector { get; }
public FrameSaver FrameSaver { get; }
public BossRunExecutor BossRunExecutor { get; }
private readonly Dictionary<string, ScrapExecutor> _scrapExecutors = new();
// Events
@ -72,6 +74,7 @@ public class BotOrchestrator : IAsyncDisposable
GameState = new GameStateDetector();
HudReader = new HudReader();
EnemyDetector = new EnemyDetector();
BossDetector = new BossDetector();
FrameSaver = new FrameSaver();
// Register on shared pipeline
@ -79,12 +82,15 @@ public class BotOrchestrator : IAsyncDisposable
pipelineService.Pipeline.AddConsumer(GameState);
pipelineService.Pipeline.AddConsumer(HudReader);
pipelineService.Pipeline.AddConsumer(EnemyDetector);
pipelineService.Pipeline.AddConsumer(BossDetector);
pipelineService.Pipeline.AddConsumer(FrameSaver);
// Pass shared pipeline to NavigationExecutor
Navigation = new NavigationExecutor(game, pipelineService.Pipeline, minimapCapture,
enemyDetector: EnemyDetector);
BossRunExecutor = new BossRunExecutor(game, screen, inventory, logWatcher, store.Settings, BossDetector);
logWatcher.AreaEntered += _ => Navigation.Reset();
logWatcher.Start(); // start early so area events fire even before Bot.Start()
_paused = store.Settings.Paused;
@ -182,6 +188,11 @@ public class BotOrchestrator : IAsyncDisposable
return;
}
}
if (BossRunExecutor.State != BossRunState.Idle)
{
State = BossRunExecutor.State.ToString();
return;
}
if (Navigation.State != NavigationState.Idle)
{
State = Navigation.State.ToString();
@ -264,26 +275,61 @@ public class BotOrchestrator : IAsyncDisposable
{
LogWatcher.Start();
await Game.FocusGame();
await Screen.Warmup();
BossRunExecutor.StateChanged += _ => UpdateExecutorState();
Navigation.StateChanged += _ => UpdateExecutorState();
_started = true;
Emit("info", "Starting map exploration...");
State = "Exploring";
_ = Navigation.RunExploreLoop().ContinueWith(t =>
if (Config.MapType == MapType.Kulemak)
{
if (t.IsFaulted)
// Boss run needs hideout first
var inHideout = LogWatcher.CurrentArea.Contains("hideout", StringComparison.OrdinalIgnoreCase);
if (!inHideout)
{
Log.Error(t.Exception!, "Explore loop failed");
Emit("error", $"Explore loop failed: {t.Exception?.InnerException?.Message}");
Emit("info", "Sending /hideout command...");
var arrivedHome = await Inventory.WaitForAreaTransition(Config.TravelTimeoutMs, () => Game.GoToHideout());
if (!arrivedHome)
Log.Warning("Timed out waiting for hideout transition on startup");
}
else
Inventory.SetLocation(true);
Emit("info", "Starting boss run loop...");
State = "Preparing";
_ = BossRunExecutor.RunBossLoop().ContinueWith(t =>
{
Emit("info", "Exploration finished");
}
State = "Idle";
StatusUpdated?.Invoke();
});
if (t.IsFaulted)
{
Log.Error(t.Exception!, "Boss run loop failed");
Emit("error", $"Boss run failed: {t.Exception?.InnerException?.Message}");
}
else
{
Emit("info", "Boss run loop finished");
}
State = "Idle";
StatusUpdated?.Invoke();
});
}
else
{
Emit("info", "Starting map exploration...");
State = "Exploring";
_ = Navigation.RunExploreLoop().ContinueWith(t =>
{
if (t.IsFaulted)
{
Log.Error(t.Exception!, "Explore loop failed");
Emit("error", $"Explore loop failed: {t.Exception?.InnerException?.Message}");
}
else
{
Emit("info", "Exploration finished");
}
State = "Idle";
StatusUpdated?.Invoke();
});
}
}
public async ValueTask DisposeAsync()