unitai.lua 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. UnitAI = class()
  2. function UnitAI:update()
  3. -- Try to find something to attack
  4. self:changeTarget(ctx.target:closest(self.unit, 'enemy', 'shrine', 'player', 'unit'))
  5. local target = self.unit.target
  6. -- Give up if there is no target
  7. if not target or target.untargetable then
  8. self.unit.target = nil
  9. target = nil
  10. end
  11. if target then
  12. if self:inRange(target) then
  13. self:startAttacking(target)
  14. else
  15. self:moveIntoRange(target)
  16. end
  17. else
  18. self.unit.animation:set('idle')
  19. end
  20. end
  21. function UnitAI:changeTarget(target)
  22. local taunt = self.unit.buffs:taunted()
  23. self.unit.target = taunt or target
  24. end
  25. function UnitAI:inRange(target)
  26. return math.abs(target.x - self.unit.x) <= self.unit.range + target.width / 2 + self.unit.width / 2
  27. end
  28. function UnitAI:moveIntoRange(target)
  29. local fear = self.unit.buffs:feared()
  30. if fear then return self:runFrom(fear.target) end
  31. if self:inRange(target) then
  32. self.unit.animation:set('idle')
  33. return
  34. end
  35. self:moveTowards(target)
  36. end
  37. function UnitAI:moveTowards(target)
  38. local fear = self.unit.buffs:feared()
  39. if fear then return self:runFrom(fear.target) end
  40. if not target then
  41. self.unit.animation:set('idle')
  42. return
  43. end
  44. local targetx = type(target) == 'number' and target or target.x
  45. if math.abs(targetx - self.unit.x) <= 1 then
  46. self.unit.animation:set('idle')
  47. return
  48. end
  49. self.unit.x = self.unit.x + math.min(self.unit.speed * ls.tickrate, math.abs(targetx - self.unit.x)) * lume.sign(targetx - self.unit.x)
  50. self.unit.animation:set('walk')
  51. self.unit.animation.flipped = self.unit.x > targetx
  52. end
  53. function UnitAI:runFrom(target)
  54. self.unit.x = self.unit.x - self.unit.speed * lume.sign(target.x - self.unit.x) * ls.tickrate
  55. self.unit.animation:set('walk')
  56. self.unit.animation.flipped = self.unit.x < target.x
  57. end
  58. function UnitAI:startAttacking(target)
  59. local fear = self.unit.buffs:feared()
  60. if fear then return self:runFrom(fear.target) end
  61. if not self:inRange(target) or self.unit.buffs:stunned() then
  62. self.unit.animation:set('idle')
  63. return
  64. end
  65. self.unit.target = target
  66. if self.unit.animation.state.name ~= 'attack' then self.unit.attackStart = tick end
  67. self.unit.animation.flipped = self.unit.x > target.x
  68. self.unit.animation:set('attack')
  69. end
  70. function UnitAI:useAbilities()
  71. if self.unit.buffs:silenced() or ctx.tutorial.active then return end
  72. table.each(self.unit.abilities, function(ability)
  73. if ability:canUse() and love.math.random() < .5 then
  74. f.exe(ability.use, ability)
  75. end
  76. end)
  77. end