Serhiy Zahoriya
2020-01-11 1a45ad19d4fa627e147bd385665e37942f6147fb
Alloy furnace: Accept only unique ItemStacks from tubes (#523)

Co-authored-by: Luke aka SwissalpS <Luke@SwissalpS.ws>
Co-authored-by: SmallJoker <SmallJoker@users.noreply.github.com>
3 files modified
89 ■■■■ changed files
technic/doc/api.md 4 ●●●● patch | view | raw | blame | history
technic/machines/register/alloy_furnace.lua 40 ●●●●● patch | view | raw | blame | history
technic/machines/register/machine_base.lua 45 ●●●●● patch | view | raw | blame | history
technic/doc/api.md
@@ -64,6 +64,10 @@
### Specific machines
* `technic.register_solar_array(data)`
    * data is a table
* `technic.can_insert_unique_stack(pos, node, stack, direction)`
* `technic.insert_object_unique_stack(pos, node, stack, direction)`
    * Functions for the parameters `can_insert` and `insert_object` to avoid
      filling multiple inventory slots with same type of item.
Used itemdef fields
-------------------
technic/machines/register/alloy_furnace.lua
@@ -1,10 +1,50 @@
local S = technic.getter
function technic.insert_object_unique_stack(pos, node, incoming_stack, direction)
    local meta = minetest.get_meta(pos)
    local inv = meta:get_inventory()
    local incoming_name = incoming_stack:get_name()
    local stack_index = nil
    for inv_index, inv_stack in pairs(inv:get_list("src")) do
        if inv_stack:get_name() == incoming_name then
            stack_index = inv_index
            break
        end
    end
    if stack_index == nil then
        return inv:add_item("src", incoming_stack)
    end
    local present_stack = inv:get_stack("src", stack_index)
    local leftover = present_stack:add_item(incoming_stack)
    inv:set_stack("src", stack_index, present_stack)
    return leftover
end
function technic.can_insert_unique_stack(pos, node, incoming_stack, direction)
    local meta = minetest.get_meta(pos)
    local inv = meta:get_inventory()
    local incoming_name = incoming_stack:get_name()
    if meta:get_int("splitstacks") == 0 then
        -- avoid looping second time with inv:contains_item("src", incoming_stack)
        for _, inv_stack in pairs(inv:get_list("src")) do
            if inv_stack:get_name() == incoming_name then
                return inv_stack:item_fits(incoming_stack)
            end
        end
    end
    return technic.default_can_insert(pos, node, incoming_stack, direction)
end
function technic.register_alloy_furnace(data)
    data.typename = "alloy"
    data.machine_name = "alloy_furnace"
    data.machine_desc = S("%s Alloy Furnace")
    data.insert_object = technic.insert_object_unique_stack
    data.can_insert = technic.can_insert_unique_stack
    technic.register_base_machine(data)
end
technic/machines/register/machine_base.lua
@@ -4,22 +4,26 @@
local fs_helpers = pipeworks.fs_helpers
local tube_entry = "^pipeworks_tube_connection_metallic.png"
local tube = {
    insert_object = function(pos, node, stack, direction)
        local meta = minetest.get_meta(pos)
        local inv = meta:get_inventory()
        return inv:add_item("src", stack)
    end,
    can_insert = function(pos, node, stack, direction)
        local meta = minetest.get_meta(pos)
        local inv = meta:get_inventory()
        if meta:get_int("splitstacks") == 1 then
            stack = stack:peek_item(1)
        end
        return inv:room_for_item("src", stack)
    end,
    connect_sides = {left = 1, right = 1, back = 1, top = 1, bottom = 1},
}
function technic.default_can_insert(pos, node, stack, direction)
    local meta = minetest.get_meta(pos)
    local inv = meta:get_inventory()
    if meta:get_int("splitstacks") == 1 then
        stack = stack:peek_item(1)
    end
    return inv:room_for_item("src", stack)
end
function technic.new_default_tube()
    return {
        insert_object = function(pos, node, stack, direction)
            local meta = minetest.get_meta(pos)
            local inv = meta:get_inventory()
            return inv:add_item("src", stack)
        end,
        can_insert = technic.default_can_insert,
        connect_sides = {left = 1, right = 1, back = 1, top = 1, bottom = 1},
    }
end
local connect_default = {"bottom", "back", "left", "right"}
@@ -62,6 +66,14 @@
            "listring[current_player;main]"..
            "listring[current_name;upgrade2]"..
            "listring[current_player;main]"
    end
    local tube = technic.new_default_tube()
    if data.can_insert then
        tube.can_insert = data.can_insert
    end
    if data.insert_object then
        tube.insert_object = data.insert_object
    end
    local run = function(pos, node)
@@ -144,6 +156,7 @@
    if ltier == "lv" then
        tentry = ""
    end
    minetest.register_node("technic:"..ltier.."_"..machine_name, {
        description = machine_desc:format(tier),
        tiles = {