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.
 
 
 

477 lines
10 KiB

  1. define([
  2. 'js/system/events',
  3. 'js/system/client',
  4. 'html!ui/templates/inventory/template',
  5. 'css!ui/templates/inventory/styles',
  6. 'html!ui/templates/inventory/templateItem',
  7. 'html!ui/templates/inventory/templateTooltip',
  8. 'js/input',
  9. 'js/rendering/spriteShader'
  10. ], function(
  11. events,
  12. client,
  13. template,
  14. styles,
  15. tplItem,
  16. tplTooltip,
  17. input,
  18. spriteShader
  19. ) {
  20. var qualityColors = [{
  21. r: 252,
  22. g: 252,
  23. b: 252
  24. }, {
  25. r: 7,
  26. g: 170,
  27. b: 214
  28. }, {
  29. r: 255,
  30. g: 255,
  31. b: 0
  32. }, {
  33. r: 192,
  34. g: 0,
  35. b: 207
  36. }, {
  37. r: 255,
  38. g: 108,
  39. b: 4
  40. }];
  41. return {
  42. tpl: template,
  43. centered: true,
  44. items: [],
  45. shiftDown: false,
  46. dragItem: null,
  47. dragEl: null,
  48. hoverCell: null,
  49. modal: true,
  50. oldSpellsZIndex: 0,
  51. postRender: function() {
  52. this.onEvent('onGetItems', this.onGetItems.bind(this));
  53. this.onEvent('onDestroyItems', this.onDestroyItems.bind(this));
  54. this.onEvent('onShowInventory', this.toggle.bind(this));
  55. this.onEvent('onKeyDown', this.onKeyDown.bind(this));
  56. this.onEvent('onKeyUp', this.onKeyUp.bind(this));
  57. this.find('.grid')
  58. .on('mousemove', this.onMouseMove.bind(this))
  59. .on('mouseleave', this.onMouseDown.bind(this, null, null, false));
  60. },
  61. build: function() {
  62. var container = this.el.find('.grid')
  63. .empty();
  64. var items = this.items
  65. .filter(function(item) {
  66. return !item.eq;
  67. });
  68. var iLen = Math.max(items.length, 50);
  69. var rendered = [];
  70. for (var i = 0; i < iLen; i++) {
  71. var item = items.find(function(item) {
  72. return ((item.pos != null) && (item.pos == i));
  73. });
  74. if (!item) {
  75. item = items.find(function(item) {
  76. if ((item.pos != null) && (i < item.pos) && (item.pos < iLen))
  77. return false;
  78. return (!rendered.some(function(r) {
  79. return (r == item);
  80. }));
  81. });
  82. if (item)
  83. rendered.push(item);
  84. } else
  85. rendered.push(item);
  86. if (!item) {
  87. var itemEl = $(tplItem)
  88. .appendTo(container);
  89. itemEl
  90. .on('mouseup', this.onMouseDown.bind(this, null, null, false))
  91. .on('mousemove', this.onHover.bind(this, itemEl, item))
  92. .on('mouseleave', this.hideTooltip.bind(this, itemEl, item))
  93. .children()
  94. .remove();
  95. continue;
  96. }
  97. var imgX = -item.sprite[0] * 64;
  98. var imgY = -item.sprite[1] * 64;
  99. var itemEl = $(tplItem)
  100. .appendTo(container);
  101. var spritesheet = item.spritesheet || 'items';
  102. if (item.material)
  103. spritesheet = 'materials';
  104. else if (item.quest)
  105. spritesheet = 'questItems';
  106. itemEl
  107. .data('item', item)
  108. //.on('click', this.onClick.bind(this, itemEl, item))
  109. .on('mousedown', this.onMouseDown.bind(this, itemEl, item, true))
  110. .on('mouseup', this.onMouseDown.bind(this, null, null, false))
  111. .on('mousemove', this.onHover.bind(this, itemEl, item))
  112. .on('mouseleave', this.hideTooltip.bind(this, itemEl, item))
  113. .find('.icon')
  114. .css('background', 'url(../../../images/' + spritesheet + '.png) ' + imgX + 'px ' + imgY + 'px')
  115. .on('contextmenu', this.showContext.bind(this, item));
  116. if (item.quantity)
  117. itemEl.find('.quantity').html(item.quantity);
  118. else if (item.eq)
  119. itemEl.find('.quantity').html('EQ');
  120. if (item.eq)
  121. itemEl.addClass('eq');
  122. else if (item.isNew) {
  123. itemEl.addClass('new');
  124. itemEl.find('.quantity').html('NEW');
  125. }
  126. }
  127. },
  128. onMouseDown: function(el, item, down, e) {
  129. if (e.button != 0)
  130. return;
  131. if (down) {
  132. this.dragEl = el.clone()
  133. .appendTo(this.find('.grid'))
  134. .hide()
  135. .on('mouseup', this.onMouseDown.bind(this, null, null, false))
  136. .addClass('dragging');
  137. this.dragItem = el;
  138. events.emit('onHideItemTooltip', this.hoverItem);
  139. this.hoverItem = null;
  140. } else if (this.dragItem) {
  141. if ((this.hoverCell) && (this.hoverCell[0] != this.dragItem[0])) {
  142. var placeholder = $('<div></div>')
  143. .insertAfter(this.dragItem);
  144. this.dragItem.insertBefore(this.hoverCell);
  145. this.hoverCell.insertBefore(placeholder);
  146. placeholder.remove();
  147. var msgs = [{
  148. id: this.dragItem.data('item').id,
  149. pos: this.dragItem.index()
  150. }];
  151. this.items.find(function(i) {
  152. return (i.id == this.dragItem.data('item').id)
  153. }, this).pos = this.dragItem.index();
  154. var hoverCellItem = this.hoverCell.data('item');
  155. if (hoverCellItem) {
  156. msgs.push({
  157. id: hoverCellItem.id,
  158. pos: this.hoverCell.index()
  159. });
  160. this.items.find(function(i) {
  161. return (i.id == hoverCellItem.id)
  162. }, this).pos = this.hoverCell.index();
  163. }
  164. client.request({
  165. cpn: 'player',
  166. method: 'performAction',
  167. data: {
  168. cpn: 'inventory',
  169. method: 'moveItem',
  170. data: msgs
  171. }
  172. });
  173. this.build();
  174. }
  175. this.dragItem = null;
  176. this.dragEl.remove();
  177. this.dragEl = null;
  178. this.hoverCell = null;
  179. this.find('.hover').removeClass('hover');
  180. }
  181. },
  182. onMouseMove: function(e) {
  183. if (!this.dragEl)
  184. return;
  185. var offset = this.find('.grid').offset();
  186. this.dragEl.css({
  187. left: e.clientX - offset.left - 40,
  188. top: e.clientY - offset.top - 40,
  189. display: 'block'
  190. });
  191. },
  192. showContext: function(item, e) {
  193. var menuItems = {
  194. drop: {
  195. text: 'drop',
  196. callback: this.performItemAction.bind(this, item, 'dropItem')
  197. },
  198. destroy: {
  199. text: 'destroy',
  200. callback: this.performItemAction.bind(this, item, 'destroyItem')
  201. },
  202. salvage: {
  203. text: 'salvage',
  204. callback: this.performItemAction.bind(this, item, 'salvageItem')
  205. },
  206. stash: {
  207. text: 'stash',
  208. callback: this.performItemAction.bind(this, item, 'stashItem')
  209. },
  210. learn: {
  211. text: 'learn',
  212. callback: this.performItemAction.bind(this, item, 'learnAbility')
  213. },
  214. equip: {
  215. text: 'equip',
  216. callback: this.performItemAction.bind(this, item, 'equip')
  217. },
  218. augment: {
  219. text: 'augment',
  220. callback: this.openAugmentUi.bind(this, item)
  221. },
  222. divider: '----------'
  223. };
  224. if (item.eq) {
  225. menuItems.learn.text = 'unlearn';
  226. menuItems.equip.text = 'unequip';
  227. }
  228. var config = [];
  229. if (item.ability)
  230. config.push(menuItems.learn);
  231. else if (item.slot) {
  232. config.push(menuItems.equip);
  233. if (!item.eq)
  234. config.push(menuItems.divider);
  235. if (!item.eq) {
  236. config.push(menuItems.augment);
  237. config.push(menuItems.divider);
  238. }
  239. }
  240. if ((!item.quest) && (!item.eq)) {
  241. if ((window.player.stash.active) && (!item.noSalvage))
  242. config.push(menuItems.stash);
  243. config.push(menuItems.drop);
  244. if ((!item.material) && (!item.noSalvage))
  245. config.push(menuItems.salvage);
  246. config.push(menuItems.destroy);
  247. }
  248. if (config.length > 0)
  249. events.emit('onContextMenu', config, e);
  250. e.preventDefault;
  251. return false;
  252. },
  253. hideTooltip: function() {
  254. if (this.dragEl) {
  255. this.hoverCell = null;
  256. return;
  257. }
  258. events.emit('onHideItemTooltip', this.hoverItem);
  259. this.hoverItem = null;
  260. },
  261. onHover: function(el, item, e) {
  262. if (this.dragEl) {
  263. this.hoverCell = el;
  264. this.find('.hover').removeClass('hover');
  265. el.addClass('hover');
  266. return;
  267. }
  268. if (item)
  269. this.hoverItem = item;
  270. else
  271. item = this.hoverItem;
  272. if (!item)
  273. return;
  274. var ttPos = null;
  275. if (el) {
  276. if (el.hasClass('new')) {
  277. el.removeClass('new');
  278. el.find('.quantity').html(item.quantity || '');
  279. delete item.isNew;
  280. }
  281. var elOffset = el.offset();
  282. ttPos = {
  283. x: ~~(e.clientX + 32),
  284. y: ~~(e.clientY)
  285. };
  286. }
  287. var compare = null;
  288. if (item.slot) {
  289. compare = this.items.find(function(i) {
  290. return ((i.eq) && (i.slot == item.slot));
  291. });
  292. }
  293. events.emit('onShowItemTooltip', item, ttPos, compare, false, this.shiftDown);
  294. },
  295. onGetItems: function(items) {
  296. this.items = items;
  297. this.items.forEach(function(item) {
  298. var prefix = -1;
  299. ['quest', 'material', 'ability'].forEach(function(p, i) {
  300. if (item[p])
  301. prefix += 1 + i;
  302. });
  303. if (prefix == -1)
  304. prefix = 3 + item.slot + item.type;
  305. item.sortName = prefix + item.name + item.level + item.id;
  306. if ((item == this.hoverItem))
  307. this.onHover(null, item);
  308. }, this);
  309. this.items.sort(function(a, b) {
  310. if (a.sortName < b.sortName)
  311. return -1;
  312. else if (a.sortName > b.sortName)
  313. return 1;
  314. else
  315. return 0;
  316. });
  317. if (this.shown)
  318. this.build();
  319. },
  320. onDestroyItems: function(itemIds) {
  321. itemIds.forEach(function(id) {
  322. var item = this.items.find(i => i.id == id);
  323. if (item == this.hoverItem) {
  324. //this.hoverItem = null;
  325. this.hideTooltip();
  326. }
  327. this.items.spliceWhere(i => i.id == id);
  328. }, this);
  329. if (this.shown)
  330. this.build();
  331. },
  332. toggle: function(show) {
  333. this.shown = !this.el.is(':visible');
  334. if (this.shown) {
  335. this.show();
  336. this.build();
  337. } else {
  338. this.hide();
  339. events.emit('onHideInventory');
  340. events.emit('onHideContextMenu');
  341. }
  342. this.hideTooltip();
  343. },
  344. beforeDestroy: function() {
  345. this.el.parent().css('background-color', 'transparent');
  346. this.el.parent().removeClass('blocking');
  347. },
  348. beforeHide: function() {
  349. if (this.oldSpellsZIndex) {
  350. $('.uiSpells').css('z-index', this.oldSpellsZIndex);
  351. this.oldSpellsZIndex = null;
  352. }
  353. },
  354. performItemAction: function(item, action) {
  355. if (!item)
  356. return;
  357. else if ((action == 'equip') && ((item.material) || (item.quast) || (item.level > window.player.stats.values.level)))
  358. return;
  359. if (item.factions) {
  360. if (item.factions.some(function(f) {
  361. return f.noEquip;
  362. }))
  363. return;
  364. }
  365. var cpn = 'inventory';
  366. if (action == 'equip')
  367. cpn = 'equipment';
  368. client.request({
  369. cpn: 'player',
  370. method: 'performAction',
  371. data: {
  372. cpn: cpn,
  373. method: action,
  374. data: item.id
  375. }
  376. });
  377. },
  378. openAugmentUi: function(item) {
  379. events.emit('onSetSmithItem', {
  380. item: item
  381. });
  382. },
  383. onKeyDown: function(key) {
  384. if (key == 'i')
  385. this.toggle();
  386. else if (key == 'shift') {
  387. this.shiftDown = true;
  388. if (this.hoverItem)
  389. this.onHover();
  390. }
  391. },
  392. onKeyUp: function(key) {
  393. if (key == 'shift') {
  394. this.shiftDown = false;
  395. if (this.hoverItem)
  396. this.onHover();
  397. }
  398. }
  399. };
  400. });