frozenorb.lua 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. local FrozenOrb = extend(Spell)
  2. FrozenOrb.depth = -10
  3. FrozenOrb.speed = 500
  4. FrozenOrb.radius = 16
  5. function FrozenOrb:activate()
  6. local unit, ability = self:getUnit(), self:getAbility()
  7. self.direction = ability:getUnitDirection()
  8. self.team = unit.team
  9. self.x = unit.x
  10. self.y = unit.y
  11. self.prevx = self.x
  12. self.startx = self.x
  13. self.angle = love.math.random() * 2 * math.pi
  14. self.prevangle = self.angle
  15. self.angularVelocity = 4 + love.math.random()
  16. ctx.sound:play(data.media.sounds.kuju.frozenorb)
  17. ctx.event:emit('view.register', {object = self})
  18. end
  19. function FrozenOrb:deactivate()
  20. ctx.event:emit('view.unregister', {object = self})
  21. end
  22. function FrozenOrb:update()
  23. local ability, unit = self:getAbility(), self:getUnit()
  24. self.prevx = self.x
  25. self.prevangle = self.angle
  26. self.x = self.x + self.direction * self.speed * ls.tickrate
  27. self.angle = self.angle + self.angularVelocity * ls.tickrate
  28. ctx.particles:emit('kujuattack', math.lerp(self.prevx, self.x, love.math.random()), self.y, 1)
  29. local target, distance = ctx.target:closest(self, 'enemy', 'unit', 'player')
  30. if target and distance < self.radius then
  31. local spiritRatio = ability.spiritRatios[unit:upgradeLevel('frozenorb')]
  32. local exhaust, slow, timer = ability.runeSlow + .4, ability.runeSlow + .4, 1.5
  33. local knockback = (ability.runeKnockback + 75) * self.direction
  34. if isa(target, Unit) then
  35. target.buffs:add('chilled', {exhaust = exhaust, slow = slow, timer = timer})
  36. if unit:upgradeLevel('avalanche') > 0 then
  37. target.buffs:add('avalanche', {offset = knockback})
  38. end
  39. end
  40. local damage = ability.runeDamage + unit.spirit * spiritRatio
  41. target:hurt(damage, unit, {'spell'})
  42. ctx.particles:emit('frozenorb', self.x, self.y, 1)
  43. ctx.sound:play(data.media.sounds.kuju.frozenorb)
  44. local wintersblight = unit:upgradeLevel('wintersblight')
  45. if wintersblight > 0 then
  46. target:hurt(target.health * (.06 * wintersblight), unit, {'spell'})
  47. end
  48. if unit:upgradeLevel('shatter') > 0 then
  49. local targets = ctx.target:inRange(self, 80, 'enemy', 'unit', 'player', 'shrine')
  50. table.each(targets, function(other)
  51. if math.sign(other.x - target.x) == self.direction then
  52. if isa(other, Unit) then
  53. other.buffs:add('chilled', {exhaust = exhaust / 2, slow = slow / 2, timer = timer / 2})
  54. if unit:upgradeLevel('avalanche') > 0 then
  55. other.buffs:add('avalanche', {offset = knockback / 2})
  56. end
  57. end
  58. other:hurt(damage / 2, unit, {'spell'})
  59. ctx.particles:emit('frozenorb', other.x, other.y, 1)
  60. if wintersblight > 0 then
  61. other:hurt(other.health * (.08 * wintersblight), unit, {'spell'})
  62. end
  63. end
  64. end)
  65. end
  66. ctx.spells:remove(self)
  67. end
  68. if not math.inside(self.x, self.y, 0, 0, ctx.map.width, ctx.map.height) then
  69. ctx.spells:remove(self)
  70. end
  71. end
  72. function FrozenOrb:draw()
  73. local g = love.graphics
  74. local image = data.media.graphics.spell.frozenorb
  75. local x = math.lerp(self.prevx, self.x, ls.accum / ls.tickrate)
  76. local angle = math.anglerp(self.prevangle, self.angle, ls.accum / ls.tickrate)
  77. local scale = self.radius * 2 / image:getWidth()
  78. g.setColor(255, 255, 255)
  79. g.draw(image, x, self.y, self.angle, scale, scale, image:getWidth() / 2, image:getHeight() / 2)
  80. end
  81. function FrozenOrb:paused()
  82. self.prevx = self.x
  83. self.prevangle = self.angle
  84. end
  85. return FrozenOrb