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 _systems; private int _spawnRarity; // 0=Normal, 1=Magic, 2=Rare, 3=Unique public DebugPanel(SimConfig config, SimWorld world, NavigationController nav, IReadOnlyList 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(); } }