shotgun.lua 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. local Shotgun = extend(app.logic.spell)
  2. Shotgun.code = 'shotgun'
  3. Shotgun.duration = .1
  4. Shotgun.activate = function(self)
  5. self.timer = self.duration
  6. self.x = self.owner.x
  7. self.y = self.owner.y
  8. local dir = self.owner.angle
  9. local dx, dy = self.owner.class.handx * self.owner.class.scale, self.owner.class.handy * self.owner.class.scale
  10. self.x = self.x + math.dx(dx, dir) - math.dy(dy, dir)
  11. self.y = self.y + math.dy(dx, dir) + math.dx(dy, dir)
  12. dx, dy = data.weapon.shotgun.tipx * data.weapon.shotgun.scale, data.weapon.shotgun.tipy * data.weapon.shotgun.scale
  13. self.x = self.x + math.dx(dx, dir) - math.dy(dy, dir)
  14. self.y = self.y + math.dy(dx, dir) + math.dx(dy, dir)
  15. self.len = 800
  16. self.bullets = {}
  17. if not ctx.collision:lineTest(self.owner.x, self.owner.y, self.x, self.y, {tag = 'wall'}) then
  18. local spread = data.weapon.shotgun.spread / (data.weapon.shotgun.count - 1)
  19. local initial = self.owner.angle - spread * ((data.weapon.shotgun.count - 1) / 2)
  20. for i = 1, data.weapon.shotgun.count do
  21. local ang, len = initial + ((i - 1) * spread), self.len
  22. local hit, d = ctx.collision:lineTest(self.x, self.y, self.x + math.dx(len, ang), self.y + math.dy(len, ang), {tag = 'wall', first = true})
  23. len = hit and d or len
  24. hit, d = ctx.collision:lineTest(self.x, self.y, self.x + math.dx(len, ang), self.y + math.dy(len, ang), {
  25. tag = 'player',
  26. fn = function(p)
  27. return p.team ~= self.owner.team
  28. end,
  29. first = true
  30. })
  31. if hit then
  32. local p = hit
  33. len = d
  34. local n, f = self.len * .25, self.len * .75
  35. local l, h = data.weapon.shotgun.damage * .4, data.weapon.shotgun.damage * 1
  36. local damage = l + ((h - l) * ((f - math.clamp(len, n, f)) / f))
  37. ctx.net:emit(app.net.events.damage, {id = p.id, amount = damage, from = self.owner.id, tick = tick})
  38. end
  39. table.insert(self.bullets, {
  40. dir = ang,
  41. dis = len
  42. })
  43. if not hit and len < self.len then
  44. for _ = 1, 4 do
  45. ctx.event:emit('particle.create', {
  46. kind = 'spark',
  47. vars = {
  48. x = self.x + math.dx(len, ang),
  49. y = self.y + math.dy(len, ang),
  50. angle = ang + math.pi + love.math.random() * 2.08 - 1.04
  51. }
  52. })
  53. end
  54. end
  55. if hit then
  56. for _ = 1, 4 do
  57. ctx.event:emit('particle.create', {
  58. kind = 'blood',
  59. vars = {
  60. x = hit.x - 10 + love.math.random() * 20,
  61. y = hit.y - 10 + love.math.random() * 20
  62. }
  63. })
  64. end
  65. end
  66. end
  67. end
  68. for _ = 1, 4 do
  69. ctx.event:emit('particle.create', {
  70. kind = 'spark',
  71. vars = {
  72. x = self.x,
  73. y = self.y,
  74. angle = self.owner.angle + love.math.random() * 1.56 - .78
  75. }
  76. })
  77. end
  78. ctx.event:emit('particle.create', {
  79. kind = 'muzzleFlash',
  80. vars = {
  81. owner = self.owner.id,
  82. weapon = 'shotgun'
  83. }
  84. })
  85. ctx.event:emit('particle.create', {
  86. kind = 'shell',
  87. vars = {
  88. x = self.x,
  89. y = self.y,
  90. direction = self.owner.angle + love.math.random() * .8 - .4
  91. }
  92. })
  93. self:playSound('shotgun')
  94. end
  95. Shotgun.update = function(self)
  96. self:rot()
  97. end
  98. Shotgun.draw = function(self)
  99. local function doDraw()
  100. love.graphics.setColor(255, 255, 255, (self.timer / self.duration) * 255)
  101. for _, bullet in pairs(self.bullets) do
  102. love.graphics.line(self.x, self.y, self.x + math.dx(bullet.dis, bullet.dir), self.y + math.dy(bullet.dis, bullet.dir))
  103. end
  104. end
  105. doDraw()
  106. ctx.effects:get('bloom'):render(doDraw)
  107. end
  108. return Shotgun