void ICraftAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGameDef *gamedef) { Inventory *inv_craft = mgr->getInventory(craft_inv); if (!inv_craft) { infostream << "ICraftAction::apply(): FAIL: inventory not found: " << "craft_inv=\"" << craft_inv.dump() << "\"" << std::endl; return; } InventoryList *list_craft = inv_craft->getList("craft"); InventoryList *list_craftresult = inv_craft->getList("craftresult"); InventoryList *list_main = inv_craft->getList("main"); /* If a list doesn't exist or the source item doesn't exist */ if (!list_craft) { infostream << "ICraftAction::apply(): FAIL: craft list not found: " << "craft_inv=\"" << craft_inv.dump() << "\"" << std::endl; return; } if (!list_craftresult) { infostream << "ICraftAction::apply(): FAIL: craftresult list not found: " << "craft_inv=\"" << craft_inv.dump() << "\"" << std::endl; return; } if (list_craftresult->getSize() < 1) { infostream << "ICraftAction::apply(): FAIL: craftresult list too short: " << "craft_inv=\"" << craft_inv.dump() << "\"" << std::endl; return; } ItemStack crafted; ItemStack craftresultitem; int count_remaining = count; std::vector<ItemStack> output_replacements; getCraftingResult(inv_craft, crafted, output_replacements, false, gamedef); PLAYER_TO_SA(player)->item_CraftPredict(crafted, player, list_craft, craft_inv); bool found = !crafted.empty(); while (found && list_craftresult->itemFits(0, crafted)) { InventoryList saved_craft_list = *list_craft; std::vector<ItemStack> temp; // Decrement input and add crafting output getCraftingResult(inv_craft, crafted, temp, true, gamedef); PLAYER_TO_SA(player)->item_OnCraft(crafted, player, &saved_craft_list, craft_inv); list_craftresult->addItem(0, crafted); mgr->setInventoryModified(craft_inv); // Add the new replacements to the list IItemDefManager *itemdef = gamedef->getItemDefManager(); for (std::vector<ItemStack>::iterator it = temp.begin(); it != temp.end(); it++) { for (std::vector<ItemStack>::iterator jt = output_replacements.begin(); jt != output_replacements.end(); jt++) { if (it->name == jt->name) { *it = jt->addItem(*it, itemdef); if (it->empty()) continue; } } output_replacements.push_back(*it); } actionstream << player->getDescription() << " crafts " << crafted.getItemString() << std::endl; // Decrement counter if (count_remaining == 1) break; else if (count_remaining > 1) count_remaining--; // Get next crafting result found = getCraftingResult(inv_craft, crafted, temp, false, gamedef); PLAYER_TO_SA(player)->item_CraftPredict(crafted, player, list_craft, craft_inv); found = !crafted.empty(); } // Put the replacements in the inventory or drop them on the floor, if // the invenotry is full for (std::vector<ItemStack>::iterator it = output_replacements.begin(); it != output_replacements.end(); it++) { if (list_main) *it = list_main->addItem(*it); if (it->empty()) continue; u16 count = it->count; do { PLAYER_TO_SA(player)->item_OnDrop(*it, player, player->getBasePosition() + v3f(0,1,0)); if (count >= it->count) { errorstream << "Couldn't drop replacement stack " << it->getItemString() << " because drop loop didn't " "decrease count." << std::endl; break; } } while (!it->empty()); } infostream<<"ICraftAction::apply(): crafted " <<" craft_inv=\""<<craft_inv.dump()<<"\"" <<std::endl; }
void ICraftAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGameDef *gamedef) { Inventory *inv_craft = mgr->getInventory(craft_inv); if(!inv_craft){ infostream<<"ICraftAction::apply(): FAIL: inventory not found: " <<"craft_inv=\""<<craft_inv.dump()<<"\""<<std::endl; return; } InventoryList *list_craft = inv_craft->getList("craft"); InventoryList *list_craftresult = inv_craft->getList("craftresult"); /* If a list doesn't exist or the source item doesn't exist */ if(!list_craft){ infostream<<"ICraftAction::apply(): FAIL: craft list not found: " <<"craft_inv=\""<<craft_inv.dump()<<"\""<<std::endl; return; } if(!list_craftresult){ infostream<<"ICraftAction::apply(): FAIL: craftresult list not found: " <<"craft_inv=\""<<craft_inv.dump()<<"\""<<std::endl; return; } if(list_craftresult->getSize() < 1){ infostream<<"ICraftAction::apply(): FAIL: craftresult list too short: " <<"craft_inv=\""<<craft_inv.dump()<<"\""<<std::endl; return; } ItemStack crafted; ItemStack craftresultitem; int count_remaining = count; bool found = getCraftingResult(inv_craft, crafted, false, gamedef); PLAYER_TO_SA(player)->item_CraftPredict(crafted, player, list_craft, craft_inv); found = !crafted.empty(); while(found && list_craftresult->itemFits(0, crafted)) { InventoryList saved_craft_list = *list_craft; // Decrement input and add crafting output getCraftingResult(inv_craft, crafted, true, gamedef); PLAYER_TO_SA(player)->item_OnCraft(crafted, player, &saved_craft_list, craft_inv); list_craftresult->addItem(0, crafted); mgr->setInventoryModified(craft_inv); actionstream<<player->getDescription() <<" crafts " <<crafted.getItemString() <<std::endl; // Decrement counter if(count_remaining == 1) break; else if(count_remaining > 1) count_remaining--; // Get next crafting result found = getCraftingResult(inv_craft, crafted, false, gamedef); PLAYER_TO_SA(player)->item_CraftPredict(crafted, player, list_craft, craft_inv); found = !crafted.empty(); } infostream<<"ICraftAction::apply(): crafted " <<" craft_inv=\""<<craft_inv.dump()<<"\"" <<std::endl; }