mirror of
https://github.com/minetest/minetest.git
synced 2024-12-24 07:02:23 +01:00
Fix bug when craft input isn't replaced
This commit is contained in:
parent
0b76e85a71
commit
17ba584fe2
@ -2077,6 +2077,8 @@ and `minetest.auth_reload` call the authetification handler.
|
|||||||
`{ stack1, stack2, stack3, stack4, stack 5, stack 6, stack 7, stack 8, stack 9 }`
|
`{ stack1, stack2, stack3, stack4, stack 5, stack 6, stack 7, stack 8, stack 9 }`
|
||||||
* `output.item` = `ItemStack`, if unsuccessful: empty `ItemStack`
|
* `output.item` = `ItemStack`, if unsuccessful: empty `ItemStack`
|
||||||
* `output.time` = a number, if unsuccessful: `0`
|
* `output.time` = a number, if unsuccessful: `0`
|
||||||
|
* `output.replacements` = list of `ItemStack`s that couldn't be placed in
|
||||||
|
`decremented_input.items`
|
||||||
* `decremented_input` = like `input`
|
* `decremented_input` = like `input`
|
||||||
* `minetest.get_craft_recipe(output)`: returns input
|
* `minetest.get_craft_recipe(output)`: returns input
|
||||||
* returns last registered recipe for output item (node)
|
* returns last registered recipe for output item (node)
|
||||||
|
@ -199,6 +199,7 @@ static void craftDecrementInput(CraftInput &input, IGameDef *gamedef)
|
|||||||
// Example: if replacements contains the pair ("bucket:bucket_water", "bucket:bucket_empty"),
|
// Example: if replacements contains the pair ("bucket:bucket_water", "bucket:bucket_empty"),
|
||||||
// a water bucket will not be removed but replaced by an empty bucket.
|
// a water bucket will not be removed but replaced by an empty bucket.
|
||||||
static void craftDecrementOrReplaceInput(CraftInput &input,
|
static void craftDecrementOrReplaceInput(CraftInput &input,
|
||||||
|
std::vector<ItemStack> &output_replacements,
|
||||||
const CraftReplacements &replacements,
|
const CraftReplacements &replacements,
|
||||||
IGameDef *gamedef)
|
IGameDef *gamedef)
|
||||||
{
|
{
|
||||||
@ -213,26 +214,30 @@ static void craftDecrementOrReplaceInput(CraftInput &input,
|
|||||||
for (std::vector<ItemStack>::iterator
|
for (std::vector<ItemStack>::iterator
|
||||||
it = input.items.begin();
|
it = input.items.begin();
|
||||||
it != input.items.end(); it++) {
|
it != input.items.end(); it++) {
|
||||||
if (it->count == 1) {
|
|
||||||
// Find an appropriate replacement
|
// Find an appropriate replacement
|
||||||
bool found_replacement = false;
|
bool found_replacement = false;
|
||||||
for (std::vector<std::pair<std::string, std::string> >::iterator
|
for (std::vector<std::pair<std::string, std::string> >::iterator
|
||||||
j = pairs.begin();
|
j = pairs.begin();
|
||||||
j != pairs.end(); j++) {
|
j != pairs.end(); j++) {
|
||||||
if (it->name == craftGetItemName(j->first, gamedef)) {
|
if (it->name == craftGetItemName(j->first, gamedef)) {
|
||||||
|
if (it->count == 1) {
|
||||||
it->deSerialize(j->second, gamedef->idef());
|
it->deSerialize(j->second, gamedef->idef());
|
||||||
found_replacement = true;
|
found_replacement = true;
|
||||||
pairs.erase(j);
|
pairs.erase(j);
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
ItemStack rep;
|
||||||
|
rep.deSerialize(j->second, gamedef->idef());
|
||||||
|
it->remove(1);
|
||||||
|
found_replacement = true;
|
||||||
|
output_replacements.push_back(rep);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// No replacement was found, simply decrement count to zero
|
// No replacement was found, simply decrement count to zero
|
||||||
if (!found_replacement)
|
if (!found_replacement)
|
||||||
it->remove(1);
|
it->remove(1);
|
||||||
} else if (it->count >= 2) {
|
|
||||||
// Ignore replacements for items with count >= 2
|
|
||||||
it->remove(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,9 +413,10 @@ CraftInput CraftDefinitionShaped::getInput(const CraftOutput &output, IGameDef *
|
|||||||
return CraftInput(CRAFT_METHOD_NORMAL,width,craftGetItems(recipe,gamedef));
|
return CraftInput(CRAFT_METHOD_NORMAL,width,craftGetItems(recipe,gamedef));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CraftDefinitionShaped::decrementInput(CraftInput &input, IGameDef *gamedef) const
|
void CraftDefinitionShaped::decrementInput(CraftInput &input, std::vector<ItemStack> &output_replacements,
|
||||||
|
IGameDef *gamedef) const
|
||||||
{
|
{
|
||||||
craftDecrementOrReplaceInput(input, replacements, gamedef);
|
craftDecrementOrReplaceInput(input, output_replacements, replacements, gamedef);
|
||||||
}
|
}
|
||||||
|
|
||||||
CraftHashType CraftDefinitionShaped::getHashType() const
|
CraftHashType CraftDefinitionShaped::getHashType() const
|
||||||
@ -529,9 +535,10 @@ CraftInput CraftDefinitionShapeless::getInput(const CraftOutput &output, IGameDe
|
|||||||
return CraftInput(CRAFT_METHOD_NORMAL, 0, craftGetItems(recipe, gamedef));
|
return CraftInput(CRAFT_METHOD_NORMAL, 0, craftGetItems(recipe, gamedef));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CraftDefinitionShapeless::decrementInput(CraftInput &input, IGameDef *gamedef) const
|
void CraftDefinitionShapeless::decrementInput(CraftInput &input, std::vector<ItemStack> &output_replacements,
|
||||||
|
IGameDef *gamedef) const
|
||||||
{
|
{
|
||||||
craftDecrementOrReplaceInput(input, replacements, gamedef);
|
craftDecrementOrReplaceInput(input, output_replacements, replacements, gamedef);
|
||||||
}
|
}
|
||||||
|
|
||||||
CraftHashType CraftDefinitionShapeless::getHashType() const
|
CraftHashType CraftDefinitionShapeless::getHashType() const
|
||||||
@ -661,7 +668,8 @@ CraftInput CraftDefinitionToolRepair::getInput(const CraftOutput &output, IGameD
|
|||||||
return CraftInput(CRAFT_METHOD_COOKING, additional_wear, stack);
|
return CraftInput(CRAFT_METHOD_COOKING, additional_wear, stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CraftDefinitionToolRepair::decrementInput(CraftInput &input, IGameDef *gamedef) const
|
void CraftDefinitionToolRepair::decrementInput(CraftInput &input, std::vector<ItemStack> &output_replacements,
|
||||||
|
IGameDef *gamedef) const
|
||||||
{
|
{
|
||||||
craftDecrementInput(input, gamedef);
|
craftDecrementInput(input, gamedef);
|
||||||
}
|
}
|
||||||
@ -720,9 +728,10 @@ CraftInput CraftDefinitionCooking::getInput(const CraftOutput &output, IGameDef
|
|||||||
return CraftInput(CRAFT_METHOD_COOKING,cooktime,craftGetItems(rec,gamedef));
|
return CraftInput(CRAFT_METHOD_COOKING,cooktime,craftGetItems(rec,gamedef));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CraftDefinitionCooking::decrementInput(CraftInput &input, IGameDef *gamedef) const
|
void CraftDefinitionCooking::decrementInput(CraftInput &input, std::vector<ItemStack> &output_replacements,
|
||||||
|
IGameDef *gamedef) const
|
||||||
{
|
{
|
||||||
craftDecrementOrReplaceInput(input, replacements, gamedef);
|
craftDecrementOrReplaceInput(input, output_replacements, replacements, gamedef);
|
||||||
}
|
}
|
||||||
|
|
||||||
CraftHashType CraftDefinitionCooking::getHashType() const
|
CraftHashType CraftDefinitionCooking::getHashType() const
|
||||||
@ -811,9 +820,10 @@ CraftInput CraftDefinitionFuel::getInput(const CraftOutput &output, IGameDef *ga
|
|||||||
return CraftInput(CRAFT_METHOD_COOKING,(int)burntime,craftGetItems(rec,gamedef));
|
return CraftInput(CRAFT_METHOD_COOKING,(int)burntime,craftGetItems(rec,gamedef));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CraftDefinitionFuel::decrementInput(CraftInput &input, IGameDef *gamedef) const
|
void CraftDefinitionFuel::decrementInput(CraftInput &input, std::vector<ItemStack> &output_replacements,
|
||||||
|
IGameDef *gamedef) const
|
||||||
{
|
{
|
||||||
craftDecrementOrReplaceInput(input, replacements, gamedef);
|
craftDecrementOrReplaceInput(input, output_replacements, replacements, gamedef);
|
||||||
}
|
}
|
||||||
|
|
||||||
CraftHashType CraftDefinitionFuel::getHashType() const
|
CraftHashType CraftDefinitionFuel::getHashType() const
|
||||||
@ -871,7 +881,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
|
virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
|
||||||
bool decrementInput, IGameDef *gamedef) const
|
std::vector<ItemStack> &output_replacement, bool decrementInput,
|
||||||
|
IGameDef *gamedef) const
|
||||||
{
|
{
|
||||||
output.item = "";
|
output.item = "";
|
||||||
output.time = 0;
|
output.time = 0;
|
||||||
@ -922,7 +933,7 @@ public:
|
|||||||
// Get output, then decrement input (if requested)
|
// Get output, then decrement input (if requested)
|
||||||
output = def->getOutput(input, gamedef);
|
output = def->getOutput(input, gamedef);
|
||||||
if (decrementInput)
|
if (decrementInput)
|
||||||
def->decrementInput(input, gamedef);
|
def->decrementInput(input, output_replacement, gamedef);
|
||||||
/*errorstream << "Check RETURNS TRUE" << std::endl;*/
|
/*errorstream << "Check RETURNS TRUE" << std::endl;*/
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,8 @@ public:
|
|||||||
// the inverse of the above
|
// the inverse of the above
|
||||||
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const=0;
|
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const=0;
|
||||||
// Decreases count of every input item
|
// Decreases count of every input item
|
||||||
virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const=0;
|
virtual void decrementInput(CraftInput &input,
|
||||||
|
std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const=0;
|
||||||
|
|
||||||
virtual CraftHashType getHashType() const = 0;
|
virtual CraftHashType getHashType() const = 0;
|
||||||
virtual u64 getHash(CraftHashType type) const = 0;
|
virtual u64 getHash(CraftHashType type) const = 0;
|
||||||
@ -187,7 +188,8 @@ public:
|
|||||||
virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
|
virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
|
||||||
virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
|
virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
|
||||||
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
|
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
|
||||||
virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
|
virtual void decrementInput(CraftInput &input,
|
||||||
|
std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
|
||||||
|
|
||||||
virtual CraftHashType getHashType() const;
|
virtual CraftHashType getHashType() const;
|
||||||
virtual u64 getHash(CraftHashType type) const;
|
virtual u64 getHash(CraftHashType type) const;
|
||||||
@ -235,7 +237,8 @@ public:
|
|||||||
virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
|
virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
|
||||||
virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
|
virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
|
||||||
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
|
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
|
||||||
virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
|
virtual void decrementInput(CraftInput &input,
|
||||||
|
std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
|
||||||
|
|
||||||
virtual CraftHashType getHashType() const;
|
virtual CraftHashType getHashType() const;
|
||||||
virtual u64 getHash(CraftHashType type) const;
|
virtual u64 getHash(CraftHashType type) const;
|
||||||
@ -278,7 +281,8 @@ public:
|
|||||||
virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
|
virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
|
||||||
virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
|
virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
|
||||||
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
|
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
|
||||||
virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
|
virtual void decrementInput(CraftInput &input,
|
||||||
|
std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
|
||||||
|
|
||||||
virtual CraftHashType getHashType() const { return CRAFT_HASH_TYPE_COUNT; }
|
virtual CraftHashType getHashType() const { return CRAFT_HASH_TYPE_COUNT; }
|
||||||
virtual u64 getHash(CraftHashType type) const { return 2; }
|
virtual u64 getHash(CraftHashType type) const { return 2; }
|
||||||
@ -320,7 +324,8 @@ public:
|
|||||||
virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
|
virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
|
||||||
virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
|
virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
|
||||||
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
|
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
|
||||||
virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
|
virtual void decrementInput(CraftInput &input,
|
||||||
|
std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
|
||||||
|
|
||||||
virtual CraftHashType getHashType() const;
|
virtual CraftHashType getHashType() const;
|
||||||
virtual u64 getHash(CraftHashType type) const;
|
virtual u64 getHash(CraftHashType type) const;
|
||||||
@ -365,7 +370,8 @@ public:
|
|||||||
virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
|
virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
|
||||||
virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
|
virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
|
||||||
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
|
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
|
||||||
virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
|
virtual void decrementInput(CraftInput &input,
|
||||||
|
std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
|
||||||
|
|
||||||
virtual CraftHashType getHashType() const;
|
virtual CraftHashType getHashType() const;
|
||||||
virtual u64 getHash(CraftHashType type) const;
|
virtual u64 getHash(CraftHashType type) const;
|
||||||
@ -398,6 +404,7 @@ public:
|
|||||||
|
|
||||||
// The main crafting function
|
// The main crafting function
|
||||||
virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
|
virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
|
||||||
|
std::vector<ItemStack> &output_replacements,
|
||||||
bool decrementInput, IGameDef *gamedef) const=0;
|
bool decrementInput, IGameDef *gamedef) const=0;
|
||||||
virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output,
|
virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output,
|
||||||
IGameDef *gamedef, unsigned limit=0) const=0;
|
IGameDef *gamedef, unsigned limit=0) const=0;
|
||||||
@ -414,6 +421,7 @@ public:
|
|||||||
|
|
||||||
// The main crafting function
|
// The main crafting function
|
||||||
virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
|
virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
|
||||||
|
std::vector<ItemStack> &output_replacements,
|
||||||
bool decrementInput, IGameDef *gamedef) const=0;
|
bool decrementInput, IGameDef *gamedef) const=0;
|
||||||
virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output,
|
virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output,
|
||||||
IGameDef *gamedef, unsigned limit=0) const=0;
|
IGameDef *gamedef, unsigned limit=0) const=0;
|
||||||
|
@ -691,72 +691,112 @@ ICraftAction::ICraftAction(std::istream &is)
|
|||||||
craft_inv.deSerialize(ts);
|
craft_inv.deSerialize(ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICraftAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGameDef *gamedef)
|
void ICraftAction::apply(InventoryManager *mgr,
|
||||||
|
ServerActiveObject *player, IGameDef *gamedef)
|
||||||
{
|
{
|
||||||
Inventory *inv_craft = mgr->getInventory(craft_inv);
|
Inventory *inv_craft = mgr->getInventory(craft_inv);
|
||||||
|
|
||||||
if(!inv_craft){
|
if (!inv_craft) {
|
||||||
infostream<<"ICraftAction::apply(): FAIL: inventory not found: "
|
infostream << "ICraftAction::apply(): FAIL: inventory not found: "
|
||||||
<<"craft_inv=\""<<craft_inv.dump()<<"\""<<std::endl;
|
<< "craft_inv=\"" << craft_inv.dump() << "\"" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
InventoryList *list_craft = inv_craft->getList("craft");
|
InventoryList *list_craft = inv_craft->getList("craft");
|
||||||
InventoryList *list_craftresult = inv_craft->getList("craftresult");
|
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 a list doesn't exist or the source item doesn't exist
|
||||||
*/
|
*/
|
||||||
if(!list_craft){
|
if (!list_craft) {
|
||||||
infostream<<"ICraftAction::apply(): FAIL: craft list not found: "
|
infostream << "ICraftAction::apply(): FAIL: craft list not found: "
|
||||||
<<"craft_inv=\""<<craft_inv.dump()<<"\""<<std::endl;
|
<< "craft_inv=\"" << craft_inv.dump() << "\"" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!list_craftresult){
|
if (!list_craftresult) {
|
||||||
infostream<<"ICraftAction::apply(): FAIL: craftresult list not found: "
|
infostream << "ICraftAction::apply(): FAIL: craftresult list not found: "
|
||||||
<<"craft_inv=\""<<craft_inv.dump()<<"\""<<std::endl;
|
<< "craft_inv=\"" << craft_inv.dump() << "\"" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(list_craftresult->getSize() < 1){
|
if (list_craftresult->getSize() < 1) {
|
||||||
infostream<<"ICraftAction::apply(): FAIL: craftresult list too short: "
|
infostream << "ICraftAction::apply(): FAIL: craftresult list too short: "
|
||||||
<<"craft_inv=\""<<craft_inv.dump()<<"\""<<std::endl;
|
<< "craft_inv=\"" << craft_inv.dump() << "\"" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack crafted;
|
ItemStack crafted;
|
||||||
ItemStack craftresultitem;
|
ItemStack craftresultitem;
|
||||||
int count_remaining = count;
|
int count_remaining = count;
|
||||||
getCraftingResult(inv_craft, crafted, false, gamedef);
|
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);
|
PLAYER_TO_SA(player)->item_CraftPredict(crafted, player, list_craft, craft_inv);
|
||||||
bool found = !crafted.empty();
|
bool found = !crafted.empty();
|
||||||
|
|
||||||
while(found && list_craftresult->itemFits(0, crafted))
|
while (found && list_craftresult->itemFits(0, crafted)) {
|
||||||
{
|
|
||||||
InventoryList saved_craft_list = *list_craft;
|
InventoryList saved_craft_list = *list_craft;
|
||||||
|
|
||||||
|
std::vector<ItemStack> temp;
|
||||||
// Decrement input and add crafting output
|
// Decrement input and add crafting output
|
||||||
getCraftingResult(inv_craft, crafted, true, gamedef);
|
getCraftingResult(inv_craft, crafted, temp, true, gamedef);
|
||||||
PLAYER_TO_SA(player)->item_OnCraft(crafted, player, &saved_craft_list, craft_inv);
|
PLAYER_TO_SA(player)->item_OnCraft(crafted, player, &saved_craft_list, craft_inv);
|
||||||
list_craftresult->addItem(0, crafted);
|
list_craftresult->addItem(0, crafted);
|
||||||
mgr->setInventoryModified(craft_inv);
|
mgr->setInventoryModified(craft_inv);
|
||||||
|
|
||||||
actionstream<<player->getDescription()
|
// Add the new replacements to the list
|
||||||
<<" crafts "
|
IItemDefManager *itemdef = gamedef->getItemDefManager();
|
||||||
<<crafted.getItemString()
|
for (std::vector<ItemStack>::iterator it = temp.begin();
|
||||||
<<std::endl;
|
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
|
// Decrement counter
|
||||||
if(count_remaining == 1)
|
if (count_remaining == 1)
|
||||||
break;
|
break;
|
||||||
else if(count_remaining > 1)
|
else if (count_remaining > 1)
|
||||||
count_remaining--;
|
count_remaining--;
|
||||||
|
|
||||||
// Get next crafting result
|
// Get next crafting result
|
||||||
found = getCraftingResult(inv_craft, crafted, false, gamedef);
|
found = getCraftingResult(inv_craft, crafted, temp, false, gamedef);
|
||||||
PLAYER_TO_SA(player)->item_CraftPredict(crafted, player, list_craft, craft_inv);
|
PLAYER_TO_SA(player)->item_CraftPredict(crafted, player, list_craft, craft_inv);
|
||||||
found = !crafted.empty();
|
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 "
|
infostream<<"ICraftAction::apply(): crafted "
|
||||||
<<" craft_inv=\""<<craft_inv.dump()<<"\""
|
<<" craft_inv=\""<<craft_inv.dump()<<"\""
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
@ -771,6 +811,7 @@ void ICraftAction::clientApply(InventoryManager *mgr, IGameDef *gamedef)
|
|||||||
|
|
||||||
// Crafting helper
|
// Crafting helper
|
||||||
bool getCraftingResult(Inventory *inv, ItemStack& result,
|
bool getCraftingResult(Inventory *inv, ItemStack& result,
|
||||||
|
std::vector<ItemStack> &output_replacements,
|
||||||
bool decrementInput, IGameDef *gamedef)
|
bool decrementInput, IGameDef *gamedef)
|
||||||
{
|
{
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
@ -792,7 +833,7 @@ bool getCraftingResult(Inventory *inv, ItemStack& result,
|
|||||||
// Find out what is crafted and add it to result item slot
|
// Find out what is crafted and add it to result item slot
|
||||||
CraftOutput co;
|
CraftOutput co;
|
||||||
bool found = gamedef->getCraftDefManager()->getCraftResult(
|
bool found = gamedef->getCraftDefManager()->getCraftResult(
|
||||||
ci, co, decrementInput, gamedef);
|
ci, co, output_replacements, decrementInput, gamedef);
|
||||||
if(found)
|
if(found)
|
||||||
result.deSerialize(co.item, gamedef->getItemDefManager());
|
result.deSerialize(co.item, gamedef->getItemDefManager());
|
||||||
|
|
||||||
|
@ -242,6 +242,7 @@ struct ICraftAction : public InventoryAction
|
|||||||
|
|
||||||
// Crafting helper
|
// Crafting helper
|
||||||
bool getCraftingResult(Inventory *inv, ItemStack& result,
|
bool getCraftingResult(Inventory *inv, ItemStack& result,
|
||||||
|
std::vector<ItemStack> &output_replacements,
|
||||||
bool decrementInput, IGameDef *gamedef);
|
bool decrementInput, IGameDef *gamedef);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -303,18 +303,23 @@ int ModApiCraft::l_get_craft_result(lua_State *L)
|
|||||||
ICraftDefManager *cdef = gdef->cdef();
|
ICraftDefManager *cdef = gdef->cdef();
|
||||||
CraftInput input(method, width, items);
|
CraftInput input(method, width, items);
|
||||||
CraftOutput output;
|
CraftOutput output;
|
||||||
bool got = cdef->getCraftResult(input, output, true, gdef);
|
std::vector<ItemStack> output_replacements;
|
||||||
|
bool got = cdef->getCraftResult(input, output, output_replacements, true, gdef);
|
||||||
lua_newtable(L); // output table
|
lua_newtable(L); // output table
|
||||||
if(got){
|
if (got) {
|
||||||
ItemStack item;
|
ItemStack item;
|
||||||
item.deSerialize(output.item, gdef->idef());
|
item.deSerialize(output.item, gdef->idef());
|
||||||
LuaItemStack::create(L, item);
|
LuaItemStack::create(L, item);
|
||||||
lua_setfield(L, -2, "item");
|
lua_setfield(L, -2, "item");
|
||||||
setintfield(L, -1, "time", output.time);
|
setintfield(L, -1, "time", output.time);
|
||||||
|
push_items(L, output_replacements);
|
||||||
|
lua_setfield(L, -2, "replacements");
|
||||||
} else {
|
} else {
|
||||||
LuaItemStack::create(L, ItemStack());
|
LuaItemStack::create(L, ItemStack());
|
||||||
lua_setfield(L, -2, "item");
|
lua_setfield(L, -2, "item");
|
||||||
setintfield(L, -1, "time", 0);
|
setintfield(L, -1, "time", 0);
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_setfield(L, -2, "replacements");
|
||||||
}
|
}
|
||||||
lua_newtable(L); // decremented input table
|
lua_newtable(L); // decremented input table
|
||||||
lua_pushstring(L, method_s.c_str());
|
lua_pushstring(L, method_s.c_str());
|
||||||
|
@ -2698,7 +2698,8 @@ void Server::UpdateCrafting(Player* player)
|
|||||||
ItemStack preview;
|
ItemStack preview;
|
||||||
InventoryLocation loc;
|
InventoryLocation loc;
|
||||||
loc.setPlayer(player->getName());
|
loc.setPlayer(player->getName());
|
||||||
getCraftingResult(&player->inventory, preview, false, this);
|
std::vector<ItemStack> output_replacements;
|
||||||
|
getCraftingResult(&player->inventory, preview, output_replacements, false, this);
|
||||||
m_env->getScriptIface()->item_CraftPredict(preview, player->getPlayerSAO(), (&player->inventory)->getList("craft"), loc);
|
m_env->getScriptIface()->item_CraftPredict(preview, player->getPlayerSAO(), (&player->inventory)->getList("craft"), loc);
|
||||||
|
|
||||||
// Put the new preview in
|
// Put the new preview in
|
||||||
|
Loading…
Reference in New Issue
Block a user