rocketboots.lua 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. local RocketBoots = {}
  2. RocketBoots.name = 'Rocket Boots'
  3. RocketBoots.code = 'rocketboots'
  4. RocketBoots.text = 'Is that a rocket in your pocket?'
  5. RocketBoots.type = 'skill'
  6. RocketBoots.needsMouse = true
  7. RocketBoots.targeted = true
  8. RocketBoots.cooldown = 12
  9. function RocketBoots:activate(owner)
  10. self.timer = 0
  11. self.targetAlpha = 0
  12. self.ghostX, self.ghostY = 0, 0
  13. self.targetGhostX, self.targetGhostY = 0, 0
  14. self.ghostTick = 0
  15. end
  16. function RocketBoots:update(owner)
  17. self.timer = timer.rot(self.timer)
  18. self.targetAlpha = math.lerp(self.targetAlpha, self.targeting and 1 or 0, math.min(10 * tickRate, 1))
  19. if self.targeting and ctx.view then
  20. if self.ghostTick == 0 then
  21. local px, py = self.targetGhostX, self.targetGhostY
  22. local ox, oy = owner.x, owner.y
  23. local mx, my = ctx.view:worldMouseX(), ctx.view:worldMouseY()
  24. local angle = math.direction(ox, oy, mx, my)
  25. local distance = math.min(data.spell.rocketboots.maxDistance, math.distance(ox, oy, mx, my))
  26. self.targetGhostX, self.targetGhostY = ox + math.dx(distance, angle), oy + math.dy(distance, angle)
  27. local s = 1
  28. local d = 10
  29. local tx, ty = self.targetGhostX, self.targetGhostY
  30. local iter = false
  31. while ctx.collision:circleTest(tx, ty, owner.radius, {tag = 'wall'}) or tx <= 0 or ty <= 0 or tx >= ctx.map.width or ty >= ctx.map.height do
  32. tx = self.targetGhostX + math.dx(d * s, angle)
  33. ty = self.targetGhostY + math.dy(d * s, angle)
  34. s = -s
  35. if s == 1 then d = d + 10 end
  36. iter = true
  37. end
  38. if d > 10 or s == -1 then
  39. s = -s
  40. while not ctx.collision:circleTest(tx, ty, owner.radius, {tag = 'wall'}) do
  41. tx = self.targetGhostX + math.dx(d * s, angle)
  42. ty = self.targetGhostY + math.dy(d * s, angle)
  43. d = d - 1
  44. end
  45. end
  46. owner.x, owner.y = tx, ty
  47. owner.moving = true
  48. owner.ghosting = true
  49. ctx.event:emit('collision.move', {object = owner, resolve = true})
  50. owner.moving = nil
  51. owner.ghosting = nil
  52. self.targetGhostX, self.targetGhostY = owner.x, owner.y
  53. owner.x, owner.y = ox, oy
  54. ctx.event:emit('collision.move', {object = owner, resolve = true})
  55. if math.distance(px, py, self.targetGhostX, self.targetGhostY) > 2 then
  56. self.ghostTick = 1
  57. else
  58. self.ghostTick = 6
  59. end
  60. end
  61. local x1, y1 = self.ghostX, self.ghostY
  62. local x2, y2 = self.targetGhostX, self.targetGhostY
  63. if x1 == 0 and y1 == 0 then x1, y1 = x2, y2 end
  64. self.ghostX = math.lerp(x1, x2, math.min(20 * tickRate, 1))
  65. self.ghostY = math.lerp(y1, y2, math.min(20 * tickRate, 1))
  66. if self.ghostTick > 0 then self.ghostTick = self.ghostTick - 1 end
  67. else
  68. self.targetGhostX, self.targetGhostY = 0, 0
  69. self.ghostX, self.ghostY = 0, 0
  70. end
  71. end
  72. function RocketBoots:canFire(owner)
  73. return self.timer == 0
  74. end
  75. function RocketBoots:fire(owner, mx, my)
  76. ctx.spells:activate(owner.id, data.spell.rocketboots, mx, my)
  77. self.timer = self.cooldown
  78. self.targetAlpha = 0
  79. end
  80. function RocketBoots:gui(owner)
  81. if self.targetAlpha > .1 then
  82. local g, v = love.graphics, ctx.view
  83. g.pop()
  84. ctx.view:worldPush()
  85. g.setColor(255, 255, 255, self.targetAlpha * 255)
  86. g.circle('line', owner.drawX, owner.drawY, data.spell.rocketboots.maxDistance, 100)
  87. if self.ghostX ~= 0 and self.ghostY ~= 0 then
  88. g.setColor(255, 255, 255, self.targetAlpha * 100)
  89. local x, y = self.ghostX, self.ghostY
  90. do
  91. local self = owner
  92. local g, c, a, s = love.graphics, self.class, self.drawAngle, self.drawScale * self.class.scale
  93. local alpha = self.alpha * (1 - (self.cloak / ((self.team == ctx.players:get(ctx.id).team or (ctx.players:get(ctx.id).killer and ctx.players:get(ctx.id).killer.id == self.id)) and 2 or 1)))
  94. g.setColor(0, 0, 0, alpha * 50)
  95. g.setColor(self.team == purple and {190, 160, 200, alpha * 100} or {240, 160, 140, alpha * 100})
  96. f.exe(self.slots[self.weapon].draw, self.slots[self.weapon], self)
  97. f.exe(self.slots[self.skill].draw, self.slots[self.skill], self)
  98. g.setColor(self.team == purple and {222, 200, 230, alpha * 100} or {250, 210, 200, alpha * 100})
  99. g.draw(c.sprite, x, y, a, s, s, c.anchorx, c.anchory)
  100. end
  101. end
  102. g.pop()
  103. g.push()
  104. g.translate(v.frame.x, v.frame.y)
  105. end
  106. end
  107. function RocketBoots:value(owner)
  108. return self.timer / self.cooldown
  109. end
  110. return RocketBoots