Added on/off Demander Toggle; Added network renaming; code cleanup

This commit is contained in:
Zenon Seth 2023-11-06 00:13:49 +00:00
parent b3f8be1eac
commit cab538cfbf
16 changed files with 220 additions and 125 deletions

24
ROADMAP.md Normal file
View File

@ -0,0 +1,24 @@
Missing Features:
- Supplier implementation
- Item Storage implementation
- On/Off state of demander and supplier
- Storage Access Point
- Crafting recipes
High Priority:
- Rework demanders to be run from controller and to have priority
- Remote Storage Access Point
- Crafting Supplier
- Ability to name storages
- Machine Upgrades
Medium Priority
- Wirelss Network Extender
- Ability to add entity display on storages
- Rework all node textures; make new textures 32x32
- Rework all UI icons to be.. 48x48? 64x64? something else?
- Direct pipeworks compatibility
- Direct tubelib compatibility
Low Priority:
- Improve node sounds

View File

@ -1,9 +1,50 @@
local SET_BUTTON = "logsetbtn"
local NAME_FIELD = "namef"
local FORMSPEC_NAME = "logconren"
local controllerForms = {}
local function get_controller_formspec(pos)
local name = logistica.get_network_name_or_nil(pos) or "<NO NETWORK>"
return "formspec_version[6]" ..
"size[10.5,2]" ..
logistica.ui.background..
"field[2.5,0.6;3,0.8;"..NAME_FIELD..";Network Name;"..name.."]" ..
"button[5.6,0.6;3,0.8;"..SET_BUTTON..";Set]"
end
local function show_controller_formspec(pos, playerName)
local pInfo = {}
pInfo.position = pos
controllerForms[playerName] = pInfo
minetest.show_formspec(playerName, FORMSPEC_NAME, get_controller_formspec(pos))
end
local function on_controller_receive_fields(player, formname, fields)
if formname ~= FORMSPEC_NAME then return end
local playerName = player:get_player_name()
minetest.chat_send_all("rec: "..logistica.ttos(fields))
if fields.quit and not fields.key_enter_field then
controllerForms[playerName] = nil
elseif (fields[SET_BUTTON] or fields.key_enter_field) and fields[NAME_FIELD] then
local pos = controllerForms[playerName].position
local newNetworkName = fields[NAME_FIELD]
logistica.rename_network(minetest.hash_node_position(pos), newNetworkName)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", "Controller of Network: "..newNetworkName)
meta:set_string("name", newNetworkName)
end
return true
end
-- registration stuff
minetest.register_on_player_receive_fields(on_controller_receive_fields)
--[[
The definition table will get the fololwing fields overriden (and currently originals are not called):
- on_construct
- after_destruct
- on_timer
- on_rightclick
The definition must also provide a `logistica_controller` table. This table should contains:
{
@ -46,11 +87,15 @@ function logistica.register_controller(simpleName, def, tier)
def.after_destruct = after_destruct
def.on_timer = on_timer
def.drop = controller_name
def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
if clicker and clicker:is_player() then
show_controller_formspec(pos, clicker:get_player_name())
end
end
minetest.register_node(controller_name, def)
local def_disabled = {}
for k, v in pairs(def) do def_disabled[k] = v end
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
@ -58,6 +103,7 @@ function logistica.register_controller(simpleName, def, tier)
def_disabled.on_construct = nil
def_disabled.after_desctruct = nil
def_disabled.on_timer = nil
def_disabled.on_rightclick = nil
minetest.register_node(controller_name.."_disabled", def_disabled)
end

View File

@ -1,22 +1,33 @@
local NUM_DEMAND_SLOTS = 4 -- maybe at some point make this a param, but why?
local PUSH_LIST_PICKER = "push_pick"
local ON_OFF_BUTTON = "on_off_btn"
local FORMSPEC_NAME = "logistica_demander"
local demanderForms = {}
local function get_demander_formspec(pos)
local posForm = "nodemeta:"..pos.x..","..pos.y..","..pos.z
local pushPos = logistica.get_demander_target(pos)
local meta = minetest.get_meta(pos)
local selectedList = meta:get_string("demtarlist")
local isOn = logistica.is_machine_on(pos)
return "formspec_version[4]" ..
"size[10.6,7]" ..
logistica.ui.background..
logistica.get_push_list_dropdown(PUSH_LIST_PICKER, 8.5, 0.7, pushPos, selectedList)..
logistica.ui.push_list_picker(PUSH_LIST_PICKER, 7.5, 0.7, pushPos, selectedList)..
logistica.ui.on_off_btn(isOn, 9.5, 0.5, ON_OFF_BUTTON)..
"list["..posForm..";filter;0.5,0.5;"..NUM_DEMAND_SLOTS..",1;0]"..
"list[current_player;main;0.5,2;8,4;0]"
"list[current_player;main;0.5,2;8,4;0]"
end
local function show_demander_formspec(playerName, pos)
local pInfo = {}
pInfo.position = pos
demanderForms[playerName] = pInfo
minetest.show_formspec(playerName, FORMSPEC_NAME, get_demander_formspec(pos))
end
local function on_player_receive_fields(player, formname, fields)
@ -26,6 +37,13 @@ local function on_player_receive_fields(player, formname, fields)
if not demanderForms[playerName] then return false end
if fields.quit then
demanderForms[playerName] = nil
elseif fields[ON_OFF_BUTTON] then
local pos = demanderForms[playerName].position
if not pos then return false end
if logistica.toggle_machine_on_off(pos) then
logistica.start_demander_timer(pos, 1)
end
show_demander_formspec(player:get_player_name(), pos)
elseif fields[PUSH_LIST_PICKER] then
local selected = fields[PUSH_LIST_PICKER]
if logistica.is_allowed_push_list(selected) then
@ -47,10 +65,7 @@ end
local function on_demander_rightclick(pos, node, clicker, itemstack, pointed_thing)
if not clicker or not clicker:is_player() then return end
local pInfo = {}
pInfo.position = pos
demanderForms[clicker:get_player_name()] = pInfo
minetest.show_formspec(clicker:get_player_name(), FORMSPEC_NAME, get_demander_formspec(pos))
show_demander_formspec(clicker:get_player_name(), pos)
end
local function after_place_demander(pos, placer, itemstack, numDemandSlots)

View File

@ -127,12 +127,14 @@ end
function logistica.start_demander_timer(pos, duration)
if duration == nil then duration = TIMER_DURATION_SHORT end
logistica.start_node_timer(pos, duration)
logistica.set_logistica_node_infotext(pos, true)
end
function logistica.on_demander_timer(pos, elapsed)
local network = logistica.get_network_or_nil(pos)
if not network then
return false -- this will get restarted once the demander is added to a network
if not network or not logistica.is_machine_on(pos) then
logistica.set_logistica_node_infotext(pos, false)
return false
end
take_demanded_items_from_network(pos, network)
return true

View File

@ -1,49 +0,0 @@
local ALLOWED_PULL_LISTS = {}
ALLOWED_PULL_LISTS["main"] = true
ALLOWED_PULL_LISTS["src"] = true
ALLOWED_PULL_LISTS["dst"] = true
ALLOWED_PULL_LISTS["output"] = true
ALLOWED_PULL_LISTS["fuel"] = true
local ALLOWED_PUSH_LISTS = {}
ALLOWED_PUSH_LISTS["main"] = true
ALLOWED_PUSH_LISTS["src"] = true
ALLOWED_PUSH_LISTS["fuel"] = true
ALLOWED_PUSH_LISTS["input"] = true
ALLOWED_PUSH_LISTS["shift"] = true
-- 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)
local defaultIndex = 0
for i, v in ipairs(itemTable) do if default == v then defaultIndex = i end end
local items = table.concat(itemTable, ",")
return "dropdown["..x..","..y..";2,0.6;"..name..";"..items..";"..defaultIndex..";false]"
end
function logistica.get_pull_list_dropdown(name, x, y, pullFromPos, default)
return list_dropdown(name, get_lists(pullFromPos, ALLOWED_PULL_LISTS), x, y, default)
end
function logistica.get_push_list_dropdown(name, x, y, pushToPos, default)
return list_dropdown(name, get_lists(pushToPos, ALLOWED_PUSH_LISTS), x, y, default)
end
function logistica.is_allowed_pull_list(listName)
return ALLOWED_PULL_LISTS[listName] == true
end
function logistica.is_allowed_push_list(listName)
return ALLOWED_PUSH_LISTS[listName] == true
end

View File

@ -1,6 +1,5 @@
local path = logistica.MODPATH .. "/logic"
dofile(path .. "/processing_queue.lua")
dofile(path .. "/inv_list_picker.lua")
dofile(path .. "/groups.lua")
dofile(path .. "/network_logic.lua")
dofile(path .. "/controller.lua")

View File

@ -4,7 +4,7 @@ local STATUS_OK = 0
local CREATE_NETWORK_STATUS_FAIL_OTHER_NETWORK = -1
local CREATE_NETWORK_STATUS_TOO_MANY_NODES = -2
logistica.networks = networks
-- logistica.networks = networks
local p2h = minetest.hash_node_position
local h2p = minetest.get_position_from_hash
@ -44,6 +44,12 @@ function logistica.get_network_name_or_nil(pos)
if not network then return nil else return network.name end
end
function logistica.rename_network(networkId, newName)
local network = networks[networkId]
if not network then return false end
network.name = newName
return true
end
function logistica.get_network_id_or_nil(pos)
local network = logistica.get_network_or_nil(pos)
@ -187,13 +193,15 @@ local function recursive_scan_for_nodes_for_controller(network, positionHashes,
else return recursive_scan_for_nodes_for_controller(network, connections, numScanned) end
end
local function create_network(controllerPosition)
local function create_network(controllerPosition, oldNetworkName)
local node = minetest.get_node(controllerPosition)
if not node.name:find("_controller") or not node.name:find("logistica:") then return false end
local meta = minetest.get_meta(controllerPosition)
local controllerHash = p2h(controllerPosition)
local network = {}
local networkName = logistica.get_network_name_for(controllerPosition)
local nameFromMeta = meta:get_string("name")
if nameFromMeta == "" then nameFromMeta = nil end
local networkName = oldNetworkName or nameFromMeta or logistica.get_network_name_for(controllerPosition)
networks[controllerHash] = network
meta:set_string("infotext", "Controller of Network: "..networkName)
network.controller = controllerHash
@ -227,14 +235,15 @@ end
-- worker functions for cable/machine/controllers
----------------------------------------------------------------
local function rescan_network(networkName)
local network = networks[networkName]
local function rescan_network(networkId)
local network = networks[networkId]
if not network then return false end
if not network.controller then return false end
local conHash = network.controller
local controllerPosition = h2p(conHash)
clear_network(networkName)
create_network(controllerPosition)
local oldNetworkName = network.name
clear_network(networkId)
create_network(controllerPosition, oldNetworkName)
end
local function find_cable_connections(pos, node)

View File

@ -1,62 +1,20 @@
local ProQ = {}
ProQ.__index = ProQ
logistica.proq = {}
local function get_meta(pos)
logistica.load_position(pos)
return minetest.get_meta(pos)
function ProQ.new()
local self = setmetatable({}, ProQ)
self.queue = {}
return self
end
local QUEUE_KEY = "log_proq"
local DELIM = "|"
-- listOfPositions must be a list (naturally numbered table) of position vectors
local function save_queue(meta, listOfPositions)
local tableOfStrings = {}
for _,v in ipairs(listOfPositions) do
table.insert(tableOfStrings, vector.to_string(v))
end
local singleString = table.concat(tableOfStrings, DELIM)
meta:set_string(singleString)
-- the : syntax here causes a "self" arg to be implicitly added before any other args
function ProQ:add_pos(newval)
self.value = newval
end
-- listOfPositions must be a list (naturally numbered table) of position vectors
function logistica.proq.add(pos, listOfPositions)
local meta = get_meta(pos)
local positions = logistica.proq.get_all(pos)
for _, v in ipairs(listOfPositions) do
table.insert(positions, v)
end
save_queue(meta, positions)
function ProQ:get_value()
return self.value
end
-- returns a table of up to the next N positions
function logistica.proq.pop_next(pos, count)
local meta = get_meta(pos)
local positions = logistica.proq.get_all(pos)
local ret = {}
local rem = {}
for i, v in ipairs(positions) do
if (i <= count) then
table.insert(ret, v)
else
table.insert(rem, v)
end
end
save_queue(meta, rem)
return ret
end
function logistica.proq.get_all(pos)
local meta = get_meta(pos)
if not meta:contains(QUEUE_KEY) then return {} end
local compressedString = meta:get_string(QUEUE_KEY)
local positionStrings = string.split(compressedString, DELIM, false)
local positions = {}
for _, v in ipairs(positionStrings) do
local vector = vector.from_string(v)
if vector then
table.insert(positions, vector)
end
end
return positions
end
local instance = ProQ.new()
-- do stuff with instance...

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,4 +1,5 @@
local META_ON_OFF_KEY = "logonoff"
local charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
local function rand_str(length, seed)
@ -87,4 +88,28 @@ function logistica.start_node_timer(pos, time)
timer:start(time)
end
return timer
end
end
function logistica.is_machine_on(pos)
local meta = minetest.get_meta(pos)
return meta:get_int(META_ON_OFF_KEY) > 0
end
-- toggles the state and returns the new state (true for on, false for off)
function logistica.toggle_machine_on_off(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)
return newState > 0
end
-- isOn is optional
function logistica.set_logistica_node_infotext(pos, isOn)
if isOn == nil then isOn = logistica.is_machine_on(pos) end
logistica.load_position(pos)
local meta = minetest.get_meta(pos)
local node = minetest.get_node(pos)
local text = minetest.registered_nodes[node.name].description..
"\n"..(isOn and "Running" or "Stopped")
meta:set_string("infotext", text)
end

View File

@ -1,3 +1,45 @@
logistica.ui = {}
logistica.ui.background = "no_prepend[]bgcolor[#0000]background9[0,0;1,1;logistica_formspec_background.png;true;8]"
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)
local defaultIndex = 0
for i, v in ipairs(itemTable) do if default == v then defaultIndex = i end end
local items = table.concat(itemTable, ",")
return "dropdown["..x..","..y..";2,0.6;"..name..";"..items..";"..defaultIndex..";false]"
end
--------------------------------
-- public functions
--------------------------------
function logistica.ui.on_off_btn(isOn, x, y, name, w, h)
if not w or not h then
w = 1; h = 1
end
local texture = (isOn and "logistica_icon_on.png" or "logistica_icon_off.png")
return "image_button["..x..","..y..";"..w..","..h..";"..
""..texture..";"..name..";;false;false;"..texture.."]"
end
function logistica.ui.pull_list_picker(name, x, y, pullFromPos, default)
return list_dropdown(name, get_lists(pullFromPos, logistica.ALLOWED_PULL_LISTS), x, y, default)
end
function logistica.ui.push_list_picker(name, x, y, pushToPos, default)
return list_dropdown(name, get_lists(pushToPos, logistica.ALLOWED_PUSH_LISTS), x, y, default)
end

23
util/ui_logic.lua Normal file
View File

@ -0,0 +1,23 @@
logistica.ALLOWED_PULL_LISTS = {}
local allowedPull = logistica.ALLOWED_PULL_LISTS
allowedPull["main"] = true
allowedPull["src"] = true
allowedPull["dst"] = true
allowedPull["output"] = true
allowedPull["fuel"] = true
logistica.ALLOWED_PUSH_LISTS = {}
local allowedPush = logistica.ALLOWED_PUSH_LISTS
allowedPush["main"] = true
allowedPush["src"] = true
allowedPush["fuel"] = true
allowedPush["input"] = true
allowedPush["shift"] = true
function logistica.is_allowed_pull_list(listName)
return allowedPull[listName] == true
end
function logistica.is_allowed_push_list(listName)
return allowedPush[listName] == true
end

View File

@ -3,4 +3,5 @@ local path = logistica.MODPATH.."/util"
dofile(path.."/common.lua")
dofile(path.."/rotations.lua")
dofile(path.."/hud.lua")
dofile(path.."/ui_logic.lua")
dofile(path.."/ui.lua")