plasmacannon.lua 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. local PlasmaCannon = {}
  2. ----------------
  3. -- Meta
  4. ----------------
  5. PlasmaCannon.name = 'Plasma Cannon'
  6. PlasmaCannon.code = 'plasmacannon'
  7. PlasmaCannon.text = 'Bwom.'
  8. PlasmaCannon.type = 'weapon'
  9. ----------------
  10. -- Data
  11. ----------------
  12. PlasmaCannon.image = data.media.graphics.smg
  13. PlasmaCannon.scale = 1
  14. PlasmaCannon.targeted = true
  15. PlasmaCannon.maxCharge = 1.5
  16. PlasmaCannon.overcharge = 2.5
  17. PlasmaCannon.minDamage = 5
  18. PlasmaCannon.maxDamage = 65
  19. PlasmaCannon.fireTime = 1
  20. PlasmaCannon.switchTime = .5
  21. PlasmaCannon.ammo = 10
  22. PlasmaCannon.recoil = 7
  23. PlasmaCannon.anchorx = 15
  24. PlasmaCannon.anchory = 7
  25. PlasmaCannon.tipx = 14
  26. PlasmaCannon.tipy = 0
  27. ----------------
  28. -- Behavior
  29. ----------------
  30. function PlasmaCannon:activate()
  31. self.timers = {}
  32. self.timers.fire = 0
  33. self.timers.switch = 0
  34. self.currentAmmo = self.ammo
  35. self.charge = 0
  36. self.targetAlpha = 0
  37. end
  38. function PlasmaCannon:update()
  39. self.timers.fire = timer.rot(self.timers.fire)
  40. self.timers.switch = timer.rot(self.timers.switch)
  41. if self.targeting then
  42. self.charge = math.min(self.charge + tickRate, self.overcharge)
  43. if self.charge == self.overcharge then
  44. self.timers.fire = self.fireTime
  45. self.charge = 0
  46. self.targeting = false
  47. end
  48. self.targetAlpha = math.lerp(self.targetAlpha, 1, math.min(10 * tickRate, 1))
  49. else
  50. self.charge = 0
  51. self.targetAlpha = math.lerp(self.targetAlpha, 0, math.min(10 * tickRate, 1))
  52. end
  53. end
  54. function PlasmaCannon:draw(owner)
  55. app.logic.weapon.draw(self, owner)
  56. end
  57. function PlasmaCannon:select(owner)
  58. app.logic.weapon.select(self, owner)
  59. self.charge = 0
  60. end
  61. function PlasmaCannon:canFire()
  62. return self.timers.fire == 0 and self.timers.switch == 0 and self.currentAmmo > 0
  63. end
  64. function PlasmaCannon:fire(owner)
  65. ctx.spells:activate(owner.id, data.spell.plasmacannon, math.min(self.charge, self.maxCharge))
  66. self.timers.fire = self.fireTime
  67. self.currentAmmo = self.currentAmmo - 1
  68. self.charge = 0
  69. owner.recoil = self.recoil
  70. end
  71. function PlasmaCannon:refillAmmo(owner)
  72. self.currentAmmo = math.min(self.currentAmmo + math.ceil(self.ammo / 4), self.ammo)
  73. end
  74. function PlasmaCannon:value(owner)
  75. if self.timers.switch > 0 then return self.timers.switch / self.switchTime
  76. elseif self.timers.fire > 0 then return self.timers.fire / self.fireTime
  77. else return 0 end
  78. end
  79. function PlasmaCannon:ammoValue(owner)
  80. return self.currentAmmo
  81. end
  82. ----------------
  83. -- Crosshair
  84. ----------------
  85. function PlasmaCannon:crosshair()
  86. local g, p, x, y = love.graphics, ctx.players:get(ctx.id), ctx.view:frameMouseX(), ctx.view:frameMouseY()
  87. local vx, vy, s = ctx.view:worldMouseX(), ctx.view:worldMouseY(), ctx.view.scale
  88. local d = math.distance(p.x, p.y, vx, vy)
  89. local len = (8 * s) + (8 * math.min(self.charge, self.maxCharge) / self.maxCharge)
  90. local dir = p.angle
  91. local dx, dy = p.class.handx * p.class.scale * s, p.class.handy * p.class.scale * s
  92. x = x + math.dx(dx, dir) - math.dy(dy, dir)
  93. y = y + math.dy(dx, dir) + math.dx(dy, dir)
  94. dx, dy = self.tipx * self.scale * s, self.tipy * self.scale * s
  95. x = x + math.dx(dx, dir) - math.dy(dy, dir)
  96. y = y + math.dy(dx, dir) + math.dx(dy, dir)
  97. local d2 = (math.distance(0, 0, p.class.handx, p.class.handy) * p.class.scale) + (math.distance(0, 0, self.tipx, self.tipy) * self.scale)
  98. x = x - math.dx(math.min(d2, d) * s, dir)
  99. y = y - math.dy(math.min(d2, d) * s, dir)
  100. local alpha = self.timers.switch > 0 and 128 or 255
  101. local factor = (1 - (math.clamp(tick - p.lastDamageDealt, 0, .4 / tickRate) / (.4 / tickRate))) ^ 2
  102. g.setColor(table.interpolate({0, 255, 255, alpha}, {255, 0, 0, alpha}, factor))
  103. g.line(x, y - len, x, y + len)
  104. g.line(x - len, y, x + len, y)
  105. g.line(x - len, y, x + len, y)
  106. g.line(x, y - len, x, y + len)
  107. g.setColor(0, 255, 255, 200 * self.targetAlpha)
  108. g.rectangle('fill', x - 30 + .5, y - 40 + .5, 30 * math.min(self.charge, self.maxCharge) / self.maxCharge, 8)
  109. g.setColor(255, 0, 0, 200 * self.targetAlpha * (self.charge / self.overcharge))
  110. g.rectangle('fill', x + .5, y - 40 + .5, 30 * math.max(self.charge - self.maxCharge, 0) / (self.overcharge - self.maxCharge), 8)
  111. g.setColor(255, 255, 255, 255 * self.targetAlpha)
  112. g.rectangle('line', x - 30 + .5, y - 40 + .5, 60, 8)
  113. g.line(x + .5, y - 40 + .5, x + .5, y - 32 + .5)
  114. end
  115. return PlasmaCannon