Added working Active Suppliers; various fixes + improvements

This commit is contained in:
Zenon Seth 2023-11-09 03:30:55 +00:00
parent 1bd9d0a667
commit 2f3297e811
24 changed files with 402 additions and 92 deletions

View File

@ -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")

View File

@ -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

View File

@ -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
View 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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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
View 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

View File

@ -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")

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -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

View File

@ -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

View File

@ -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