dusk.lua 4.3 KB

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