InfoPanelUI.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. using UnityEngine;
  2. namespace MazeGen
  3. {
  4. /// <summary>
  5. /// Right-side panel showing detailed info about the followed agent:
  6. /// - Vitals (room, HP, stats, equipment)
  7. /// - Inventory listing (equipped + unequipped items)
  8. /// - Decision narration (newest first)
  9. /// - Global combat log
  10. /// </summary>
  11. public class InfoPanelUI
  12. {
  13. private Vector2 thoughtScroll;
  14. private Vector2 combatLogScroll;
  15. private CombatDirector director;
  16. public InfoPanelUI(CombatDirector combatDirector)
  17. {
  18. director = combatDirector;
  19. }
  20. public void Draw(MazeAgent followedAgent)
  21. {
  22. float width = 400f;
  23. float x = Screen.width - width - 10f;
  24. float height = Screen.height - 20f;
  25. GUILayout.BeginArea(new Rect(x, 10f, width, height), GUI.skin.box);
  26. if (followedAgent == null)
  27. {
  28. GUILayout.Label("AGENT THOUGHTS AND INFO", GUI.skin.box);
  29. GUILayout.Label("Click an agent on the left to follow it and read what it's thinking.");
  30. }
  31. else
  32. {
  33. DrawAgentInfo(followedAgent, height, Color.white);
  34. }
  35. GUILayout.EndArea();
  36. }
  37. private void DrawAgentInfo(MazeAgent agent, float panelHeight, Color agentColor)
  38. {
  39. CharacterSheet sheet = agent.CharacterSheet;
  40. GUI.color = agentColor;
  41. GUILayout.Label($"{agent.DisplayName.ToUpperInvariant()} - {DescribeStatus(agent)}", GUI.skin.box);
  42. GUI.color = Color.white;
  43. // Vitals
  44. GUILayout.Label($"Room {agent.CurrentRoom?.Id.ToString() ?? "?"} New rooms seen: {agent.NewRoomsVisited} Path: {agent.PathHistory.Count} hop(s)");
  45. GUILayout.Label($"HP {sheet.Stats.CurrentHealth:0.#}/{sheet.Stats.MaxHealth:0.#} ATK {sheet.GetEffectiveAttack():0.#} DEF {sheet.GetEffectiveDefense():0.#} SPD {sheet.GetEffectiveSpeed():0.#}");
  46. GUILayout.Label($"Weapon: {sheet.EquippedWeapon?.ItemName ?? "none"} Armor: {sheet.EquippedArmor?.ItemName ?? "none"}");
  47. // Threat assessment for current room
  48. Room room = agent.CurrentRoom;
  49. int hostiles = room?.Encounter != null ? room.Encounter.AliveMonsterCount : 0;
  50. GUILayout.Label(hostiles > 0
  51. ? $"This room: {hostiles} living hostile(s), threat {room.Encounter.GetPerceivedChallengeRating(sheet):0.00}"
  52. : "This room: clear");
  53. // Inventory listing
  54. GUILayout.Space(4);
  55. DrawInventory(sheet);
  56. GUILayout.Space(4);
  57. GUILayout.Label("Thoughts (newest first):");
  58. thoughtScroll = GUILayout.BeginScrollView(thoughtScroll, GUILayout.Height(Mathf.Max(80f, panelHeight * 0.30f)));
  59. var thoughts = agent.Thoughts.Entries;
  60. for (int i = thoughts.Count - 1; i >= 0; i--)
  61. {
  62. Thought thought = thoughts[i];
  63. GUI.color = AgentThoughtLog.ColorFor(thought.Kind);
  64. GUILayout.Label($"[{thought.Time:0.0}s] {thought.Text}");
  65. }
  66. GUI.color = Color.white;
  67. GUILayout.EndScrollView();
  68. GUILayout.Space(4);
  69. GUILayout.Label("Combat log (all fights):");
  70. combatLogScroll = GUILayout.BeginScrollView(combatLogScroll, GUILayout.Height(Mathf.Max(100f, panelHeight * 0.25f)));
  71. var log = director.CombatLog;
  72. for (int i = log.Count - 1; i >= 0; i--)
  73. GUILayout.Label(log[i]);
  74. GUILayout.EndScrollView();
  75. }
  76. private void DrawInventory(CharacterSheet sheet)
  77. {
  78. GUILayout.Label("Inventory:", GUI.skin.box);
  79. if (sheet.Inventory.Count == 0)
  80. {
  81. GUILayout.Label("(Empty)");
  82. return;
  83. }
  84. foreach (var item in sheet.Inventory)
  85. {
  86. string itemType = item is Consumable ? "[Consumable]" : item is Weapon ? "[Weapon]" : "[Item]";
  87. string details = "";
  88. if (item is Consumable cons)
  89. {
  90. if (cons.HealthBonus > 0)
  91. details = $" +{cons.HealthBonus:0.#} HP";
  92. }
  93. else if (item is Weapon weap)
  94. {
  95. details = $" (ATK +{weap.AttackBonus:0.#})";
  96. }
  97. else if (item is Armor armor)
  98. {
  99. details = $" (DEF +{armor.DefenseBonus:0.#})";
  100. }
  101. GUI.color = new Color(0.7f, 0.85f, 1f);
  102. GUILayout.Label($" {itemType} {item.ItemName}{details}");
  103. }
  104. GUI.color = Color.white;
  105. }
  106. private string DescribeStatus(MazeAgent agent)
  107. {
  108. if (agent.IsDead) return "dead";
  109. if (agent.IsFinished) return "reached exit";
  110. if (agent.IsEngaged) return "fighting";
  111. return $"exploring ({agent.CharacterSheet.Stats.CurrentHealth:0}hp)";
  112. }
  113. }
  114. }