mirror of
https://github.com/joe7575/techpack.git
synced 2024-11-26 09:03:46 +01:00
distribution algorithm reviced
This commit is contained in:
parent
b72b703dfc
commit
37ab82b371
@ -20,34 +20,6 @@ local CYCLE_TIME = 2
|
|||||||
local STOP_STATE = 0
|
local STOP_STATE = 0
|
||||||
local STANDBY_STATE = -1
|
local STANDBY_STATE = -1
|
||||||
|
|
||||||
-- Get one item-stack from the given ItemList, specified by stack number (1..n).
|
|
||||||
-- Returns nil if ItemList is empty.
|
|
||||||
local function get_this_stack(meta, listname, number)
|
|
||||||
if meta == nil or meta.get_inventory == nil then return nil end
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
if inv:is_empty(listname) then
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
local items = inv:get_stack(listname, number)
|
|
||||||
if items:get_count() > 0 then
|
|
||||||
return inv:remove_item(listname, items)
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Return a key/value table with all items and the corresponding stack numbers
|
|
||||||
local function invlist_content_as_kvlist(list)
|
|
||||||
local res = {}
|
|
||||||
for idx,items in ipairs(list) do
|
|
||||||
local name = items:get_name()
|
|
||||||
if name ~= "" then
|
|
||||||
res[name] = idx
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return res
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Return the total number of list entries
|
-- Return the total number of list entries
|
||||||
local function invlist_num_entries(list)
|
local function invlist_num_entries(list)
|
||||||
local res = 0
|
local res = 0
|
||||||
@ -75,10 +47,9 @@ local function invlist_entries_as_list(list)
|
|||||||
return res
|
return res
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function AddToTbl(kvTbl, new_items, val)
|
||||||
local function AddToTbl(kvTbl, new_items)
|
|
||||||
for _, l in ipairs(new_items) do
|
for _, l in ipairs(new_items) do
|
||||||
kvTbl[l] = true
|
kvTbl[l] = val
|
||||||
end
|
end
|
||||||
return kvTbl
|
return kvTbl
|
||||||
end
|
end
|
||||||
@ -139,6 +110,7 @@ local function allow_metadata_inventory_move(pos, from_list, from_index, to_list
|
|||||||
return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
|
return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local Side2Color = {B="red", L="green", F="blue", R="yellow"}
|
||||||
local SlotColors = {"red", "green", "blue", "yellow"}
|
local SlotColors = {"red", "green", "blue", "yellow"}
|
||||||
local Num2Ascii = {"B", "L", "F", "R"} -- color to side translation
|
local Num2Ascii = {"B", "L", "F", "R"} -- color to side translation
|
||||||
local FilterCache = {} -- local cache for filter settings
|
local FilterCache = {} -- local cache for filter settings
|
||||||
@ -148,8 +120,8 @@ local function filter_settings(pos)
|
|||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
local inv = meta:get_inventory()
|
local inv = meta:get_inventory()
|
||||||
local filter = minetest.deserialize(meta:get_string("filter")) or {false,false,false,false}
|
local filter = minetest.deserialize(meta:get_string("filter")) or {false,false,false,false}
|
||||||
local kvFilterItemNames = {} -- {<item:name> = true,...}
|
local kvFilterItemNames = {} -- {<item:name> = side,...}
|
||||||
local kvSide2ItemNames = {} -- {"F" = {<item:name>,...},...}
|
local kvOpenPorts = {} -- {side = true, ...}
|
||||||
|
|
||||||
-- collect all filter settings
|
-- collect all filter settings
|
||||||
for idx,slot in ipairs(SlotColors) do
|
for idx,slot in ipairs(SlotColors) do
|
||||||
@ -157,14 +129,16 @@ local function filter_settings(pos)
|
|||||||
if filter[idx] == true then
|
if filter[idx] == true then
|
||||||
local list = inv:get_list(slot)
|
local list = inv:get_list(slot)
|
||||||
local filter = invlist_entries_as_list(list)
|
local filter = invlist_entries_as_list(list)
|
||||||
AddToTbl(kvFilterItemNames, filter)
|
AddToTbl(kvFilterItemNames, filter, side)
|
||||||
kvSide2ItemNames[side] = filter
|
if not next(filter) then
|
||||||
|
kvOpenPorts[side] = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
FilterCache[hash] = {
|
FilterCache[hash] = {
|
||||||
kvFilterItemNames = kvFilterItemNames,
|
kvFilterItemNames = kvFilterItemNames,
|
||||||
kvSide2ItemNames = kvSide2ItemNames
|
kvOpenPorts = kvOpenPorts,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -215,14 +189,6 @@ local function keep_running(pos, elapsed)
|
|||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
local running = meta:get_int("running") - 1
|
local running = meta:get_int("running") - 1
|
||||||
local player_name = meta:get_string("player_name")
|
local player_name = meta:get_string("player_name")
|
||||||
--print("running", running)
|
|
||||||
local slot_idx = meta:get_int("slot_idx") or 1
|
|
||||||
meta:set_int("slot_idx", (slot_idx + 1) % NUM_FILTER_SLOTS)
|
|
||||||
local side = Num2Ascii[slot_idx+1]
|
|
||||||
local listname = SlotColors[slot_idx+1]
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
local list = inv:get_list("src")
|
|
||||||
local kvSrc = invlist_content_as_kvlist(list)
|
|
||||||
local counter = minetest.deserialize(meta:get_string("item_counter")) or
|
local counter = minetest.deserialize(meta:get_string("item_counter")) or
|
||||||
{red=0, green=0, blue=0, yellow=0}
|
{red=0, green=0, blue=0, yellow=0}
|
||||||
|
|
||||||
@ -233,50 +199,58 @@ local function keep_running(pos, elapsed)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- read data from Cache
|
-- read data from Cache
|
||||||
-- all filter items as key/value {<item:name> = true,...}
|
|
||||||
local kvFilterItemNames = FilterCache[hash].kvFilterItemNames
|
local kvFilterItemNames = FilterCache[hash].kvFilterItemNames
|
||||||
-- filter items of one slot as list {<item:name>,...}
|
local open_ports = table.copy(FilterCache[hash].kvOpenPorts)
|
||||||
local names = FilterCache[hash].kvSide2ItemNames[side]
|
|
||||||
|
|
||||||
if names == nil then
|
-- no filter configured?
|
||||||
-- this slot is empty
|
if next(kvFilterItemNames) == nil then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
local busy = false
|
local busy = false
|
||||||
-- move items from configured filters to the output
|
local unused_outputs = {B=true, L=true, F=true, R=true}
|
||||||
if next(names) then
|
|
||||||
for _,name in ipairs(names) do
|
|
||||||
if kvSrc[name] then
|
|
||||||
local item = get_this_stack(meta, "src", kvSrc[name])
|
|
||||||
if item then
|
|
||||||
if not tubelib.push_items(pos, side, item, player_name) then
|
|
||||||
tubelib.put_item(meta, "src", item)
|
|
||||||
else
|
|
||||||
counter[listname] = counter[listname] + 1
|
|
||||||
busy = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- move additional items from unconfigured filters to the output
|
local inv = meta:get_inventory()
|
||||||
if next(names) == nil then
|
local list = inv:get_list("src")
|
||||||
for name,_ in pairs(kvSrc) do
|
for _,stack in ipairs(list) do
|
||||||
if kvFilterItemNames[name] == nil then -- not in the filter so far?
|
if stack:get_count() > 0 then
|
||||||
local item = get_this_stack(meta, "src", kvSrc[name])
|
local name = stack:get_name()
|
||||||
if item then
|
local second_try = false
|
||||||
if not tubelib.push_items(pos, side, item, player_name) then
|
|
||||||
tubelib.put_item(meta, "src", item)
|
-- try configured output ports
|
||||||
|
local side = kvFilterItemNames[name]
|
||||||
|
if side then -- configured
|
||||||
|
if unused_outputs[side] then
|
||||||
|
if tubelib.push_items(pos, side, stack, player_name) then
|
||||||
|
stack:set_count(0)
|
||||||
|
unused_outputs[side] = false
|
||||||
|
local color = Side2Color[side]
|
||||||
|
counter[color] = counter[color] + 1
|
||||||
|
busy = true
|
||||||
else
|
else
|
||||||
counter[listname] = counter[listname] + 1
|
second_try = true -- port blocked
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
second_try = true -- not configured
|
||||||
|
end
|
||||||
|
|
||||||
|
-- try unconfigured open output ports
|
||||||
|
if second_try then
|
||||||
|
side,_ = next(open_ports)
|
||||||
|
if side then
|
||||||
|
if tubelib.push_items(pos, side, stack, player_name) then
|
||||||
|
stack:set_count(0)
|
||||||
|
open_ports[side] = nil
|
||||||
|
local color = Side2Color[side]
|
||||||
|
counter[color] = counter[color] + 1
|
||||||
busy = true
|
busy = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
inv:set_list("src", list)
|
||||||
|
|
||||||
if busy == true then
|
if busy == true then
|
||||||
if running <= 0 then
|
if running <= 0 then
|
||||||
|
Loading…
Reference in New Issue
Block a user