From 8fdb71a6025732d97d62883a06a5e3ea421b867f Mon Sep 17 00:00:00 2001 From: Evert Prants Date: Thu, 21 Jun 2018 16:08:32 +0300 Subject: [PATCH] Change power network code, add some craftitems --- elepower_dynamics/craftitems.lua | 12 + elepower_dynamics/tank.lua | 10 - .../textures/elepower_induction_coil.png | Bin 0 -> 333 bytes .../elepower_induction_coil_advanced.png | Bin 0 -> 352 bytes elepower_dynamics/worldgen.lua | 6 +- elepower_machines/craft.lua | 2 +- elepower_machines/register.lua | 27 +- elepower_papi/helpers.lua | 5 + elepower_papi/machine.lua | 3 +- elepower_papi/network.lua | 262 ++++++++++-------- 10 files changed, 184 insertions(+), 143 deletions(-) delete mode 100644 elepower_dynamics/tank.lua create mode 100644 elepower_dynamics/textures/elepower_induction_coil.png create mode 100644 elepower_dynamics/textures/elepower_induction_coil_advanced.png diff --git a/elepower_dynamics/craftitems.lua b/elepower_dynamics/craftitems.lua index 20db472..317d410 100644 --- a/elepower_dynamics/craftitems.lua +++ b/elepower_dynamics/craftitems.lua @@ -63,6 +63,18 @@ minetest.register_craftitem("elepower_dynamics:tree_tap", { groups = {treetap = 1, component = 1} }) +minetest.register_craftitem("elepower_dynamics:induction_coil", { + description = "Induction Coil", + inventory_image = "elepower_induction_coil.png", + groups = {induction_coil = 1, component = 1} +}) + +minetest.register_craftitem("elepower_dynamics:induction_coil_advanced", { + description = "Advanced Induction Coil\nSuitable for high-power operations", + inventory_image = "elepower_induction_coil_advanced.png", + groups = {induction_coil = 1, component = 1} +}) + --------------- -- Overrides -- --------------- diff --git a/elepower_dynamics/tank.lua b/elepower_dynamics/tank.lua deleted file mode 100644 index 9710d1c..0000000 --- a/elepower_dynamics/tank.lua +++ /dev/null @@ -1,10 +0,0 @@ - -fluid_tanks.register_tank("elepower_dynamics:portable_tank", { - description = "Portable Tank", - capacity = 8000, - accepts = true, - tiles = { - "elepower_tank_base.png", "elepower_tank_base.png", "elepower_tank_side.png", - "elepower_tank_side.png", "elepower_tank_side.png", "elepower_tank_side.png" - } -}) diff --git a/elepower_dynamics/textures/elepower_induction_coil.png b/elepower_dynamics/textures/elepower_induction_coil.png new file mode 100644 index 0000000000000000000000000000000000000000..5a1f2f3be0440d26b7e1b1aa722ef0f057607595 GIT binary patch literal 333 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE(|k)@YvD`Qcr*)oCO|{ z#S9F3${@^GvDCf{D9B#o>Fdh=h)tABLX4&T)i0osWQl7;iF1B#Zfaf$gL6@8Vo7R> zLV0FMhJw4NZ$Nk>pEyv_R!Va!u1BqZYgrzBMTmrgqIdOi=2eBH!^1MTrVJhN&9Zr}gk zw&DK7qysC&B_vvIXnbj6kY;Yyur7={FjIWfjAwt{{Z5_b(OdGAHRUYGNf&q+7`Eu< Vi2Cqt+Y0mmgQu&X%Q~loCIA*ec}f5P literal 0 HcmV?d00001 diff --git a/elepower_dynamics/textures/elepower_induction_coil_advanced.png b/elepower_dynamics/textures/elepower_induction_coil_advanced.png new file mode 100644 index 0000000000000000000000000000000000000000..cd31b83c5f76ae6ded8d784aae938466db74153c GIT binary patch literal 352 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE(|k)@YvD`Qcr*)oCO|{ z#S9F3${@^GvDCf{D9B#o>Fdh=h)tABM%~a<{|Hb>vcxr_#5q4VH#M(>!MP|ku_QG` zp**uBL&4qCHz2%`PaLS|gr|#Rh{fsTgarZyNy2B6W_^$UF<<6z^fGsz6D7vY+-+5A zIcy1+|4e%+Sg3a+=kSO75fd68@-60Qp0PooS-_h4aBup1iI9K$6D@wvYdrX!W0f3_ z_@3WK4}5s0&fF}e&wTjzeIB0o3*Nk*FCoEl(;&7XvB8L+`S9!cJUsdJPB-4yJKva9 z!^2a)Um)?o?|6Zu`Sp%D;m;a3+;_Oi!h7Ip>vem@w%{kN<@??CHk{>-`0S*6c;5dT rlRj;!_dN2HHD^}q|C5FnSQr>er6!79k#K1O`ia5Q)z4*}Q$iB}mk))Y literal 0 HcmV?d00001 diff --git a/elepower_dynamics/worldgen.lua b/elepower_dynamics/worldgen.lua index 950d5e7..bb39247 100644 --- a/elepower_dynamics/worldgen.lua +++ b/elepower_dynamics/worldgen.lua @@ -9,7 +9,7 @@ minetest.register_ore({ ore_type = "scatter", ore = "elepower_dynamics:stone_with_lead", wherein = "default:stone", - clust_scarcity = 9 * 9 * 9, + clust_scarcity = 5 * 5 * 5, clust_num_ores = 12, clust_size = 3, y_max = 31000, @@ -20,7 +20,7 @@ minetest.register_ore({ ore_type = "scatter", ore = "elepower_dynamics:stone_with_lead", wherein = "default:stone", - clust_scarcity = 7 * 7 * 7, + clust_scarcity = 4 * 4 * 4, clust_num_ores = 5, clust_size = 3, y_max = 0, @@ -31,7 +31,7 @@ minetest.register_ore({ ore_type = "scatter", ore = "elepower_dynamics:stone_with_lead", wherein = "default:stone", - clust_scarcity = 18 * 18 * 18, + clust_scarcity = 10 * 10 * 10, clust_num_ores = 5, clust_size = 3, y_max = -128, diff --git a/elepower_machines/craft.lua b/elepower_machines/craft.lua index fcf7724..158d93a 100644 --- a/elepower_machines/craft.lua +++ b/elepower_machines/craft.lua @@ -57,7 +57,7 @@ function elepm.register_craft(craftdef) end function elepm.get_recipe(type, inputs) - if not elepm.craft[type] then + if not elepm.craft[type] or not inputs then return nil end diff --git a/elepower_machines/register.lua b/elepower_machines/register.lua index e4a2857..5e68318 100644 --- a/elepower_machines/register.lua +++ b/elepower_machines/register.lua @@ -8,12 +8,27 @@ elepm.register_craft_type("alloy", { inputs = 2, }) -elepm.register_craft({ - type = "alloy", - recipe = { "elepower_dynamics:iron_ingot", "elepower_dynamics:coal_dust 4" }, - output = "default:steel_ingot", - time = 6, -}) +local alloy_recipes = { + { + recipe = { "elepower_dynamics:iron_ingot", "elepower_dynamics:coal_dust 4" }, + output = "default:steel_ingot", + time = 6, + }, + { + recipe = { "default:copper_ingot 2", "default:tin_ingot" }, + output = "default:bronze_ingot 3", + } +} + +-- Register alloy furnace recipes +for _,i in pairs(alloy_recipes) do + elepm.register_craft({ + type = "alloy", + recipe = i.recipe, + output = i.output, + time = i.time or 4 + }) +end elepm.register_crafter("elepower_machines:alloy_furnace", { description = "Alloy Furnace", diff --git a/elepower_papi/helpers.lua b/elepower_papi/helpers.lua index 77e34ef..262f2ce 100644 --- a/elepower_papi/helpers.lua +++ b/elepower_papi/helpers.lua @@ -98,3 +98,8 @@ function ele.helpers.face_front(pos, fd) return front end + +function ele.helpers.comma_value(n) -- credit http://richard.warburton.it + local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$') + return left..(num:reverse():gsub('(%d%d%d)','%1,'):reverse())..right +end diff --git a/elepower_papi/machine.lua b/elepower_papi/machine.lua index 774dc83..c105778 100644 --- a/elepower_papi/machine.lua +++ b/elepower_papi/machine.lua @@ -119,7 +119,8 @@ local function retrieve_metadata(pos, placer, itemstack, pointed_thing) end function ele.capacity_text(capacity, storage) - return "Charge: " .. storage .. "/" .. capacity .. " " ..ele.unit + return ("Charge: %s / %s %s"):format(ele.helpers.comma_value(storage), + ele.helpers.comma_value(capacity), ele.unit) end local tube = { diff --git a/elepower_papi/network.lua b/elepower_papi/network.lua index ae463bc..6dd524f 100644 --- a/elepower_papi/network.lua +++ b/elepower_papi/network.lua @@ -14,18 +14,30 @@ ele.graphcache = {devices = {}} -- Graph Functions -- --------------------- -local function clear_networks_from_node(pos) - local meta = minetest.get_meta(pos) - meta:set_string("network_id", "") +local function table_has_string(arr, str) + for _,astr in ipairs(arr) do + if astr == str then + return true + end + end + return false end local function add_node(nodes, pos, pnodeid) local node_id = minetest.hash_node_position(pos) - if ele.graphcache.devices[node_id] and ele.graphcache.devices[node_id] ~= pnodeid then return end - ele.graphcache.devices[node_id] = pnodeid + + if not ele.graphcache.devices[node_id] then + ele.graphcache.devices[node_id] = {} + end + + if not table_has_string(ele.graphcache.devices[node_id], pnodeid) then + table.insert(ele.graphcache.devices[node_id], pnodeid) + end + if nodes[node_id] then return false end + nodes[node_id] = pos return true end @@ -36,14 +48,15 @@ local function add_conductor_node(nodes, pos, pnodeid, queue) end end -local function check_node(users, providers, all_nodes, pos, pr_pos, pnodeid, queue) +local function check_node(users, providers, conductors, pos, pr_pos, pnodeid, queue) + if minetest.pos_to_string(pos) == pnodeid then return end + ele.helpers.get_or_load_node(pos) local node = minetest.get_node(pos) local meta = minetest.get_meta(pos) if ele.helpers.get_item_group(node.name, "ele_conductor") then - local nodedef = minetest.registered_nodes[node.name] - add_conductor_node(all_nodes, pos, pnodeid, queue) + add_conductor_node(conductors, pos, pnodeid, queue) return end @@ -51,26 +64,15 @@ local function check_node(users, providers, all_nodes, pos, pr_pos, pnodeid, que return end - -- Don't add already networked nodes to this network - if meta:get_string("network_id") ~= "" and meta:get_string("network_id") ~= pnodeid then - return - end - - meta:set_string("network_id", pnodeid) - - if ele.helpers.get_item_group(node.name, "ele_user") then + if ele.helpers.get_item_group(node.name, "ele_user") or + ele.helpers.get_item_group(node.name, "ele_storage") then add_node(users, pos, pnodeid) elseif ele.helpers.get_item_group(node.name, "ele_provider") then - if ele.helpers.get_item_group(node.name, "ele_storage") then - -- Storage gets added to users, for now - add_node(users, pos, pnodeid) - else - add_node(providers, pos, pnodeid) - end + add_node(providers, pos, pnodeid) end end -local function traverse_network(users, providers, all_nodes, pos, pr_pos, pnodeid, queue) +local function traverse_network(users, providers, conductors, pos, pr_pos, pnodeid, queue) local positions = { {x=pos.x+1, y=pos.y, z=pos.z}, {x=pos.x-1, y=pos.y, z=pos.z}, @@ -79,11 +81,11 @@ local function traverse_network(users, providers, all_nodes, pos, pr_pos, pnodei {x=pos.x, y=pos.y, z=pos.z+1}, {x=pos.x, y=pos.y, z=pos.z-1}} for _, cur_pos in pairs(positions) do - check_node(users, providers, all_nodes, cur_pos, pr_pos, pnodeid, queue) + check_node(users, providers, conductors, cur_pos, pr_pos, pnodeid, queue) end end -local function power_networks(pr_pos, positions) +local function discover_branches(pr_pos, positions) local provider = minetest.get_node(pr_pos) local pnodeid = minetest.pos_to_string(pr_pos) @@ -92,17 +94,17 @@ local function power_networks(pr_pos, positions) return cached.users, cached.providers end - local users = {} - local providers = {} - local queue = {} - local all_nodes = {} + local users = {} + local providers = {} + local queue = {} + local conductors = {} - for pos in pairs(positions) do + for _,pos in ipairs(positions) do queue = {} local node = minetest.get_node(pos) if node and ele.helpers.get_item_group(node.name, "ele_conductor") then - add_conductor_node(all_nodes, pos, pnodeid, queue) + add_conductor_node(conductors, pos, pnodeid, queue) elseif node and ele.helpers.get_item_group(node.name, "ele_machine") then queue = {pr_pos} end @@ -110,22 +112,20 @@ local function power_networks(pr_pos, positions) while next(queue) do local to_visit = {} for _, posi in ipairs(queue) do - traverse_network(users, providers, all_nodes, posi, pr_pos, pnodeid, to_visit) + traverse_network(users, providers, conductors, posi, pr_pos, pnodeid, to_visit) end queue = to_visit end end -- Add self to providers - local prov_id = minetest.hash_node_position(pr_pos) - ele.graphcache.devices[prov_id] = pnodeid - providers[prov_id] = pr_pos + add_node(providers, pr_pos, pnodeid) - users = ele.helpers.flatten(users) - providers = ele.helpers.flatten(providers) - all_nodes = ele.helpers.flatten(all_nodes) + users = ele.helpers.flatten(users) + providers = ele.helpers.flatten(providers) + conductors = ele.helpers.flatten(conductors) - ele.graphcache[pnodeid] = {all_nodes = all_nodes, users = users, providers = providers} + ele.graphcache[pnodeid] = {conductors = conductors, users = users, providers = providers} return users, providers end @@ -199,30 +199,26 @@ minetest.register_abm({ {x=pos.x, y=pos.y, z=pos.z+1} } - local ntwks = {} - local errored = false - local nw_branches = 0 + local branches = {} for _,pos1 in pairs(positions) do - local name = node.name + local pnode = minetest.get_node(pos1) + local name = pnode.name local networked = ele.helpers.get_item_group(name, "ele_machine") or ele.helpers.get_item_group(name, "ele_conductor") if networked then - ntwks[pos1] = true - nw_branches = nw_branches + 1 + branches[#branches + 1] = pos1 end end - if errored then - return - end - - if nw_branches == 0 then + -- No possible branches found + if #branches == 0 then minetest.forceload_free_block(pos) return else minetest.forceload_block(pos) end - users, providers = power_networks(pos, ntwks) + -- Find all users and providers + users, providers = discover_branches(pos, branches) -- Calculate power data local pw_supply = 0 @@ -246,7 +242,9 @@ minetest.register_abm({ break end - local user_gets, user_storage = give_node_power(ndv, pw_supply - pw_demand) + -- Sharing: Determine how much each user gets + local user_supply = (pw_supply - pw_demand) / #users + local user_gets, user_storage = give_node_power(ndv, user_supply) pw_demand = pw_demand + user_gets local user_meta = minetest.get_meta(ndv) @@ -261,14 +259,16 @@ minetest.register_abm({ end end - -- Take the power from a provider node + -- Take the power from provider nodes if pw_demand > 0 then for _, spos in ipairs(providers) do + if pw_demand == 0 then break end local smeta = minetest.get_meta(spos) local pw_storage = smeta:get_int("storage") if pw_storage >= pw_demand then smeta:set_int("storage", pw_storage - pw_demand) + pw_demand = 0 else pw_demand = pw_demand - pw_storage smeta:set_int("storage", 0) @@ -308,84 +308,102 @@ function ele.clear_networks(pos) if #positions < 1 then return end local dead_end = #positions == 1 for _,connected_pos in pairs(positions) do - local net = ele.graphcache.devices[minetest.hash_node_position(connected_pos)] or minetest.pos_to_string(connected_pos) - if net and ele.graphcache[net] then - if dead_end and placed then - -- Dead end placed, add it to the network - -- Get the network - local node_at = minetest.get_node(positions[1]) - local network_id = ele.graphcache.devices[minetest.hash_node_position(positions[1])] or minetest.pos_to_string(positions[1]) + local networks = ele.graphcache.devices[minetest.hash_node_position(connected_pos)] or + {minetest.pos_to_string(connected_pos)} - if not network_id or not ele.graphcache[network_id] then - -- We're evidently not on a network, nothing to add ourselves to - return - end - local c_pos = minetest.string_to_pos(network_id) - local network = ele.graphcache[network_id] + for _,net in ipairs(networks) do + if net and ele.graphcache[net] then + -- This is so we can break the pipeline instead of the network search loop + while true do + if dead_end and placed then + -- Dead end placed, add it to the network + -- Get the networks + local network_ids = ele.graphcache.devices[minetest.hash_node_position(positions[1])] or + {minetest.pos_to_string(positions[1])} - -- Actually add it to the (cached) network - -- This is similar to check_node_subp - ele.graphcache.devices[minetest.hash_node_position(pos)] = network_id - pos.visited = 1 - - if ele.helpers.get_item_group(name, "ele_conductor") then - table.insert(network.all_nodes, pos) - end - - if ele.helpers.get_item_group(name, "ele_machine") then - meta:set_string("ele_network", network_id) - - if ele.helpers.get_item_group(name, "ele_provider") then - if ele.helpers.get_item_group(name, "ele_storage") then - -- TODO: Add storage to users for now - table.insert(network.users, pos) - else - table.insert(network.providers, pos) + if not #network_ids then + -- We're evidently not on a network, nothing to add ourselves to + break end - elseif ele.helpers.get_item_group(name, "ele_user") then - table.insert(network.users, pos) - end - end - elseif dead_end and not placed then - -- Dead end removed, remove it from the network - -- Get the network - local network_id = ele.graphcache.devices[minetest.hash_node_position(positions[1])] or minetest.pos_to_string(positions[1]) - if not network_id or not ele.graphcache[network_id] then - -- We're evidently not on a network, nothing to remove ourselves from - return - end - local network = ele.graphcache[network_id] - -- The network was deleted. - if network_id == minetest.pos_to_string(pos) then - for _,v in ipairs(network.all_nodes) do - local pos1 = minetest.hash_node_position(v) - clear_networks_from_node(v) - ele.graphcache.devices[pos1] = nil - end - ele.graphcache[network_id] = nil - return - end + for _, int_net in ipairs(network_ids) do + if ele.graphcache[int_net] then + local c_pos = minetest.string_to_pos(int_net) + local network = ele.graphcache[int_net] - -- Search for and remove device - ele.graphcache.devices[minetest.hash_node_position(pos)] = nil - for tblname,table in pairs(network) do - if type(table) == "table" then - for devicenum,device in pairs(table) do - if vector.equals(device, pos) then - table[devicenum] = nil + -- Actually add it to the (cached) network + if not ele.graphcache.devices[minetest.hash_node_position(pos)] then + ele.graphcache.devices[minetest.hash_node_position(pos)] = {} + end + + local t = ele.graphcache.devices[minetest.hash_node_position(pos)] + if not table_has_string(t, int_net) then + table.insert(t, int_net) + end + + if ele.helpers.get_item_group(name, "ele_conductor") then + table.insert(network.conductors, pos) + elseif ele.helpers.get_item_group(name, "ele_machine") then + if ele.helpers.get_item_group(name, "ele_user") or + ele.helpers.get_item_group(name, "ele_storage") then + table.insert(network.users, pos) + elseif ele.helpers.get_item_group(name, "ele_provider") then + table.insert(network.providers, pos) + end + end end end + + break + elseif dead_end and not placed then + -- Dead end removed, remove it from the network + -- Get the network + local network_ids = ele.graphcache.devices[minetest.hash_node_position(positions[1])] or + {minetest.pos_to_string(positions[1])} + + if not #network_ids then + -- We're evidently not on a network, nothing to remove ourselves from + break + end + + for _,int_net in ipairs(network_ids) do + if ele.graphcache[int_net] then + local network = ele.graphcache[int_net] + + -- The network was deleted. + if int_net == minetest.pos_to_string(pos) then + for _,v in ipairs(network.conductors) do + local pos1 = minetest.hash_node_position(v) + ele.graphcache.devices[pos1] = nil + end + ele.graphcache[int_net] = nil + else + -- Search for and remove device + ele.graphcache.devices[minetest.hash_node_position(pos)] = nil + for tblname, table in pairs(network) do + if type(table) == "table" then + for devicenum, device in pairs(table) do + if vector.equals(device, pos) then + table[devicenum] = nil + end + end + end + end + end + end + end + break + else + -- Not a dead end, so the whole network needs to be recalculated + for _,v in ipairs(ele.graphcache[net].conductors) do + local pos1 = minetest.hash_node_position(v) + ele.graphcache.devices[pos1] = nil + end + ele.graphcache[net] = nil + break end + break end - else - -- Not a dead end, so the whole network needs to be recalculated - for _,v in ipairs(ele.graphcache[net].all_nodes) do - local pos1 = minetest.hash_node_position(v) - clear_networks_from_node(v) - ele.graphcache.devices[pos1] = nil - end - ele.graphcache[net] = nil end end end