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.
 
 
 

479 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.eq) {
  241. if (!item.quest) {
  242. if ((window.player.stash.active) && (!item.noSalvage))
  243. config.push(menuItems.stash);
  244. config.push(menuItems.drop);
  245. if ((!item.material) && (!item.noSalvage))
  246. config.push(menuItems.salvage);
  247. }
  248. config.push(menuItems.destroy);
  249. }
  250. if (config.length > 0)
  251. events.emit('onContextMenu', config, e);
  252. e.preventDefault;
  253. return false;
  254. },
  255. hideTooltip: function() {
  256. if (this.dragEl) {
  257. this.hoverCell = null;
  258. return;
  259. }
  260. events.emit('onHideItemTooltip', this.hoverItem);
  261. this.hoverItem = null;
  262. },
  263. onHover: function(el, item, e) {
  264. if (this.dragEl) {
  265. this.hoverCell = el;
  266. this.find('.hover').removeClass('hover');
  267. el.addClass('hover');
  268. return;
  269. }
  270. if (item)
  271. this.hoverItem = item;
  272. else
  273. item = this.hoverItem;
  274. if (!item)
  275. return;
  276. var ttPos = null;
  277. if (el) {
  278. if (el.hasClass('new')) {
  279. el.removeClass('new');
  280. el.find('.quantity').html(item.quantity || '');
  281. delete item.isNew;
  282. }
  283. var elOffset = el.offset();
  284. ttPos = {
  285. x: ~~(e.clientX + 32),
  286. y: ~~(e.clientY)
  287. };
  288. }
  289. var compare = null;
  290. if (item.slot) {
  291. compare = this.items.find(function(i) {
  292. return ((i.eq) && (i.slot == item.slot));
  293. });
  294. }
  295. events.emit('onShowItemTooltip', item, ttPos, compare, false, this.shiftDown);
  296. },
  297. onGetItems: function(items) {
  298. this.items = items;
  299. this.items.forEach(function(item) {
  300. var prefix = -1;
  301. ['quest', 'material', 'ability'].forEach(function(p, i) {
  302. if (item[p])
  303. prefix += 1 + i;
  304. });
  305. if (prefix == -1)
  306. prefix = 3 + item.slot + item.type;
  307. item.sortName = prefix + item.name + item.level + item.id;
  308. if ((item == this.hoverItem))
  309. this.onHover(null, item);
  310. }, this);
  311. this.items.sort(function(a, b) {
  312. if (a.sortName < b.sortName)
  313. return -1;
  314. else if (a.sortName > b.sortName)
  315. return 1;
  316. else
  317. return 0;
  318. });
  319. if (this.shown)
  320. this.build();
  321. },
  322. onDestroyItems: function(itemIds) {
  323. itemIds.forEach(function(id) {
  324. var item = this.items.find(i => i.id == id);
  325. if (item == this.hoverItem) {
  326. //this.hoverItem = null;
  327. this.hideTooltip();
  328. }
  329. this.items.spliceWhere(i => i.id == id);
  330. }, this);
  331. if (this.shown)
  332. this.build();
  333. },
  334. toggle: function(show) {
  335. this.shown = !this.el.is(':visible');
  336. if (this.shown) {
  337. this.show();
  338. this.build();
  339. } else {
  340. this.hide();
  341. events.emit('onHideInventory');
  342. events.emit('onHideContextMenu');
  343. }
  344. this.hideTooltip();
  345. },
  346. beforeDestroy: function() {
  347. this.el.parent().css('background-color', 'transparent');
  348. this.el.parent().removeClass('blocking');
  349. },
  350. beforeHide: function() {
  351. if (this.oldSpellsZIndex) {
  352. $('.uiSpells').css('z-index', this.oldSpellsZIndex);
  353. this.oldSpellsZIndex = null;
  354. }
  355. },
  356. performItemAction: function(item, action) {
  357. if (!item)
  358. return;
  359. else if ((action == 'equip') && ((item.material) || (item.quast) || (item.level > window.player.stats.values.level)))
  360. return;
  361. if (item.factions) {
  362. if (item.factions.some(function(f) {
  363. return f.noEquip;
  364. }))
  365. return;
  366. }
  367. var cpn = 'inventory';
  368. if (action == 'equip')
  369. cpn = 'equipment';
  370. client.request({
  371. cpn: 'player',
  372. method: 'performAction',
  373. data: {
  374. cpn: cpn,
  375. method: action,
  376. data: item.id
  377. }
  378. });
  379. },
  380. openAugmentUi: function(item) {
  381. events.emit('onSetSmithItem', {
  382. item: item
  383. });
  384. },
  385. onKeyDown: function(key) {
  386. if (key == 'i')
  387. this.toggle();
  388. else if (key == 'shift') {
  389. this.shiftDown = true;
  390. if (this.hoverItem)
  391. this.onHover();
  392. }
  393. },
  394. onKeyUp: function(key) {
  395. if (key == 'shift') {
  396. this.shiftDown = false;
  397. if (this.hoverItem)
  398. this.onHover();
  399. }
  400. }
  401. };
  402. });