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.
 
 
 

159 lines
3.1 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(
  72. this.reachDestination.bind(this, target, targetPos, targetEffect, selfEffect),
  73. ttl - 50,
  74. this.destroyEffectOnTarget.bind(this, target, targetEffect)
  75. );
  76. return true;
  77. },
  78. reachDestination: function (target, targetPos, targetEffect, selfEffect) {
  79. if (this.obj.destroyed)
  80. return;
  81. let obj = this.obj;
  82. const moveEvent = {
  83. oldPos: {
  84. x: obj.x,
  85. y: obj.y
  86. },
  87. newPos: targetPos,
  88. source: this.obj,
  89. target: this.obj,
  90. spellName: 'charge',
  91. spell: this
  92. };
  93. obj.instance.physics.removeObject(obj, obj.x, obj.y);
  94. obj.x = targetPos.x;
  95. obj.y = targetPos.y;
  96. let syncer = obj.syncer;
  97. syncer.o.x = targetPos.x;
  98. syncer.o.y = targetPos.y;
  99. obj.instance.physics.addObject(obj, obj.x, obj.y);
  100. obj.effects.removeEffect(selfEffect.id);
  101. this.obj.aggro.move();
  102. if (targetEffect)
  103. targetEffect.ttl = this.stunDuration;
  104. let damage = this.getDamage(target);
  105. target.stats.takeDamage({
  106. damage,
  107. threatMult: this.threatMult,
  108. source: this.obj,
  109. target,
  110. spellName: 'charge',
  111. noEvents: this.noEvents
  112. });
  113. this.obj.fireEvent('afterPositionChange', moveEvent);
  114. if (this.castOnEnd)
  115. this.obj.spellbook.spells[this.castOnEnd].cast();
  116. },
  117. destroyEffectOnTarget: function (target, targetEffect) {
  118. target.effects.removeEffect(targetEffect.id);
  119. },
  120. isTileValid: function (physics, fromX, fromY, toX, toY) {
  121. if (physics.isTileBlocking(toX, toY))
  122. return false;
  123. return physics.hasLos(fromX, fromY, toX, toY);
  124. }
  125. };