CraftingStorage.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #include <InMemoryBuffer.h>
  2. #include "CraftingStorage.h"
  3. #include "Game.h"
  4. #include "Inventory.h"
  5. #include "Item.h"
  6. BasicShapedCrafter::BasicShapedCrafter(int width, int height, Inventory* zInventory, Framework::Text recipieList)
  7. : zInventory(zInventory),
  8. currentRecipie(0),
  9. recipieList(recipieList),
  10. width(width),
  11. height(height)
  12. {
  13. for (int i = 0; i < width * height; i++)
  14. {
  15. ItemSlot* slot = new ItemSlot("CraftingGrid", 1, std::numeric_limits<int>::max(), std::numeric_limits<int>::max(), INSIDE, INSIDE, 0);
  16. zInventory->addSlot(slot);
  17. craftingInput.add(slot);
  18. }
  19. std::function<void(ItemSlot* zSlot, Direction dir, const Item* zItem, int count)> onChange = [this, recipieList](ItemSlot* zSlot, Direction dir, const Item* zItem, int count)
  20. {
  21. if (!zSlot->getName().istGleich("CraftingGrid"))
  22. return;
  23. calculateOutputPreview();
  24. };
  25. zInventory->registerAfterPullStackCall(onChange);
  26. zInventory->registerAfterPushStackCall(onChange);
  27. zInventory->registerObserverAddedCall([this](Entity* zSource, Framework::Text id)
  28. {
  29. ShapedRecipie* old = currentRecipie;
  30. calculateOutputPreview();
  31. if (old == currentRecipie)
  32. {
  33. NetworkMessage* message = new NetworkMessage();
  34. getOutputPreview(message);
  35. message->addressGui(id);
  36. Game::INSTANCE->sendMessage(message, zSource);
  37. }
  38. });
  39. }
  40. void BasicShapedCrafter::getOutputPreview(NetworkMessage* zMessage)
  41. {
  42. if (currentRecipie)
  43. {
  44. Framework::Array<ItemInfo> output = currentRecipie->getOutput(this);
  45. Framework::InMemoryBuffer buffer;
  46. int count = 0;
  47. for (ItemInfo slot : output)
  48. {
  49. count++;
  50. int itemCount = slot.count;
  51. buffer.schreibe((char*)&itemCount, 4);
  52. if (itemCount > 0)
  53. {
  54. float f = slot.damage;
  55. buffer.schreibe((char*)&f, 4);
  56. f = slot.maxDamage;
  57. buffer.schreibe((char*)&f, 4);
  58. f = slot.durability;
  59. buffer.schreibe((char*)&f, 4);
  60. f = slot.maxDurability;
  61. buffer.schreibe((char*)&f, 4);
  62. int id = slot.type;
  63. buffer.schreibe((char*)&id, 4);
  64. }
  65. }
  66. char* msg = new char[5 + buffer.getSize()];
  67. msg[0] = 100; // set crafting result
  68. *(int*)(msg + 1) = count;
  69. buffer.lese(msg + 5, (int)buffer.getSize());
  70. zMessage->setMessage(msg, 5 + (int)buffer.getSize());
  71. }
  72. else
  73. {
  74. char* msg = new char[5];
  75. msg[0] = 100; // set crafting result
  76. *(int*)(msg + 1) = 0;
  77. zMessage->setMessage(msg, 5);
  78. }
  79. }
  80. bool BasicShapedCrafter::isAllAvailable(Framework::RCArray<ItemFilter>& filters, int width, int height)
  81. {
  82. for (int x = 0; x <= this->width - width; x++)
  83. {
  84. for (int y = 0; y <= this->height - height; y++)
  85. {
  86. bool wrong = 0;
  87. for (int w = 0; w < width; w++)
  88. {
  89. for (int h = 0; h < height; h++)
  90. {
  91. ItemFilter* f = filters.z(h * width + w);
  92. ItemSlot* s = craftingInput.get((h + y) * this->width + (x + w));
  93. const Item* item = 0;
  94. if (s && s->zStack())
  95. item = s->zStack()->zItem();
  96. wrong |= (item && !f) || (!item && f);
  97. wrong |= item && f && !f->matchItem(item);
  98. if (wrong)
  99. break;
  100. }
  101. if (wrong)
  102. break;
  103. }
  104. if (!wrong)
  105. {
  106. int i = 0;
  107. for (ItemSlot* slot : craftingInput)
  108. {
  109. int w = i % this->width;
  110. int h = i / this->width;
  111. if ((w < x || w >= x + width || h < y || h >= y + height) && slot->zStack())
  112. return 0; // more items then needed are in crafting grid
  113. i++;
  114. }
  115. return 1;
  116. }
  117. }
  118. }
  119. return 0;
  120. }
  121. bool BasicShapedCrafter::hasFreeSpace(const Item* zItem, int amount)
  122. {
  123. ItemStack* stack = new ItemStack(zItem->zItemType()->cloneItem(zItem), amount);
  124. int addable = zInventory->numberOfAddableItems(stack, NO_DIRECTION);
  125. stack->release();
  126. return addable >= amount;
  127. }
  128. bool BasicShapedCrafter::consume(Framework::RCArray<ItemFilter>& filters, int width, int height)
  129. {
  130. for (ItemSlot* slot : craftingInput)
  131. {
  132. if (slot && slot->zStack())
  133. {
  134. ItemStack* stack = zInventory->takeItemsOut(slot, 1, INSIDE);
  135. if (stack)
  136. stack->release();
  137. }
  138. }
  139. for (int x = 0; x < width; x++)
  140. {
  141. for (int y = 0; y < height; y++)
  142. {
  143. ItemFilter* f = filters.z(x * width + y);
  144. if (f)
  145. {
  146. ItemSlot* target = craftingInput.get(x * this->width + y);
  147. Framework::Array< ItemSlot*> tmp;
  148. tmp.add(target);
  149. zInventory->localTransaction(0, &tmp, f, 1, NO_DIRECTION, INSIDE);
  150. }
  151. }
  152. }
  153. return 1;
  154. }
  155. void BasicShapedCrafter::addCraftingResult(ItemStack* stack)
  156. {
  157. zInventory->addItems(stack, NO_DIRECTION);
  158. }
  159. void BasicShapedCrafter::applyCurrentRecipie()
  160. {
  161. if (currentRecipie && currentRecipie->testApplicability(this))
  162. currentRecipie->apply(this);
  163. }
  164. void BasicShapedCrafter::calculateOutputPreview()
  165. {
  166. ShapedRecipieList* recipies = Game::INSTANCE->getRecipies().zShapedRecipieList(recipieList);
  167. if (recipies)
  168. {
  169. ShapedRecipie* recipie = recipies->zFirstRecipie(this);
  170. if (recipie != currentRecipie)
  171. {
  172. currentRecipie = recipie;
  173. NetworkMessage* message = new NetworkMessage();
  174. getOutputPreview(message);
  175. zInventory->notyObservers(message);
  176. }
  177. }
  178. }