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.
 
 
 

254 lines
5.4 KiB

  1. define([
  2. 'js/system/client',
  3. 'js/rendering/renderer',
  4. 'js/system/events',
  5. 'js/input'
  6. ], function (
  7. client,
  8. renderer,
  9. events,
  10. input
  11. ) {
  12. let objects = null;
  13. require(['js/objects/objects'], function (o) {
  14. objects = o;
  15. });
  16. return {
  17. type: 'spellbook',
  18. hoverTarget: null,
  19. target: null,
  20. targetSprite: null,
  21. reticleState: 0,
  22. reticleCd: 0,
  23. reticleCdMax: 10,
  24. reticleSprite: null,
  25. groundTargetSpell: false,
  26. init: function (blueprint) {
  27. this.targetSprite = renderer.buildObject({
  28. sheetName: 'ui',
  29. layerName: 'effects',
  30. cell: 0,
  31. visible: false
  32. });
  33. this.reticleSprite = renderer.buildObject({
  34. sheetName: 'ui',
  35. layerName: 'effects',
  36. cell: 8,
  37. visible: false
  38. });
  39. events.emit('onGetSpells', this.spells);
  40. this.reticleCd = this.reticleCdMax;
  41. this.obj.on('onDeath', this.onDeath.bind(this));
  42. this.obj.on('onMobHover', this.onMobHover.bind(this));
  43. this.obj.on('mouseDown', this.onMouseDown.bind(this));
  44. this.obj.on('onKeyDown', this.onKeyDown.bind(this));
  45. },
  46. extend: function (blueprint) {
  47. if (blueprint.removeSpells) {
  48. blueprint.removeSpells.forEach(r => this.spells.spliceWhere(s => s.id === r));
  49. events.emit('onGetSpells', this.spells);
  50. }
  51. if (blueprint.getSpells) {
  52. blueprint.getSpells.forEach(function (s) {
  53. let existIndex = this.spells.findIndex(f => f.id === s.id);
  54. if (existIndex > -1) {
  55. this.spells.splice(existIndex, 1, s);
  56. return;
  57. }
  58. this.spells.push(s);
  59. this.spells.sort((a, b) => a.id - b.id);
  60. }, this);
  61. events.emit('onGetSpells', this.spells);
  62. }
  63. },
  64. getSpell: function (number) {
  65. let spellNumber = (number === ' ') ? 0 : number;
  66. let spell = this.spells.find(s => s.id === spellNumber);
  67. return spell;
  68. },
  69. onMobHover: function (target) {
  70. this.hoverTarget = target;
  71. },
  72. onMouseDown: function (e, target) {
  73. if (isMobile && this.groundTargetSpell) {
  74. this.groundTarget = {
  75. x: ~~(e.worldX / scale),
  76. y: ~~(e.worldY / scale)
  77. };
  78. this.onKeyDown(this.groundTargetSpell);
  79. this.groundTargetSpell = null;
  80. }
  81. if (!target && this.target && (!this.hoverTarget || this.hoverTarget.id !== this.target.id)) {
  82. client.request({
  83. cpn: 'player',
  84. method: 'queueAction',
  85. data: {
  86. action: 'spell',
  87. priority: true,
  88. target: null
  89. }
  90. });
  91. }
  92. this.target = target || this.hoverTarget;
  93. if (this.target) {
  94. this.targetSprite.x = this.target.x * scale;
  95. this.targetSprite.y = this.target.y * scale;
  96. this.targetSprite.visible = true;
  97. } else
  98. this.targetSprite.visible = false;
  99. events.emit('onSetTarget', this.target, e);
  100. },
  101. tabTarget: function (ignoreIfSet) {
  102. let compareAgainst = ignoreIfSet ? null : this.target;
  103. let closest = objects.getClosest(window.player.x, window.player.y, 10, input.isKeyDown('shift'), compareAgainst);
  104. this.target = closest;
  105. this.targetSprite.visible = !!this.target;
  106. events.emit('onSetTarget', this.target, null);
  107. },
  108. onKeyDown: function (key) {
  109. if (key === 'tab') {
  110. this.tabTarget();
  111. return;
  112. } else if (isNaN(key))
  113. return;
  114. let spell = this.getSpell(~~key);
  115. if (!spell)
  116. return;
  117. let isShiftDown = input.isKeyDown('shift');
  118. let oldTarget = null;
  119. if (isShiftDown || spell.targetPlayerPos) {
  120. oldTarget = this.target;
  121. this.target = this.obj;
  122. }
  123. if (!spell.aura && !spell.targetGround && !spell.autoTargetFollower && !this.target)
  124. return;
  125. let hoverTile = this.groundTarget || (this.obj.mouseMover || this.obj.touchMover).hoverTile;
  126. let target = hoverTile;
  127. if (spell.autoTargetFollower && !this.target)
  128. target = null;
  129. else if (!spell.targetGround && this.target)
  130. target = this.target.id;
  131. else if (spell.targetPlayerPos)
  132. isShiftDown = true;
  133. if (isShiftDown)
  134. this.target = oldTarget;
  135. if (target === this.obj && spell.noTargetSelf)
  136. return;
  137. else if (isMobile && spell.targetGround && !spell.targetPlayerPos && !this.groundTarget) {
  138. if (this.groundTargetSpell === key) {
  139. this.groundTargetSpell = null;
  140. events.emit('onGetAnnouncement', {
  141. msg: `Cancelled casting ${spell.name}`
  142. });
  143. return;
  144. }
  145. this.groundTargetSpell = key;
  146. events.emit('onGetAnnouncement', {
  147. msg: `Pick a location to cast ${spell.name}`
  148. });
  149. return;
  150. }
  151. client.request({
  152. cpn: 'player',
  153. method: 'queueAction',
  154. data: {
  155. action: 'spell',
  156. priority: input.isKeyDown('ctrl'),
  157. spell: spell.id,
  158. target: target,
  159. self: isShiftDown
  160. }
  161. });
  162. if (isMobile)
  163. this.groundTarget = null;
  164. },
  165. onDeath: function () {
  166. this.target = null;
  167. this.targetSprite.visible = false;
  168. },
  169. update: function () {
  170. if (this.reticleCd > 0)
  171. this.reticleCd--;
  172. else {
  173. this.reticleCd = this.reticleCdMax;
  174. this.reticleState++;
  175. if (this.reticleState === 4)
  176. this.reticleState = 0;
  177. }
  178. let target = this.target;
  179. if (!target)
  180. return;
  181. if (this.target.destroyed || this.target.nonSelectable || !this.target.isVisible) {
  182. this.target = null;
  183. this.targetSprite.visible = false;
  184. }
  185. this.targetSprite.x = target.x * scale;
  186. this.targetSprite.y = target.y * scale;
  187. renderer.setSprite({
  188. sprite: this.targetSprite,
  189. cell: this.reticleState,
  190. sheetName: 'ui'
  191. });
  192. },
  193. destroy: function () {
  194. if (this.targetSprite) {
  195. renderer.destroyObject({
  196. layerName: 'effects',
  197. sprite: this.targetSprite
  198. });
  199. }
  200. }
  201. };
  202. });