diff --git a/api/api.lua b/api/api.lua index 468d292..fc5b13f 100644 --- a/api/api.lua +++ b/api/api.lua @@ -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") diff --git a/api/cables.lua b/api/cables.lua index c674f48..a8ea308 100644 --- a/api/cables.lua +++ b/api/cables.lua @@ -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 diff --git a/api/cables_toggleable.lua b/api/cables_toggleable.lua new file mode 100644 index 0000000..f8de1c4 --- /dev/null +++ b/api/cables_toggleable.lua @@ -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 diff --git a/api/controller.lua b/api/controller.lua index 05c3425..fcb6f80 100644 --- a/api/controller.lua +++ b/api/controller.lua @@ -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) diff --git a/logic/groups.lua b/logic/groups.lua index 539a618..7567fd7 100644 --- a/logic/groups.lua +++ b/logic/groups.lua @@ -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 diff --git a/logic/network_logic.lua b/logic/network_logic.lua index 0767e32..7695be9 100644 --- a/logic/network_logic.lua +++ b/logic/network_logic.lua @@ -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 diff --git a/registration/machines_api_reg.lua b/registration/machines_api_reg.lua index 3f8a2ad..bc080b6 100644 --- a/registration/machines_api_reg.lua +++ b/registration/machines_api_reg.lua @@ -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 -------------------------------- diff --git a/textures/logistica_cable_toggleable_off.png b/textures/logistica_cable_toggleable_off.png new file mode 100644 index 0000000..2778543 Binary files /dev/null and b/textures/logistica_cable_toggleable_off.png differ diff --git a/textures/logistica_cable_toggleable_on.png b/textures/logistica_cable_toggleable_on.png new file mode 100644 index 0000000..30efe2a Binary files /dev/null and b/textures/logistica_cable_toggleable_on.png differ diff --git a/util/common.lua b/util/common.lua index 97d1cf5..5c68ae3 100644 --- a/util/common.lua +++ b/util/common.lua @@ -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 diff --git a/util/util.lua b/util/util.lua index c307749..a09cd5d 100644 --- a/util/util.lua +++ b/util/util.lua @@ -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))