mods that hopefully work for a TechAge-based pack
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
local ui = unified_inventory
|
||||
local uip = unified_inventory_plus
|
||||
local has = uip.has
|
||||
local settings = uip.settings
|
||||
local S = uip.S
|
||||
local F = minetest.formspec_escape
|
||||
|
||||
-- Backup to inject code
|
||||
uip.craft_all = ui.pages["craft"].get_formspec
|
||||
|
||||
ui.pages["craft"] = {
|
||||
get_formspec = function(player, perplayer_formspec)
|
||||
local formspec = uip.craft_all(player, perplayer_formspec).formspec
|
||||
formspec = formspec ..
|
||||
("image[%f,%f;%f,%f;ui_crafting_long_arrow.png]"):format(
|
||||
perplayer_formspec.craft_arrow_x,
|
||||
perplayer_formspec.craft_y,
|
||||
ui.imgscale,
|
||||
ui.imgscale * 3) ..
|
||||
("button[%f,%f;%f,%f;craft_craftall;%s]"):format(
|
||||
perplayer_formspec.craft_arrow_x + 0.23,
|
||||
perplayer_formspec.craft_y + 1.50,
|
||||
perplayer_formspec.btn_size,
|
||||
perplayer_formspec.btn_size,
|
||||
F(S("All"))
|
||||
)
|
||||
return { formspec = formspec }
|
||||
end,
|
||||
}
|
||||
|
||||
-- make sure the width is right
|
||||
local function infer_width(list, expected)
|
||||
if not expected or expected:is_empty() then
|
||||
return
|
||||
end
|
||||
local width
|
||||
for i = 1, 3 do
|
||||
local output, _ = minetest.get_craft_result({ method = "normal", width = i, items = list })
|
||||
if output.item:to_string() == expected:to_string() then
|
||||
width = i
|
||||
break
|
||||
end
|
||||
end
|
||||
if not width then
|
||||
uip.log("warning", "Can't infer recipe width for %s", expected:to_string())
|
||||
end
|
||||
return width
|
||||
end
|
||||
|
||||
-- Craft max possible items and put the result in the main inventory
|
||||
local function craft_craftall(player)
|
||||
local player_name = player:get_player_name()
|
||||
local player_inv = player:get_inventory()
|
||||
local craft_list = player_inv:get_list("craft")
|
||||
local expected_result = player_inv:get_stack("craftpreview", 1)
|
||||
local craft_width = infer_width(craft_list, expected_result)
|
||||
if not craft_width then
|
||||
return
|
||||
end
|
||||
|
||||
local num_crafted = 0
|
||||
-- don't modify player's inventory until we're done, in case something goes wrong (e.g. crash)
|
||||
-- use a fake inventory instead of a detached inventory, because detached inventory actions all result in packets
|
||||
-- sent to the player.
|
||||
local tmp_inv = fakelib.create_inventory()
|
||||
tmp_inv:set_list("main", player_inv:get_list("main"))
|
||||
tmp_inv:set_list("craft", craft_list)
|
||||
|
||||
while true do
|
||||
if (
|
||||
has.stamina and
|
||||
stamina.get_saturation and
|
||||
stamina.get_saturation(player) <= settings.craft_all_min_saturation
|
||||
) then
|
||||
minetest.chat_send_player(player_name, S("You are too hungry to use Craft All at this time."))
|
||||
break
|
||||
end
|
||||
|
||||
-- note that get_craft_result can be *very* slow, until minetest 5.7.0 is released.
|
||||
-- see https://github.com/minetest/minetest/issues/13231
|
||||
local output, decremented_input = minetest.get_craft_result({
|
||||
method = "normal",
|
||||
width = craft_width,
|
||||
items = craft_list,
|
||||
})
|
||||
|
||||
if output.item:get_name() ~= expected_result:get_name() then
|
||||
-- the recipe changed, so we've run out of something. stop processing.
|
||||
break
|
||||
end
|
||||
|
||||
-- minetest.on_craft expects to see the decremented input list.
|
||||
tmp_inv:set_list("craft", decremented_input.items)
|
||||
|
||||
-- invoke callbacks, for compatibility w/ stamina, skyblock, moretrees, etc.
|
||||
-- note that this is an *undocumented* handler of the minetest lua API, and possibly is subject to change
|
||||
-- in the future.
|
||||
output.item = minetest.on_craft(output.item, player, craft_list, tmp_inv)
|
||||
|
||||
-- track items added to the inventory, in case we need to remove them later
|
||||
local added = {}
|
||||
|
||||
if tmp_inv:room_for_item("main", output.item) then
|
||||
tmp_inv:add_item("main", output.item) -- should be no remainder, ignore it
|
||||
table.insert(added, output.item)
|
||||
else
|
||||
-- no room for the output item, stop
|
||||
break
|
||||
end
|
||||
|
||||
-- we now try to add all replacements.
|
||||
local all_added = true
|
||||
for _, replacement_stk in ipairs(output.replacements) do
|
||||
if tmp_inv:room_for_item("main", replacement_stk) then
|
||||
tmp_inv:add_item("main", replacement_stk) -- should be no remainder, ignore it
|
||||
table.insert(added, replacement_stk)
|
||||
else
|
||||
all_added = false
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not all_added then
|
||||
-- if we failed to add all the replacements, remove what we've added, and abort
|
||||
for _, stk in ipairs(added) do
|
||||
tmp_inv:remove_item("main", stk) -- should be no remainder, ignore it
|
||||
end
|
||||
break
|
||||
end
|
||||
|
||||
-- the craft list can be modified by the callbacks, so re-load it
|
||||
craft_list = tmp_inv:get_list("craft")
|
||||
|
||||
num_crafted = num_crafted + 1
|
||||
end
|
||||
|
||||
player_inv:set_list("craft", craft_list)
|
||||
player_inv:set_list("main", tmp_inv:get_list("main"))
|
||||
|
||||
uip.log("action", "player %s crafts %s %i", player_name, expected_result:to_string(), num_crafted)
|
||||
end
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
for k, _ in pairs(fields) do
|
||||
if k:match("craft_craftall") then
|
||||
craft_craftall(player)
|
||||
return
|
||||
end
|
||||
end
|
||||
end)
|
||||
Reference in New Issue
Block a user