poe2-bot/src/Nexus.Simulator/Rendering/DebugPanel.cs
2026-03-07 09:53:57 -05:00

132 lines
4.8 KiB
C#

using System.Numerics;
using ImGuiNET;
using Nexus.Core;
using Nexus.Pathfinding;
using Nexus.Simulator.Config;
using Nexus.Simulator.World;
namespace Nexus.Simulator.Rendering;
public class DebugPanel
{
private readonly SimConfig _config;
private readonly SimWorld _world;
private readonly NavigationController _nav;
private readonly IReadOnlyList<ISystem> _systems;
private int _spawnRarity; // 0=Normal, 1=Magic, 2=Rare, 3=Unique
public DebugPanel(SimConfig config, SimWorld world, NavigationController nav, IReadOnlyList<ISystem> systems)
{
_config = config;
_world = world;
_nav = nav;
_systems = systems;
}
public void Draw(GameState? state)
{
ImGui.Begin("Simulator Controls");
// Simulation controls
if (ImGui.CollapsingHeader("Simulation", ImGuiTreeNodeFlags.DefaultOpen))
{
var paused = _config.IsPaused;
if (ImGui.Checkbox("Paused", ref paused))
_config.IsPaused = paused;
ImGui.SameLine();
if (ImGui.Button("Step"))
{
_config.IsPaused = false;
}
var speed = _config.SpeedMultiplier;
if (ImGui.SliderFloat("Speed", ref speed, 0.1f, 4f, "%.1fx"))
_config.SpeedMultiplier = speed;
if (ImGui.Button("Regenerate Terrain"))
_world.RegenerateTerrain();
}
// Player stats
if (ImGui.CollapsingHeader("Player", ImGuiTreeNodeFlags.DefaultOpen))
{
var player = _world.Player;
ImGui.Text($"Position: ({player.Position.X:F0}, {player.Position.Y:F0})");
var hpPct = player.MaxHealth > 0 ? (float)player.Health / player.MaxHealth : 0;
ImGui.ProgressBar(hpPct, new Vector2(-1, 0), $"HP: {player.Health}/{player.MaxHealth}");
var manaPct = player.MaxMana > 0 ? (float)player.Mana / player.MaxMana : 0;
ImGui.ProgressBar(manaPct, new Vector2(-1, 0), $"MP: {player.Mana}/{player.MaxMana}");
}
// Enemy stats
if (ImGui.CollapsingHeader("Enemies", ImGuiTreeNodeFlags.DefaultOpen))
{
var enemies = _world.Enemies.ToArray(); // snapshot — list mutated by SimPoller thread
var alive = enemies.Count(e => e.IsAlive);
var dead = enemies.Count(e => !e.IsAlive);
var chasing = enemies.Count(e => e.AiState == EnemyAiState.Chasing);
var attacking = enemies.Count(e => e.AiState == EnemyAiState.Attacking);
ImGui.Text($"Total: {enemies.Length} Alive: {alive} Dead: {dead}");
ImGui.Text($"Chasing: {chasing} Attacking: {attacking}");
ImGui.Separator();
ImGui.Text("Spawn Enemy:");
string[] rarities = ["Normal", "Magic", "Rare", "Unique"];
ImGui.Combo("Rarity", ref _spawnRarity, rarities, rarities.Length);
if (ImGui.Button("Spawn at Player"))
{
var rarity = (MonsterRarity)_spawnRarity;
var offset = new Vector2(200, 0);
_world.SpawnEnemyAt(_world.Player.Position + offset, rarity);
}
}
// Navigation
if (ImGui.CollapsingHeader("Navigation"))
{
ImGui.Text($"Mode: {_nav.Mode}");
ImGui.Text($"Status: {_nav.Status}");
ImGui.Text($"Direction: {(_nav.DesiredDirection.HasValue ? $"({_nav.DesiredDirection.Value.X:F2}, {_nav.DesiredDirection.Value.Y:F2})" : "none")}");
var path = _nav.CurrentPath;
ImGui.Text($"Path: {path?.Count ?? 0} waypoints");
ImGui.Text($"Exploration complete: {_nav.IsExplorationComplete}");
}
// Systems
if (ImGui.CollapsingHeader("Systems"))
{
foreach (var sys in _systems)
{
var enabled = sys.IsEnabled;
if (ImGui.Checkbox(sys.Name, ref enabled))
sys.IsEnabled = enabled;
}
}
// Threat info
if (state is not null && ImGui.CollapsingHeader("Threat"))
{
ImGui.Text($"Danger: {state.Danger}");
var threats = state.Threats;
ImGui.Text($"Close: {threats.CloseRange} Mid: {threats.MidRange} Far: {threats.FarRange}");
ImGui.Text($"Closest: {threats.ClosestDistance:F0}");
ImGui.Text($"Has Rare/Unique: {threats.HasRareOrUnique}");
}
// Action queue
if (state is not null && ImGui.CollapsingHeader("State"))
{
ImGui.Text($"Tick: {state.TickNumber}");
ImGui.Text($"Entities: {state.Entities.Count}");
ImGui.Text($"Hostile: {state.HostileMonsters.Count}");
ImGui.Text($"Nearest: {state.NearestEnemies.Count}");
}
ImGui.End();
}
}