Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 

313 řádky
6.8 KiB

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