132 lines
4.8 KiB
C#
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();
|
|
}
|
|
}
|