Add Reservoir access to Access Point; add related network storage funcs
This commit is contained in:
parent
2bf30a11b6
commit
370e6162c3
@ -43,6 +43,11 @@ local function on_access_point_rightclick(pos, node, clicker, itemstack, pointed
|
||||
logistica.access_point_on_rightclick(pos, node, clicker, itemstack, pointed_thing)
|
||||
end
|
||||
|
||||
local function after_dig_access_point(pos, oldnode, oldmeta, digger)
|
||||
logistica.on_access_point_change(pos, oldnode, oldmeta)
|
||||
logistica.access_point_on_dug(pos)
|
||||
end
|
||||
|
||||
local function can_dig_access_point(pos, player)
|
||||
return true
|
||||
end
|
||||
@ -83,7 +88,7 @@ function logistica.register_access_point(desc, name, tiles)
|
||||
can_dig = can_dig_access_point,
|
||||
connect_sides = {"top", "bottom", "left", "back", "right" },
|
||||
after_place_node = after_place_access_point,
|
||||
after_dig_node = logistica.on_access_point_change,
|
||||
after_dig_node = after_dig_access_point,
|
||||
on_rightclick = on_access_point_rightclick,
|
||||
-- on_metadata_inventory_move = on_access_point_inv_move,
|
||||
-- on_metadata_inventory_put = on_access_point_inv_put,
|
||||
|
@ -66,13 +66,14 @@ local function after_place_node(pos, placer, itemstack, pointed_thing)
|
||||
if not nodeDef or not nodeDef.logistica then return end
|
||||
|
||||
local liquidLevel = stackMeta:get_int(META_LIQUID_LEVEL)
|
||||
local liquidDesc = nodeDef.logistica.liquidDesc
|
||||
local liquidDesc = logistica.reservoir_get_description_of_liquid(nodeDef.logistica.liquidName)
|
||||
local maxBuckets = nodeDef.logistica.maxBuckets
|
||||
|
||||
nodeMeta:set_int(META_LIQUID_LEVEL, liquidLevel)
|
||||
node.param2 = logistica.reservoir_make_param2(liquidLevel, maxBuckets)
|
||||
minetest.swap_node(pos, node)
|
||||
nodeMeta:set_string("infotext", logistica.reservoir_get_description(liquidLevel, maxBuckets, liquidDesc))
|
||||
logistica.on_reservoir_change(pos)
|
||||
end
|
||||
|
||||
|
||||
@ -84,7 +85,7 @@ local function preserve_metadata(pos, oldnode, oldmeta, drops)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local drop = drops[1]
|
||||
local dropMeta = drop:get_meta()
|
||||
local liquidDesc = nodeDef.logistica.liquidDesc
|
||||
local liquidDesc = logistica.reservoir_get_description_of_liquid(nodeDef.logistica.liquidName)
|
||||
local maxBuckets = nodeDef.logistica.maxBuckets
|
||||
local liquidLevel = meta:get_int(META_LIQUID_LEVEL)
|
||||
|
||||
@ -118,9 +119,10 @@ local commonDef = {
|
||||
paramtype2 = "glasslikeliquidlevel",
|
||||
is_ground_content = false,
|
||||
sunlight_propagates = false,
|
||||
groups = {cracky = 3, level = 1},
|
||||
groups = {cracky = 3, level = 1, [logistica.TIER_ALL] = 1},
|
||||
preserve_metadata = preserve_metadata,
|
||||
after_place_node = after_place_node,
|
||||
after_dig_node = logistica.on_reservoir_change,
|
||||
on_rightclick = on_rightclick,
|
||||
stack_max = 1,
|
||||
backface_culling = false,
|
||||
@ -144,8 +146,8 @@ for _, variantName in ipairs(variants) do
|
||||
local nodeName = L("reservoir_"..variantName..EMPTY_SUFFIX)
|
||||
def.drops = nodeName
|
||||
def.logistica.liquidName = LIQUID_NONE
|
||||
def.logistica.liquidDesc = LIQUID_NONE
|
||||
minetest.register_node(nodeName, def)
|
||||
logistica.reservoirs[nodeName] = true
|
||||
end
|
||||
|
||||
--[[
|
||||
@ -165,12 +167,12 @@ function logistica.register_reservoir(liquidName, liquidDesc, bucketItemName, li
|
||||
def.drops = nodeName
|
||||
def.special_tiles = {liquidTexture}
|
||||
def.logistica.liquidName = lname
|
||||
def.logistica.liquidDesc = liquidDesc
|
||||
def.groups.not_in_creative_inventory = 1
|
||||
def.light_source = optLight
|
||||
|
||||
minetest.register_node(nodeName, def)
|
||||
logistica.reservoirs[nodeName] = true
|
||||
|
||||
logistica.reservoir_register_names(lname, bucketItemName, optEmptyBucketName)
|
||||
logistica.reservoir_register_names(lname, bucketItemName, optEmptyBucketName, liquidDesc, liquidTexture)
|
||||
end
|
||||
end
|
||||
|
@ -1,10 +1,19 @@
|
||||
local S = logistica.TRANSLATOR
|
||||
|
||||
local META_CURR_PAGE = "ap_curr_p"
|
||||
local META_SORT_TYPE = "ap_sort"
|
||||
local META_FILTER_TYPE = "ap_fltr"
|
||||
local META_CURR_SEARCH = "ap_curr_s"
|
||||
local META_IGNORE_METADATA = "ap_usemd"
|
||||
local META_CURR_LIQUID_INDEX = "ap_curr_l"
|
||||
|
||||
local STR_NO_LIQUID = S("No Liquid Storage")
|
||||
local STR_EMPTY_RESERVOIRS = S("Free Capacity:")
|
||||
|
||||
local fakeInvMap = {}
|
||||
local liquidsMap = {}
|
||||
|
||||
local LIQUID_NONE = -1
|
||||
|
||||
local SORT_NAME = 1
|
||||
local SORT_MOD = 2
|
||||
@ -126,6 +135,26 @@ local function build_stack_list(pos)
|
||||
}
|
||||
end
|
||||
|
||||
-- { description = "description here", capacity = "3/32", texture = "texture_name.png"}
|
||||
local function make_display_info(name, currBuckets, maxBuckets)
|
||||
if not currBuckets or not maxBuckets then return { description = name, capacity = "", texture = ""} end
|
||||
|
||||
local desc, cap
|
||||
if name == "" then
|
||||
desc = STR_EMPTY_RESERVOIRS
|
||||
cap = tostring(maxBuckets)
|
||||
else
|
||||
desc = logistica.reservoir_get_description_of_liquid(name)
|
||||
cap = tostring(currBuckets).." / "..tostring(maxBuckets)
|
||||
end
|
||||
|
||||
local texture = logistica.reservoir_get_texture_of_liquid(name)
|
||||
return {
|
||||
description = desc,
|
||||
capacity = cap,
|
||||
texture = texture,
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------
|
||||
-- public functions
|
||||
@ -133,6 +162,7 @@ end
|
||||
|
||||
function logistica.access_point_on_player_close(playerName)
|
||||
fakeInvMap[playerName] = nil
|
||||
liquidsMap[playerName] = nil
|
||||
end
|
||||
|
||||
function logistica.update_fake_inv(pos, invName, listName, listSize, playerName)
|
||||
@ -242,4 +272,62 @@ end
|
||||
|
||||
function logistica.access_point_get_current_search_term(meta)
|
||||
return meta:get_string(META_CURR_SEARCH)
|
||||
end
|
||||
end
|
||||
|
||||
function logistica.access_point_change_liquid(meta, dir, playerName)
|
||||
local liquidsInfo = liquidsMap[playerName]
|
||||
if not liquidsInfo then return end
|
||||
local currLiquidIndex = meta:get_int(META_CURR_LIQUID_INDEX)
|
||||
if currLiquidIndex == LIQUID_NONE then return end
|
||||
local numLiquids = #liquidsInfo
|
||||
if numLiquids <= 0 then return end
|
||||
local next = currLiquidIndex + dir
|
||||
|
||||
if next > numLiquids then next = 1 end
|
||||
if next < 1 then next = numLiquids end
|
||||
|
||||
meta:set_int(META_CURR_LIQUID_INDEX, next)
|
||||
return true
|
||||
end
|
||||
|
||||
function logistica.access_point_refresh_liquids(pos, playerName)
|
||||
local liquidsInfo = logistica.get_available_liquids_in_network(pos)
|
||||
liquidsMap[playerName] = liquidsInfo
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
if #liquidsInfo <= 0 then
|
||||
meta:set_int(META_CURR_LIQUID_INDEX, LIQUID_NONE)
|
||||
return
|
||||
end
|
||||
|
||||
local currLiquid = meta:get_int(META_CURR_LIQUID_INDEX)
|
||||
local validSelected = currLiquid >= 1 and currLiquid <= #liquidsInfo
|
||||
if not validSelected then
|
||||
meta:set_int(META_CURR_LIQUID_INDEX, 1)
|
||||
end
|
||||
end
|
||||
|
||||
-- returns a table: { description = "description here", capacity = "3/32", texture = "texture_name.png"}
|
||||
function logistica.access_point_get_current_liquid_display_info(meta, playerName)
|
||||
local liquidsInfo = liquidsMap[playerName]
|
||||
if not liquidsInfo then return make_display_info(STR_NO_LIQUID, nil, nil) end
|
||||
local currLiquid = meta:get_int(META_CURR_LIQUID_INDEX)
|
||||
local liquidInfo = liquidsInfo[currLiquid]
|
||||
|
||||
if currLiquid == LIQUID_NONE or not liquidInfo then return make_display_info(STR_NO_LIQUID, nil, nil) end
|
||||
|
||||
return make_display_info(liquidInfo.name, liquidInfo.curr, liquidInfo.max)
|
||||
end
|
||||
|
||||
-- returns the current liquid name (which may be "" for the empty reservoirs) or nil if invalid/no reservoirs
|
||||
function logistica.access_point_get_current_liquid_name(meta, playerName)
|
||||
local liquidsInfo = liquidsMap[playerName]
|
||||
if not liquidsInfo then return nil end
|
||||
|
||||
local currLiquid = meta:get_int(META_CURR_LIQUID_INDEX)
|
||||
if currLiquid == LIQUID_NONE then return "" end
|
||||
|
||||
local liquidInfo = liquidsInfo[currLiquid]
|
||||
if not liquidInfo then return nil
|
||||
else return liquidInfo.name end
|
||||
end
|
||||
|
@ -19,9 +19,12 @@ local SORT_COUNT_BTN = "sort_cnt"
|
||||
local SORT_WEAR_BTN = "sort_wer"
|
||||
local SEARCH_FIELD = "srch_fld"
|
||||
local USE_META_BTN = "tgl_meta"
|
||||
local LIQUID_NEXT_BTN = "liq_nxt"
|
||||
local LIQUID_PREV_BTN = "liq_prv"
|
||||
|
||||
local INV_FAKE = "fake"
|
||||
local INV_INSERT = "isert"
|
||||
local INV_LIQUID = "liqd"
|
||||
local FAKE_INV_W = 12
|
||||
local FAKE_INV_H = 4
|
||||
local FAKE_INV_SIZE = FAKE_INV_W * FAKE_INV_H
|
||||
@ -49,15 +52,16 @@ local STR_LIGHT_DESC = S("Show Light sources only")
|
||||
local STR_SERCH_DESC = S("Search by text\nUse group:some_group to find items belongong to some_group")
|
||||
local STR_CLEAR_DESC = S("Clear search")
|
||||
|
||||
|
||||
local detachedInventories = {}
|
||||
local accessPointForms = {}
|
||||
|
||||
-- creates the inv and returns the inv name
|
||||
local function get_or_create_detached_inventory(pos, playerName)
|
||||
if accessPointForms[playerName] and accessPointForms[playerName].invName then
|
||||
return accessPointForms[playerName].invName
|
||||
local hash = minetest.hash_node_position(pos)
|
||||
if detachedInventories[hash] then
|
||||
return detachedInventories[hash]
|
||||
end
|
||||
local invName = playerName.."_LAP_"..logistica.get_rand_string_for(pos)
|
||||
local invName = "Logistica_AP_"..logistica.get_rand_string_for(pos)
|
||||
local inv = minetest.create_detached_inventory(invName, {
|
||||
allow_move = logistica.access_point_allow_move,
|
||||
allow_put = logistica.access_point_allow_put,
|
||||
@ -68,6 +72,8 @@ local function get_or_create_detached_inventory(pos, playerName)
|
||||
}, playerName)
|
||||
inv:set_size(INV_FAKE, FAKE_INV_SIZE)
|
||||
inv:set_size(INV_INSERT, 1)
|
||||
inv:set_size(INV_LIQUID, 1)
|
||||
detachedInventories[hash] = invName
|
||||
return invName
|
||||
end
|
||||
|
||||
@ -144,6 +150,17 @@ local function get_search_and_page_section(searchTerm, pageInfo) return
|
||||
"image_button[13.9,6.5;0.8,0.8;logistica_icon_last.png;"..LAST_BTN..";;false;false;]"
|
||||
end
|
||||
|
||||
local function get_liquid_section(invName, meta, playerName)
|
||||
local currInfo = logistica.access_point_get_current_liquid_display_info(meta, playerName)
|
||||
|
||||
return
|
||||
"list[detached:"..invName..";"..INV_LIQUID..";1.2,7.3;1,1;0]"..
|
||||
"image[1.3,6;0.8,0.8;"..currInfo.texture.."]"..
|
||||
"label[1.0,7.1;"..currInfo.description.." "..currInfo.capacity.."]"..
|
||||
"image_button[0.7,6;0.6,0.8;logistica_icon_prev.png;"..LIQUID_PREV_BTN..";;false;false]"..
|
||||
"image_button[2.1,6;0.6,0.8;logistica_icon_next.png;"..LIQUID_NEXT_BTN..";;false;false]"
|
||||
end
|
||||
|
||||
local function get_access_point_formspec(pos, invName, optMeta, playerName)
|
||||
--local posForm = "nodemeta:"..pos.x..","..pos.y..","..pos.z
|
||||
local meta = optMeta or minetest.get_meta(pos)
|
||||
@ -158,12 +175,13 @@ local function get_access_point_formspec(pos, invName, optMeta, playerName)
|
||||
"size[15.2,12.5]"..
|
||||
logistica.ui.background..
|
||||
"list[detached:"..invName..";"..INV_FAKE..";0.2,0.2;"..FAKE_INV_W..","..FAKE_INV_H..";0]"..
|
||||
"image[2.8,6.4;1,1;logistica_icon_input.png]"..
|
||||
"list[detached:"..invName..";"..INV_INSERT..";3.8,6.4;1,1;0]"..
|
||||
"image[3.2,6.5;0.8,0.8;logistica_icon_input.png]"..
|
||||
"list[detached:"..invName..";"..INV_INSERT..";4.0,6.4;1,1;0]"..
|
||||
"list[current_player;main;5.2,7.5;8.0,4.0;0]"..
|
||||
"label[1.4,12.2;"..S("Crafting").."]"..
|
||||
"list[current_player;craft;0.2,8.4;3,3;]"..
|
||||
"list[current_player;craftpreview;3.9,8.4;1,1;]"..
|
||||
get_liquid_section(invName, meta, playerName)..
|
||||
get_listrings(invName)..
|
||||
get_filter_section(usesMetaStr, filterHighImg)..
|
||||
get_tooltips()..
|
||||
@ -180,6 +198,7 @@ local function show_access_point_formspec(pos, playerName, optMeta)
|
||||
invName = invName,
|
||||
}
|
||||
logistica.access_point_refresh_fake_inv(pos, invName, INV_FAKE, FAKE_INV_SIZE, playerName)
|
||||
logistica.access_point_refresh_liquids(pos, playerName)
|
||||
minetest.show_formspec(
|
||||
playerName,
|
||||
FORMSPEC_NAME,
|
||||
@ -207,7 +226,6 @@ function logistica.on_receive_access_point_formspec(player, formname, fields)
|
||||
if minetest.is_protected(pos, playerName) or not pos then return true end
|
||||
|
||||
if fields.quit and not fields.key_enter_field then
|
||||
logistica.access_point_on_player_leave(playerName)
|
||||
return true
|
||||
elseif fields[FRST_BTN] then
|
||||
if not logistica.access_point_change_page(pos, -2, playerName, FAKE_INV_SIZE) then return true end
|
||||
@ -241,6 +259,10 @@ function logistica.on_receive_access_point_formspec(player, formname, fields)
|
||||
logistica.access_point_on_search_clear(pos)
|
||||
elseif fields[SEARCH_BTN] or fields.key_enter_field then
|
||||
logistica.access_point_on_search_change(pos, fields[SEARCH_FIELD])
|
||||
elseif fields[LIQUID_PREV_BTN] then
|
||||
if not logistica.access_point_change_liquid(minetest.get_meta(pos),-1, playerName) then return true end
|
||||
elseif fields[LIQUID_NEXT_BTN] then
|
||||
if not logistica.access_point_change_liquid(minetest.get_meta(pos), 1, playerName) then return true end
|
||||
end
|
||||
show_access_point_formspec(pos, playerName)
|
||||
return true
|
||||
@ -252,9 +274,18 @@ end
|
||||
|
||||
function logistica.access_point_allow_put(inv, listname, index, stack, player)
|
||||
if listname == INV_FAKE then return 0 end
|
||||
|
||||
local pos = get_curr_pos(player)
|
||||
if not pos then return 0 end
|
||||
if not logistica.get_network_or_nil(pos) then return 0 end
|
||||
|
||||
if listname == INV_LIQUID then
|
||||
if logistica.reservoir_is_known_bucket(stack:get_name()) then
|
||||
local currStack = inv:get_stack(listname, index)
|
||||
if currStack:is_empty() then return 1 else return 0 end
|
||||
else return 0 end
|
||||
end
|
||||
|
||||
return stack:get_count()
|
||||
end
|
||||
|
||||
@ -298,6 +329,7 @@ end
|
||||
|
||||
function logistica.access_point_allow_move(inv, from_list, from_index, to_list, to_index, count, player)
|
||||
if from_list == INV_FAKE or to_list == INV_FAKE then return 0 end
|
||||
if to_list == INV_LIQUID then return 0 end
|
||||
return count
|
||||
end
|
||||
|
||||
@ -319,6 +351,13 @@ function logistica.access_point_on_put(inv, listname, index, stack, player)
|
||||
end
|
||||
inv:set_stack(listname, index, ItemStack(""))
|
||||
show_access_point_formspec(pos, player:get_player_name())
|
||||
elseif listname == INV_LIQUID then
|
||||
local currLiquid = logistica.access_point_get_current_liquid_name(minetest.get_meta(pos), player:get_player_name())
|
||||
local newStack = logistica.use_bucket_for_liquid_in_network(pos, stack, currLiquid)
|
||||
if newStack then
|
||||
inv:set_stack(listname, index, newStack)
|
||||
show_access_point_formspec(pos, player:get_player_name())
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -342,8 +381,28 @@ end
|
||||
function logistica.access_point_on_player_leave(playerName)
|
||||
local info = accessPointForms[playerName]
|
||||
if info and info.invName then
|
||||
minetest.remove_detached_inventory(info.invName)
|
||||
local onlyRef = true
|
||||
for _, otherInfo in pairs(accessPointForms) do
|
||||
if otherInfo.invName == info.invName then onlyRef = false end
|
||||
end
|
||||
if onlyRef then
|
||||
minetest.remove_detached_inventory(info.invName)
|
||||
end
|
||||
end
|
||||
accessPointForms[playerName] = nil
|
||||
logistica.access_point_on_player_close(playerName)
|
||||
end
|
||||
|
||||
function logistica.access_point_on_dug(pos)
|
||||
local removeForPlayers = {}
|
||||
local i =0
|
||||
for playerName, info in pairs(accessPointForms) do
|
||||
if info.position and vector.equals(pos, info.position) then
|
||||
i = i + 1
|
||||
removeForPlayers[i] = playerName
|
||||
end
|
||||
end
|
||||
for _, playerName in ipairs(removeForPlayers) do
|
||||
logistica.access_point_on_player_leave(playerName)
|
||||
end
|
||||
end
|
||||
|
@ -9,6 +9,7 @@ logistica.item_storage = {}
|
||||
logistica.misc_machines = {}
|
||||
logistica.trashcans = {}
|
||||
logistica.vaccuum_suppliers = {}
|
||||
logistica.reservoirs = {}
|
||||
logistica.TIER_ALL = "logistica_all_tiers"
|
||||
logistica.GROUP_ALL = "group:" .. logistica.TIER_ALL
|
||||
logistica.TIER_CONTROLLER = "logistica_controller"
|
||||
@ -20,7 +21,7 @@ function logistica.is_machine(name)
|
||||
return logistica.is_requester(name) or logistica.is_supplier(name) or logistica.is_mass_storage(name)
|
||||
or logistica.is_item_storage(name) or logistica.is_controller(name) or logistica.is_injector(name)
|
||||
or logistica.is_crafting_supplier(name) or logistica.is_trashcan(name) or logistica.is_vaccuum_supplier(name)
|
||||
or logistica.is_misc(name)
|
||||
or logistica.is_misc(name) or logistica.is_reservoir(name)
|
||||
end
|
||||
|
||||
function logistica.is_cable(name)
|
||||
@ -66,3 +67,7 @@ end
|
||||
function logistica.is_vaccuum_supplier(name)
|
||||
return logistica.vaccuum_suppliers[name] ~= nil
|
||||
end
|
||||
|
||||
function logistica.is_reservoir(name)
|
||||
return logistica.reservoirs[name] ~= nil
|
||||
end
|
||||
|
@ -23,6 +23,7 @@ local function has_machine(network, id)
|
||||
or network.injectors[id]
|
||||
or network.misc[id]
|
||||
or network.trashcans[id]
|
||||
or network.reservoirs[id]
|
||||
then
|
||||
return true
|
||||
else
|
||||
@ -204,6 +205,10 @@ local function recursive_scan_for_nodes_for_controller(network, positionHashes,
|
||||
network.trashcans[otherHash] = true
|
||||
valid = true
|
||||
end
|
||||
if logistica.is_reservoir(otherName) then
|
||||
network.reservoirs[otherHash] = true
|
||||
valid = true
|
||||
end
|
||||
if valid then
|
||||
newToScan = newToScan + 1
|
||||
set_cache_network_id(minetest.get_meta(otherPos), network.controller)
|
||||
@ -242,6 +247,7 @@ local function create_network(controllerPosition, oldNetworkName)
|
||||
network.storage_cache = {}
|
||||
network.supplier_cache = {}
|
||||
network.requester_cache = {}
|
||||
network.reservoirs = {}
|
||||
local startPos = {}
|
||||
startPos[controllerHash] = true
|
||||
local status = recursive_scan_for_nodes_for_controller(network, startPos)
|
||||
@ -369,6 +375,12 @@ local TRASHCAN_OPS = {
|
||||
update_cache_node_removed = function(_) end,
|
||||
}
|
||||
|
||||
local RESERVOIR_OPS = {
|
||||
get_list = function(network) return network.reservoirs 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)
|
||||
if not node then return false end
|
||||
@ -494,3 +506,7 @@ end
|
||||
function logistica.on_trashcan_change(pos, oldNode, oldMeta)
|
||||
on_node_change(pos, oldNode, oldMeta, TRASHCAN_OPS)
|
||||
end
|
||||
|
||||
function logistica.on_reservoir_change(pos, oldNode, oldMeta)
|
||||
on_node_change(pos, oldNode, oldMeta, RESERVOIR_OPS)
|
||||
end
|
||||
|
@ -3,11 +3,75 @@ local MASS_STORAGE_LIST_NAME = "storage"
|
||||
local ITEM_STORAGE_LIST_NAME = "main"
|
||||
local MAX_NETWORK_DEPTH_SEARCH = 16 -- somewhat arbitrary but prevents stackoverflows
|
||||
|
||||
local h2p = minetest.get_position_from_hash
|
||||
|
||||
local function get_meta(pos)
|
||||
logistica.load_position(pos)
|
||||
return minetest.get_meta(pos)
|
||||
end
|
||||
|
||||
local function fill_bucket_from_network(network, bucketItemStack, liquidName)
|
||||
local lowestReservoirPos = nil
|
||||
local lowestReservoirLvl = 999999
|
||||
for hash, _ in pairs(network.reservoirs or {}) do
|
||||
local pos = h2p(hash)
|
||||
logistica.load_position(pos)
|
||||
if logistica.reservoir_get_liquid_name(pos) == liquidName then
|
||||
local levels = logistica.reservoir_get_liquid_level(pos)
|
||||
if levels and levels[1] < lowestReservoirLvl then
|
||||
lowestReservoirPos = pos
|
||||
lowestReservoirLvl = levels[1]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if lowestReservoirPos then
|
||||
return logistica.reservoir_use_item_on(lowestReservoirPos, bucketItemStack)
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
local function empty_bucket_into_network(network, bucketItemStack)
|
||||
local bucketName = bucketItemStack:get_name()
|
||||
local liquidName = logistica.reservoir_get_liquid_name_for_bucket(bucketName)
|
||||
|
||||
local highestReservoirPos = nil
|
||||
local emptyReservoirPos = nil
|
||||
local emptyResrvoirMinCap = 999999
|
||||
local highestReservoirLvl = 0
|
||||
for hash, _ in pairs(network.reservoirs or {}) do
|
||||
local pos = h2p(hash)
|
||||
logistica.load_position(pos)
|
||||
local liquidInReservoir = logistica.reservoir_get_liquid_name(pos)
|
||||
if liquidInReservoir == liquidName then
|
||||
local levels = logistica.reservoir_get_liquid_level(pos)
|
||||
if levels and levels[1] < levels[2] and levels[1] > highestReservoirLvl then
|
||||
highestReservoirPos = pos
|
||||
highestReservoirLvl = levels[1]
|
||||
end
|
||||
elseif liquidInReservoir == "" then
|
||||
local levels = logistica.reservoir_get_liquid_level(pos)
|
||||
if levels and levels[2] < emptyResrvoirMinCap then
|
||||
emptyResrvoirMinCap = levels[2]
|
||||
emptyReservoirPos = pos
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if highestReservoirPos then
|
||||
return logistica.reservoir_use_item_on(highestReservoirPos, bucketItemStack)
|
||||
elseif emptyReservoirPos then
|
||||
return logistica.reservoir_use_item_on(emptyReservoirPos, bucketItemStack)
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------
|
||||
-- public functions
|
||||
--------------------------------
|
||||
|
||||
-- tries to take a stack from the network locations
|
||||
-- calls the collectorFunc with the stack - collectorFunc needs to return how many were left-over<br>
|
||||
-- `collectorFunc = function(stackToInsert)`<br>
|
||||
@ -40,7 +104,7 @@ function logistica.take_stack_from_suppliers(stackToTake, network, collectorFunc
|
||||
local stackName = stackToTake:get_name()
|
||||
local validSupplers = network.supplier_cache[stackName] or {}
|
||||
for hash, _ in pairs(validSupplers) do
|
||||
local pos = minetest.get_position_from_hash(hash)
|
||||
local pos = h2p(hash)
|
||||
logistica.load_position(pos)
|
||||
local nodeName = minetest.get_node(pos).name
|
||||
if logistica.is_supplier(nodeName) or logistica.is_vaccuum_supplier(nodeName) then
|
||||
@ -64,7 +128,7 @@ function logistica.take_stack_from_item_storage(stack, network, collectorFunc, i
|
||||
if useMetadata then eq = function(s1, s2) return s1:equals(s2) end end
|
||||
|
||||
for storageHash, _ in pairs(network.item_storage) do
|
||||
local storagePos = minetest.get_position_from_hash(storageHash)
|
||||
local storagePos = h2p(storageHash)
|
||||
local storageInv = get_meta(storagePos):get_inventory()
|
||||
local storageList = storageInv:get_list(ITEM_STORAGE_LIST_NAME) or {}
|
||||
for i, storedStack in ipairs(storageList) do
|
||||
@ -97,7 +161,7 @@ function logistica.take_stack_from_mass_storage(stackToTake, network, collectorF
|
||||
if stackToTake:get_count() == 0 then return end
|
||||
if massLocations == nil then return end
|
||||
for storageHash, _ in pairs(massLocations) do
|
||||
local storagePos = minetest.get_position_from_hash(storageHash)
|
||||
local storagePos = h2p(storageHash)
|
||||
local meta = get_meta(storagePos)
|
||||
local storageInv = meta:get_inventory()
|
||||
local storageList = storageInv:get_list(MASS_STORAGE_LIST_NAME) or {}
|
||||
@ -155,7 +219,7 @@ function logistica.insert_item_in_network(itemstack, networkId, dryRun)
|
||||
-- check requesters first
|
||||
local listOfRequestersInNeedOfItem = network.requester_cache[itemstack:get_name()] or {}
|
||||
for hash, _ in pairs(listOfRequestersInNeedOfItem) do
|
||||
local pos = minetest.get_position_from_hash(hash)
|
||||
local pos = h2p(hash)
|
||||
logistica.load_position(pos)
|
||||
local leftover = logistica.insert_itemstack_for_requester(pos, workingStack, true)
|
||||
if leftover <= 0 then return 0 end -- we took all items
|
||||
@ -173,7 +237,7 @@ function logistica.insert_item_in_network(itemstack, networkId, dryRun)
|
||||
addFunc = logistica.insert_item_into_mass_storage
|
||||
end
|
||||
for hash, _ in pairs(storages) do
|
||||
local pos = minetest.get_position_from_hash(hash)
|
||||
local pos = h2p(hash)
|
||||
local inv = get_meta(pos):get_inventory()
|
||||
local remainingStack = addFunc(pos, inv, workingStack, dryRun)
|
||||
if remainingStack:is_empty() then return 0 end -- we took all items
|
||||
@ -183,7 +247,7 @@ function logistica.insert_item_in_network(itemstack, networkId, dryRun)
|
||||
-- try to add to passive suppliers that accept this
|
||||
local suppliers = network.suppliers
|
||||
for hash, _ in pairs(suppliers) do
|
||||
local pos = minetest.get_position_from_hash(hash)
|
||||
local pos = h2p(hash)
|
||||
logistica.load_position(pos)
|
||||
local leftover = logistica.put_item_in_supplier(pos, workingStack)
|
||||
if leftover:is_empty() then return 0 end
|
||||
@ -193,11 +257,67 @@ function logistica.insert_item_in_network(itemstack, networkId, dryRun)
|
||||
-- [Keep this last] delete the item if any trashcan accepts it
|
||||
local trashcans = network.trashcans or {}
|
||||
for hash, _ in pairs(trashcans) do
|
||||
local pos = minetest.get_position_from_hash(hash)
|
||||
local pos = h2p(hash)
|
||||
logistica.load_position(pos)
|
||||
workingStack = logistica.trashcan_trash_item(pos, workingStack)
|
||||
if workingStack:is_empty() then return 0 end
|
||||
end
|
||||
|
||||
return workingStack:get_count()
|
||||
end
|
||||
end
|
||||
|
||||
--[[ returns a natural-indexed list of tables - or empty table if there's no network or no liquids:
|
||||
```
|
||||
[1] = {
|
||||
name = "liquid_name", -- name of the liquid or "" if for empty reservoirs
|
||||
curr = 0 -- amount of liquid stored in network
|
||||
max = 32 -- combined max capacity of the reservoirs occupied by liquid
|
||||
},
|
||||
[2] = {...}
|
||||
```
|
||||
]]
|
||||
function logistica.get_available_liquids_in_network(pos)
|
||||
local network = logistica.get_network_or_nil(pos)
|
||||
if not network then return {} end
|
||||
local liquidInfo = {}
|
||||
for hash, _ in pairs(network.reservoirs or {}) do
|
||||
local resPos = h2p(hash)
|
||||
local liquidName = logistica.reservoir_get_liquid_name(resPos)
|
||||
local liquidLevels = logistica.reservoir_get_liquid_level(resPos)
|
||||
if liquidName and liquidLevels then
|
||||
local info = liquidInfo[liquidName] or {curr = 0, max = 0}
|
||||
info.curr = info.curr + liquidLevels[1]
|
||||
info.max = info.max + liquidLevels[2]
|
||||
liquidInfo[liquidName] = info
|
||||
end
|
||||
end
|
||||
return
|
||||
logistica.table_to_list_indexed(liquidInfo, function(lName, lInfo)
|
||||
return {
|
||||
name = lName,
|
||||
curr = lInfo.curr,
|
||||
max = lInfo.max,
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
-- attempts to use, either fill or empty, the given bucket in/from liquid storage on
|
||||
-- the network.<br>
|
||||
-- `liquidName` is only used if the bucketItem is a type of empty bucket<br>
|
||||
-- Otherwise a full bucket will attempt to fill any applicable reservoir on the network.
|
||||
-- This function attempts to take from the lowest filled reservoir, and insert into the highest filled reservoir first.<br>
|
||||
-- returns new itemstack to replace the old one, or `nil` if it wasn't changed
|
||||
function logistica.use_bucket_for_liquid_in_network(pos, bucketItemStack, liquidName)
|
||||
local network = logistica.get_network_or_nil(pos)
|
||||
if not network then return nil end
|
||||
|
||||
local bucketName = bucketItemStack:get_name()
|
||||
local isEmptyBucket = logistica.reservoir_is_empty_bucket(bucketName)
|
||||
local isFullBucket = logistica.reservoir_is_full_bucket(bucketName)
|
||||
if isEmptyBucket then
|
||||
if not liquidName then return nil end
|
||||
return fill_bucket_from_network(network, bucketItemStack, liquidName)
|
||||
elseif isFullBucket then
|
||||
return empty_bucket_into_network(network, bucketItemStack)
|
||||
end
|
||||
end
|
||||
|
@ -3,6 +3,9 @@ local S = logistica.TRANSLATOR
|
||||
local BUCKET_TO_NAME = {}
|
||||
local NAME_TO_BUCKET = {}
|
||||
local NAME_TO_EMPTY_BUCKET = {}
|
||||
local NAME_TO_DESC = {}
|
||||
local NAME_TO_TEXTURE = {}
|
||||
|
||||
local EMPTY_BUCKET = "bucket:bucket_empty"
|
||||
local EMPTY_SUFFIX = "_empty"
|
||||
|
||||
@ -54,6 +57,14 @@ end
|
||||
-- public functions
|
||||
--------------------------------
|
||||
|
||||
function logistica.reservoir_get_description_of_liquid(liquidName)
|
||||
return NAME_TO_DESC[liquidName] or LIQUID_NONE
|
||||
end
|
||||
|
||||
function logistica.reservoir_get_texture_of_liquid(liquidName)
|
||||
return NAME_TO_TEXTURE[liquidName] or ""
|
||||
end
|
||||
|
||||
function logistica.reservoir_make_param2(val, max)
|
||||
local ret = math.floor(63*(val/max))
|
||||
if val > 0 and ret == 0 then
|
||||
@ -66,12 +77,14 @@ function logistica.reservoir_get_description(currBuckets, maxBuckets, liquidName
|
||||
return strDescription.."\n"..getStrContains(currBuckets, maxBuckets, liquidName)
|
||||
end
|
||||
|
||||
function logistica.reservoir_register_names(liquidName, bucketName, emptyBucketName)
|
||||
function logistica.reservoir_register_names(liquidName, bucketName, emptyBucketName, liquidDesc, liquidTexture)
|
||||
BUCKET_TO_NAME[bucketName] = liquidName
|
||||
NAME_TO_BUCKET[liquidName] = bucketName
|
||||
if emptyBucketName then
|
||||
NAME_TO_EMPTY_BUCKET[liquidName] = emptyBucketName
|
||||
end
|
||||
NAME_TO_DESC[liquidName] = liquidDesc
|
||||
NAME_TO_TEXTURE[liquidName] = liquidTexture
|
||||
end
|
||||
|
||||
-- returns nil if item had no effect<br>
|
||||
@ -86,7 +99,7 @@ function logistica.reservoir_use_item_on(pos, itemstack, optNode)
|
||||
local nodeLiquidLevel = meta:get_int(META_LIQUID_LEVEL)
|
||||
local liquidName = nodeDef.logistica.liquidName
|
||||
local maxBuckets = nodeDef.logistica.maxBuckets
|
||||
local liquidDesc = nodeDef.logistica.liquidDesc
|
||||
local liquidDesc = logistica.reservoir_get_description_of_liquid(liquidName)
|
||||
|
||||
local emptyBucket = get_empty_bucket_needed_for(liquidName)
|
||||
local fullBucket = get_full_bucket_needed_for(liquidName)
|
||||
@ -127,14 +140,57 @@ function logistica.reservoir_use_item_on(pos, itemstack, optNode)
|
||||
minetest.swap_node(pos, node)
|
||||
local newNodeName = get_liquid_reservoir_name_for(node.name, newLiquidName)
|
||||
|
||||
if not minetest.registered_nodes[newNodeName] then return nil end
|
||||
local nodeDef = minetest.registered_nodes[newNodeName]
|
||||
if not nodeDef or not nodeDef.logistica then return nil end
|
||||
if nodeLiquidLevel == 1 then -- first bucket we added, swap to that reservoir type
|
||||
logistica.swap_node(pos, newNodeName)
|
||||
end
|
||||
local newLiquidDesc = minetest.registered_nodes[newNodeName].logistica.liquidDesc
|
||||
local newLiquidDesc = logistica.reservoir_get_description_of_liquid(nodeDef.logistica.liquidName)
|
||||
meta:set_string("infotext", logistica.reservoir_get_description(nodeLiquidLevel, maxBuckets, newLiquidDesc))
|
||||
meta:set_int(META_LIQUID_LEVEL, nodeLiquidLevel)
|
||||
return ItemStack(newEmptyBucket)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- returns the liquid name for the reservoir; or "" if there's no liquid stored, or nil if its not a reservoir
|
||||
function logistica.reservoir_get_liquid_name(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
if not logistica.is_reservoir(node.name) then return nil end
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
if not def or not def.logistica or not def.logistica.liquidName then return nil end
|
||||
return def.logistica.liquidName
|
||||
end
|
||||
|
||||
-- return {currentLevel, maxLevel} measured in buckets; or nil if its not a reservoir
|
||||
function logistica.reservoir_get_liquid_level(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
if not logistica.is_reservoir(node.name) then return nil end
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
if not def or not def.logistica or not def.logistica.maxBuckets then return nil end
|
||||
local meta = minetest.get_meta(pos)
|
||||
return { meta:get_int(META_LIQUID_LEVEL), def.logistica.maxBuckets }
|
||||
end
|
||||
|
||||
function logistica.reservoir_is_empty_bucket(bucketName)
|
||||
if bucketName == EMPTY_BUCKET then return true end
|
||||
for _, bucket in pairs(NAME_TO_EMPTY_BUCKET) do
|
||||
if bucket == bucketName then return true end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function logistica.reservoir_is_full_bucket(bucketName)
|
||||
if BUCKET_TO_NAME[bucketName] ~= nil then return true end
|
||||
return false
|
||||
end
|
||||
|
||||
-- returns true if the itemname is a known empty or filled bucket that can be used in a reservoir
|
||||
function logistica.reservoir_is_known_bucket(bucketName)
|
||||
return logistica.reservoir_is_empty_bucket(bucketName) or logistica.reservoir_is_full_bucket(bucketName)
|
||||
end
|
||||
|
||||
-- return the liquid name for the given bucket name, or nil if there's none registered
|
||||
function logistica.reservoir_get_liquid_name_for_bucket(bucketName)
|
||||
return BUCKET_TO_NAME[bucketName]
|
||||
end
|
Binary file not shown.
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.2 KiB |
Loading…
x
Reference in New Issue
Block a user