You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

150 lines
3.0 KiB

  1. module.exports = {
  2. type: 'projectile',
  3. applyEffect: null,
  4. cdMax: 7,
  5. manaCost: 0,
  6. range: 9,
  7. speed: 150,
  8. statMult: 1,
  9. damage: 1,
  10. row: 3,
  11. col: 0,
  12. needLos: true,
  13. shootAll: false,
  14. percentDamage: false,
  15. cast: function (action) {
  16. if (this.shootAll) {
  17. this.castAll(action);
  18. return true;
  19. }
  20. let obj = this.obj;
  21. let target = action.target;
  22. let ttl = (Math.sqrt(Math.pow(target.x - obj.x, 2) + Math.pow(target.y - obj.y, 2)) * this.speed) - 50;
  23. let projectileConfig = {
  24. caster: this.obj.id,
  25. extraTargets: 0,
  26. x: obj.x,
  27. y: obj.y,
  28. components: [{
  29. idSource: this.obj.id,
  30. idTarget: target.id,
  31. type: 'projectile',
  32. ttl: ttl,
  33. projectileOffset: this.projectileOffset,
  34. particles: this.particles
  35. }, {
  36. type: 'attackAnimation',
  37. layer: 'projectiles',
  38. loop: -1,
  39. row: this.row,
  40. col: this.col,
  41. spriteSheet: this.spriteSheet
  42. }]
  43. };
  44. this.obj.fireEvent('beforeSpawnProjectile', this, projectileConfig);
  45. this.sendBump(target);
  46. let targets = [target];
  47. let aggroList = this.obj.aggro.list
  48. .filter(function (l) {
  49. return (l.obj !== target);
  50. });
  51. for (let i = 0; i < Math.min(aggroList.length, projectileConfig.extraTargets); i++) {
  52. let pick = ~~(Math.random() * aggroList.length);
  53. targets.push(aggroList[pick].obj);
  54. aggroList.splice(pick, 1);
  55. }
  56. targets.forEach(function (t) {
  57. ttl = (Math.sqrt(Math.pow(t.x - obj.x, 2) + Math.pow(t.y - obj.y, 2)) * this.speed) - 50;
  58. let config = extend({}, projectileConfig);
  59. config.components[0].ttl = ttl;
  60. config.components[0].idTarget = t.id;
  61. this.sendAnimation(config);
  62. this.queueCallback(this.explode.bind(this, t), ttl, null, t);
  63. }, this);
  64. return true;
  65. },
  66. getAllTargets: function () {
  67. const targets = this.obj.aggro.list.map(a => a.obj);
  68. return targets;
  69. },
  70. castAll: function (action) {
  71. const { obj, projectileOffset, particles, row, col, speed } = this;
  72. const targets = this.getAllTargets();
  73. targets.forEach(t => {
  74. let ttl = (Math.sqrt(Math.pow(t.x - obj.x, 2) + Math.pow(t.y - obj.y, 2)) * speed) - 50;
  75. let projectileConfig = {
  76. caster: obj.id,
  77. x: obj.x,
  78. y: obj.y,
  79. components: [{
  80. idSource: obj.id,
  81. idTarget: t.id,
  82. type: 'projectile',
  83. ttl: ttl,
  84. projectileOffset: projectileOffset,
  85. particles: particles
  86. }, {
  87. type: 'attackAnimation',
  88. layer: 'projectiles',
  89. loop: -1,
  90. row: row,
  91. col: col,
  92. spriteSheet: this.spriteSheet
  93. }]
  94. };
  95. obj.fireEvent('beforeSpawnProjectile', this, projectileConfig);
  96. this.sendAnimation(projectileConfig);
  97. this.sendBump(t);
  98. this.queueCallback(this.explode.bind(this, t), ttl, null, t);
  99. });
  100. },
  101. explode: function (target) {
  102. if ((this.obj.destroyed) || (target.destroyed))
  103. return;
  104. let damage = this.getDamage(target);
  105. if (!target.stats)
  106. return;
  107. if (this.applyEffect)
  108. target.effects.addEffect(this.applyEffect, this.obj);
  109. target.stats.takeDamage({
  110. damage,
  111. threatMult: this.threatMult,
  112. source: this.obj,
  113. target,
  114. spellName: 'projectile'
  115. });
  116. }
  117. };