Added working Active Suppliers; various fixes + improvements
@ -5,3 +5,4 @@ dofile(path.."/controller.lua")
|
||||
dofile(path.."/mass_storage.lua")
|
||||
dofile(path.."/supplier.lua")
|
||||
dofile(path.."/demander.lua")
|
||||
dofile(path.."/injector.lua")
|
@ -102,7 +102,7 @@ function logistica.register_controller(simpleName, def, tier)
|
||||
def_disabled.tiles = tiles_disabled
|
||||
def_disabled.groups = { oddly_breakable_by_hand = 3, cracky = 3, choppy = 3, not_in_creative_inventory = 1 }
|
||||
def_disabled.on_construct = nil
|
||||
def_disabled.after_desctruct = nil
|
||||
def_disabled.after_destruct = nil
|
||||
def_disabled.on_timer = nil
|
||||
def_disabled.on_rightclick = nil
|
||||
|
||||
|
@ -71,6 +71,7 @@ local function after_place_demander(pos, placer, itemstack, numDemandSlots)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("filter", numDemandSlots)
|
||||
logistica.on_demander_change(pos)
|
||||
logistica.update_demander_on_item_added(pos)
|
||||
logistica.start_demander_timer(pos)
|
||||
end
|
||||
|
||||
@ -80,6 +81,7 @@ local function allow_demander_storage_inv_put(pos, listname, index, stack, playe
|
||||
local slotStack = inv:get_stack(listname, index)
|
||||
slotStack:add_item(stack)
|
||||
inv:set_stack(listname, index, slotStack)
|
||||
logistica.update_demander_on_item_added(pos)
|
||||
logistica.start_demander_timer(pos, 1)
|
||||
return 0
|
||||
end
|
||||
@ -90,6 +92,7 @@ local function allow_demander_inv_take(pos, listname, index, stack, player)
|
||||
local slotStack = inv:get_stack(listname, index)
|
||||
slotStack:take_item(stack:get_count())
|
||||
inv:set_stack(listname, index, slotStack)
|
||||
logistica.update_demander_cache_pos(pos)
|
||||
return 0
|
||||
end
|
||||
|
||||
@ -136,6 +139,7 @@ function logistica.register_demander(simpleName, transferRate)
|
||||
after_place_node = function (pos, placer, itemstack)
|
||||
after_place_demander(pos, placer, itemstack, NUM_DEMAND_SLOTS)
|
||||
end,
|
||||
after_destruct = logistica.on_demander_change,
|
||||
on_punch = on_demander_punch,
|
||||
on_rightclick = on_demander_rightclick,
|
||||
allow_metadata_inventory_put = allow_demander_storage_inv_put,
|
||||
@ -163,7 +167,7 @@ function logistica.register_demander(simpleName, transferRate)
|
||||
def_disabled.tiles = tiles_disabled
|
||||
def_disabled.groups = { oddly_breakable_by_hand = 3, cracky = 3, choppy = 3, not_in_creative_inventory = 1 }
|
||||
def_disabled.on_construct = nil
|
||||
def_disabled.after_desctruct = nil
|
||||
def_disabled.after_destruct = nil
|
||||
def_disabled.on_punch = nil
|
||||
def_disabled.on_rightclick = nil
|
||||
def_disabled.on_timer = nil
|
||||
|
150
api/injector.lua
Normal file
@ -0,0 +1,150 @@
|
||||
|
||||
local PULL_LIST_PICKER = "pull_pick"
|
||||
local ON_OFF_BUTTON = "on_off_btn"
|
||||
local FORMSPEC_NAME = "logistica_storinject"
|
||||
|
||||
local injectorForms = {}
|
||||
|
||||
local function get_injector_formspec(pos)
|
||||
local posForm = "nodemeta:"..pos.x..","..pos.y..","..pos.z
|
||||
local pushPos = logistica.get_injector_target(pos)
|
||||
local selectedList = logistica.get_injector_target_list(pos)
|
||||
local isOn = logistica.is_machine_on(pos)
|
||||
return "formspec_version[4]" ..
|
||||
"size[7,2.0]" ..
|
||||
logistica.ui.background..
|
||||
"label[0.5,0.3;Active Suppliers try to insert items in the network one at a time]"..
|
||||
logistica.ui.pull_list_picker(PULL_LIST_PICKER, 0.5, 1.0, pushPos, selectedList, "Take items from:")..
|
||||
logistica.ui.on_off_btn(isOn, 4.5, 0.8, ON_OFF_BUTTON, "Enable")
|
||||
end
|
||||
|
||||
local function show_injector_formspec(playerName, pos)
|
||||
local pInfo = {}
|
||||
pInfo.position = pos
|
||||
injectorForms[playerName] = pInfo
|
||||
minetest.show_formspec(playerName, FORMSPEC_NAME, get_injector_formspec(pos))
|
||||
end
|
||||
|
||||
-- callbacks
|
||||
|
||||
local function on_player_receive_fields(player, formname, fields)
|
||||
if not player or not player:is_player() then return false end
|
||||
if formname ~= FORMSPEC_NAME then return false end
|
||||
local playerName = player:get_player_name()
|
||||
if not injectorForms[playerName] then return false end
|
||||
if fields.quit then
|
||||
injectorForms[playerName] = nil
|
||||
elseif fields[ON_OFF_BUTTON] then
|
||||
local pos = injectorForms[playerName].position
|
||||
if not pos then return false end
|
||||
logistica.toggle_machine_on_off(pos)
|
||||
show_injector_formspec(player:get_player_name(), pos)
|
||||
elseif fields[PULL_LIST_PICKER] then
|
||||
local selected = fields[PULL_LIST_PICKER]
|
||||
if logistica.is_allowed_pull_list(selected) then
|
||||
local pos = injectorForms[playerName].position
|
||||
if not pos then return false end
|
||||
logistica.set_injector_target_list(pos, selected)
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function on_injector_punch(pos, node, puncher, pointed_thing)
|
||||
local targetPos = logistica.get_injector_target(pos)
|
||||
if targetPos and puncher:is_player() and puncher:get_player_control().sneak then
|
||||
minetest.add_entity(targetPos, "logistica:input_entity")
|
||||
end
|
||||
end
|
||||
|
||||
local function on_injector_rightclick(pos, node, clicker, itemstack, pointed_thing)
|
||||
if not clicker or not clicker:is_player() then return end
|
||||
show_injector_formspec(clicker:get_player_name(), pos)
|
||||
end
|
||||
|
||||
local function after_place_injector(pos, placer, itemstack)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if placer and placer:is_player() then
|
||||
meta:set_string("owner", placer:get_player_name())
|
||||
end
|
||||
logistica.set_injector_target_list(pos, "main")
|
||||
logistica.on_injector_change(pos)
|
||||
logistica.start_injector_timer(pos)
|
||||
end
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Minetest registration
|
||||
----------------------------------------------------------------
|
||||
|
||||
minetest.register_on_player_receive_fields(on_player_receive_fields)
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Public Registration API
|
||||
----------------------------------------------------------------
|
||||
|
||||
-- `simpleName` is used for the description and for the name (can contain spaces)
|
||||
-- transferRate is how many items per tick this injector can transfer, -1 for unlimited
|
||||
function logistica.register_injector(simpleName, transferRate)
|
||||
local lname = string.lower(simpleName:gsub(" ", "_"))
|
||||
local injectorName = "logistica:injector_"..lname
|
||||
logistica.injectors[injectorName] = true
|
||||
local grps = {oddly_breakable_by_hand = 3, cracky = 3 }
|
||||
grps[logistica.TIER_ALL] = 1
|
||||
local def = {
|
||||
description = simpleName.." Active Supplier",
|
||||
drawtype = "normal",
|
||||
tiles = {
|
||||
"logistica_"..lname.."_injector_side.png^[transformR270",
|
||||
"logistica_"..lname.."_injector_side.png^[transformR90",
|
||||
"logistica_"..lname.."_injector_side.png^[transformR180",
|
||||
"logistica_"..lname.."_injector_side.png",
|
||||
"logistica_"..lname.."_injector_back.png",
|
||||
"logistica_"..lname.."_injector_front.png",
|
||||
},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
groups = grps,
|
||||
drop = injectorName,
|
||||
sounds = logistica.node_sound_metallic(),
|
||||
on_timer = logistica.on_injector_timer,
|
||||
after_place_node = function (pos, placer, itemstack)
|
||||
after_place_injector(pos, placer, itemstack)
|
||||
end,
|
||||
after_destruct = logistica.on_injector_change,
|
||||
on_punch = on_injector_punch,
|
||||
on_rightclick = on_injector_rightclick,
|
||||
logistica = {
|
||||
injector_transfer_rate = transferRate,
|
||||
on_connect_to_network = function(pos, networkId)
|
||||
logistica.start_injector_timer(pos)
|
||||
end,
|
||||
on_power = function(pos, isPoweredOn)
|
||||
if isPoweredOn then
|
||||
logistica.start_injector_timer(pos)
|
||||
end
|
||||
end,
|
||||
}
|
||||
}
|
||||
|
||||
minetest.register_node(injectorName, def)
|
||||
|
||||
local def_disabled = table.copy(def)
|
||||
local tiles_disabled = {}
|
||||
for k, v in pairs(def.tiles) do tiles_disabled[k] = v.."^logistica_disabled.png" end
|
||||
|
||||
def_disabled.tiles = tiles_disabled
|
||||
def_disabled.groups = { oddly_breakable_by_hand = 3, cracky = 3, choppy = 3, not_in_creative_inventory = 1 }
|
||||
def_disabled.on_construct = nil
|
||||
def_disabled.after_destruct = nil
|
||||
def_disabled.on_punch = nil
|
||||
def_disabled.on_rightclick = nil
|
||||
def_disabled.on_timer = nil
|
||||
def_disabled.logistica = nil
|
||||
|
||||
minetest.register_node(injectorName.."_disabled", def_disabled)
|
||||
|
||||
end
|
||||
|
||||
logistica.register_injector("Item", 1)
|
||||
logistica.register_injector("Stack", 99)
|
@ -190,12 +190,12 @@ local function after_place_mass_storage(pos, placer, itemstack, numSlots, numUpg
|
||||
logistica.set_mass_storage_image_slot(meta, selImgIndex)
|
||||
for i, v in ipairs(reserves) do logistica.set_mass_storage_reserve(meta, i, v) end
|
||||
logistica.update_mass_storage_front_image(pos)
|
||||
logistica.on_storage_change(pos)
|
||||
logistica.on_mass_storage_change(pos)
|
||||
end
|
||||
|
||||
local function after_mass_storage_destruct(pos, oldNode)
|
||||
logistica.remove_item_on_block_front(pos)
|
||||
logistica.on_storage_change(pos, oldNode)
|
||||
logistica.on_mass_storage_change(pos, oldNode)
|
||||
end
|
||||
|
||||
local function on_mass_storage_preserve_metadata(pos, oldnode, oldmeta, drops)
|
||||
@ -366,6 +366,7 @@ function logistica.register_mass_storage(simpleName, numSlots, numItemsPerSlot,
|
||||
for k, v in pairs(def.tiles) do tiles_disabled[k] = v.."^logistica_disabled.png" end
|
||||
def_disabled.tiles = tiles_disabled
|
||||
def_disabled.groups = { cracky = 3, choppy = 3, oddly_breakable_by_hand = 3, not_in_creative_inventory = 1 }
|
||||
def_disabled.after_destruct = nil
|
||||
|
||||
minetest.register_node(storageName.."_disabled", def_disabled)
|
||||
|
||||
|
@ -14,9 +14,9 @@ local function get_supplier_formspec(pos)
|
||||
return "formspec_version[4]" ..
|
||||
"size[10.6,8]" ..
|
||||
logistica.ui.background..
|
||||
logistica.ui.pull_list_picker(PULL_LIST_PICKER, 6.7, 0.7, pushPos, selectedList, "Take from:")..
|
||||
logistica.ui.pull_list_picker(PULL_LIST_PICKER, 6.7, 0.7, pushPos, selectedList, "Supply from:")..
|
||||
logistica.ui.on_off_btn(isOn, 9.3, 0.5, ON_OFF_BUTTON, "Enable")..
|
||||
"label[0.6,1.2;Items to Supply (if empty nothing will be taken)]"..
|
||||
"label[0.6,1.2;Items to make available as Supply. If left empty, nothing is supplied]"..
|
||||
"list["..posForm..";filter;0.5,1.5;"..NUM_SUPPLY_SLOTS..",1;0]"..
|
||||
"list[current_player;main;0.5,3;8,4;0]"
|
||||
end
|
||||
@ -135,6 +135,7 @@ function logistica.register_supplier(simpleName, maxTransferRate)
|
||||
after_place_node = function (pos, placer, itemstack)
|
||||
after_place_supplier(pos, placer, itemstack, NUM_SUPPLY_SLOTS)
|
||||
end,
|
||||
after_destruct = logistica.on_supplier_change,
|
||||
on_punch = on_supplier_punch,
|
||||
on_rightclick = on_supplier_rightclick,
|
||||
allow_metadata_inventory_put = allow_supplier_storage_inv_put,
|
||||
@ -154,7 +155,7 @@ function logistica.register_supplier(simpleName, maxTransferRate)
|
||||
def_disabled.tiles = tiles_disabled
|
||||
def_disabled.groups = { oddly_breakable_by_hand = 3, cracky = 3, choppy = 3, not_in_creative_inventory = 1 }
|
||||
def_disabled.on_construct = nil
|
||||
def_disabled.after_desctruct = nil
|
||||
def_disabled.after_destruct = nil
|
||||
def_disabled.on_punch = nil
|
||||
def_disabled.on_rightclick = nil
|
||||
def_disabled.on_timer = nil
|
||||
|
@ -3,6 +3,9 @@ local TIMER_DURATION_LONG = 3.0
|
||||
local META_DEMANDER_LISTNAME = "demtarlist"
|
||||
local TARGET_NODES_REQUIRING_TIMER = {}
|
||||
TARGET_NODES_REQUIRING_TIMER["default:furnace"] = true
|
||||
TARGET_NODES_REQUIRING_TIMER["gravelsieve:auto_sieve0"] = true
|
||||
TARGET_NODES_REQUIRING_TIMER["gravelsieve:auto_sieve1"] = true
|
||||
TARGET_NODES_REQUIRING_TIMER["gravelsieve:auto_sieve2"] = true
|
||||
TARGET_NODES_REQUIRING_TIMER["gravelsieve:auto_sieve3"] = true
|
||||
|
||||
local function get_meta(pos)
|
||||
@ -45,7 +48,7 @@ local function get_valid_demander_and_target_inventory(demanderPos)
|
||||
}
|
||||
end
|
||||
|
||||
local function get_actual_demand_for_item(demandStack, invs)
|
||||
local function get_target_missing_item_stack(demandStack, invs)
|
||||
local storageList = invs.targetInventory:get_list(invs.targetList)
|
||||
local remaining = demandStack:get_count()
|
||||
for i,_ in ipairs(storageList) do
|
||||
@ -77,7 +80,7 @@ local function get_next_demanded_stack(pos)
|
||||
repeat
|
||||
if nextSlot <= 0 then return nil end
|
||||
local filterStack = inventories.demanderInventory:get_list("filter")[nextSlot]
|
||||
demandStack = get_actual_demand_for_item(filterStack, inventories)
|
||||
demandStack = get_target_missing_item_stack(filterStack, inventories)
|
||||
if demandStack:get_count() > 0 then return demandStack end
|
||||
nextSlot = logistica.get_next_filled_item_slot(get_meta(pos), "filter")
|
||||
until( nextSlot == startingSlot ) -- until we get back to the starting slot
|
||||
@ -95,6 +98,15 @@ local function take_demanded_items_from_network(pos, network)
|
||||
return true
|
||||
end
|
||||
|
||||
local function get_filter_demand_for(inv, itemName)
|
||||
local filterList = inv:get_list("filter")
|
||||
local maxDemand = 0
|
||||
for _, v in ipairs(filterList) do
|
||||
if v:get_name() == itemName and v:get_count() > maxDemand then maxDemand = v:get_count() end
|
||||
end
|
||||
return maxDemand
|
||||
end
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Storage operation functions
|
||||
----------------------------------------------------------------
|
||||
@ -155,27 +167,38 @@ end
|
||||
function logistica.get_demander_target(pos)
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
if not node then return nil end
|
||||
local shift = logistica.get_rot_directions(node.param2).backward
|
||||
if not shift then return nil end
|
||||
return {x = (pos.x + shift.x),
|
||||
y = (pos.y + shift.y),
|
||||
z = (pos.z + shift.z)}
|
||||
return vector.add(pos, logistica.get_rot_directions(node.param2).backward)
|
||||
end
|
||||
|
||||
-- returns how many items remain from the itemstack after we attempt to insert it
|
||||
-- `targetInventory` and `targetList` are optional (tied together), if not passed, it will be looked up
|
||||
function logistica.insert_itemstack_for_demander(demanderPos, itemstack)
|
||||
-- `limitByDemand` is optional - if set to true, no more items than needed will be inserted
|
||||
function logistica.insert_itemstack_for_demander(demanderPos, itemstack, limitByDemand)
|
||||
if not itemstack or itemstack:is_empty() then return 0 end
|
||||
if not logistica.is_machine_on(demanderPos) then return itemstack:get_count() end
|
||||
|
||||
local itemStackCount = itemstack:get_count()
|
||||
local itemStackName = itemstack:get_name()
|
||||
local inventories = get_valid_demander_and_target_inventory(demanderPos)
|
||||
if not inventories then return itemstack:get_count() end
|
||||
if not inventories then return itemStackCount end
|
||||
local targetInventory = inventories.targetInventory
|
||||
local targetList = inventories.targetList
|
||||
|
||||
local leftover = targetInventory:add_item(targetList, itemstack)
|
||||
local toInsertStack = ItemStack(itemstack)
|
||||
local demand = itemStackCount
|
||||
if limitByDemand then
|
||||
demand = get_filter_demand_for(inventories.demanderInventory, itemStackName)
|
||||
minetest.chat_send_all("-- filterDemand = "..demand)
|
||||
toInsertStack:set_count(demand)
|
||||
toInsertStack = get_target_missing_item_stack(toInsertStack, inventories)
|
||||
minetest.chat_send_all("-- missing item stack = "..toInsertStack:get_count())
|
||||
end
|
||||
if toInsertStack:is_empty() then return itemStackCount end
|
||||
|
||||
local leftover = targetInventory:add_item(targetList, toInsertStack)
|
||||
local targetNode = minetest.get_node(inventories.targetPos)
|
||||
if leftover:get_count() < itemstack:get_count() and TARGET_NODES_REQUIRING_TIMER[targetNode.name] then
|
||||
if leftover:get_count() < toInsertStack:get_count() and TARGET_NODES_REQUIRING_TIMER[targetNode.name] then
|
||||
logistica.start_node_timer(inventories.targetPos, 1)
|
||||
end
|
||||
return leftover:get_count()
|
||||
return leftover:get_count() + itemStackCount - demand
|
||||
end
|
||||
|
@ -1,6 +1,7 @@
|
||||
logistica.cables = {}
|
||||
logistica.machines = {}
|
||||
logistica.controllers = {}
|
||||
logistica.injectors = {}
|
||||
logistica.demanders = {}
|
||||
logistica.suppliers = {}
|
||||
logistica.mass_storage = {}
|
||||
@ -46,6 +47,10 @@ function logistica.is_controller(name)
|
||||
return logistica.controllers[name] ~= nil
|
||||
end
|
||||
|
||||
function logistica.is_injector(name)
|
||||
return logistica.injectors[name] ~= nil
|
||||
end
|
||||
|
||||
function logistica.get_item_tiers(name)
|
||||
local tiers = {}
|
||||
for tier,_ in pairs(logistica.tiers) do
|
||||
|
73
logic/injector.lua
Normal file
@ -0,0 +1,73 @@
|
||||
local META_INJECTOR_LISTNAME = "tarinjlist"
|
||||
local TIMER_DURATION_SHORT = 1
|
||||
local TIMER_DURATION_LONG = 3
|
||||
|
||||
local function get_meta(pos)
|
||||
logistica.load_position(pos)
|
||||
return minetest.get_meta(pos)
|
||||
end
|
||||
|
||||
local function get_injector_rate(nodeName)
|
||||
local def = minetest.registered_nodes[nodeName]
|
||||
if def and def.logistica and def.logistica.injector_transfer_rate then
|
||||
return def.logistica.injector_transfer_rate
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
-- public functions
|
||||
|
||||
function logistica.get_injector_target(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
if not node then return pos end
|
||||
return vector.add(pos, logistica.get_rot_directions(node.param2).backward)
|
||||
end
|
||||
|
||||
function logistica.get_injector_target_list(pos)
|
||||
local meta = get_meta(pos)
|
||||
return meta:get_string(META_INJECTOR_LISTNAME)
|
||||
end
|
||||
|
||||
function logistica.set_injector_target_list(pos, listName)
|
||||
local meta = get_meta(pos)
|
||||
meta:set_string(META_INJECTOR_LISTNAME, listName)
|
||||
end
|
||||
|
||||
function logistica.start_injector_timer(pos)
|
||||
logistica.start_node_timer(pos, TIMER_DURATION_SHORT)
|
||||
end
|
||||
|
||||
function logistica.on_injector_timer(pos, elapsed)
|
||||
local networkId = logistica.get_network_id_or_nil(pos)
|
||||
if not networkId then
|
||||
logistica.set_node_on_off_state(pos, false)
|
||||
return false
|
||||
end
|
||||
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if not node then
|
||||
logistica.start_node_timer(pos, TIMER_DURATION_LONG)
|
||||
return false
|
||||
end
|
||||
local targetList = logistica.get_injector_target_list(pos)
|
||||
local targetPos = logistica.get_injector_target(pos)
|
||||
local targetMeta = minetest.get_meta(targetPos)
|
||||
local targetSlot = logistica.get_next_filled_item_slot(targetMeta, targetList)
|
||||
local maxStack = get_injector_rate(node.name)
|
||||
if targetSlot <= 0 or maxStack <= 0 then
|
||||
logistica.start_node_timer(pos, TIMER_DURATION_LONG)
|
||||
return false
|
||||
end
|
||||
|
||||
local inv = targetMeta:get_inventory()
|
||||
local copyStack = inv:get_stack(targetList, targetSlot)
|
||||
local copyStackSize = copyStack:get_count()
|
||||
local numRemaining = logistica.insert_item_in_network(copyStack, networkId)
|
||||
minetest.chat_send_all("attempted to insert: "..copyStackSize..", remain: "..numRemaining)
|
||||
copyStack:set_count(numRemaining)
|
||||
inv:set_stack(targetList, targetSlot, copyStack)
|
||||
|
||||
logistica.start_node_timer(pos, TIMER_DURATION_SHORT)
|
||||
return false
|
||||
end
|
@ -9,3 +9,4 @@ dofile(path .. "/controller.lua")
|
||||
dofile(path .. "/mass_storage.lua")
|
||||
dofile(path .. "/supplier.lua")
|
||||
dofile(path .. "/demander.lua")
|
||||
dofile(path .. "/injector.lua")
|
||||
|
@ -84,7 +84,10 @@ end
|
||||
|
||||
function logistica.pull_items_from_network_into_mass_storage(pos)
|
||||
local network = logistica.get_network_or_nil(pos)
|
||||
if not network then return end
|
||||
if not network then
|
||||
logistica.set_node_on_off_state(pos, false)
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local stackPos = logistica.get_next_filled_item_slot(meta, "filter")
|
||||
if stackPos <= 0 then return end
|
||||
|
@ -11,6 +11,12 @@ local CACHE_PICKER_SUPPLIER = {
|
||||
cache = function (network) return network.supplier_cache end,
|
||||
nodes = function (network) return network.suppliers end,
|
||||
}
|
||||
local CACHE_PICKER_DEMANDER = {
|
||||
listName = "filter",
|
||||
clear = function (network) network.demander_cache = {} end,
|
||||
cache = function (network) return network.demander_cache end,
|
||||
nodes = function (network) return network.demanders end,
|
||||
}
|
||||
|
||||
-- local function notify_demanders_of_new_cache(network)
|
||||
-- for hash, _ in pairs(network.demanders) do
|
||||
@ -111,3 +117,15 @@ end
|
||||
function logistica.update_supplier_on_item_added(pos)
|
||||
update_cache_on_item_added_at_pos(pos, CACHE_PICKER_SUPPLIER)
|
||||
end
|
||||
|
||||
function logistica.update_demander_cache_pos(pos)
|
||||
update_network_cache_for_pos(pos, CACHE_PICKER_DEMANDER)
|
||||
end
|
||||
|
||||
function logistica.update_demander_cache(network)
|
||||
update_network_cache(network, CACHE_PICKER_DEMANDER)
|
||||
end
|
||||
|
||||
function logistica.update_demander_on_item_added(pos)
|
||||
update_cache_on_item_added_at_pos(pos, CACHE_PICKER_DEMANDER)
|
||||
end
|
@ -20,7 +20,11 @@ local adjecent = {
|
||||
|
||||
local function has_machine(network, id)
|
||||
if not network then return false end
|
||||
if network.demanders[id] or network.suppliers[id] or network.mass_storage[id] or network.item_storage[id]
|
||||
if network.demanders[id]
|
||||
or network.suppliers[id]
|
||||
or network.mass_storage[id]
|
||||
or network.item_storage[id]
|
||||
or network.injectors[id]
|
||||
then
|
||||
return true
|
||||
else
|
||||
@ -139,6 +143,9 @@ local function recursive_scan_for_nodes_for_controller(network, positionHashes,
|
||||
elseif logistica.is_demander(otherNode.name) then
|
||||
network.demanders[otherHash] = true
|
||||
valid = true
|
||||
elseif logistica.is_injector(otherNode.name) then
|
||||
network.injectors[otherHash] = true
|
||||
valid = true
|
||||
elseif logistica.is_supplier(otherNode.name) then
|
||||
network.suppliers[otherHash] = true
|
||||
valid = true
|
||||
@ -178,11 +185,13 @@ local function create_network(controllerPosition, oldNetworkName)
|
||||
network.name = networkName
|
||||
network.cables = {}
|
||||
network.demanders = {}
|
||||
network.injectors = {}
|
||||
network.suppliers = {}
|
||||
network.mass_storage = {}
|
||||
network.item_storage = {}
|
||||
network.storage_cache = {}
|
||||
network.supplier_cache = {}
|
||||
network.demander_cache = {}
|
||||
local startPos = {}
|
||||
startPos[controllerHash] = true
|
||||
local status = recursive_scan_for_nodes_for_controller(network, startPos)
|
||||
@ -196,6 +205,7 @@ local function create_network(controllerPosition, oldNetworkName)
|
||||
-- controller scan skips updating storage cache, do so now
|
||||
logistica.update_mass_storage_cache(network)
|
||||
logistica.update_supplier_cache(network)
|
||||
logistica.update_demander_cache(network)
|
||||
end
|
||||
if errorMsg ~= nil then
|
||||
networks[controllerHash] = nil
|
||||
@ -269,25 +279,12 @@ local function MASS_STORAGE_OPS(pos) return {
|
||||
update_cache_node_added = function(_) logistica.update_mass_storage_cache_on_item_added(pos) end,
|
||||
update_cache_node_removed = function(network) logistica.update_mass_storage_cache(network) end,
|
||||
} end
|
||||
local function try_to_add_mass_storage_to_network(pos)
|
||||
try_to_add_to_network(pos, MASS_STORAGE_OPS(pos))
|
||||
end
|
||||
|
||||
local function remove_mass_storage_from_network(pos)
|
||||
remove_from_network(pos, MASS_STORAGE_OPS(pos))
|
||||
end
|
||||
|
||||
local DEMANDER_OPS = {
|
||||
local function DEMANDER_OPS(pos) return {
|
||||
get_list = function(network) return network.demanders end,
|
||||
update_cache_node_added = function(_) end,
|
||||
update_cache_node_removed = function(_) end,
|
||||
}
|
||||
local function try_to_add_demander_to_network(pos)
|
||||
try_to_add_to_network(pos,DEMANDER_OPS)
|
||||
end
|
||||
local function remove_demander_from_network(pos)
|
||||
remove_from_network(pos, DEMANDER_OPS)
|
||||
end
|
||||
update_cache_node_added = function(_) logistica.update_demander_on_item_added(pos) end,
|
||||
update_cache_node_removed = function(network) logistica.update_demander_cache(network) end,
|
||||
} end
|
||||
|
||||
local function SUPPLIER_OPS(pos) return {
|
||||
get_list = function(network) return network.suppliers end,
|
||||
@ -295,13 +292,11 @@ local function SUPPLIER_OPS(pos) return {
|
||||
update_cache_node_removed = function(network) logistica.update_supplier_cache(network) end,
|
||||
} end
|
||||
|
||||
local function try_to_add_supplier_to_network(pos)
|
||||
try_to_add_to_network(pos, SUPPLIER_OPS(pos))
|
||||
end
|
||||
|
||||
local function remove_supplier_from_network(pos)
|
||||
remove_from_network(pos, SUPPLIER_OPS(pos))
|
||||
end
|
||||
local INJECTOR_OPS = {
|
||||
get_list = function(network) return network.injectors end,
|
||||
update_cache_node_added = function(_) end,
|
||||
update_cache_node_removed = function(_) end,
|
||||
}
|
||||
|
||||
local function cable_can_extend_network_from(pos)
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
@ -370,29 +365,38 @@ function logistica.on_controller_change(pos, oldNode)
|
||||
end
|
||||
end
|
||||
|
||||
function logistica.on_storage_change(pos, oldNode)
|
||||
function logistica.on_mass_storage_change(pos, oldNode)
|
||||
local placed = (oldNode == nil) -- if oldNode is nil, we placed a new one
|
||||
if placed == true then
|
||||
try_to_add_mass_storage_to_network(pos)
|
||||
try_to_add_to_network(pos, MASS_STORAGE_OPS(pos))
|
||||
else
|
||||
remove_mass_storage_from_network(pos)
|
||||
remove_from_network(pos, MASS_STORAGE_OPS(pos))
|
||||
end
|
||||
end
|
||||
|
||||
function logistica.on_demander_change(pos, oldNode)
|
||||
local placed = (oldNode == nil) -- if oldNode is nil, we placed a new one
|
||||
if placed == true then
|
||||
try_to_add_demander_to_network(pos)
|
||||
try_to_add_to_network(pos, DEMANDER_OPS(pos))
|
||||
else
|
||||
remove_demander_from_network(pos)
|
||||
remove_from_network(pos, DEMANDER_OPS(pos))
|
||||
end
|
||||
end
|
||||
|
||||
function logistica.on_supplier_change(pos, oldNode)
|
||||
local placed = (oldNode == nil) -- if oldNode is nil, we placed a new one
|
||||
if placed == true then
|
||||
try_to_add_supplier_to_network(pos)
|
||||
try_to_add_to_network(pos, SUPPLIER_OPS(pos))
|
||||
else
|
||||
remove_supplier_from_network(pos)
|
||||
remove_from_network(pos, SUPPLIER_OPS(pos))
|
||||
end
|
||||
end
|
||||
|
||||
function logistica.on_injector_change(pos, oldNode)
|
||||
local placed = (oldNode == nil) -- if oldNode is nil, we placed a new one
|
||||
if placed == true then
|
||||
try_to_add_to_network(pos, INJECTOR_OPS)
|
||||
else
|
||||
remove_from_network(pos, INJECTOR_OPS)
|
||||
end
|
||||
end
|
||||
|
@ -79,7 +79,7 @@ function logistica.take_stack_from_mass_storage(stackToTake, network, collectorF
|
||||
return false
|
||||
end
|
||||
|
||||
-- try to insert the item into the storage, returning how many items were taken
|
||||
-- try to insert the item into the storage, returning how many items remain
|
||||
function logistica.try_to_add_item_to_storage(pos, inputStack, dryRun)
|
||||
local node = minetest.get_node(pos)
|
||||
if not logistica.is_mass_storage(node.name) and not logistica.is_item_storage(node.name) then return 0 end
|
||||
@ -88,30 +88,33 @@ function logistica.try_to_add_item_to_storage(pos, inputStack, dryRun)
|
||||
local inv = minetest.get_meta(pos):get_inventory()
|
||||
if isMassStorage then
|
||||
local remainingStack = logistica.insert_item_into_mass_storage(pos, inv, inputStack, dryRun)
|
||||
return inputStack:get_count() - remainingStack:get_count()
|
||||
return remainingStack:get_count()
|
||||
else -- it's not mass storage, must be tool storage
|
||||
if inputStack:get_stack_max() == 1 and inv:room_for_item("main", inputStack) then
|
||||
-- tool storage only takes individual items
|
||||
inv:add_item("main", inputStack)
|
||||
return 1
|
||||
return 0
|
||||
end
|
||||
end
|
||||
return 0
|
||||
return inputStack:get_count()
|
||||
end
|
||||
|
||||
-- attempts to insert the given itemstack in the network, returns how many items were inserted
|
||||
-- attempts to insert the given itemstack in the network, returns how many items remain
|
||||
function logistica.insert_item_in_network(itemstack, networkId)
|
||||
local network = logistica.networks[networkId]
|
||||
if not itemstack or not network then return 0 end
|
||||
local network = logistica.get_network_by_id_or_nil(networkId)
|
||||
if not itemstack or itemstack:is_empty() then return 0 end
|
||||
if not network then return itemstack:get_count() end
|
||||
|
||||
local workingStack = ItemStack(itemstack)
|
||||
|
||||
-- check demanders first
|
||||
for hash, _ in pairs(network.demanders) do
|
||||
local listOfDemandersInNeedOfItem = network.demander_cache[itemstack:get_name()] or {}
|
||||
for hash, _ in pairs(listOfDemandersInNeedOfItem) do
|
||||
local pos = minetest.get_position_from_hash(hash)
|
||||
logistica.load_position(pos)
|
||||
local taken = 0 -- logistica.try_to_give_item_to_demander(pos, workingStack)
|
||||
local leftover = workingStack:get_count() - taken
|
||||
if leftover <= 0 then return itemstack:get_count() end -- we took all items
|
||||
local leftover = logistica.insert_itemstack_for_demander(pos, workingStack, true)
|
||||
minetest.chat_send_all("insert_in_network: from: "..itemstack:get_count().." remain "..leftover)
|
||||
if leftover <= 0 then return 0 end -- we took all items
|
||||
workingStack:set_count(leftover)
|
||||
end
|
||||
|
||||
@ -125,11 +128,10 @@ function logistica.insert_item_in_network(itemstack, networkId)
|
||||
for hash, _ in pairs(storages) do
|
||||
local pos = minetest.get_position_from_hash(hash)
|
||||
logistica.load_position(pos)
|
||||
local taken = logistica.try_to_add_item_to_storage(pos, workingStack)
|
||||
local leftover = workingStack:get_count() - taken
|
||||
if leftover <= 0 then return itemstack:get_count() end -- we took all items
|
||||
workingStack:set_count(leftover)
|
||||
local remain = logistica.try_to_add_item_to_storage(pos, workingStack)
|
||||
if remain <= 0 then return 0 end -- we took all items
|
||||
workingStack:set_count(remain)
|
||||
end
|
||||
|
||||
return itemstack:get_count() - workingStack:get_count()
|
||||
return workingStack:get_count()
|
||||
end
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
BIN
textures/logistica_item_injector_back.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
textures/logistica_item_injector_front.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
textures/logistica_item_injector_side.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
textures/logistica_stack_injector_back.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
textures/logistica_stack_injector_front.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
textures/logistica_stack_injector_side.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
@ -87,15 +87,16 @@ end
|
||||
-- toggles the state and returns the new state (true for on, false for off)
|
||||
function logistica.toggle_machine_on_off(pos)
|
||||
logistica.load_position(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local newState = (meta:get_int(META_ON_OFF_KEY) + 1) % 2
|
||||
meta:set_int(META_ON_OFF_KEY, newState)
|
||||
local node = minetest.get_node(pos)
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
if def and def.logistica and def.logistica.on_power then
|
||||
def.logistica.on_power(pos, newState)
|
||||
meta:set_int(META_ON_OFF_KEY, newState)
|
||||
return newState > 0
|
||||
end
|
||||
return newState > 0
|
||||
return nil
|
||||
end
|
||||
|
||||
-- isOn is optional
|
||||
|
16
util/ui.lua
@ -2,18 +2,6 @@ logistica.ui = {}
|
||||
|
||||
logistica.ui.background = "no_prepend[]bgcolor[#0000]background9[0,0;1,1;logistica_formspec_background.png;true;8]"
|
||||
|
||||
-- returns a string of comma separated lists we're allowed to push to at the given pushToPos
|
||||
local function get_lists(pushToPos, allowedLists)
|
||||
logistica.load_position(pushToPos)
|
||||
local availableLists = minetest.get_meta(pushToPos):get_inventory():get_lists()
|
||||
local pushLists = {}
|
||||
for name, _ in pairs(availableLists) do
|
||||
if allowedLists[name] then
|
||||
table.insert(pushLists, name)
|
||||
end
|
||||
end
|
||||
return pushLists
|
||||
end
|
||||
|
||||
|
||||
local function list_dropdown(name, itemTable, x, y, default, label)
|
||||
@ -42,9 +30,9 @@ function logistica.ui.on_off_btn(isOn, x, y, name, label, w, h)
|
||||
end
|
||||
|
||||
function logistica.ui.pull_list_picker(name, x, y, pullFromPos, default, label)
|
||||
return list_dropdown(name, get_lists(pullFromPos, logistica.ALLOWED_PULL_LISTS), x, y, default, label)
|
||||
return list_dropdown(name, logistica.get_pull_lists(pullFromPos), x, y, default, label)
|
||||
end
|
||||
|
||||
function logistica.ui.push_list_picker(name, x, y, pushToPos, default, label)
|
||||
return list_dropdown(name, get_lists(pushToPos, logistica.ALLOWED_PUSH_LISTS), x, y, default, label)
|
||||
return list_dropdown(name, logistica.get_push_lists(pushToPos), x, y, default, label)
|
||||
end
|
||||
|
@ -1,23 +1,58 @@
|
||||
logistica.ALLOWED_PULL_LISTS = {}
|
||||
local allowedPull = logistica.ALLOWED_PULL_LISTS
|
||||
local allowedPull = {}
|
||||
allowedPull["main"] = true
|
||||
allowedPull["src"] = true
|
||||
--allowedPull["src"] = true
|
||||
allowedPull["dst"] = true
|
||||
allowedPull["output"] = true
|
||||
allowedPull["fuel"] = true
|
||||
--allowedPull["fuel"] = true
|
||||
|
||||
logistica.ALLOWED_PUSH_LISTS = {}
|
||||
local allowedPush = logistica.ALLOWED_PUSH_LISTS
|
||||
local allowedPush = {}
|
||||
allowedPush["main"] = true
|
||||
allowedPush["src"] = true
|
||||
allowedPush["fuel"] = true
|
||||
allowedPush["input"] = true
|
||||
allowedPush["shift"] = true
|
||||
|
||||
local function get_lists(targetPosition, allowedLists)
|
||||
logistica.load_position(targetPosition)
|
||||
local availableLists = minetest.get_meta(targetPosition):get_inventory():get_lists()
|
||||
local pushLists = {}
|
||||
for name, _ in pairs(availableLists) do
|
||||
if allowedLists[name] then
|
||||
table.insert(pushLists, name)
|
||||
end
|
||||
end
|
||||
return pushLists
|
||||
end
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- API
|
||||
----------------------------------------------------------------
|
||||
|
||||
-- returns a string of comma separated lists allowed to push to at the given position
|
||||
function logistica.get_push_lists(targetPosition)
|
||||
return get_lists(targetPosition, allowedPush)
|
||||
end
|
||||
|
||||
-- returns a string of comma separated lists allowed to pull to at the given position
|
||||
function logistica.get_pull_lists(targetPosition)
|
||||
return get_lists(targetPosition, allowedPull)
|
||||
end
|
||||
|
||||
function logistica.is_allowed_pull_list(listName)
|
||||
return allowedPull[listName] == true
|
||||
end
|
||||
|
||||
function logistica.is_allowed_push_list(listName)
|
||||
return allowedPush[listName] == true
|
||||
end
|
||||
end
|
||||
|
||||
function logistica.add_allowed_push_list(listName)
|
||||
if not listName then return end
|
||||
allowedPush[listName] = true
|
||||
end
|
||||
|
||||
function logistica.add_allowed_pull_list(listName)
|
||||
if not listName then return end
|
||||
allowedPull[listName] = true
|
||||
end
|
||||
|
||||
|