Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 

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