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.
 
 
 

375 lines
8.5 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. showNames: false,
  16. objects: [],
  17. dirty: false,
  18. init: function () {
  19. events.on('onKeyDown', this.onKeyDown.bind(this));
  20. events.on('onGetObject', this.onGetObject.bind(this));
  21. events.on('onRezone', this.onRezone.bind(this));
  22. events.on('onChangeHoverTile', this.getLocation.bind(this));
  23. events.on('onTilesVisible', this.onTilesVisible.bind(this));
  24. //Get saved value for showNames, or use the value set above
  25. let showNames = window.localStorage.getItem('iwd_opt_shownames');
  26. this.showNames = showNames ? (showNames === 'true') : this.showNames;
  27. config.showNames = this.showNames;
  28. },
  29. getLocation: function (x, y) {
  30. let objects = this.objects;
  31. let oLen = objects.length;
  32. let closest = 999;
  33. let mob = null;
  34. for (let i = 0; i < oLen; i++) {
  35. let o = objects[i];
  36. if ((!o.stats) || (o.nonSelectable) || (o === window.player) || (!o.sprite.visible))
  37. continue;
  38. let dx = Math.abs(o.x - x);
  39. if ((dx < 3) && (dx < closest)) {
  40. let dy = Math.abs(o.y - y);
  41. if ((dy < 3) && (dy < closest)) {
  42. mob = o;
  43. closest = Math.max(dx, dy);
  44. }
  45. }
  46. }
  47. events.emit('onMobHover', mob);
  48. },
  49. getClosest: function (x, y, maxDistance, reverse, fromMob) {
  50. let objects = this.objects;
  51. let list = objects.filter(function (o) {
  52. if ((!o.stats) || (o.nonSelectable) || (o === window.player) || (!o.sprite.visible))
  53. return false;
  54. let dx = Math.abs(o.x - x);
  55. if (dx < maxDistance) {
  56. let dy = Math.abs(o.y - y);
  57. if (dy < maxDistance)
  58. return true;
  59. }
  60. });
  61. if (list.length === 0)
  62. return null;
  63. list.sort(function (a, b) {
  64. let aDistance = Math.max(Math.abs(x - a.x), Math.abs(y - a.y));
  65. let bDistance = Math.max(Math.abs(x - b.x), Math.abs(y - b.y));
  66. return (aDistance - bDistance);
  67. });
  68. list = list.filter(o => ((o.aggro) && (o.aggro.faction !== window.player.aggro.faction)));
  69. if (!fromMob)
  70. return list[0];
  71. let fromIndex = list.firstIndex(function (l) {
  72. return (l.id === fromMob.id);
  73. });
  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. onRezone: function (oldZone) {
  81. let objects = this.objects;
  82. let oLen = objects.length;
  83. for (let i = 0; i < oLen; i++) {
  84. let o = objects[i];
  85. if (oldZone === null)
  86. o.destroy();
  87. else if ((o.zoneId === oldZone) && (!o.has('player')))
  88. o.destroy();
  89. }
  90. window.player.offEvents();
  91. },
  92. onGetObject: function (obj) {
  93. this.dirty = true;
  94. //Things like attacks don't have ids
  95. let exists = null;
  96. if (obj.has('id'))
  97. exists = this.objects.find(f => (f.id === obj.id && !f.destroyed));
  98. if (!exists)
  99. exists = this.buildObject(obj);
  100. else
  101. this.updateObject(exists, obj);
  102. },
  103. buildObject: function (template) {
  104. let obj = $.extend(true, {}, objBase);
  105. let components = template.components || [];
  106. delete template.components;
  107. let syncTypes = ['portrait', 'area'];
  108. for (let p in template) {
  109. let value = template[p];
  110. let type = typeof (value);
  111. if (type === 'object') {
  112. if (syncTypes.indexOf(p) > -1)
  113. obj[p] = value;
  114. } else
  115. obj[p] = value;
  116. }
  117. components.forEach(function (c) {
  118. //Map ids to objects
  119. let keys = Object.keys(c).filter(function (k) {
  120. return ((k.indexOf('id') === 0) && (k.length > 2));
  121. });
  122. keys.forEach(function (k) {
  123. let value = c[k];
  124. let newKey = k.substr(2, k.length).toLowerCase();
  125. c[newKey] = this.objects.find(function (o) {
  126. return (o.id === value);
  127. });
  128. delete c[k];
  129. }, this);
  130. obj.addComponent(c.type, c);
  131. }, this);
  132. if (obj.sheetName) {
  133. obj.sprite = renderer.buildObject(obj);
  134. if (template.hidden) {
  135. obj.sprite.visible = false;
  136. if (obj.nameSprite)
  137. obj.nameSprite.visible = false;
  138. if ((obj.stats) && (obj.stats.hpSprite)) {
  139. obj.stats.hpSprite.visible = false;
  140. obj.stats.hpSpriteInner.visible = false;
  141. }
  142. }
  143. }
  144. this.objects.push(obj);
  145. if (obj.self) {
  146. events.emit('onGetPlayer', obj);
  147. window.player = obj;
  148. sound.init(obj.zoneId);
  149. renderer.setPosition({
  150. x: (obj.x - (renderer.width / (scale * 2))) * scale,
  151. y: (obj.y - (renderer.height / (scale * 2))) * scale
  152. }, true);
  153. }
  154. if ((obj.name) && (obj.sprite)) {
  155. obj.nameSprite = renderer.buildText({
  156. layerName: 'effects',
  157. text: obj.name,
  158. x: (obj.x * scale) + (scale / 2),
  159. y: (obj.y * scale) + scale
  160. });
  161. }
  162. if (renderer.sprites) {
  163. let isVisible = ((obj.self) || ((renderer.sprites[obj.x]) && (renderer.sprites[obj.x][obj.y].length > 0)));
  164. obj.setVisible(isVisible);
  165. }
  166. return obj;
  167. },
  168. updateObject: function (obj, template) {
  169. let components = template.components || [];
  170. components.forEach(function (c) {
  171. //Map ids to objects
  172. let keys = Object.keys(c).filter(function (k) {
  173. return ((k.indexOf('id') === 0) && (k.length > 2));
  174. });
  175. keys.forEach(function (k) {
  176. let value = c[k];
  177. let newKey = k.substr(2, k.length).toLowerCase();
  178. c[newKey] = this.objects.find(function (o) {
  179. return (o.id === value);
  180. });
  181. delete c[k];
  182. }, this);
  183. obj.addComponent(c.type, c);
  184. }, this);
  185. delete template.components;
  186. if (template.removeComponents) {
  187. template.removeComponents.forEach(function (r) {
  188. obj.removeComponent(r);
  189. });
  190. delete template.removeComponents;
  191. }
  192. let oldX = obj.x;
  193. let sprite = obj.sprite;
  194. let moved = false;
  195. for (let p in template) {
  196. let value = template[p];
  197. let type = typeof (value);
  198. if (type !== 'object')
  199. obj[p] = value;
  200. if ((p === 'x') || (p === 'y'))
  201. moved = true;
  202. if (p === 'casting') {
  203. if (obj === window.player)
  204. events.emit('onGetSelfCasting', value);
  205. else
  206. events.emit('onGetTargetCasting', value);
  207. }
  208. if (sprite) {
  209. if (p === 'x') {
  210. if (obj.x < oldX)
  211. obj.flipX = true;
  212. else if (obj.x > oldX)
  213. obj.flipX = false;
  214. }
  215. }
  216. }
  217. if (moved)
  218. obj.setSpritePosition();
  219. if (((template.sheetName) || (template.cell)) && (sprite))
  220. renderer.setSprite(obj);
  221. if (sprite) {
  222. if (template.hidden !== null) {
  223. sprite.visible = !template.hidden;
  224. if (obj.nameSprite)
  225. obj.nameSprite.visible = this.showNames;
  226. if ((obj.stats) && (obj.stats.hpSprite)) {
  227. obj.stats.hpSprite.visible = !template.hidden;
  228. obj.stats.hpSpriteInner.visible = !template.hidden;
  229. }
  230. }
  231. }
  232. if ((template.x !== 0) || (template.y !== 0)) {
  233. if (obj.stats)
  234. obj.stats.updateHpSprite();
  235. }
  236. if ((!obj.sprite) && (template.sheetName))
  237. obj.sprite = renderer.buildObject(obj);
  238. if ((!obj.nameSprite) && (template.name)) {
  239. obj.nameSprite = renderer.buildText({
  240. layerName: 'effects',
  241. text: template.name,
  242. x: (obj.x * scale) + (scale / 2),
  243. y: (obj.y * scale) + scale
  244. });
  245. obj.nameSprite.visible = this.showNames;
  246. }
  247. if (obj.sprite) {
  248. let isVisible = ((!!obj.player) || (renderer.sprites[obj.x][obj.y].length > 0));
  249. obj.setVisible(isVisible);
  250. }
  251. obj.setSpritePosition();
  252. },
  253. update: function () {
  254. let objects = this.objects;
  255. let len = objects.length;
  256. for (let i = 0; i < len; i++) {
  257. let o = objects[i];
  258. if (o.destroyed) {
  259. o.destroy();
  260. objects.splice(i, 1);
  261. i--;
  262. len--;
  263. continue;
  264. }
  265. o.update();
  266. if (o.dirty)
  267. this.dirty = true;
  268. }
  269. },
  270. onKeyDown: function (key) {
  271. if (key === 'v') {
  272. this.showNames = !this.showNames;
  273. //Set new value in localStorage for showNames
  274. window.localStorage.setItem('iwd_opt_shownames', this.showNames);
  275. config.showNames = this.showNames;
  276. let showNames = this.showNames;
  277. let objects = this.objects;
  278. let oLen = objects.length;
  279. for (let i = 0; i < oLen; i++) {
  280. let obj = objects[i];
  281. let ns = obj.nameSprite;
  282. if ((!ns) || (obj.dead) || ((obj.sprite) && (!obj.sprite.visible)))
  283. continue;
  284. ns.visible = showNames;
  285. }
  286. }
  287. },
  288. onTilesVisible: function (tiles, visible) {
  289. let objects = this.objects;
  290. let oLen = objects.length;
  291. for (let i = 0; i < oLen; i++) {
  292. let o = objects[i];
  293. let onPos = tiles.some(function (t) {
  294. return ((t.x === o.x) && (t.y === o.y));
  295. });
  296. if (!onPos)
  297. continue;
  298. o.setVisible(visible);
  299. }
  300. }
  301. };
  302. });