Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

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