CombatEvent.cs 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using System.Collections.Generic;
  2. namespace MazeGen
  3. {
  4. public enum CombatEventKind
  5. {
  6. FightStart,
  7. RoundStart,
  8. MovementStart, // Actor begins moving
  9. MovementComplete, // Actor completes movement
  10. OutOfRange, // Attack failed: target out of weapon range
  11. TooFarForMelee, // Attack failed: not adjacent for melee
  12. TargetUnreachable, // Movement failed: destination unreachable
  13. Hit,
  14. Miss,
  15. Death,
  16. FightEnd,
  17. HealthPotionUsed
  18. }
  19. /// <summary>
  20. /// One atomic thing that happened during a battle. A resolved battle is nothing but an
  21. /// ordered list of these.
  22. ///
  23. /// This is the seam that lets "just log it" and "watch it on a grid" share one outcome: the
  24. /// resolver runs to completion up front and emits this list, log-only mode prints it, and the
  25. /// arena replays the exact same list as animation. The view therefore cannot desync from the
  26. /// simulation, and switching modes can never change who wins.
  27. /// </summary>
  28. public class CombatEvent
  29. {
  30. public CombatEventKind Kind;
  31. public int Round;
  32. /// <summary>Combatant id of whoever acted, or -1 for battle/round-level events.</summary>
  33. public int ActorId = -1;
  34. /// <summary>Combatant id of whoever was acted upon, or -1.</summary>
  35. public int TargetId = -1;
  36. /// <summary>Damage dealt (Hit), or the target's remaining health (Death).</summary>
  37. public float Amount;
  38. /// <summary>Pre-rendered log line, so the log/thought/feed surfaces don't each re-describe it.</summary>
  39. public string Text;
  40. /// <summary>Starting position for movement events (grid coordinates).</summary>
  41. public UnityEngine.Vector2Int SourcePosition = UnityEngine.Vector2Int.zero;
  42. /// <summary>Destination position for movement events, or target position for attacks (grid coordinates).</summary>
  43. public UnityEngine.Vector2Int TargetPosition = UnityEngine.Vector2Int.zero;
  44. /// <summary>Distance moved in squares (for MovementComplete events).</summary>
  45. public int MovementDistance = 0;
  46. }
  47. public enum BattleOutcome
  48. {
  49. AgentsVictory,
  50. MonstersVictory,
  51. Stalemate
  52. }
  53. /// <summary>The complete, already-decided result of one battle.</summary>
  54. public class BattleResult
  55. {
  56. public BattleOutcome Outcome;
  57. public int Rounds;
  58. public readonly List<CombatEvent> Events = new List<CombatEvent>();
  59. public IReadOnlyList<Combatant> Combatants;
  60. /// <summary>Agents who were reduced to 0 health in this battle.</summary>
  61. public readonly List<Combatant> FallenAgents = new List<Combatant>();
  62. /// <summary>Monsters killed in this battle.</summary>
  63. public readonly List<Combatant> FallenMonsters = new List<Combatant>();
  64. /// <summary>Agents still standing when the battle ended.</summary>
  65. public readonly List<Combatant> SurvivingAgents = new List<Combatant>();
  66. public string Summary
  67. {
  68. get
  69. {
  70. switch (Outcome)
  71. {
  72. case BattleOutcome.AgentsVictory:
  73. return $"Agents won in {Rounds} round(s) - {FallenMonsters.Count} monster(s) killed, {FallenAgents.Count} agent(s) lost.";
  74. case BattleOutcome.MonstersVictory:
  75. return $"Monsters won in {Rounds} round(s) - all {FallenAgents.Count} agent(s) died.";
  76. default:
  77. return $"Stalemate after {Rounds} round(s) - both sides still standing, everyone disengages.";
  78. }
  79. }
  80. }
  81. }
  82. }