CharacterSheet.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. namespace MazeGen
  4. {
  5. /// <summary>
  6. /// Represents a character's complete combat state: base stats, equipped items,
  7. /// temporary bonuses, and inventory. Both agents and monsters use this.
  8. /// </summary>
  9. public class CharacterSheet
  10. {
  11. private CharacterStats _baseStats;
  12. private Weapon _equippedWeapon;
  13. private Armor _equippedArmor;
  14. private List<Item> _inventory = new List<Item>();
  15. // Temporary stat bonuses (key = source name, value = bonus amount)
  16. private Dictionary<string, float> _attackBonuses = new Dictionary<string, float>();
  17. private Dictionary<string, float> _defenseBonuses = new Dictionary<string, float>();
  18. private Dictionary<string, float> _magicBonuses = new Dictionary<string, float>();
  19. private Dictionary<string, float> _speedBonuses = new Dictionary<string, float>();
  20. private Dictionary<string, float> _healthBonuses = new Dictionary<string, float>();
  21. public CharacterStats Stats => _baseStats;
  22. public Weapon EquippedWeapon => _equippedWeapon;
  23. public Armor EquippedArmor => _equippedArmor;
  24. public IReadOnlyList<Item> Inventory => _inventory.AsReadOnly();
  25. public CharacterSheet(CharacterStats baseStats)
  26. {
  27. _baseStats = baseStats;
  28. }
  29. /// <summary>
  30. /// Get the effective attack stat including all bonuses.
  31. /// This is what's actually used in combat calculations.
  32. /// </summary>
  33. public float GetEffectiveAttack()
  34. {
  35. float bonus = 0;
  36. foreach (var b in _attackBonuses.Values) bonus += b;
  37. return _baseStats.Attack + bonus;
  38. }
  39. /// <summary>Get effective defense after all bonuses.</summary>
  40. public float GetEffectiveDefense()
  41. {
  42. float bonus = 0;
  43. foreach (var b in _defenseBonuses.Values) bonus += b;
  44. return _baseStats.Defense + bonus;
  45. }
  46. /// <summary>Get effective magic after all bonuses.</summary>
  47. public float GetEffectiveMagic()
  48. {
  49. float bonus = 0;
  50. foreach (var b in _magicBonuses.Values) bonus += b;
  51. return _baseStats.Magic + bonus;
  52. }
  53. /// <summary>Get effective speed (affects initiative and movement).</summary>
  54. public float GetEffectiveSpeed()
  55. {
  56. float bonus = 0;
  57. foreach (var b in _speedBonuses.Values) bonus += b;
  58. return Mathf.Max(0.1f, _baseStats.Speed + bonus);
  59. }
  60. /// <summary>Get effective max health including armor bonuses.</summary>
  61. public float GetEffectiveMaxHealth()
  62. {
  63. float bonus = 0;
  64. foreach (var b in _healthBonuses.Values) bonus += b;
  65. return _baseStats.MaxHealth + bonus;
  66. }
  67. /// <summary>Equip a weapon (unequips the previous one).</summary>
  68. public bool EquipWeapon(Weapon weapon)
  69. {
  70. if (_equippedWeapon != null)
  71. _equippedWeapon.OnUnequip(this);
  72. if (weapon != null && !weapon.OnEquip(this))
  73. return false;
  74. _equippedWeapon = weapon;
  75. return true;
  76. }
  77. /// <summary>Equip armor (unequips the previous armor).</summary>
  78. public bool EquipArmor(Armor armor)
  79. {
  80. if (_equippedArmor != null)
  81. _equippedArmor.OnUnequip(this);
  82. if (armor != null && !armor.OnEquip(this))
  83. return false;
  84. _equippedArmor = armor;
  85. return true;
  86. }
  87. /// <summary>Add an item to inventory without equipping it.</summary>
  88. public void AddToInventory(Item item)
  89. {
  90. if (item != null && !_inventory.Contains(item))
  91. _inventory.Add(item);
  92. }
  93. /// <summary>Apply a temporary stat bonus (e.g., from a weapon, buff, or potion).</summary>
  94. public void ApplyTemporaryBonus(string key, float attackBonus = 0, float defenseBonus = 0, float magicBonus = 0, float speedBonus = 0, float healthBonus = 0)
  95. {
  96. if (attackBonus != 0)
  97. _attackBonuses[key] = attackBonus;
  98. if (defenseBonus != 0)
  99. _defenseBonuses[key] = defenseBonus;
  100. if (magicBonus != 0)
  101. _magicBonuses[key] = magicBonus;
  102. if (speedBonus != 0)
  103. _speedBonuses[key] = speedBonus;
  104. if (healthBonus != 0)
  105. _healthBonuses[key] = healthBonus;
  106. }
  107. /// <summary>Overload for single-stat bonus (most common case).</summary>
  108. public void ApplyTemporaryBonus(string key, float bonus, string statType = "attack")
  109. {
  110. switch (statType.ToLower())
  111. {
  112. case "attack": _attackBonuses[key] = bonus; break;
  113. case "defense": _defenseBonuses[key] = bonus; break;
  114. case "magic": _magicBonuses[key] = bonus; break;
  115. case "speed": _speedBonuses[key] = bonus; break;
  116. case "health": _healthBonuses[key] = bonus; break;
  117. }
  118. }
  119. /// <summary>Remove a temporary bonus by its source key.</summary>
  120. public void RemoveTemporaryBonus(string key)
  121. {
  122. _attackBonuses.Remove(key);
  123. _defenseBonuses.Remove(key);
  124. _magicBonuses.Remove(key);
  125. _speedBonuses.Remove(key);
  126. _healthBonuses.Remove(key);
  127. }
  128. /// <summary>Reset this character for a new fight (restore health, clear temporary bonuses, keep equipment).</summary>
  129. public void ResetForNewFight()
  130. {
  131. _baseStats.RestoreHealth();
  132. _attackBonuses.Clear();
  133. _defenseBonuses.Clear();
  134. _magicBonuses.Clear();
  135. _speedBonuses.Clear();
  136. _healthBonuses.Clear();
  137. // Re-apply equipment bonuses
  138. if (_equippedWeapon != null)
  139. _equippedWeapon.OnEquip(this);
  140. if (_equippedArmor != null)
  141. _equippedArmor.OnEquip(this);
  142. }
  143. }
  144. }