mirror of
https://github.com/joe7575/techpack.git
synced 2024-11-26 00:53:44 +01:00
distributing algorithm further improved
This commit is contained in:
parent
37ab82b371
commit
4c86e4e6b5
@ -20,6 +20,11 @@ local CYCLE_TIME = 2
|
|||||||
local STOP_STATE = 0
|
local STOP_STATE = 0
|
||||||
local STANDBY_STATE = -1
|
local STANDBY_STATE = -1
|
||||||
|
|
||||||
|
local Side2Color = {B="red", L="green", F="blue", R="yellow"}
|
||||||
|
local SlotColors = {"red", "green", "blue", "yellow"}
|
||||||
|
local Num2Ascii = {"B", "L", "F", "R"}
|
||||||
|
local FilterCache = {} -- local cache for filter settings
|
||||||
|
|
||||||
-- 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
|
||||||
@ -49,11 +54,24 @@ end
|
|||||||
|
|
||||||
local function AddToTbl(kvTbl, new_items, val)
|
local function AddToTbl(kvTbl, new_items, val)
|
||||||
for _, l in ipairs(new_items) do
|
for _, l in ipairs(new_items) do
|
||||||
kvTbl[l] = val
|
if kvTbl[l] == nil then
|
||||||
|
kvTbl[l] = {val}
|
||||||
|
else
|
||||||
|
kvTbl[l][#kvTbl[l] + 1] = val
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return kvTbl
|
return kvTbl
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function random_list_elem(list)
|
||||||
|
if list == nil then
|
||||||
|
return nil
|
||||||
|
elseif #list > 1 then
|
||||||
|
return list[math.random(1, #list)]
|
||||||
|
else
|
||||||
|
return list[1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function distributor_formspec(state, filter)
|
local function distributor_formspec(state, filter)
|
||||||
return "size[10,8.5]"..
|
return "size[10,8.5]"..
|
||||||
@ -80,6 +98,33 @@ local function distributor_formspec(state, filter)
|
|||||||
"listring[current_player;main]"
|
"listring[current_player;main]"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function filter_settings(pos)
|
||||||
|
local hash = minetest.hash_node_position(pos)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
local filter = minetest.deserialize(meta:get_string("filter")) or {false,false,false,false}
|
||||||
|
local kvFilterItemNames = {} -- {<item:name> = side,...}
|
||||||
|
local OpenPorts = {} -- {side, ...}
|
||||||
|
|
||||||
|
-- collect all filter settings
|
||||||
|
for idx,slot in ipairs(SlotColors) do
|
||||||
|
local side = Num2Ascii[idx]
|
||||||
|
if filter[idx] == true then
|
||||||
|
local list = inv:get_list(slot)
|
||||||
|
local filter = invlist_entries_as_list(list)
|
||||||
|
AddToTbl(kvFilterItemNames, filter, side)
|
||||||
|
if not next(filter) then
|
||||||
|
OpenPorts[#OpenPorts + 1] = side
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
FilterCache[hash] = {
|
||||||
|
kvFilterItemNames = kvFilterItemNames,
|
||||||
|
OpenPorts = OpenPorts,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
|
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
local inv = meta:get_inventory()
|
local inv = meta:get_inventory()
|
||||||
@ -91,6 +136,7 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player)
|
|||||||
if listname == "src" then
|
if listname == "src" then
|
||||||
return stack:get_count()
|
return stack:get_count()
|
||||||
elseif invlist_num_entries(list) < NUM_FILTER_ELEM then
|
elseif invlist_num_entries(list) < NUM_FILTER_ELEM then
|
||||||
|
filter_settings(pos)
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
return 0
|
return 0
|
||||||
@ -100,6 +146,7 @@ local function allow_metadata_inventory_take(pos, listname, index, stack, player
|
|||||||
if minetest.is_protected(pos, player:get_player_name()) then
|
if minetest.is_protected(pos, player:get_player_name()) then
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
filter_settings(pos)
|
||||||
return stack:get_count()
|
return stack:get_count()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -110,37 +157,6 @@ 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 Num2Ascii = {"B", "L", "F", "R"} -- color to side translation
|
|
||||||
local FilterCache = {} -- local cache for filter settings
|
|
||||||
|
|
||||||
local function filter_settings(pos)
|
|
||||||
local hash = minetest.hash_node_position(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
local filter = minetest.deserialize(meta:get_string("filter")) or {false,false,false,false}
|
|
||||||
local kvFilterItemNames = {} -- {<item:name> = side,...}
|
|
||||||
local kvOpenPorts = {} -- {side = true, ...}
|
|
||||||
|
|
||||||
-- collect all filter settings
|
|
||||||
for idx,slot in ipairs(SlotColors) do
|
|
||||||
local side = Num2Ascii[idx]
|
|
||||||
if filter[idx] == true then
|
|
||||||
local list = inv:get_list(slot)
|
|
||||||
local filter = invlist_entries_as_list(list)
|
|
||||||
AddToTbl(kvFilterItemNames, filter, side)
|
|
||||||
if not next(filter) then
|
|
||||||
kvOpenPorts[side] = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
FilterCache[hash] = {
|
|
||||||
kvFilterItemNames = kvFilterItemNames,
|
|
||||||
kvOpenPorts = kvOpenPorts,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
local function start_the_machine(pos)
|
local function start_the_machine(pos)
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
@ -184,6 +200,7 @@ local function goto_sleep(pos)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- move items to the output slots
|
-- move items to the output slots
|
||||||
local function keep_running(pos, elapsed)
|
local function keep_running(pos, elapsed)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
@ -200,48 +217,51 @@ local function keep_running(pos, elapsed)
|
|||||||
|
|
||||||
-- read data from Cache
|
-- read data from Cache
|
||||||
local kvFilterItemNames = FilterCache[hash].kvFilterItemNames
|
local kvFilterItemNames = FilterCache[hash].kvFilterItemNames
|
||||||
local open_ports = table.copy(FilterCache[hash].kvOpenPorts)
|
local open_ports = table.copy(FilterCache[hash].OpenPorts)
|
||||||
|
|
||||||
-- no filter configured?
|
-- no filter configured?
|
||||||
if next(kvFilterItemNames) == nil then
|
if next(kvFilterItemNames) == nil then
|
||||||
return true
|
return goto_sleep(pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
local busy = false
|
local busy = false
|
||||||
local unused_outputs = {B=true, L=true, F=true, R=true}
|
|
||||||
|
|
||||||
local inv = meta:get_inventory()
|
local inv = meta:get_inventory()
|
||||||
local list = inv:get_list("src")
|
local list = inv:get_list("src")
|
||||||
for _,stack in ipairs(list) do
|
|
||||||
|
-- take one stack from inventory, which fits to one output port
|
||||||
|
local stack
|
||||||
|
local start_idx = math.random(1, 8)
|
||||||
|
for i = start_idx,start_idx+8 do
|
||||||
|
stack = list[(i % 8) + 1]
|
||||||
|
if stack:get_count() > 0 and (kvFilterItemNames[stack:get_name()] or next(open_ports)) then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if stack:get_count() > 0 then
|
if stack:get_count() > 0 then
|
||||||
local name = stack:get_name()
|
local name = stack:get_name()
|
||||||
local second_try = false
|
local second_try = false
|
||||||
|
|
||||||
-- try configured output ports
|
-- try configured output ports
|
||||||
local side = kvFilterItemNames[name]
|
local side = random_list_elem(kvFilterItemNames[name])
|
||||||
if side then -- configured
|
if side then -- configured
|
||||||
if unused_outputs[side] then
|
|
||||||
if tubelib.push_items(pos, side, stack, player_name) then
|
if tubelib.push_items(pos, side, stack, player_name) then
|
||||||
stack:set_count(0)
|
stack:set_count(0)
|
||||||
unused_outputs[side] = false
|
|
||||||
local color = Side2Color[side]
|
local color = Side2Color[side]
|
||||||
counter[color] = counter[color] + 1
|
counter[color] = counter[color] + 1
|
||||||
busy = true
|
busy = true
|
||||||
else
|
else
|
||||||
second_try = true -- port blocked
|
second_try = true -- port blocked
|
||||||
end
|
end
|
||||||
end
|
|
||||||
else
|
else
|
||||||
second_try = true -- not configured
|
second_try = true -- not configured
|
||||||
end
|
end
|
||||||
|
|
||||||
-- try unconfigured open output ports
|
-- try unconfigured open output ports
|
||||||
if second_try then
|
if second_try then
|
||||||
side,_ = next(open_ports)
|
side = random_list_elem(open_ports)
|
||||||
if side then
|
if side then
|
||||||
if tubelib.push_items(pos, side, stack, player_name) then
|
if tubelib.push_items(pos, side, stack, player_name) then
|
||||||
stack:set_count(0)
|
stack:set_count(0)
|
||||||
open_ports[side] = nil
|
|
||||||
local color = Side2Color[side]
|
local color = Side2Color[side]
|
||||||
counter[color] = counter[color] + 1
|
counter[color] = counter[color] + 1
|
||||||
busy = true
|
busy = true
|
||||||
@ -249,7 +269,6 @@ local function keep_running(pos, elapsed)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
inv:set_list("src", list)
|
inv:set_list("src", list)
|
||||||
|
|
||||||
if busy == true then
|
if busy == true then
|
||||||
|
Loading…
Reference in New Issue
Block a user