Add Access Point with working sort, filter, take, insert
@ -3,7 +3,6 @@ Missing Features:
|
||||
- Crafting recipes
|
||||
|
||||
High Priority:
|
||||
- Storage Upgrades
|
||||
- Wirelss Network Extender
|
||||
- Mesecons compat
|
||||
|
||||
@ -17,10 +16,11 @@ Medium Priority
|
||||
Low Priority:
|
||||
- Liquid Storage
|
||||
- Improve node sounds
|
||||
- Direct pipeworks compatibility
|
||||
- Direct tubelib compatibility
|
||||
|
||||
Maybe not needed, unless specific common usecase found to support:
|
||||
- Demander modes: AND/OR
|
||||
- Mode AND: supply target with "item 1 AND item 2..."
|
||||
- Mode OR: supply target with "item 1" OR (if not available) "item 2"
|
||||
- Direct pipeworks compatibility
|
||||
- Direct tubelib compatibility
|
||||
- API improvements: The API isn't much of an API in most cases, it barely allows customization. May be worth generifiying some of it sometime.
|
118
api/access_point.lua
Normal file
@ -0,0 +1,118 @@
|
||||
|
||||
local function after_place_access_point(pos, placer, itemstack, numSlots, numUpgradeSlots)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if placer and placer:is_player() then
|
||||
meta:set_string("owner", placer:get_player_name())
|
||||
end
|
||||
logistica.access_point_after_place(pos, meta)
|
||||
logistica.on_access_point_change(pos)
|
||||
end
|
||||
|
||||
local function allow_access_point_inv_put(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then return 0 end
|
||||
return logistica.access_point_allow_put(pos, listname, index, stack, player)
|
||||
end
|
||||
|
||||
local function allow_access_point_inv_take(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then return 0 end
|
||||
return logistica.access_point_allow_take(pos, listname, index, stack, player)
|
||||
end
|
||||
|
||||
local function allow_access_point_inv_move(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then return 0 end
|
||||
return logistica.access_point_allow_move(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
end
|
||||
|
||||
local function on_access_point_inv_move(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then return 0 end
|
||||
logistica.access_point_on_inv_move(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
end
|
||||
|
||||
local function on_access_point_inv_put(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then return 0 end
|
||||
logistica.access_point_on_put(pos, listname, index, stack, player)
|
||||
end
|
||||
|
||||
local function on_access_point_inv_take(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then return 0 end
|
||||
logistica.access_point_on_take(pos, listname, index, stack, player)
|
||||
end
|
||||
|
||||
local function on_access_point_rightclick(pos, node, clicker, itemstack, pointed_thing)
|
||||
if minetest.is_protected(pos, clicker:get_player_name()) then return 0 end
|
||||
logistica.access_point_on_rightclick(pos, node, clicker, itemstack, pointed_thing)
|
||||
end
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- registration calls
|
||||
----------------------------------------------------------------
|
||||
|
||||
minetest.register_on_leaveplayer(function(objRef, timed_out)
|
||||
if objRef:is_player() then
|
||||
logistica.access_point_on_player_close(objRef:get_player_name())
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_player_receive_fields(logistica.on_receive_access_point_formspec)
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- public api
|
||||
----------------------------------------------------------------
|
||||
|
||||
-- `simpleName` is used for the description and for the name (can contain spaces)
|
||||
function logistica.register_access_point(desc, name, tiles)
|
||||
local lname = string.lower(name:gsub(" ", "_"))
|
||||
local access_point_name = "logistica:access_point_"..lname
|
||||
logistica.misc_machines[access_point_name] = true
|
||||
local grps = {oddly_breakable_by_hand = 3, cracky = 3 }
|
||||
grps[logistica.TIER_ALL] = 1
|
||||
local def = {
|
||||
description = desc,
|
||||
drawtype = "normal",
|
||||
tiles = tiles,
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
groups = grps,
|
||||
drop = access_point_name,
|
||||
sounds = logistica.node_sound_metallic(),
|
||||
connect_sides = {"top", "bottom", "left", "back", "right" },
|
||||
after_place_node = after_place_access_point,
|
||||
after_destruct = logistica.on_access_point_change,
|
||||
on_rightclick = on_access_point_rightclick,
|
||||
on_metadata_inventory_move = on_access_point_inv_move,
|
||||
on_metadata_inventory_put = on_access_point_inv_put,
|
||||
on_metadata_inventory_take = on_access_point_inv_take,
|
||||
allow_metadata_inventory_put = allow_access_point_inv_put,
|
||||
allow_metadata_inventory_take = allow_access_point_inv_take,
|
||||
allow_metadata_inventory_move = allow_access_point_inv_move,
|
||||
logistica = {}
|
||||
}
|
||||
|
||||
minetest.register_node(access_point_name, 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(access_point_name.."_disabled", def_disabled)
|
||||
|
||||
end
|
||||
|
||||
logistica.register_access_point("Access Point", "base", {
|
||||
"logistica_access_point_top.png",
|
||||
"logistica_access_point_bottom.png",
|
||||
"logistica_access_point_side.png^[transformFX",
|
||||
"logistica_access_point_side.png",
|
||||
"logistica_access_point_back.png",
|
||||
"logistica_access_point_front.png",
|
||||
})
|
@ -7,3 +7,4 @@ dofile(path.."/supplier.lua")
|
||||
dofile(path.."/requester.lua")
|
||||
dofile(path.."/injector.lua")
|
||||
dofile(path.."/item_storage.lua")
|
||||
dofile(path.."/access_point.lua")
|
||||
|
@ -1,11 +1,12 @@
|
||||
local SET_BUTTON = "logsetbtn"
|
||||
local NAME_FIELD = "namef"
|
||||
local FORMSPEC_NAME = "logconren"
|
||||
local MAX_NETWORK_NAME_LENGTH = 20
|
||||
local controllerForms = {}
|
||||
|
||||
local function get_controller_formspec(pos)
|
||||
local name = logistica.get_network_name_or_nil(pos) or "<ERROR>"
|
||||
return "formspec_version[6]" ..
|
||||
return "formspec_version[4]" ..
|
||||
"size[10.5,2]" ..
|
||||
logistica.ui.background..
|
||||
"field[2.5,0.6;3,0.8;"..NAME_FIELD..";Network Name;"..name.."]" ..
|
||||
@ -28,6 +29,9 @@ local function on_controller_receive_fields(player, formname, fields)
|
||||
controllerForms[playerName] = nil
|
||||
elseif (fields[SET_BUTTON] or fields.key_enter_field) and fields[NAME_FIELD] then
|
||||
local newNetworkName = fields[NAME_FIELD]
|
||||
if #newNetworkName > MAX_NETWORK_NAME_LENGTH then
|
||||
newNetworkName = string.sub(newNetworkName, 1, MAX_NETWORK_NAME_LENGTH)
|
||||
end
|
||||
logistica.rename_network(minetest.hash_node_position(pos), newNetworkName)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", "Controller of Network: "..newNetworkName)
|
||||
|
@ -61,6 +61,7 @@ end
|
||||
|
||||
local function on_injector_rightclick(pos, node, clicker, itemstack, pointed_thing)
|
||||
if not clicker or not clicker:is_player() then return end
|
||||
if minetest.is_protected(pos, clicker:get_player_name()) then return end
|
||||
show_injector_formspec(clicker:get_player_name(), pos)
|
||||
end
|
||||
|
||||
|
@ -55,6 +55,7 @@ end
|
||||
|
||||
local function on_item_storage_rightclick(pos, _, clicker, _, _)
|
||||
if not clicker or not clicker:is_player() then return end
|
||||
if minetest.is_protected(pos, clicker:get_player_name()) then return 0 end
|
||||
show_item_storage_formspec(clicker:get_player_name(), pos)
|
||||
end
|
||||
|
||||
|
@ -272,12 +272,11 @@ end
|
||||
|
||||
|
||||
local function on_mass_storage_inv_move(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
if minetest.is_protected(pos, player) then return 0 end
|
||||
if minetest.is_protected(pos, player:get_player_name()) then return 0 end
|
||||
return 0
|
||||
end
|
||||
|
||||
local function on_mass_storage_inv_put(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player) then return 0 end
|
||||
if listname == "main" then
|
||||
local remaining = logistica.try_to_add_item_to_storage(pos, stack)
|
||||
local taken = stack:get_count() - remaining
|
||||
@ -298,7 +297,6 @@ local function on_mass_storage_inv_put(pos, listname, index, stack, player)
|
||||
end
|
||||
|
||||
local function on_mass_storage_inv_take(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player) then return 0 end
|
||||
if listname == "upgrade" then
|
||||
logistica.on_mass_storage_upgrade_change(pos, stack:get_name(), false)
|
||||
end
|
||||
@ -306,13 +304,14 @@ end
|
||||
|
||||
local function on_mass_storage_punch(pos, node, puncher, pointed_thing)
|
||||
if not puncher and not puncher:is_player() then return end
|
||||
if minetest.is_protected(pos, puncher) then return end
|
||||
if minetest.is_protected(pos, puncher:get_player_name()) then return end
|
||||
logistica.try_to_add_player_wield_item_to_mass_storage(pos, puncher)
|
||||
end
|
||||
|
||||
local function on_mass_storage_right_click(pos, node, clicker, itemstack, pointed_thing)
|
||||
local name = clicker:get_player_name()
|
||||
show_mass_storage_formspec(pos, name)
|
||||
if not clicker or not clicker:is_player() then return end
|
||||
if minetest.is_protected(pos, clicker:get_player_name()) then return end
|
||||
show_mass_storage_formspec(pos, clicker:get_player_name())
|
||||
end
|
||||
|
||||
local function on_mass_storage_rotate(pos, node, player, mode, newParam2)
|
||||
|
@ -59,6 +59,7 @@ end
|
||||
|
||||
local function on_requester_rightclick(pos, node, clicker, itemstack, pointed_thing)
|
||||
if not clicker or not clicker:is_player() then return end
|
||||
if minetest.is_protected(pos, clicker:get_player_name()) then return end
|
||||
show_requester_formspec(clicker:get_player_name(), pos)
|
||||
end
|
||||
|
||||
|
@ -42,6 +42,7 @@ end
|
||||
|
||||
local function on_supplier_rightclick(pos, node, clicker, itemstack, pointed_thing)
|
||||
if not clicker or not clicker:is_player() then return end
|
||||
if minetest.is_protected(pos, clicker:get_player_name()) then return end
|
||||
show_supplier_formspec(clicker:get_player_name(), pos)
|
||||
end
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
local path = logistica.MODPATH .. "/entity"
|
||||
|
||||
dofile(path .. "/io_entity.lua")
|
||||
dofile(path .. "/display_item.lua")
|
||||
dofile(path.."/io_entity.lua")
|
||||
dofile(path.."/display_item.lua")
|
@ -1,4 +1,4 @@
|
||||
local path = logistica.MODPATH .. "/item"
|
||||
logistica.craftitem = {}
|
||||
|
||||
dofile(path .. "/storage_upgrade.lua")
|
||||
dofile(path.."/storage_upgrade.lua")
|
||||
|
208
logic/access_point.lua
Normal file
@ -0,0 +1,208 @@
|
||||
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 fakeInvMap = {}
|
||||
|
||||
local SORT_NAME = 1
|
||||
local SORT_MOD = 2
|
||||
local SORT_COUNT = 3
|
||||
local SORT_WEAR = 4
|
||||
local sortMethodMap = {
|
||||
[SORT_NAME] = function(list) return logistica.sort_list_by(list, LOG_SORT_NAME_AZ) end,
|
||||
[SORT_MOD] = function(list) return logistica.sort_list_by(list, LOG_SORT_MOD_AZ) end,
|
||||
[SORT_COUNT] = function(list) return logistica.sort_list_by(list, LOG_SORT_STACK_SIZE_REV) end,
|
||||
[SORT_WEAR] = function(list) return logistica.sort_list_by(list, LOG_SORT_DURABILITY_FWD) end,
|
||||
}
|
||||
|
||||
local FILTER_ALL = 1
|
||||
local FILTER_NODES = 2
|
||||
local FILTER_ITEMS = 3
|
||||
local FILTER_TOOLS = 4
|
||||
local FILTER_LIGHTS = 5
|
||||
|
||||
local filterMethodMap = {
|
||||
[FILTER_ALL] = function(list) return list end,
|
||||
[FILTER_NODES] = function(list) return logistica.filter_list_by(list, LOG_FILTER_NODE) end,
|
||||
[FILTER_ITEMS] = function(list) return logistica.filter_list_by(list, LOG_FILTER_CRAFTITEM) end,
|
||||
[FILTER_TOOLS] = function(list) return logistica.filter_list_by(list, LOG_FILTER_TOOL) end,
|
||||
[FILTER_LIGHTS] = function(list) return logistica.filter_list_by(list, LOG_FILTER_LIGHT) end,
|
||||
}
|
||||
|
||||
local h2p = minetest.get_position_from_hash
|
||||
local pth = minetest.hash_node_position
|
||||
local get_meta = minetest.get_meta
|
||||
|
||||
local function get_curr_sort_method_int(meta)
|
||||
local curr = meta:get_int(META_SORT_TYPE)
|
||||
if curr <= 0 or curr >= 5 then return 1 else return curr end
|
||||
end
|
||||
|
||||
local function set_curr_sort_method_int(meta, methodIndex)
|
||||
meta:set_int(META_SORT_TYPE, methodIndex)
|
||||
end
|
||||
|
||||
local function get_curr_filter_method_int(meta)
|
||||
local curr = meta:get_int(META_FILTER_TYPE)
|
||||
if curr <= 0 or curr >= 6 then return 1 else return curr end
|
||||
end
|
||||
|
||||
local function set_curr_filter_method_int(meta, methodIndex)
|
||||
meta:set_int(META_FILTER_TYPE, methodIndex)
|
||||
end
|
||||
|
||||
local function add_list_to_itemmap(itemMap, list, useMetadata)
|
||||
for _, stack in ipairs(list) do
|
||||
if not stack:is_empty() then
|
||||
local stackName = stack:get_name()
|
||||
if useMetadata then stackName = stack:to_string() end
|
||||
if itemMap[stackName] == nil then itemMap[stackName] = 0 end
|
||||
itemMap[stackName] = itemMap[stackName] + stack:get_count()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function build_stack_list(pos)
|
||||
local network = logistica.get_network_or_nil(pos)
|
||||
if not network then return {stackList = {}, stackListSize = 0} end
|
||||
local useMetadata = logistica.access_point_is_set_to_use_metadata(pos)
|
||||
local meta = get_meta(pos)
|
||||
|
||||
local itemMap = {}
|
||||
-- we scan all supply chests and mass storage and item storage
|
||||
for hash, _ in pairs(network.suppliers) do
|
||||
local mPos = logistica.load_position(h2p(hash))
|
||||
local list = get_meta(mPos):get_inventory():get_list("main") or {}
|
||||
add_list_to_itemmap(itemMap, list, useMetadata)
|
||||
end
|
||||
for hash, _ in pairs(network.mass_storage) do
|
||||
local mPos = logistica.load_position(h2p(hash))
|
||||
local list = get_meta(mPos):get_inventory():get_list("storage") or {}
|
||||
add_list_to_itemmap(itemMap, list, useMetadata)
|
||||
end
|
||||
for hash, _ in pairs(network.item_storage) do
|
||||
local mPos = logistica.load_position(h2p(hash))
|
||||
local list = get_meta(mPos):get_inventory():get_list("main") or {}
|
||||
add_list_to_itemmap(itemMap, list, useMetadata)
|
||||
end
|
||||
local itemList = {}
|
||||
local listSize = 0
|
||||
for item, count in pairs(itemMap) do
|
||||
local stack = ItemStack(item)
|
||||
stack:set_count(count)
|
||||
listSize = listSize + 1
|
||||
itemList[listSize] = stack
|
||||
end
|
||||
local filtered = filterMethodMap[get_curr_filter_method_int(meta)](itemList)
|
||||
local sorted = sortMethodMap[get_curr_sort_method_int(meta)](filtered)
|
||||
return {
|
||||
stackList = sorted,
|
||||
stackListSize = listSize,
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
--------------------------------
|
||||
-- public functions
|
||||
--------------------------------
|
||||
|
||||
function logistica.access_point_on_player_close(playerName)
|
||||
fakeInvMap[playerName] = nil
|
||||
end
|
||||
|
||||
function logistica.update_fake_inv(pos, listName, listSize, playerName)
|
||||
local meta = get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local pageInfo = logistica.access_point_get_current_page_info(pos, playerName, listSize, meta)
|
||||
if pageInfo.max == 0 then inv:set_list(listName, {}) ; return end
|
||||
local startingPos = (pageInfo.curr - 1) * listSize + 1
|
||||
local fullList = fakeInvMap[playerName].stackList
|
||||
if not fullList then return end
|
||||
local fakeInvList = {}
|
||||
for i = startingPos, startingPos + listSize do
|
||||
fakeInvList[i - startingPos + 1] = fullList[i] or ItemStack("")
|
||||
end
|
||||
inv:set_list(listName, fakeInvList)
|
||||
end
|
||||
|
||||
-- returns a table representing pages: {curr = #, max = #}
|
||||
function logistica.access_point_get_current_page_info(pos, playerName, listSize, optMeta)
|
||||
if not fakeInvMap[playerName] then return {curr = 0, max = 0} end
|
||||
local meta = optMeta or get_meta(pos)
|
||||
local storedPage = meta:get_int(META_CURR_PAGE)
|
||||
if storedPage <= 0 then storedPage = 1 end
|
||||
local fakeInv = fakeInvMap[playerName]
|
||||
local maxPages = math.ceil(fakeInv.stackListSize / listSize)
|
||||
if storedPage > maxPages then
|
||||
storedPage = maxPages
|
||||
meta:set_int(META_CURR_PAGE, storedPage)
|
||||
end
|
||||
return {curr = storedPage, max = maxPages}
|
||||
end
|
||||
|
||||
function logistica.access_point_is_set_to_use_metadata(pos)
|
||||
local meta = get_meta(pos)
|
||||
return meta:get_int(META_IGNORE_METADATA) == 0
|
||||
end
|
||||
|
||||
-- toggles whether to use metadata and returns the new state
|
||||
function logistica.access_point_toggle_use_metadata(pos)
|
||||
local meta = get_meta(pos)
|
||||
local curr = meta:get_int(META_IGNORE_METADATA)
|
||||
local new = (curr + 1) % 2
|
||||
meta:set_int(META_IGNORE_METADATA, new)
|
||||
return new == 0
|
||||
end
|
||||
|
||||
-- returns true if page was changed, false if it wasn't
|
||||
function logistica.access_point_change_page(pos, op, playerName, listSize)
|
||||
local meta = get_meta(pos)
|
||||
local currInfo = logistica.access_point_get_current_page_info(pos, playerName, listSize, meta)
|
||||
if currInfo.max == 0 then return false end
|
||||
local newPage = currInfo.curr
|
||||
if op == 1 then newPage = newPage + 1
|
||||
elseif op > 1 then newPage = currInfo.max
|
||||
elseif op == -1 then newPage = newPage - 1
|
||||
elseif op < -1 then newPage = 1 end
|
||||
newPage = logistica.clamp(newPage, 1, currInfo.max)
|
||||
if currInfo.curr == newPage then return false end
|
||||
meta:set_int(META_CURR_PAGE, newPage)
|
||||
return true
|
||||
end
|
||||
|
||||
function logistica.access_point_get_filter_highlight_images(meta, highlightImg, blankImg)
|
||||
local method = get_curr_filter_method_int(meta)
|
||||
return {
|
||||
all = (method == FILTER_ALL and highlightImg) or blankImg,
|
||||
node = (method == FILTER_NODES and highlightImg) or blankImg,
|
||||
craftitem = (method == FILTER_ITEMS and highlightImg) or blankImg,
|
||||
tools = (method == FILTER_TOOLS and highlightImg) or blankImg,
|
||||
lights = (method == FILTER_LIGHTS and highlightImg) or blankImg,
|
||||
}
|
||||
end
|
||||
|
||||
function logistica.access_point_get_sort_highlight_images(meta, highlightImg, blankImg)
|
||||
local method = get_curr_sort_method_int(meta)
|
||||
return {
|
||||
name = (method == SORT_NAME and highlightImg) or blankImg,
|
||||
mod = (method == SORT_MOD and highlightImg) or blankImg,
|
||||
count = (method == SORT_COUNT and highlightImg) or blankImg,
|
||||
wear = (method == SORT_WEAR and highlightImg) or blankImg,
|
||||
}
|
||||
end
|
||||
|
||||
function logistica.access_point_refresh_fake_inv(pos, listName, listSize, playerName)
|
||||
local listInfo = build_stack_list(pos)
|
||||
fakeInvMap[playerName] = listInfo
|
||||
logistica.update_fake_inv(pos, listName, listSize, playerName)
|
||||
end
|
||||
|
||||
function logistica.access_point_set_filter_method(pos, playerName, method)
|
||||
set_curr_filter_method_int(get_meta(pos), method)
|
||||
end
|
||||
|
||||
function logistica.access_point_set_sort_method(pos, playerName, method)
|
||||
set_curr_sort_method_int(get_meta(pos), method)
|
||||
end
|
239
logic/access_point_formspec.lua
Normal file
@ -0,0 +1,239 @@
|
||||
local S = logistica.TRANSLATOR
|
||||
|
||||
local FORMSPEC_NAME = "accesspoint_formspec"
|
||||
-- local LOCK_BTN = "on_off"
|
||||
local NEXT_BTN = "next"
|
||||
local PREV_BTN = "prev"
|
||||
local FRST_BTN = "frst"
|
||||
local LAST_BTN = "last"
|
||||
local SEARCH_BTN = "search"
|
||||
local CLEAR_BTN = "clear"
|
||||
local FILTER_ALL_BTN = "filter_all"
|
||||
local FILTER_NODES_BTN = "filter_blk"
|
||||
local FILTER_CRFTITM_BTN = "filter_cft"
|
||||
local FILTER_TOOLS_BTN = "filter_tol"
|
||||
local FILTER_LIGHTS_BTN = "filter_lig"
|
||||
local SORT_NAME_BTN = "sort_name"
|
||||
local SORT_MOD_BTN = "sort_mod"
|
||||
local SORT_COUNT_BTN = "sort_cnt"
|
||||
local SORT_WEAR_BTN = "sort_wer"
|
||||
local SEARCH_FIELD = "srch_fld"
|
||||
local USE_META_BTN = "tgl_meta"
|
||||
|
||||
local INV_FAKE = "fake"
|
||||
local INV_CRAFT = "craft"
|
||||
local INV_CRAFT_OUTPUT = "output"
|
||||
local INV_INSERT = "isert"
|
||||
local FAKE_INV_W = 12
|
||||
local FAKE_INV_H = 4
|
||||
local FAKE_INV_SIZE = FAKE_INV_W * FAKE_INV_H
|
||||
|
||||
local IMG_HIGHLGIHT = "logistica_icon_highlight.png"
|
||||
local IMG_BLANK = "logistica_blank.png"
|
||||
local IMG_SORT_NAME = "logistica_icon_sort_name_az.png"
|
||||
local IMG_SORT_MOD = "logistica_icon_sort_mod_az.png"
|
||||
local IMG_SORT_COUNT = "logistica_icon_sort_count_99_1.png"
|
||||
local IMG_SORT_WEAR = "logistica_icon_sort_wear_0_100.png"
|
||||
local IMG_FILT_ALL = "logistica_icon_all.png"
|
||||
local IMG_FILT_NODE = "logistica_icon_node.png"
|
||||
local IMG_FILT_ITEM = "logistica_icon_craftitem.png"
|
||||
local IMG_FILT_TOOL = "logistica_icon_tool.png"
|
||||
local IMG_FILT_LIGHT = "logistica_icon_torch.png"
|
||||
|
||||
local ACCESS_POINT_TIMER = 1
|
||||
|
||||
local accessPointForms = {}
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- formspec
|
||||
----------------------------------------------------------------
|
||||
|
||||
local function get_access_point_formspec(pos, optMeta, playerName)
|
||||
local posForm = "nodemeta:"..pos.x..","..pos.y..","..pos.z
|
||||
local meta = optMeta or minetest.get_meta(pos)
|
||||
local currentNetwork = logistica.get_network_name_or_nil(pos) or S("<NONE>")
|
||||
local filterHighImg = logistica.access_point_get_filter_highlight_images(meta, IMG_HIGHLGIHT, IMG_BLANK)
|
||||
local sortHighImg = logistica.access_point_get_sort_highlight_images(meta, IMG_HIGHLGIHT, IMG_BLANK)
|
||||
local pageInfo = logistica.access_point_get_current_page_info(pos, playerName, FAKE_INV_SIZE, meta)
|
||||
local usesMetadata = logistica.access_point_is_set_to_use_metadata(pos)
|
||||
local usesMetaStr = usesMetadata and S("Metadata: ON") or S("Metadata: OFF")
|
||||
return "formspec_version[4]"..
|
||||
"size[15.2,12.5]"..
|
||||
logistica.ui.background..
|
||||
"list["..posForm..";"..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["..posForm..";"..INV_INSERT..";3.8,6.4;1,1;0]"..
|
||||
"list[current_player;main;5.2,7.5;8.0,4.0;0]"..
|
||||
"listring[]"..
|
||||
"label[1.4,12.2;"..S("Crafting").."]"..
|
||||
"list["..posForm..";"..INV_CRAFT..";0.2,8.4;3,3;0]"..
|
||||
"list["..posForm..";"..INV_CRAFT_OUTPUT..";3.9,8.4;1,1;0]"..
|
||||
"button[1.4,5.2;2.6,0.6;"..USE_META_BTN..";"..usesMetaStr.."]"..
|
||||
"label[4.3,5.5;"..S("Filter").."]"..
|
||||
"image[5.1,5;1,1;"..filterHighImg.all.."]"..
|
||||
"image[6.0,5;1,1;"..filterHighImg.node.."]"..
|
||||
"image[6.9,5;1,1;"..filterHighImg.craftitem.."]"..
|
||||
"image[7.8,5;1,1;"..filterHighImg.tools.."]"..
|
||||
"image[8.7,5;1,1;"..filterHighImg.lights.."]"..
|
||||
"image_button[5.2,5.1;0.8,0.8;"..IMG_FILT_ALL..";"..FILTER_ALL_BTN..";;false;false;]"..
|
||||
"image_button[6.1,5.1;0.8,0.8;"..IMG_FILT_NODE..";"..FILTER_NODES_BTN..";;false;false;]"..
|
||||
"image_button[7.0,5.1;0.8,0.8;"..IMG_FILT_ITEM..";"..FILTER_CRFTITM_BTN..";;false;false;]"..
|
||||
"image_button[7.9,5.1;0.8,0.8;"..IMG_FILT_TOOL..";"..FILTER_TOOLS_BTN..";;false;false;]"..
|
||||
"image_button[8.8,5.1;0.8,0.8;"..IMG_FILT_LIGHT..";"..FILTER_LIGHTS_BTN..";;false;false;]"..
|
||||
"label[10.5,5.5;"..S("Sort").."]"..
|
||||
"image[11.0,5;1,1;"..sortHighImg.name.."]"..
|
||||
"image[11.9,5;1,1;"..sortHighImg.mod.."]"..
|
||||
"image[12.8,5;1,1;"..sortHighImg.count.."]"..
|
||||
"image[13.7,5;1,1;"..sortHighImg.wear.."]"..
|
||||
"image_button[11.1,5.1;0.8,0.8;"..IMG_SORT_NAME..";"..SORT_NAME_BTN..";;false;false;]"..
|
||||
"image_button[12.0,5.1;0.8,0.8;"..IMG_SORT_MOD..";"..SORT_MOD_BTN..";;false;false;]"..
|
||||
"image_button[12.9,5.1;0.8,0.8;"..IMG_SORT_COUNT..";"..SORT_COUNT_BTN..";;false;false;]"..
|
||||
"image_button[13.8,5.1;0.8,0.8;"..IMG_SORT_WEAR..";"..SORT_WEAR_BTN..";;false;false;]"..
|
||||
"label[5.3,6.3;"..S("Network: ")..currentNetwork.."]"..
|
||||
"field[5.2,6.5;2.8,0.8;"..SEARCH_FIELD..";;]"..
|
||||
"image_button[8.1,6.5;0.8,0.8;logistica_icon_search.png;"..SEARCH_BTN..";;false;false;]"..
|
||||
"image_button[9.2,6.5;0.8,0.8;logistica_icon_cancel.png;"..CLEAR_BTN..";;false;false;]"..
|
||||
"label[12.0,6.3;"..S("Page")..": "..pageInfo.curr.." / "..pageInfo.max.."]"..
|
||||
"image_button[10.6,6.5;0.8,0.8;logistica_icon_first.png;"..FRST_BTN..";;false;false;]"..
|
||||
"image_button[11.7,6.5;0.8,0.8;logistica_icon_prev.png;"..PREV_BTN..";;false;false;]"..
|
||||
"image_button[12.8,6.5;0.8,0.8;logistica_icon_next.png;"..NEXT_BTN..";;false;false;]"..
|
||||
"image_button[13.9,6.5;0.8,0.8;logistica_icon_last.png;"..LAST_BTN..";;false;false;]"
|
||||
-- TODO tooltips
|
||||
end
|
||||
|
||||
local function show_access_point_formspec(pos, playerName, optMeta)
|
||||
local meta = optMeta or minetest.get_meta(pos)
|
||||
accessPointForms[playerName] = { position = pos }
|
||||
logistica.access_point_refresh_fake_inv(pos, INV_FAKE, FAKE_INV_SIZE, playerName)
|
||||
minetest.show_formspec(
|
||||
playerName,
|
||||
FORMSPEC_NAME,
|
||||
get_access_point_formspec(pos, meta, playerName)
|
||||
)
|
||||
end
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- callbacks
|
||||
----------------------------------------------------------------
|
||||
|
||||
function logistica.on_receive_access_point_formspec(player, formname, fields)
|
||||
if formname ~= FORMSPEC_NAME then return end
|
||||
local playerName = player:get_player_name()
|
||||
if not accessPointForms[playerName] then return true end
|
||||
local pos = accessPointForms[playerName].position
|
||||
if minetest.is_protected(pos, playerName) or not pos then return true end
|
||||
|
||||
if fields.quit and not fields.key_enter_field then
|
||||
accessPointForms[playerName] = nil
|
||||
logistica.access_point_on_player_close(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
|
||||
elseif fields[PREV_BTN] then
|
||||
if not logistica.access_point_change_page(pos, -1, playerName, FAKE_INV_SIZE) then return true end
|
||||
elseif fields[NEXT_BTN] then
|
||||
if not logistica.access_point_change_page(pos, 1, playerName, FAKE_INV_SIZE) then return true end
|
||||
elseif fields[LAST_BTN] then
|
||||
if not logistica.access_point_change_page(pos, 2, playerName, FAKE_INV_SIZE) then return true end
|
||||
elseif fields[USE_META_BTN] then
|
||||
logistica.access_point_toggle_use_metadata(pos)
|
||||
elseif fields[FILTER_ALL_BTN] then
|
||||
logistica.access_point_set_filter_method(pos, playerName, 1)
|
||||
elseif fields[FILTER_NODES_BTN] then
|
||||
logistica.access_point_set_filter_method(pos, playerName, 2)
|
||||
elseif fields[FILTER_CRFTITM_BTN] then
|
||||
logistica.access_point_set_filter_method(pos, playerName, 3)
|
||||
elseif fields[FILTER_TOOLS_BTN] then
|
||||
logistica.access_point_set_filter_method(pos, playerName, 4)
|
||||
elseif fields[FILTER_LIGHTS_BTN] then
|
||||
logistica.access_point_set_filter_method(pos, playerName, 5)
|
||||
elseif fields[SORT_NAME_BTN] then
|
||||
logistica.access_point_set_sort_method(pos, playerName, 1)
|
||||
elseif fields[SORT_MOD_BTN] then
|
||||
logistica.access_point_set_sort_method(pos, playerName, 2)
|
||||
elseif fields[SORT_COUNT_BTN] then
|
||||
logistica.access_point_set_sort_method(pos, playerName, 3)
|
||||
elseif fields[SORT_WEAR_BTN] then
|
||||
logistica.access_point_set_sort_method(pos, playerName, 4)
|
||||
end
|
||||
show_access_point_formspec(pos, playerName)
|
||||
return true
|
||||
end
|
||||
|
||||
function logistica.access_point_after_place(pos, meta)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size(INV_FAKE, FAKE_INV_SIZE)
|
||||
inv:set_size(INV_CRAFT, 9)
|
||||
inv:set_width(INV_CRAFT, 3)
|
||||
inv:set_size(INV_CRAFT_OUTPUT, 1)
|
||||
inv:set_size(INV_INSERT, 1)
|
||||
end
|
||||
|
||||
function logistica.access_point_allow_put(pos, listname, index, stack, player)
|
||||
if listname == INV_FAKE or listname == INV_CRAFT_OUTPUT then return 0 end
|
||||
return stack:get_count()
|
||||
end
|
||||
|
||||
function logistica.access_point_allow_take(pos, listname, index, _stack, player)
|
||||
local stack = ItemStack(_stack)
|
||||
if listname == INV_FAKE then
|
||||
local network = logistica.get_network_or_nil(pos)
|
||||
if not network then
|
||||
show_access_point_formspec(pos, player:get_player_name())
|
||||
return 0
|
||||
end
|
||||
-- either way, only allow taking up to stack max
|
||||
stack:set_count(math.min(stack:get_count(), stack:get_stack_max()))
|
||||
if stack:get_stack_max() > 1 then
|
||||
local taken = nil
|
||||
local acceptTaken = function(st) taken = st; return 0 end
|
||||
logistica.take_stack_from_network(stack, network, acceptTaken)
|
||||
if not taken or taken:is_empty() then return 0 end
|
||||
return math.min(taken:get_count(), stack:get_stack_max())
|
||||
else -- individual items are trickier
|
||||
-- we want to take the actual item, so place it in the slot before its taken
|
||||
local useMetadata = logistica.access_point_is_set_to_use_metadata(pos)
|
||||
local taken = nil
|
||||
local acceptTaken = function(st) taken = st; return 0 end
|
||||
logistica.take_stack_from_network(stack, network, acceptTaken, false, useMetadata)
|
||||
if not taken or taken:is_empty() then return 0 end
|
||||
local inv = minetest.get_meta(pos):get_inventory()
|
||||
inv:set_stack(listname, index, taken)
|
||||
return taken:get_count()
|
||||
end
|
||||
end
|
||||
return stack:get_count()
|
||||
end
|
||||
|
||||
function logistica.access_point_allow_move(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
if from_list == INV_FAKE or to_list == INV_FAKE or to_list == INV_CRAFT_OUTPUT then return 0 end
|
||||
return count
|
||||
end
|
||||
|
||||
function logistica.access_point_on_inv_move(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
|
||||
end
|
||||
|
||||
function logistica.access_point_on_put(pos, listname, index, stack, player)
|
||||
local networkId = logistica.get_network_id_or_nil(pos)
|
||||
if not networkId then show_access_point_formspec(pos, player:get_player_name()) ; return end
|
||||
if listname == INV_INSERT then
|
||||
local leftover = logistica.insert_item_in_network(stack, networkId)
|
||||
stack:set_count(leftover)
|
||||
minetest.get_meta(pos):get_inventory():set_stack(listname, index, stack)
|
||||
show_access_point_formspec(pos, player:get_player_name())
|
||||
end
|
||||
end
|
||||
|
||||
function logistica.access_point_on_take(pos, listname, index, stack, player)
|
||||
if listname == INV_FAKE then
|
||||
-- refresh the page in case we had to swap out a fake item or a stack is gone
|
||||
logistica.access_point_refresh_fake_inv(pos, listname, FAKE_INV_SIZE, player:get_player_name())
|
||||
end
|
||||
end
|
||||
|
||||
function logistica.access_point_on_rightclick(pos, node, clicker, itemstack, pointed_thing)
|
||||
show_access_point_formspec(pos, clicker:get_player_name())
|
||||
end
|
@ -1,13 +1,15 @@
|
||||
local path = logistica.MODPATH .. "/logic"
|
||||
-- once again, order is important
|
||||
dofile(path .. "/processing_queue.lua")
|
||||
dofile(path .. "/groups.lua")
|
||||
dofile(path .. "/network_cache.lua")
|
||||
dofile(path .. "/network_logic.lua")
|
||||
dofile(path .. "/network_storage.lua")
|
||||
dofile(path .. "/controller.lua")
|
||||
dofile(path .. "/mass_storage.lua")
|
||||
dofile(path .. "/supplier.lua")
|
||||
dofile(path .. "/requester.lua")
|
||||
dofile(path .. "/injector.lua")
|
||||
dofile(path .. "/item_storage.lua")
|
||||
dofile(path.."/processing_queue.lua")
|
||||
dofile(path.."/groups.lua")
|
||||
dofile(path.."/network_cache.lua")
|
||||
dofile(path.."/network_logic.lua")
|
||||
dofile(path.."/network_storage.lua")
|
||||
dofile(path.."/controller.lua")
|
||||
dofile(path.."/mass_storage.lua")
|
||||
dofile(path.."/supplier.lua")
|
||||
dofile(path.."/requester.lua")
|
||||
dofile(path.."/injector.lua")
|
||||
dofile(path.."/item_storage.lua")
|
||||
dofile(path.."/access_point.lua")
|
||||
dofile(path.."/access_point_formspec.lua")
|
||||
|
@ -1,5 +1,5 @@
|
||||
local networks = {}
|
||||
local HARD_NETWORK_NODE_LIMIT = 1000 -- A network cannot consist of more than this many nodes
|
||||
local HARD_NETWORK_NODE_LIMIT = 4000 -- A network cannot consist of more than this many nodes
|
||||
local STATUS_OK = 0
|
||||
local CREATE_NETWORK_STATUS_FAIL_OTHER_NETWORK = -1
|
||||
local CREATE_NETWORK_STATUS_TOO_MANY_NODES = -2
|
||||
@ -10,12 +10,8 @@ local p2h = minetest.hash_node_position
|
||||
local h2p = minetest.get_position_from_hash
|
||||
|
||||
local adjecent = {
|
||||
vector.new( 1, 0, 0),
|
||||
vector.new( 0, 1, 0),
|
||||
vector.new( 0, 0, 1),
|
||||
vector.new(-1, 0, 0),
|
||||
vector.new( 0, -1, 0),
|
||||
vector.new( 0, 0, -1),
|
||||
vector.new( 1, 0, 0), vector.new( 0, 1, 0), vector.new( 0, 0, 1),
|
||||
vector.new(-1, 0, 0), vector.new( 0, -1, 0), vector.new( 0, 0, -1),
|
||||
}
|
||||
|
||||
local function has_machine(network, id)
|
||||
@ -25,6 +21,7 @@ local function has_machine(network, id)
|
||||
or network.mass_storage[id]
|
||||
or network.item_storage[id]
|
||||
or network.injectors[id]
|
||||
or network.misc[id]
|
||||
then
|
||||
return true
|
||||
else
|
||||
@ -192,10 +189,10 @@ local function create_network(controllerPosition, oldNetworkName)
|
||||
network.suppliers = {}
|
||||
network.mass_storage = {}
|
||||
network.item_storage = {}
|
||||
network.misc = {}
|
||||
network.storage_cache = {}
|
||||
network.supplier_cache = {}
|
||||
network.requester_cache = {}
|
||||
network.misc = {}
|
||||
local startPos = {}
|
||||
startPos[controllerHash] = true
|
||||
local status = recursive_scan_for_nodes_for_controller(network, startPos)
|
||||
@ -280,6 +277,15 @@ local function remove_from_network(pos, ops)
|
||||
ops.get_list(network)[hash] = nil
|
||||
end
|
||||
|
||||
local function on_node_change(pos, oldNode, ops)
|
||||
local placed = (oldNode == nil) -- if oldNode is nil, we placed a new one
|
||||
if placed == true then
|
||||
try_to_add_to_network(pos, ops)
|
||||
else
|
||||
remove_from_network(pos, ops)
|
||||
end
|
||||
end
|
||||
|
||||
local MASS_STORAGE_OPS = {
|
||||
get_list = function(network) return network.mass_storage end,
|
||||
update_cache_node_added = function(pos) logistica.update_cache_at_pos(pos, LOG_CACHE_MASS_STORAGE) end,
|
||||
@ -304,13 +310,18 @@ local INJECTOR_OPS = {
|
||||
update_cache_node_removed = function(_) end,
|
||||
}
|
||||
|
||||
|
||||
local ITEM_STORAGE_OPS = {
|
||||
get_list = function(network) return network.item_storage end,
|
||||
update_cache_node_added = function(_) end,
|
||||
update_cache_node_removed = function(_) end,
|
||||
}
|
||||
|
||||
local ACCESS_POINT_OPS = {
|
||||
get_list = function(network) return network.misc 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
|
||||
@ -379,46 +390,25 @@ function logistica.on_controller_change(pos, oldNode)
|
||||
end
|
||||
|
||||
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_to_network(pos, MASS_STORAGE_OPS)
|
||||
else
|
||||
remove_from_network(pos, MASS_STORAGE_OPS)
|
||||
end
|
||||
on_node_change(pos, oldNode, MASS_STORAGE_OPS)
|
||||
end
|
||||
|
||||
function logistica.on_requester_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, REQUESTER_OPS)
|
||||
else
|
||||
remove_from_network(pos, REQUESTER_OPS)
|
||||
end
|
||||
on_node_change(pos, oldNode, REQUESTER_OPS)
|
||||
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_to_network(pos, SUPPLIER_OPS)
|
||||
else
|
||||
remove_from_network(pos, SUPPLIER_OPS)
|
||||
end
|
||||
on_node_change(pos, oldNode, SUPPLIER_OPS)
|
||||
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
|
||||
on_node_change(pos, oldNode, INJECTOR_OPS)
|
||||
end
|
||||
|
||||
function logistica.on_item_storage_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, ITEM_STORAGE_OPS)
|
||||
else
|
||||
remove_from_network(pos, ITEM_STORAGE_OPS)
|
||||
end
|
||||
on_node_change(pos, oldNode, ITEM_STORAGE_OPS)
|
||||
end
|
||||
|
||||
function logistica.on_access_point_change(pos, oldNode)
|
||||
on_node_change(pos, oldNode, ACCESS_POINT_OPS)
|
||||
end
|
||||
|
@ -18,15 +18,17 @@ end
|
||||
-- calls the collectorFunc with the stack - collectorFunc needs to return how many were left-over<br>
|
||||
-- `collectorFunc = function(stackToInsert)`<br>
|
||||
-- note that it may be called multiple times as the itemstack is gathered from mass storage
|
||||
function logistica.take_stack_from_network(stackToTake, network, collectorFunc, isAutomatedRequest)
|
||||
-- `isAutomatedRequest` is optional, assumed to be false if not set
|
||||
-- `useMetaData` is optional, assume false if not set - only applies to items with stack_max = 1
|
||||
function logistica.take_stack_from_network(stackToTake, network, collectorFunc, isAutomatedRequest, useMetadata)
|
||||
if not network then return false end
|
||||
-- first check suppliers
|
||||
if logistica.take_stack_from_suppliers(stackToTake, network, collectorFunc, isAutomatedRequest) then
|
||||
if logistica.take_stack_from_suppliers(stackToTake, network, collectorFunc, isAutomatedRequest, useMetadata) then
|
||||
return
|
||||
end
|
||||
-- then check storages
|
||||
if stackToTake:get_stack_max() <= 1 then
|
||||
logistica.take_stack_from_item_storage(stackToTake, network, collectorFunc, isAutomatedRequest)
|
||||
logistica.take_stack_from_item_storage(stackToTake, network, collectorFunc, isAutomatedRequest, useMetadata)
|
||||
else
|
||||
logistica.take_stack_from_mass_storage(stackToTake, network, collectorFunc, isAutomatedRequest)
|
||||
end
|
||||
@ -35,7 +37,9 @@ end
|
||||
-- tries to take the given stack from the passive suppliers on the network
|
||||
-- calls the collectorFunc with the stack when necessary
|
||||
-- note that it may be called multiple times as the itemstack is gathered from mass storage
|
||||
function logistica.take_stack_from_suppliers(stackToTake, network, collectorFunc, isAutomatedRequest)
|
||||
function logistica.take_stack_from_suppliers(stackToTake, network, collectorFunc, isAutomatedRequest, useMetadata)
|
||||
local eq = function(s1, s2) return s1:get_name() == s2:get_name() end
|
||||
if stackToTake:get_stack_max() == 1 and useMetadata then eq = function(s1, s2) return s1:equals(s2) end end
|
||||
local requestedAmount = stackToTake:get_count()
|
||||
local remaining = requestedAmount
|
||||
local stackName = stackToTake:get_name()
|
||||
@ -46,7 +50,7 @@ function logistica.take_stack_from_suppliers(stackToTake, network, collectorFunc
|
||||
local supplierInv = get_meta(supplierPos):get_inventory()
|
||||
local supplyList = supplierInv:get_list(SUPPLIER_LIST_NAME)
|
||||
for i, supplyStack in ipairs(supplyList) do
|
||||
if supplyStack:get_name() == stackName then
|
||||
if eq(supplyStack, stackToTake) then
|
||||
table.insert(modifiedPos, supplierPos)
|
||||
local supplyCount = supplyStack:get_count()
|
||||
if supplyCount >= remaining then -- enough to fulfil requested
|
||||
@ -82,15 +86,17 @@ end
|
||||
-- calls the collectorFunc with the stack - collectorFunc needs to return how many were left-over<br>
|
||||
-- `collectorFunc = function(stackToInsert)`<br>
|
||||
-- returns true if item successfully found and given to collector, false otherwise
|
||||
function logistica.take_stack_from_item_storage(stack, network, collectorFunc, isAutomatedRequest)
|
||||
local stackName = stack:get_name()
|
||||
function logistica.take_stack_from_item_storage(stack, network, collectorFunc, isAutomatedRequest, useMetadata)
|
||||
local eq = function(s1, s2) return s1:get_name() == s2:get_name() end
|
||||
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 storageInv = get_meta(storagePos):get_inventory()
|
||||
if logistica.is_machine_on(storagePos) then
|
||||
local storageList = storageInv:get_list(ITEM_STORAGE_LIST_NAME) or {}
|
||||
for i, storedStack in ipairs(storageList) do
|
||||
if storedStack:get_name() == stackName then
|
||||
if (not storedStack:is_empty()) and eq(storedStack, stack) then
|
||||
local leftover = collectorFunc(storedStack)
|
||||
if leftover == 0 then -- stack max is 1, so just take the whole itemstack out
|
||||
storageList[i] = ItemStack("")
|
||||
|
BIN
textures/logistica_access_point_back.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
textures/logistica_access_point_bottom.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
textures/logistica_access_point_front.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
textures/logistica_access_point_side.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
textures/logistica_access_point_top.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
textures/logistica_blank.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
textures/logistica_icon_all.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
textures/logistica_icon_cancel.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
textures/logistica_icon_craftitem.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
textures/logistica_icon_first.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
textures/logistica_icon_highlight.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
textures/logistica_icon_last.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
textures/logistica_icon_next.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
textures/logistica_icon_node.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
textures/logistica_icon_prev.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
textures/logistica_icon_search.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
textures/logistica_icon_sort_count_99_1.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
textures/logistica_icon_sort_mod_az.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
textures/logistica_icon_sort_name_az.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
textures/logistica_icon_sort_wear_0_100.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
textures/logistica_icon_tool.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
textures/logistica_icon_torch.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
@ -20,12 +20,14 @@ end
|
||||
-- global namespaced functions
|
||||
----------------------------------------------------------------
|
||||
|
||||
-- Loads and returns the given position, or nil if its outisde the current bounds
|
||||
function logistica.load_position(pos)
|
||||
if pos.x < -30912 or pos.y < -30912 or pos.z < -30912 or
|
||||
pos.x > 30927 or pos.y > 30927 or pos.z > 30927 then return end
|
||||
if minetest.get_node_or_nil(pos) then return end
|
||||
if minetest.get_node_or_nil(pos) then return pos end
|
||||
local vm = minetest.get_voxel_manip()
|
||||
vm:read_from_map(pos, pos)
|
||||
return pos
|
||||
end
|
||||
|
||||
function logistica.swap_node(pos, newName)
|
||||
|
63
util/inv_list_filtering.lua
Normal file
@ -0,0 +1,63 @@
|
||||
|
||||
local lights_map = {}
|
||||
|
||||
-- all these get initialized after loadtime
|
||||
|
||||
LOG_FILTER_NODE = function(_) return true end
|
||||
LOG_FILTER_CRAFTITEM = function(_) return true end
|
||||
LOG_FILTER_TOOL = function(_) return true end
|
||||
LOG_FILTER_LIGHT = function(_) return true end
|
||||
|
||||
local function load_lights()
|
||||
for name, def in pairs(minetest.registered_items) do
|
||||
if def.light_source and def.light_source > 0 then
|
||||
lights_map[name] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function create_filter(lookupTable)
|
||||
return function(name)
|
||||
return lookupTable[name] ~= nil
|
||||
end
|
||||
end
|
||||
|
||||
local function load_filters()
|
||||
LOG_FILTER_NODE = create_filter(minetest.registered_nodes)
|
||||
LOG_FILTER_CRAFTITEM = create_filter(minetest.registered_craftitems)
|
||||
LOG_FILTER_TOOL = create_filter(minetest.registered_tools)
|
||||
LOG_FILTER_LIGHT = create_filter(lights_map)
|
||||
end
|
||||
|
||||
local function do_filter(stackList, filterMethod)
|
||||
local res = {}
|
||||
local idx = 1
|
||||
for _, stack in ipairs(stackList) do
|
||||
if filterMethod(stack:get_name()) then
|
||||
res[idx] = stack
|
||||
idx = idx + 1
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
--------------------------------
|
||||
-- public funcs
|
||||
--------------------------------
|
||||
|
||||
-- returns a new list that cotains only matching items
|
||||
-- or return just the same list immediately for convenience if `filterMethod` is nil
|
||||
-- filterMethod should be one of LOG_FILTER_NODE, LOG_FILTER_CRAFTITEM, LOG_FILTER_TOOL, LOG_FILTER_LIGHT
|
||||
function logistica.filter_list_by(stackList, filterMethod)
|
||||
if not filterMethod then return stackList end
|
||||
return do_filter(stackList, filterMethod)
|
||||
end
|
||||
|
||||
--------------------------------
|
||||
-- registration
|
||||
--------------------------------
|
||||
|
||||
minetest.register_on_mods_loaded(function()
|
||||
load_lights()
|
||||
load_filters()
|
||||
end)
|
@ -5,7 +5,7 @@ local LANG_EN = "en"
|
||||
--------------------------------
|
||||
|
||||
local function get_description(st) return minetest.get_translated_string(LANG_EN, st:get_short_description()) end
|
||||
local function get_name(st) d.log(st:get_name()) ; return st:get_name() end
|
||||
local function get_name(st) return st:get_name() end
|
||||
local function get_stack_size(st) return st:get_count() end
|
||||
local function get_wear(st) return st:get_wear() end
|
||||
|
||||
|
@ -7,6 +7,7 @@ dofile(path.."/ui_logic.lua")
|
||||
dofile(path.."/ui.lua")
|
||||
dofile(path.."/sound.lua")
|
||||
dofile(path.."/inv_list_sorting.lua")
|
||||
dofile(path.."/inv_list_filtering.lua")
|
||||
|
||||
-- bad debug
|
||||
d = {}
|
||||
|