25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

147 lines
3.3 KiB

  1. const events = require('../../misc/events');
  2. const { isItemStackable } = require('./helpers');
  3. const getNextId = items => {
  4. let id = 0;
  5. let iLen = items.length;
  6. for (let i = 0; i < iLen; i++) {
  7. let fItem = items[i];
  8. if (fItem.id >= id)
  9. id = fItem.id + 1;
  10. }
  11. return id;
  12. };
  13. const dropBagForOverflow = (cpnInv, item) => {
  14. const { obj: { x, y, name, instance } } = cpnInv;
  15. const dropCell = instance.physics.getOpenCellInArea(x - 1, y - 1, x + 1, y + 1);
  16. if (dropCell) {
  17. cpnInv.createBag(dropCell.x, dropCell.y, [item], name);
  18. const msg = `Your inventory is too full to receive (${item.name}). It has been dropped on the ground.`;
  19. cpnInv.notifyNoBagSpace(msg);
  20. }
  21. };
  22. module.exports = (cpnInv, item, hideMessage, noStack, hideAlert, createBagIfFull = false) => {
  23. const obj = cpnInv.obj;
  24. obj.instance.eventEmitter.emit('onBeforeGetItem', item, obj);
  25. events.emit('beforePlayerGetItem', obj, item);
  26. //We need to know if a mob dropped it for quest purposes
  27. let fromMob = item.fromMob;
  28. if (!item.has('quality'))
  29. item.quality = 0;
  30. //Store the quantity to send to the player
  31. let quantity = item.quantity;
  32. let exists = false;
  33. if (isItemStackable(item) && !noStack) {
  34. let existItem = cpnInv.items.find(i => i.name === item.name);
  35. if (existItem) {
  36. exists = true;
  37. existItem.quantity = ~~(existItem.quantity || 1) + ~~(item.quantity || 1);
  38. item = existItem;
  39. }
  40. }
  41. if (!exists)
  42. delete item.pos;
  43. //Get next id
  44. if (!exists) {
  45. if (!cpnInv.hasSpace(item)) {
  46. if (createBagIfFull)
  47. dropBagForOverflow(cpnInv, item);
  48. else if (!hideMessage)
  49. cpnInv.notifyNoBagSpace();
  50. return false;
  51. }
  52. const items = cpnInv.items;
  53. item.id = getNextId(items);
  54. if (item.eq)
  55. delete item.pos;
  56. if (!item.has('pos') && !item.eq) {
  57. const iLen = items.length;
  58. let pos = iLen;
  59. for (let i = 0; i < iLen; i++) {
  60. if (!items.some(fi => fi.pos === i)) {
  61. pos = i;
  62. break;
  63. }
  64. }
  65. item.pos = pos;
  66. }
  67. }
  68. //Players can't have fromMob items in their inventory but bags can (dropped by a mob)
  69. if (obj.player)
  70. delete item.fromMob;
  71. if (obj.player) {
  72. let msg = item.name;
  73. if (quantity)
  74. msg += ' x' + quantity;
  75. else if ((item.stats) && (item.stats.weight))
  76. msg += ` ${item.stats.weight}lb`;
  77. const messages = [{
  78. class: 'q' + item.quality,
  79. message: 'loot: {' + msg + '}',
  80. item: item,
  81. type: 'loot'
  82. }];
  83. if (!hideAlert) {
  84. obj.instance.syncer.queue('onGetDamage', {
  85. id: obj.id,
  86. event: true,
  87. text: 'loot'
  88. }, -1);
  89. }
  90. if (!hideMessage) {
  91. obj.instance.syncer.queue('onGetMessages', {
  92. id: obj.id,
  93. messages: messages
  94. }, [obj.serverId]);
  95. }
  96. }
  97. if (item.effects)
  98. cpnInv.hookItemEvents([item]);
  99. if (!exists)
  100. cpnInv.items.push(item);
  101. if (item.eq) {
  102. delete item.eq;
  103. if (item.ability)
  104. cpnInv.learnAbility({ itemId: item.id, slot: item.runeSlot });
  105. else
  106. obj.equipment.equip({ itemId: item.id });
  107. } else if (item.has('quickSlot')) {
  108. obj.equipment.setQuickSlot({
  109. itemId: item.id,
  110. slot: item.quickSlot
  111. });
  112. } else {
  113. obj.syncer.deleteFromArray(true, 'inventory', 'getItems', i => i.id === item.id);
  114. obj.syncer.setArray(true, 'inventory', 'getItems', cpnInv.simplifyItem(item), true);
  115. }
  116. if (!hideMessage && fromMob)
  117. obj.fireEvent('afterLootMobItem', item);
  118. return item;
  119. };