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.

98 lines
2.6 KiB

  1. const recipes = require('../../config/recipes/recipes');
  2. const generator = require('../../items/generator');
  3. const { applyItemStats } = require('../equipment/helpers');
  4. const buildRecipe = require('../workbench/buildRecipe');
  5. const buildMaterials = require('../workbench/buildMaterials');
  6. const buildPickedItems = require('../workbench/buildPickedItems');
  7. module.exports = (cpnWorkbench, msg) => {
  8. const { craftType, obj: { instance: { objects: { objects } } } } = cpnWorkbench;
  9. const { name: recipeName, sourceId } = msg;
  10. const crafter = objects.find(o => o.serverId === sourceId);
  11. if (!crafter || !crafter.player)
  12. return null;
  13. const recipe = recipes.getRecipe(craftType, recipeName);
  14. if (!recipe)
  15. return null;
  16. const { needItems = [] } = recipe;
  17. const { syncer, inventory, equipment, spellbook } = crafter;
  18. const materials = buildMaterials(crafter, recipe, msg);
  19. const pickedItems = buildPickedItems(crafter, recipe, msg);
  20. const canCraft = (
  21. !materials.some(m => m.noHaveEnough) &&
  22. pickedItems.length === needItems.length &&
  23. !pickedItems.some(i => !i)
  24. );
  25. if (!canCraft)
  26. return null;
  27. materials.forEach(m => inventory.destroyItem(m.id, m.needQuantity));
  28. let resultMsg = null;
  29. if (recipe.craftAction) {
  30. pickedItems.forEach(p => {
  31. if (p.eq)
  32. applyItemStats(crafter, p, false);
  33. });
  34. const oldSlots = pickedItems.map(p => p.slot);
  35. resultMsg = recipe.craftAction(crafter, pickedItems);
  36. pickedItems.forEach((p, i) => {
  37. if (!p.eq) {
  38. pickedItems.forEach(item => syncer.setArray(true, 'inventory', 'getItems', inventory.simplifyItem(item)));
  39. return;
  40. }
  41. applyItemStats(crafter, p, true);
  42. if (p.slot !== oldSlots[i])
  43. equipment.unequip(p.id);
  44. spellbook.calcDps();
  45. pickedItems.forEach(item => syncer.setArray(true, 'inventory', 'getItems', inventory.simplifyItem(item)));
  46. });
  47. equipment.unequipAttrRqrGear();
  48. }
  49. if (recipe.item || recipe.items) {
  50. const outputItems = recipe.item ? [ recipe.item ] : recipe.items;
  51. outputItems.forEach(itemBpt => {
  52. let item = null;
  53. if (itemBpt.generate)
  54. item = generator.generate(itemBpt);
  55. else
  56. item = extend({}, itemBpt);
  57. if (item.description)
  58. item.description += `<br /><br />(Crafted by ${crafter.name})`;
  59. else
  60. item.description = `<br /><br />(Crafted by ${crafter.name})`;
  61. const quantity = item.quantity;
  62. if (quantity && quantity.push)
  63. item.quantity = quantity[0] + ~~(Math.random() * (quantity[1] - quantity[0]));
  64. crafter.inventory.getItem(item);
  65. });
  66. }
  67. const result = {
  68. resultMsg,
  69. recipe: buildRecipe(craftType, crafter, msg)
  70. };
  71. return result;
  72. };