Cleanup network tier and cable logic, remove tier checks; Add new Toggleable Cable

This commit is contained in:
Zenon Seth 2023-11-17 23:34:10 +00:00
parent 3bd4c1d3f4
commit abc3107c6a
11 changed files with 177 additions and 135 deletions

View File

@ -1,6 +1,7 @@
local path = logistica.MODPATH.."/api"
dofile(path.."/cables.lua")
dofile(path.."/cables_toggleable.lua")
dofile(path.."/controller.lua")
dofile(path.."/mass_storage.lua")
dofile(path.."/supplier.lua")

View File

@ -1,25 +1,24 @@
local SIZE = 1/16
-- Main function to register a new cable of certain tier
-- customNodeBox can specify any of the fixed/connect_DIR - values will be overwritten per-item basis
function logistica.register_cable(desc, name, size, customNodeBox)
function logistica.register_cable(desc, name, customNodeBox)
local lname = string.lower(name)
local cable_name = "logistica:" .. lname
local cable_group = logistica.get_cable_group(lname)
local cable_group = logistica.TIER_ALL
logistica.cables[cable_name] = name
logistica.tiers[lname] = true
local cnb = customNodeBox or {}
local node_box = {
type = "connected",
fixed = cnb.fixed or { -size, -size, -size, size, size, size },
connect_top = cnb.connect_top or { -size, -size, -size, size, 0.5, size }, -- y+
connect_bottom = cnb.connect_bottom or { -size, -0.5, -size, size, size, size }, -- y-
connect_front = cnb.connect_front or { -size, -size, -0.5, size, size, size }, -- z-
connect_back = cnb.connect_back or { -size, -size, size, size, size, 0.5 }, -- z+
connect_left = cnb.connect_left or { -0.5, -size, -size, size, size, size }, -- x-
connect_right = cnb.connect_right or { -size, -size, -size, 0.5, size, size }, -- x+
fixed = cnb.fixed or { -SIZE, -SIZE, -SIZE, SIZE, SIZE, SIZE },
connect_top = cnb.connect_top or { -SIZE, -SIZE, -SIZE, SIZE, 0.5, SIZE }, -- y+
connect_bottom = cnb.connect_bottom or { -SIZE, -0.5, -SIZE, SIZE, SIZE, SIZE }, -- y-
connect_front = cnb.connect_front or { -SIZE, -SIZE, -0.5, SIZE, SIZE, SIZE }, -- z-
connect_back = cnb.connect_back or { -SIZE, -SIZE, SIZE, SIZE, SIZE, 0.5 }, -- z+
connect_left = cnb.connect_left or { -0.5, -SIZE, -SIZE, SIZE, SIZE, SIZE }, -- x-
connect_right = cnb.connect_right or { -SIZE, -SIZE, -SIZE, 0.5, SIZE, SIZE }, -- x+
}
local def = {
@ -40,7 +39,7 @@ function logistica.register_cable(desc, name, size, customNodeBox)
sunlight_propagates = true,
drawtype = "nodebox",
node_box = node_box,
connects_to = { "group:" .. cable_group, "group:"..logistica.get_machine_group(lname), logistica.GROUP_ALL },
connects_to = { "group:" .. cable_group, logistica.GROUP_ALL },
on_construct = function(pos) logistica.on_cable_change(pos, nil) end,
after_destruct = function(pos, oldnode) logistica.on_cable_change(pos, oldnode) end,
}
@ -53,7 +52,7 @@ function logistica.register_cable(desc, name, size, customNodeBox)
def_broken.inventory_image = "logistica_" .. lname .. "_inv.png^logistica_broken.png"
def_broken.groups = { cracky = 3, choppy = 3, oddly_breakable_by_hand = 2, not_in_creative_inventory = 1 }
def_broken.description = "Broken " .. desc
def_broken.node_box = { type = "fixed", fixed = { -0.5, -size, -size, 0.5, size, size } }
def_broken.node_box = { type = "fixed", fixed = { -0.5, -SIZE, -SIZE, 0.5, SIZE, SIZE } }
def_broken.selection_box = def_broken.node_box
def_broken.connects_to = nil
def_broken.on_construct = nil

97
api/cables_toggleable.lua Normal file
View File

@ -0,0 +1,97 @@
local SIZE = 1/16
local function ends_with(str, ending)
return str:sub(-#ending) == ending
end
local function toggle_cable(pos, node, clicker, itemstack, pointed_thing)
if clicker:is_player() and minetest.is_protected(pos, clicker:get_player_name()) then return end
local nodeName = node.name
if ends_with(nodeName, "_on") then
nodeName = nodeName:sub(1, #nodeName - 3).."_off"
logistica.swap_node(pos, nodeName)
logistica.on_cable_change(pos, nil, false)
elseif ends_with(nodeName, "_off") then
nodeName = nodeName:sub(1, #nodeName - 4).."_on"
logistica.swap_node(pos, nodeName)
logistica.on_cable_change(pos, nil, true)
end
end
-- Main function to register a new toggleable cable
function logistica.register_cable_toggleable(desc, name, tilesOn, tilesOff)
local lname = string.lower(name)
local nameOff = "logistica:"..lname.."_off"
for _, state in ipairs({"on", "off"}) do
local node_box = {
type = "connected",
fixed = { -0.25, -0.25, -0.25, 0.25, 0.25, 0.25},
connect_top = { -SIZE, -SIZE, -SIZE, SIZE, 0.5, SIZE }, -- y+
connect_bottom = { -SIZE, -0.5, -SIZE, SIZE, SIZE, SIZE }, -- y-
connect_front = { -SIZE, -SIZE, -0.5, SIZE, SIZE, SIZE }, -- z-
connect_back = { -SIZE, -SIZE, SIZE, SIZE, SIZE, 0.5 }, -- z+
connect_left = { -0.5, -SIZE, -SIZE, SIZE, SIZE, SIZE }, -- x-
connect_right = { -SIZE, -SIZE, -SIZE, 0.5, SIZE, SIZE }, -- x+
}
local cable_name = "logistica:"..lname.."_"..state
local connectsTo = { logistica.GROUP_ALL }
local tiles = tilesOn
local onConst = function(p) logistica.on_cable_change(p, nil) end
local onDest = function(p, oldnode) logistica.on_cable_change(p, oldnode) end
if state == "off" then
tiles = tilesOff
connectsTo = {}
onConst = nil
onDest = nil
end
local def = {
description = desc,
tiles = tiles,
-- inventory_image = "logistica_" .. lname .. "_inv.png",
-- wield_image = "logistica_" .. lname .. "_inv.png",
groups = {
cracky = 3,
choppy = 3,
oddly_breakable_by_hand = 2,
},
sounds = logistica.node_sound_metallic(),
drop = nameOff,
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = true,
drawtype = "nodebox",
node_box = node_box,
connects_to = connectsTo,
on_construct = onConst,
after_destruct = onDest,
on_rightclick = toggle_cable,
}
if state == "on" then
logistica.cables[cable_name] = name
def.groups[logistica.TIER_ALL] = 1
def.groups.not_in_creative_inventory = 1
end
minetest.register_node(cable_name, def)
local def_broken = table.copy(def)
def_broken.tiles = logistica.table_map(tiles, function(s) return s.."^logistica_broken.png" end)
-- def_broken.inventory_image = "logistica_" .. lname .. "_inv.png^logistica_broken.png"
def_broken.groups = { cracky = 3, choppy = 3, oddly_breakable_by_hand = 2, not_in_creative_inventory = 1 }
def_broken.description = "Broken " .. desc
def_broken.node_box = { type = "fixed", fixed = { -0.5, -SIZE, -SIZE, 0.5, SIZE, SIZE } }
def_broken.selection_box = def_broken.node_box
def_broken.connects_to = nil
def_broken.on_construct = nil
def_broken.after_destruct = nil
def_broken.on_rightclick = nil
minetest.register_node(cable_name .. "_disabled", def_broken)
end
end

View File

@ -74,17 +74,10 @@ end)
tier may be `nil` which will result in the controller connecting to everything
]]
function logistica.register_controller(name, def, tier)
local controller_group = nil
if not tier then
tier = logistica.TIER_ALL
controller_group = logistica.TIER_ALL
else
local ltier = string.lower(tier)
logistica.tiers[ltier] = true
controller_group = logistica.get_machine_group(ltier)
end
local controller_name = "logistica:" .. string.lower(name:gsub(" ", "_"))
function logistica.register_controller(name, def)
local controller_group = logistica.TIER_ALL
local tier = logistica.TIER_ALL
local controller_name = "logistica:" .. string.lower(name:gsub(" ", "_"))
logistica.controllers[controller_name] = tier
local on_construct = function(pos)

View File

@ -8,19 +8,10 @@ logistica.item_storage = {}
logistica.misc_machines = {}
logistica.trashcans = {}
logistica.vaccuum_suppliers = {}
logistica.tiers = {}
logistica.TIER_ALL = "logistica_all_tiers"
logistica.GROUP_ALL = "group:" .. logistica.TIER_ALL
logistica.TIER_CONTROLLER = "controller"
function logistica.get_cable_group(tier)
return "logistica_" .. tier .. "_cable"
end
function logistica.get_machine_group(tier)
return "logistica_" .. tier .. "_machine"
end
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)
@ -66,32 +57,3 @@ end
function logistica.is_vaccuum_supplier(name)
return logistica.vaccuum_suppliers[name] ~= nil
end
function logistica.get_item_tiers(name)
local tiers = {}
for tier,_ in pairs(logistica.tiers) do
local cable_group = logistica.get_cable_group(tier)
local machine_group = logistica.get_machine_group(tier)
if minetest.get_item_group(name, cable_group) > 0 then
tiers[tier] = true
end
if minetest.get_item_group(name, machine_group) > 0 then
tiers[tier] = true
end
if minetest.get_item_group(name, logistica.TIER_ALL) > 0 then
tiers[logistica.TIER_ALL] = true
end
end
return tiers
end
function logistica.do_tiers_match(tiers1, tiers2)
for t1, _ in pairs(tiers1) do
for t2, _ in pairs(tiers2) do
if t1 == logistica.TIER_ALL or t2 == logistica.TIER_ALL or t1 == t2 then
return true
end
end
end
return false
end

View File

@ -115,8 +115,6 @@ local function recursive_scan_for_nodes_for_controller(network, positionHashes,
local pos = h2p(posHash)
numScanned = numScanned + 1
logistica.load_position(pos)
local tiers = logistica.get_item_tiers(minetest.get_node(pos).name)
local isAllTier = tiers[logistica.TIER_ALL] == true
for _, offset in pairs(adjecent) do
local otherPos = vector.add(pos, offset)
logistica.load_position(otherPos)
@ -125,51 +123,44 @@ local function recursive_scan_for_nodes_for_controller(network, positionHashes,
if network.controller ~= otherHash
and not has_machine(network, otherHash)
and network.cables[otherHash] == nil then
local tiersMatch = isAllTier
if tiersMatch ~= true then
local otherTiers = logistica.get_item_tiers(minetest.get_node(otherPos).name)
tiersMatch = logistica.do_tiers_match(tiers, otherTiers)
local existingNetwork = logistica.get_network_id_or_nil(otherPos)
if existingNetwork ~= nil and existingNetwork ~= network then
return CREATE_NETWORK_STATUS_FAIL_OTHER_NETWORK
end
local valid = false
if logistica.is_cable(otherName) then
network.cables[otherHash] = true
connections[otherHash] = true
valid = true
elseif logistica.is_requester(otherName) then
network.requesters[otherHash] = true
valid = true
elseif logistica.is_injector(otherName) then
network.injectors[otherHash] = true
valid = true
elseif logistica.is_supplier(otherName) then
network.suppliers[otherHash] = true
valid = true
elseif logistica.is_vaccuum_supplier(otherName) then
network.suppliers[otherHash] = true
valid = true
elseif logistica.is_mass_storage(otherName) then
network.mass_storage[otherHash] = true
valid = true
elseif logistica.is_item_storage(otherName) then
network.item_storage[otherHash] = true
valid = true
elseif logistica.is_misc(otherName) then
network.misc[otherHash] = true
valid = true
elseif logistica.is_trashcan(otherName) then
network.trashcans[otherHash] = true
valid = true
end
if valid then
newToScan = newToScan + 1
notify_connected(otherPos, otherName, network.controller)
end
if tiersMatch then
local existingNetwork = logistica.get_network_id_or_nil(otherPos)
if existingNetwork ~= nil and existingNetwork ~= network then
return CREATE_NETWORK_STATUS_FAIL_OTHER_NETWORK
end
local valid = false
if logistica.is_cable(otherName) then
network.cables[otherHash] = true
connections[otherHash] = true
valid = true
elseif logistica.is_requester(otherName) then
network.requesters[otherHash] = true
valid = true
elseif logistica.is_injector(otherName) then
network.injectors[otherHash] = true
valid = true
elseif logistica.is_supplier(otherName) then
network.suppliers[otherHash] = true
valid = true
elseif logistica.is_vaccuum_supplier(otherName) then
network.suppliers[otherHash] = true
valid = true
elseif logistica.is_mass_storage(otherName) then
network.mass_storage[otherHash] = true
valid = true
elseif logistica.is_item_storage(otherName) then
network.item_storage[otherHash] = true
valid = true
elseif logistica.is_misc(otherName) then
network.misc[otherHash] = true
valid = true
elseif logistica.is_trashcan(otherName) then
network.trashcans[otherHash] = true
valid = true
end
if valid then
newToScan = newToScan + 1
notify_connected(otherPos, otherName, network.controller)
end
end -- end if tiersMatch
end -- end of general checks
end -- end inner for loop
end -- end outer for loop
@ -239,23 +230,13 @@ local function rescan_network(networkId)
create_network(controllerPosition, oldNetworkName)
end
local function find_cable_connections(pos, node)
local function find_cable_connections(pos)
local connections = {}
for _, offset in pairs(adjecent) do
local otherPos = vector.add(pos, offset)
local otherNode = minetest.get_node_or_nil(otherPos)
if otherNode then
if otherNode.name == node.name then
table.insert(connections, otherPos)
elseif minetest.get_item_group(otherNode, logistica.GROUP_ALL) > 0 then
table.insert(connections, otherPos)
else -- check if adjecent node is a machine of same tier
local nodeTiers = logistica.get_item_tiers(node.name)
local otherTiers = logistica.get_item_tiers(otherNode.name)
if logistica.do_tiers_match(nodeTiers, otherTiers) then
table.insert(connections, otherPos)
end
end
if otherNode and minetest.get_item_group(otherNode.name, logistica.TIER_ALL) > 0 then
table.insert(connections, otherPos)
end
end
return connections
@ -349,12 +330,15 @@ end
-- global namespaced functions
----------------------------------------------------------------
function logistica.on_cable_change(pos, oldNode)
function logistica.on_cable_change(pos, oldNode, wasPlacedOverride)
local node = oldNode or minetest.get_node(pos)
local meta = minetest.get_meta(pos)
local placed = (oldNode == nil) -- if oldNode is nil, we placed it
local placed = wasPlacedOverride
if placed == nil then
placed = (oldNode == nil) -- if oldNode is nil, we placed it
end
local connections = find_cable_connections(pos, node)
local connections = find_cable_connections(pos)
if not connections or #connections < 1 then return end -- nothing to update
local networkEnd = #connections == 1
@ -362,7 +346,7 @@ function logistica.on_cable_change(pos, oldNode)
if not placed then -- removed a network end
local network = logistica.get_network_or_nil(pos)
if network then network.cables[p2h(pos)] = nil end
elseif cable_can_extend_network_from(connections[1]) then
elseif cable_can_extend_network_from(connections[1]) then
local otherNetwork = logistica.get_network_or_nil(connections[1])
if otherNetwork then
otherNetwork.cables[p2h(pos)] = true
@ -375,7 +359,7 @@ function logistica.on_cable_change(pos, oldNode)
local connectedNetworks = {}
for _, connectedPos in pairs(connections) do
local otherNetwork = logistica.get_network_id_or_nil(connectedPos)
if otherNetwork and cable_can_extend_network_from(connectedPos) then
if otherNetwork then
connectedNetworks[otherNetwork] = true
end
end

View File

@ -15,14 +15,21 @@ logistica.register_access_point("Access Point", "access_point", {
-- Cables
--------------------------------
local CABLE_SIZE = 1/16
logistica.register_cable("Optic cable", "optic_cable", CABLE_SIZE)
-- regular
logistica.register_cable("Optic cable", "optic_cable")
-- TODO: plate + cable = masked cable
-- logistica.register_cable("Optic cable", "optic_wall", CABLE_SIZE, {
-- fixed = {
-- { -CABLE_SIZE, -CABLE_SIZE, -CABLE_SIZE, CABLE_SIZE, CABLE_SIZE, CABLE_SIZE }
-- }
-- })
-- toggleable
logistica.register_cable_toggleable("Toggleable Cable", "toggleable_cable",
{"logistica_cable_toggleable_on.png"},
{"logistica_cable_toggleable_off.png"}
)
--------------------------------
-- Controller
--------------------------------

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -197,3 +197,8 @@ function logistica.random_chance(percent)
return percent >= math.random(1, 100)
end
function logistica.table_map(table, func)
local t = {}
for k,v in pairs(table) do t[k] = func(v) end
return t
end

View File

@ -13,13 +13,7 @@ dofile(path.."/inv_list_filtering.lua")
local d = {}
d.ttos = logistica.ttos
d.log = minetest.chat_send_all
function d.table_map(self, f)
local t = {}
for k,v in pairs(self) do
t[k] = f(v)
end
return t
end
d.table_map = logistica.table_map
function d.ltos(list)
if not list then return "{NIL}" end
return d.ttos(d.table_map(list, function(st) return st:to_string() end))