- // Disallow moving items if not allowed to build
- else if((getPlayerPrivs(player) & PRIV_BUILD) == 0)
- {
- disable_action = true;
- }
- // if it's a locking chest, only allow the owner or server admins to move items
- else if (ma->from_inv != "current_player" && (getPlayerPrivs(player) & PRIV_SERVER) == 0)
+ /*
+ Disable action if there are no free slots in
+ destination
+
+ If the item is placed on an item that is not of the
+ same kind, the existing item will be first moved to
+ craftresult and immediately moved to the free slot.
+ */
+ do{
+ Inventory *inv_to = getInventory(&c, ma->to_inv);
+ if(!inv_to) break;
+ InventoryList *list_to = inv_to->getList(ma->to_list);
+ if(!list_to) break;
+ if(list_to->getFreeSlots() == 0){
+ infostream<<"Cannot craft: Destination doesn't have"
+ <<" free slots"<<std::endl;
+ delete a;
+ return;
+ }
+ }while(0); // Allow break
+
+ /*
+ Ok, craft normally.
+ */
+ player->craftresult_is_preview = false;
+ clist->decrementMaterials(1);
+
+ /* Print out action */
+ InventoryItem *item = rlist->getItem(0);
+ std::string itemstring = "NULL";
+ if(item)
+ itemstring = item->getItemString();
+ actionstream<<player->getName()<<" crafts "
+ <<itemstring<<std::endl;
+
+ // Do the action
+ a->apply(&c, this, m_env);
+
+ delete a;
+ return;
+ }
+
+ /*
+ Non-crafting move
+ */
+
+ // Disallow moving items in elsewhere than player's inventory
+ // if not allowed to build
+ if((getPlayerPrivs(player) & PRIV_BUILD) == 0
+ && (ma->from_inv != "current_player"
+ || ma->to_inv != "current_player"))
+ {
+ infostream<<"Cannot move outside of player's inventory: "
+ <<"No build privilege"<<std::endl;
+ delete a;
+ return;
+ }
+
+ // If player is not an admin, check for ownership of src
+ if(ma->from_inv != "current_player"
+ && (getPlayerPrivs(player) & PRIV_SERVER) == 0)
+ {
+ Strfnd fn(ma->from_inv);
+ std::string id0 = fn.next(":");
+ if(id0 == "nodemeta")