Skill.gd 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. extends Object
  2. class_name Skill
  3. #
  4. class AlterationInfo:
  5. var value : int = 0
  6. var type : ActorCommons.Alteration = ActorCommons.Alteration.MISS
  7. enum TargetMode
  8. {
  9. SINGLE = 0,
  10. ZONE,
  11. SELF,
  12. }
  13. # Skill Flow
  14. static func Cast(agent : BaseAgent, target : BaseAgent, skill : SkillCell):
  15. if not ActorCommons.IsAlive(agent) or not SkillCommons.HasSkill(agent, skill) or SkillCommons.IsCoolingDown(agent, skill) or SkillCommons.IsCasting(agent, skill):
  16. return
  17. if skill.mode == TargetMode.SINGLE and (not target or not ActorCommons.IsAlive(target)):
  18. return
  19. var map : WorldMap = WorldAgent.GetMapFromAgent(agent)
  20. if map and map.HasFlags(WorldMap.Flags.NO_SPELL):
  21. return
  22. if SkillCommons.TryConsume(agent, CellCommons.Modifier.Mana, skill):
  23. Stopped(agent)
  24. agent.SetSkillCastID(skill.id)
  25. Callback.StartTimer(agent.actionTimer, skill.castTime + agent.stat.current.castAttackDelay, Skill.Attack.bind(agent, target, skill), true)
  26. if skill.mode == TargetMode.SINGLE:
  27. agent.LookAt(target)
  28. static func Attack(agent : BaseAgent, target : BaseAgent, skill : SkillCell):
  29. if ActorCommons.IsAlive(agent) and SkillCommons.IsCasting(agent) and SkillCommons.HasSkill(agent, skill):
  30. var hasStamina : bool = SkillCommons.TryConsume(agent, CellCommons.Modifier.Stamina, skill)
  31. match skill.mode:
  32. TargetMode.SINGLE:
  33. if not ActorCommons.IsAlive(target):
  34. Stopped(agent)
  35. return
  36. if SkillCommons.IsAttackable(agent, target, skill):
  37. var handle : Callable = Skill.Handle.bind(agent, target, skill, SkillCommons.GetRNG(hasStamina))
  38. if SkillCommons.IsDelayed(skill):
  39. Callback.SelfDestructTimer(agent, agent.stat.current.castAttackDelay, handle)
  40. ThrowProjectile(agent, target.position, skill)
  41. else:
  42. handle.call()
  43. Casted(agent, target, skill)
  44. return
  45. if SkillCommons.IsInteractable(agent, target):
  46. ThrowProjectile(agent, agent.position + agent.currentOrientation * Vector2(skill.cellRange, skill.cellRange), skill)
  47. TargetMode.ZONE:
  48. var handle : Callable = Skill.HandleZone.bind(agent, agent.get_position(), skill, SkillCommons.GetRNG(hasStamina))
  49. if SkillCommons.IsDelayed(skill):
  50. Callback.SelfDestructTimer(agent, agent.stat.current.castAttackDelay, handle)
  51. ThrowProjectile(agent, agent.position, skill)
  52. else:
  53. handle.call()
  54. Casted(agent, agent, skill)
  55. return
  56. TargetMode.SELF:
  57. Handle(agent, agent, skill, SkillCommons.GetRNG(hasStamina))
  58. Casted(agent, agent, skill)
  59. return
  60. Missed(agent, target)
  61. static func HandleZone(agent : BaseAgent, zonePos : Vector2, skill : SkillCell, rng : float):
  62. var targets : Array[BaseAgent] = SkillCommons.GetZoneTargets(WorldAgent.GetInstanceFromAgent(agent), zonePos, skill)
  63. if targets.is_empty():
  64. return
  65. var halfRNG : float = rng / 2.0
  66. var scaledRNG : float = halfRNG + halfRNG / targets.size()
  67. for target in targets:
  68. Handle(agent, target, skill, scaledRNG)
  69. static func Handle(agent : BaseAgent, target : BaseAgent, skill : SkillCell, rng : float):
  70. if skill.modifiers.Get(CellCommons.Modifier.Attack) != 0 or skill.modifiers.Get(CellCommons.Modifier.MAttack) != 0:
  71. Damaged(agent, target, skill, rng)
  72. if skill.modifiers.Get(CellCommons.Modifier.Health) != 0:
  73. Healed(agent, target, skill, rng)
  74. # Handling
  75. static func Casted(agent : BaseAgent, target : BaseAgent, skill : SkillCell):
  76. agent.cooldownTimers[skill.id] = true
  77. agent.SetSkillCastID(DB.UnknownHash)
  78. var timeLeft : float = SkillCommons.GetCooldown(agent, skill)
  79. Callback.SelfDestructTimer(agent, timeLeft, CooledDown, [agent, target, skill], skill.name + " CoolDown")
  80. Network.NotifyNeighbours(agent, "Casted", [skill.id, timeLeft])
  81. static func CooledDown(agent : BaseAgent, target : BaseAgent, skill : SkillCell):
  82. agent.cooldownTimers[skill.id] = false
  83. if skill.repeat and ActorCommons.IsAlive(target):
  84. Skill.Cast(agent, target, skill)
  85. static func Damaged(agent : BaseAgent, target : BaseAgent, skill : SkillCell, rng : float):
  86. var info : AlterationInfo = SkillCommons.GetDamage(agent, target, skill, rng)
  87. if target is AIAgent:
  88. target.AddAttacker(agent, info.value)
  89. AI.Refresh(target)
  90. target.stat.SetHealth(-info.value)
  91. Network.NotifyNeighbours(agent, "TargetAlteration", [target.get_rid().get_id(), info.value, info.type, skill.id], true, true)
  92. static func Healed(agent : BaseAgent, target : BaseAgent, skill : SkillCell, rng : float):
  93. var heal : int = SkillCommons.GetHeal(agent, target, skill, rng)
  94. target.stat.SetHealth(heal)
  95. Network.NotifyNeighbours(agent, "TargetAlteration", [target.get_rid().get_id(), heal, ActorCommons.Alteration.HEAL, skill.id], true, true)
  96. static func Stopped(agent : BaseAgent):
  97. if SkillCommons.HasActionInProgress(agent):
  98. agent.SetSkillCastID(DB.UnknownHash)
  99. Callback.ClearTimer(agent.actionTimer)
  100. if agent is AIAgent:
  101. AI.Refresh(agent)
  102. static func Missed(agent : BaseAgent, target : BaseAgent):
  103. if target == null:
  104. return
  105. Network.NotifyNeighbours(agent, "TargetAlteration", [target.get_rid().get_id(), 0, ActorCommons.Alteration.MISS, DB.UnknownHash], true, true)
  106. Stopped(agent)
  107. static func ThrowProjectile(agent : BaseAgent, targetPos : Vector2, skill : SkillCell):
  108. Network.NotifyNeighbours(agent, "ThrowProjectile", [targetPos, skill.id])