Stats.gd 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. extends Object
  2. class_name ActorStats
  3. # Public and private stats, can be initialized through a dictionary from a SQL query or entities.json
  4. var level : int = 0
  5. var experience : int = 0
  6. var gp : int = 0
  7. var health : int = ActorCommons.MaxStatValue
  8. var mana : int = ActorCommons.MaxStatValue
  9. var stamina : int = ActorCommons.MaxStatValue
  10. var karma : int = 0
  11. var weight : float = 0.0
  12. var hairstyle : int = DB.UnknownHash
  13. var haircolor : int = DB.UnknownHash
  14. var gender : int = ActorCommons.Gender.MALE
  15. var race : int = DB.UnknownHash
  16. var skintone : int = DB.UnknownHash
  17. var shape : int = DB.UnknownHash
  18. var spirit : int = DB.UnknownHash
  19. var currentShape : int = DB.UnknownHash
  20. var baseExp : int = 1
  21. # Attributes
  22. var strength : int = 0
  23. var vitality : int = 0
  24. var agility : int = 0
  25. var endurance : int = 0
  26. var concentration : int = 0
  27. # Entity Stats
  28. var entityStat : BaseStats = BaseStats.new()
  29. var morphStat : BaseStats = BaseStats.new()
  30. var current : BaseStats = BaseStats.new()
  31. var actor : Actor = null
  32. var modifiers : CellModifier = CellModifier.new()
  33. # Signals
  34. signal vital_stats_updated
  35. signal attributes_updated
  36. signal entity_stats_updated
  37. #
  38. func RefreshVitalStats():
  39. health = Formula.ClampHealth(self)
  40. stamina = Formula.ClampStamina(self)
  41. mana = Formula.ClampMana(self)
  42. vital_stats_updated.emit()
  43. func RefreshRegenStats():
  44. current.regenHealth = Formula.GetRegenHealth(self)
  45. current.regenMana = Formula.GetRegenMana(self)
  46. current.regenStamina = Formula.GetRegenStamina(self)
  47. func RefreshEntityStats():
  48. # Current Stats
  49. current.maxHealth = Formula.GetMaxHealth(self)
  50. current.maxMana = Formula.GetMaxMana(self)
  51. current.maxStamina = Formula.GetMaxStamina(self)
  52. current.attack = Formula.GetAttack(self)
  53. current.attackRange = Formula.GetAttackRange(self)
  54. current.mattack = Formula.GetMAttack(self)
  55. current.defense = Formula.GetDefense(self)
  56. current.mdefense = Formula.GetMDefense(self)
  57. current.critRate = Formula.GetCritRate(self)
  58. current.dodgeRate = Formula.GetDodgeRate(self)
  59. current.castAttackDelay = Formula.GetCastAttackDelay(self)
  60. current.cooldownAttackDelay = Formula.GetCooldownAttackDelay(self)
  61. current.walkSpeed = Formula.GetWalkSpeed(self)
  62. current.weightCapacity = Formula.GetWeightCapacity(self)
  63. entity_stats_updated.emit()
  64. RefreshVitalStats()
  65. RefreshRegenStats()
  66. func RefreshAttributes():
  67. RefreshEntityStats()
  68. attributes_updated.emit()
  69. #
  70. func SetStats(stats : Dictionary):
  71. for statName in stats:
  72. if stats[statName] != null and statName in self:
  73. self[statName] = stats[statName]
  74. if actor.type == ActorCommons.Type.MONSTER:
  75. FillRandomAttributes()
  76. RefreshAttributes()
  77. #
  78. func SetEntityStats(newStats : Dictionary):
  79. for modifier in newStats:
  80. if modifier in entityStat:
  81. entityStat[modifier] = newStats[modifier]
  82. morphStat[modifier] = entityStat[modifier]
  83. RefreshEntityStats()
  84. func SetMorphStats(newStats : Dictionary):
  85. for modifier in newStats:
  86. if modifier in morphStat:
  87. morphStat[modifier] = (entityStat[modifier] + newStats[modifier]) / 2 if IsMorph() else newStats[modifier]
  88. RefreshEntityStats()
  89. #
  90. func Init(actorNode : Actor, data : EntityData):
  91. assert(actorNode != null, "Caller actor node should never be null")
  92. actor = actorNode
  93. var stats : Dictionary = data._stats
  94. shape = data._id
  95. currentShape = shape
  96. SetStats(stats)
  97. SetEntityStats(stats)
  98. RefreshVitalStats()
  99. func FillRandomAttributes():
  100. var maxPoints : int = Formula.GetMaxAttributePoints(level)
  101. var assignedPoints : int = Formula.GetAssignedAttributePoints(self)
  102. if maxPoints > assignedPoints:
  103. const attributeNames = ["strength", "vitality", "agility", "endurance", "concentration"]
  104. var attributes : Dictionary = {}
  105. var pointToDispatch : int = maxPoints - assignedPoints
  106. for att in attributeNames:
  107. var points : int = randi_range(0, pointToDispatch)
  108. pointToDispatch -= points
  109. attributes[att] = self[att] + points
  110. if pointToDispatch == 0:
  111. break
  112. SetStats(attributes)
  113. func Morph(data : EntityData):
  114. currentShape = data._id
  115. SetMorphStats(data._stats)
  116. func IsMorph() -> bool:
  117. return currentShape != shape
  118. func IsSailing() -> bool:
  119. return currentShape == DB.ShipHash
  120. func AddAttribute(attribute : ActorCommons.Attribute):
  121. if Formula.GetMaxAttributePoints(level) - Formula.GetAssignedAttributePoints(self) > 0:
  122. match attribute:
  123. ActorCommons.Attribute.STRENGTH:
  124. strength = min(ActorCommons.MaxPointPerAttributes, strength + 1)
  125. ActorCommons.Attribute.VITALITY:
  126. vitality = min(ActorCommons.MaxPointPerAttributes, vitality + 1)
  127. ActorCommons.Attribute.AGILITY:
  128. agility = min(ActorCommons.MaxPointPerAttributes, agility + 1)
  129. ActorCommons.Attribute.ENDURANCE:
  130. endurance = min(ActorCommons.MaxPointPerAttributes, endurance + 1)
  131. ActorCommons.Attribute.CONCENTRATION:
  132. concentration = min(ActorCommons.MaxPointPerAttributes, concentration + 1)
  133. RefreshAttributes()
  134. func Regen():
  135. if ActorCommons.IsAlive(actor):
  136. var bonus : float = 1.0
  137. if ActorCommons.IsSitting(actor):
  138. bonus *= 2.0
  139. RefreshRegenStats()
  140. if actor.stat.health < actor.stat.current.maxHealth:
  141. SetHealth(floori(current.regenHealth * bonus))
  142. if actor.stat.mana < actor.stat.current.maxMana:
  143. SetMana(floori(current.regenMana * bonus))
  144. if not ActorCommons.IsAttacking(actor) and actor.stat.stamina < actor.stat.current.maxStamina:
  145. SetStamina(floori(current.regenStamina * bonus))
  146. Callback.LoopTimer(actor.regenTimer, ActorCommons.RegenDelay)
  147. func SetHealth(bonus : int):
  148. health = clampi(health + bonus, 0, current.maxHealth)
  149. if health <= 0:
  150. actor.Killed()
  151. func SetMana(bonus : int):
  152. mana = clampi(mana + bonus, 0, current.maxMana)
  153. func SetStamina(bonus : int):
  154. stamina = clampi(stamina + bonus, 0, current.maxStamina)
  155. func AddExperience(value : int):
  156. if not ActorCommons.IsAlive(actor) or value <= 0:
  157. return
  158. experience += value
  159. # Manage level up
  160. var experiencelNeeded = Experience.GetNeededExperienceForNextLevel(level)
  161. while experiencelNeeded != Experience.MAX_LEVEL_REACHED and experience >= experiencelNeeded:
  162. experience -= experiencelNeeded
  163. level += 1
  164. experiencelNeeded = Experience.GetNeededExperienceForNextLevel(level)
  165. func AddGP(value : int):
  166. if not ActorCommons.IsAlive(actor) or value <= 0:
  167. return
  168. gp += value