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.
 
 
 

144 lines
2.9 KiB

  1. module.exports = {
  2. type: 'charge',
  3. cdMax: 20,
  4. manaCost: 10,
  5. range: 9,
  6. damage: 1,
  7. speed: 70,
  8. isAttack: true,
  9. stunDuration: 15,
  10. needLos: true,
  11. cast: function (action) {
  12. let obj = this.obj;
  13. let target = action.target;
  14. let x = obj.x;
  15. let y = obj.y;
  16. let dx = target.x - x;
  17. let dy = target.y - y;
  18. //We need to stop just short of the target
  19. let offsetX = 0;
  20. if (dx !== 0)
  21. offsetX = dx / Math.abs(dx);
  22. let offsetY = 0;
  23. if (dy !== 0)
  24. offsetY = dy / Math.abs(dy);
  25. let targetPos = {
  26. x: target.x,
  27. y: target.y
  28. };
  29. let physics = obj.instance.physics;
  30. //Check where we should land
  31. if (!this.isTileValid(physics, x, y, targetPos.x - offsetX, targetPos.y - offsetY)) {
  32. if (!this.isTileValid(physics, x, y, targetPos.x - offsetX, targetPos.y))
  33. targetPos.y -= offsetY;
  34. else
  35. targetPos.x -= offsetX;
  36. } else {
  37. targetPos.x -= offsetX;
  38. targetPos.y -= offsetY;
  39. }
  40. let distance = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
  41. let ttl = distance * this.speed;
  42. let targetEffect = target.effects.addEffect({
  43. type: 'stunned'
  44. });
  45. let selfEffect = this.obj.effects.addEffect({
  46. type: 'stunned',
  47. silent: true,
  48. force: true
  49. });
  50. const moveAnimationEffect = {
  51. type: 'moveAnimation',
  52. idTarget: target.id,
  53. targetX: targetPos.x,
  54. targetY: targetPos.y,
  55. ttl: ttl
  56. };
  57. this.obj.fireEvent('beforeAddSpellEffect', this, moveAnimationEffect);
  58. this.sendAnimation({
  59. id: this.obj.id,
  60. components: [moveAnimationEffect]
  61. });
  62. if (this.animation) {
  63. this.obj.instance.syncer.queue('onGetObject', {
  64. id: this.obj.id,
  65. components: [{
  66. type: 'animation',
  67. template: this.animation
  68. }]
  69. }, -1);
  70. }
  71. this.queueCallback(this.reachDestination.bind(this, target, targetPos, targetEffect, selfEffect), ttl - 50);
  72. return true;
  73. },
  74. reachDestination: function (target, targetPos, targetEffect, selfEffect) {
  75. if (this.obj.destroyed)
  76. return;
  77. let obj = this.obj;
  78. obj.instance.physics.removeObject(obj, obj.x, obj.y);
  79. obj.x = targetPos.x;
  80. obj.y = targetPos.y;
  81. let syncer = obj.syncer;
  82. syncer.o.x = targetPos.x;
  83. syncer.o.y = targetPos.y;
  84. obj.instance.physics.addObject(obj, obj.x, obj.y);
  85. obj.effects.removeEffect(selfEffect.id);
  86. this.obj.aggro.move();
  87. if (targetEffect)
  88. targetEffect.ttl = this.stunDuration;
  89. let damage = this.getDamage(target);
  90. target.stats.takeDamage({
  91. damage,
  92. threatMult: this.threatMult,
  93. source: this.obj,
  94. target,
  95. spellName: 'charge'
  96. });
  97. const moveEvent = {
  98. newPos: targetPos,
  99. source: this,
  100. target: this,
  101. spellName: 'charge',
  102. spell: this
  103. };
  104. this.obj.fireEvent('afterPositionChange', moveEvent);
  105. if (this.castOnEnd)
  106. this.obj.spellbook.spells[this.castOnEnd].cast();
  107. },
  108. isTileValid: function (physics, fromX, fromY, toX, toY) {
  109. if (physics.isTileBlocking(toX, toY))
  110. return false;
  111. return physics.hasLos(fromX, fromY, toX, toY);
  112. }
  113. };