CharacterSheet.cs 6.6 KB

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