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.
 
 
 

278 lines
5.8 KiB

  1. define([
  2. 'js/objects/objBaseLegacy',
  3. 'js/objects/objBase',
  4. 'js/system/events',
  5. 'js/rendering/renderer',
  6. 'js/sound/sound',
  7. 'js/config',
  8. 'js/system/globals'
  9. ], function (
  10. objBaseLegacy,
  11. objBase,
  12. events,
  13. renderer,
  14. sound,
  15. config,
  16. globals
  17. ) {
  18. return {
  19. objects: [],
  20. init: function () {
  21. globals.objects = this;
  22. events.on('onChangeHoverTile', this.getLocation.bind(this));
  23. [
  24. 'onGetObject',
  25. 'onTilesVisible',
  26. 'onToggleNameplates',
  27. 'destroyAllObjects'
  28. ]
  29. .forEach(e => events.on(e, this[e].bind(this)));
  30. },
  31. getLocation: function (x, y) {
  32. let objects = this.objects;
  33. let oLen = objects.length;
  34. let closest = 999;
  35. let mob = null;
  36. for (let i = 0; i < oLen; i++) {
  37. let o = objects[i];
  38. if (!o.stats || o.nonSelectable || o === window.player || !o.sprite || !o.sprite.visible)
  39. continue;
  40. let dx = Math.abs(o.x - x);
  41. if ((dx < 3) && (dx < closest)) {
  42. let dy = Math.abs(o.y - y);
  43. if ((dy < 3) && (dy < closest)) {
  44. mob = o;
  45. closest = Math.max(dx, dy);
  46. }
  47. }
  48. }
  49. events.emit('onMobHover', mob);
  50. },
  51. getClosest: function (x, y, maxDistance, reverse, fromMob) {
  52. let objects = this.objects;
  53. let list = objects.filter(o => {
  54. if ((!o.stats) || (o.nonSelectable) || (o === window.player) || (!o.isVisible))
  55. return false;
  56. let dx = Math.abs(o.x - x);
  57. if (dx < maxDistance) {
  58. let dy = Math.abs(o.y - y);
  59. if (dy < maxDistance)
  60. return true;
  61. }
  62. });
  63. if (list.length === 0)
  64. return null;
  65. list.sort((a, b) => {
  66. let aDistance = Math.max(Math.abs(x - a.x), Math.abs(y - a.y));
  67. let bDistance = Math.max(Math.abs(x - b.x), Math.abs(y - b.y));
  68. return (aDistance - bDistance);
  69. });
  70. list = list.filter(o => ((o.aggro) && (o.aggro.faction !== window.player.aggro.faction)));
  71. if (!fromMob)
  72. return list[0];
  73. let fromIndex = list.findIndex(l => l.id === fromMob.id);
  74. if (reverse)
  75. fromIndex = (fromIndex === 0 ? list.length : fromIndex) - 1;
  76. else
  77. fromIndex = (fromIndex + 1) % list.length;
  78. return list[fromIndex];
  79. },
  80. destroyAllObjects: function () {
  81. this.objects.forEach(o => {
  82. o.destroy();
  83. });
  84. this.objects.length = 0;
  85. window?.player?.offEvents();
  86. },
  87. onGetObject: function (obj) {
  88. //Things like attacks don't have ids
  89. let exists = null;
  90. if (obj.has('id'))
  91. exists = this.objects.find(({ id, destroyed }) => id === obj.id && !destroyed);
  92. if (!exists)
  93. exists = this.buildObject(obj);
  94. else
  95. this.updateObject(exists, obj);
  96. },
  97. buildObject: function (template) {
  98. const base = template.components?.some(c => c.type === 'sprite') ? objBase : objBaseLegacy;
  99. const obj = $.extend(true, {}, base);
  100. obj.init(template);
  101. this.objects.push(obj);
  102. if (obj.self) {
  103. events.emit('onGetPlayer', obj);
  104. window.player = obj;
  105. sound.unload(obj.zoneId);
  106. renderer.setPosition({
  107. x: (obj.x - (renderer.width / (scale * 2))) * scale,
  108. y: (obj.y - (renderer.height / (scale * 2))) * scale
  109. }, true);
  110. }
  111. return obj;
  112. },
  113. updateObject: function (obj, template) {
  114. let components = template.components || [];
  115. components.forEach(c => {
  116. //Map ids to objects
  117. let keys = Object.keys(c).filter(k => {
  118. return (k.indexOf('id') === 0 && k.length > 2);
  119. });
  120. keys.forEach(k => {
  121. let value = c[k];
  122. let newKey = k.substr(2, k.length).toLowerCase();
  123. c[newKey] = this.objects.find(o => o.id === value);
  124. delete c[k];
  125. });
  126. obj.addComponent(c.type, c);
  127. });
  128. delete template.components;
  129. if (template.removeComponents) {
  130. template.removeComponents.forEach(r => {
  131. obj.removeComponent(r);
  132. });
  133. delete template.removeComponents;
  134. }
  135. let oldX = obj.x;
  136. let sprite = obj.sprite;
  137. for (let p in template) {
  138. let value = template[p];
  139. let type = typeof (value);
  140. if (type !== 'object')
  141. obj[p] = value;
  142. if (p === 'casting') {
  143. if (obj === window.player)
  144. events.emit('onGetSelfCasting', value);
  145. else
  146. events.emit('onGetTargetCasting', obj.id, value);
  147. }
  148. if (sprite) {
  149. if (p === 'x') {
  150. if (obj.x < oldX)
  151. obj.flipX = true;
  152. else if (obj.x > oldX)
  153. obj.flipX = false;
  154. }
  155. }
  156. }
  157. if (((template.sheetName) || (template.cell)) && (sprite))
  158. renderer.setSprite(obj);
  159. if ((!obj.sprite) && (template.sheetName))
  160. obj.sprite = renderer.buildObject(obj);
  161. if (template.name) {
  162. if (obj.nameSprite)
  163. renderer.destroyObject({ sprite: obj.nameSprite });
  164. obj.nameSprite = renderer.buildText({
  165. layerName: 'effects',
  166. text: template.name,
  167. x: (obj.x * scale) + (scale / 2),
  168. y: (obj.y * scale) + scale
  169. });
  170. obj.nameSprite.visible = config.showNames;
  171. }
  172. if ((template.x !== 0) || (template.y !== 0)) {
  173. obj.updateVisibility();
  174. obj.setSpritePosition();
  175. if (obj.stats)
  176. obj.stats.updateHpSprite();
  177. }
  178. },
  179. update: function () {
  180. let objects = this.objects;
  181. let len = objects.length;
  182. for (let i = 0; i < len; i++) {
  183. let o = objects[i];
  184. if (o.destroyed) {
  185. o.destroy();
  186. objects.splice(i, 1);
  187. i--;
  188. len--;
  189. continue;
  190. }
  191. o.update();
  192. }
  193. },
  194. onTilesVisible: function (tiles, visible) {
  195. let objects = this.objects;
  196. let oLen = objects.length;
  197. for (let i = 0; i < oLen; i++) {
  198. let o = objects[i];
  199. let onPos = tiles.some(t => {
  200. return (!(t.x !== o.x || t.y !== o.y));
  201. });
  202. if (!onPos)
  203. continue;
  204. o.updateVisibility();
  205. }
  206. },
  207. onToggleNameplates: function (show) {
  208. let objects = this.objects;
  209. let oLen = objects.length;
  210. for (let i = 0; i < oLen; i++) {
  211. let obj = objects[i];
  212. let ns = obj.nameSprite;
  213. if ((!ns) || (obj.dead) || ((obj.sprite) && (!obj.sprite.visible)))
  214. continue;
  215. ns.visible = show;
  216. }
  217. }
  218. };
  219. });