diff --git a/CHANGELOG.md b/CHANGELOG.md index 11a6ff4..960869b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ Notable Game Changes: - Improved hudbars - Improved command system and added Command Blocks - Added many new commands, while also improving some builtin Luanti ones. +- Redesign the electricity system using a system similar to [Age of Mending's](https://content.luanti.org/packages/Sumianvoice/pmb_core/) wiring system Other Game Changes: diff --git a/mods/ITEMS/pyutest_electricity/api.lua b/mods/ITEMS/pyutest_electricity/api.lua new file mode 100644 index 0000000..321dae8 --- /dev/null +++ b/mods/ITEMS/pyutest_electricity/api.lua @@ -0,0 +1,62 @@ +PyuTest.electricity_activate = function(pos, sender_pos) + local node = core.get_node(pos) + local def = core.registered_nodes[node.name] + + if def.__on_electricity_input then + def.__on_electricity_input(pos, node, sender_pos) + end +end + +PyuTest.component_after_place_node = function (pos) + local meta = core.get_meta(pos) + meta:set_string(PyuTest.WIRECUTTER_META_NAME, core.serialize({})) +end + +PyuTest.component_action = function (pos, interacter) + core.sound_play("button", { + pos = pos, + gain = 1 + }) + + local p = PyuTest.get_node_electricity_targets(pos) + + if p then + for _, pp in pairs(p) do + PyuTest.electricity_activate(pp, pos) + end + else + core.chat_send_player(interacter:get_player_name(), "This component isn't bound to anything!") + end +end + +PyuTest.make_button = function(id, desc, groups, tiles) + PyuTest.make_node(id, desc, PyuTest.util.tableconcat(groups, { + electric = 1 + }), tiles, { + is_ground_content = false, + after_place_node = PyuTest.component_after_place_node, + on_rightclick = function(pos, node, clicker) + PyuTest.component_action(pos, clicker) + end + }) +end + +PyuTest.make_electricity_device = function(id, desc, groups, tiles, craftitem, opts, ifn) + PyuTest.make_node(id, desc, PyuTest.util.tableconcat(groups, { + electric = 1 + }), tiles, PyuTest.util.tableconcat(opts or {}, { + __on_electricity_input = ifn, + })) + + -- Dont create a recipe if it is nil + if craftitem ~= nil then + core.register_craft({ + output = id, + recipe = { + { "group:cobble", "group:cobble", "group:cobble" }, + { "group:cobble", craftitem, "group:cobble" }, + { "group:cobble", "group:cobble", "group:cobble" } + }, + }) + end +end diff --git a/mods/ITEMS/pyutest_electricity/components.lua b/mods/ITEMS/pyutest_electricity/components.lua index 935eafa..5098931 100644 --- a/mods/ITEMS/pyutest_electricity/components.lua +++ b/mods/ITEMS/pyutest_electricity/components.lua @@ -1 +1,13 @@ -- Nodes that can power other nodes +PyuTest.make_button("pyutest_electricity:button", "Button", { + cracky = PyuTest.BLOCK_NORMAL, +}, { "pyutest-button.png" }) + +core.register_craft({ + output = "pyutest_electricity:button", + recipe = { + { "group:cobble", "group:cobble", "group:cobble" }, + { "group:cobble", "pyutest_ores:copper_ingot", "group:cobble" }, + { "group:cobble", "group:cobble", "group:cobble" } + }, +}) diff --git a/mods/ITEMS/pyutest_electricity/delayer.lua b/mods/ITEMS/pyutest_electricity/delayer.lua deleted file mode 100644 index 48acccb..0000000 --- a/mods/ITEMS/pyutest_electricity/delayer.lua +++ /dev/null @@ -1,42 +0,0 @@ -local delay_multipliers = { - 100, -- Default, 0.1 seconds - 200, -- 0.2 seconds - 400, -- 0.4 seconds - 800, -- 0.8 seconds -} - -local function index_name(n) - if n == 1 or n == nil then - return "pyutest_electricity:zinc_wire" - else - return string.format("pyutest_electricity:zinc_wire_%d", n) - end -end - -for i, v in ipairs(delay_multipliers) do - PyuTest.make_wire(index_name(i), "Zinc Wire", { - snappy = PyuTest.BLOCK_NORMAL, - not_in_creative_inventory = i ~= 1 and 1 or nil - }, "#bed3d4", { - drop = index_name(), - on_rightclick = function(pos, node, clicker) - local ni = v - - if i == #delay_multipliers then - ni = 1 - else - ni = i + 1 - end - - core.set_node(pos, { name = index_name(ni) }) - end - }, string.format("pyutest-wire-d%d.png", i), v) -end - -core.register_craft({ - output = string.format("%s 4", index_name()), - recipe = { - "pyutest_ores:zinc_ingot" - }, - type = "shapeless" -}) diff --git a/mods/ITEMS/pyutest_electricity/devices.lua b/mods/ITEMS/pyutest_electricity/devices.lua index 9639ff5..9970fa2 100644 --- a/mods/ITEMS/pyutest_electricity/devices.lua +++ b/mods/ITEMS/pyutest_electricity/devices.lua @@ -1,5 +1,4 @@ -- Nodes that are to be powered by other nodes - PyuTest.make_electricity_device("pyutest_electricity:freezer_device", "Freezer Device", { cracky = PyuTest.BLOCK_FAST }, { "pyutest-freezer.png" }, "pyutest_blocks:ice_block", nil, function(pos, node, sender_pos) @@ -34,23 +33,6 @@ PyuTest.make_electricity_device("pyutest_electricity:heater_device", "Heater Dev end) end) - -PyuTest.make_electricity_device("pyutest_electricity:lamp_device", "Lamp Device", { - cracky = PyuTest.BLOCK_FAST, -}, { "pyutest-lamp.png" }, "pyutest_blocks:light", nil, function(pos, node, sender_pos) - core.set_node(pos, { name = "pyutest_electricity:lamp_device_on" }) -end) - -PyuTest.make_electricity_device("pyutest_electricity:lamp_device_on", "Lamp Device", { - cracky = PyuTest.BLOCK_FAST, - not_in_creative_inventory = 1 -}, { "pyutest-lamp.png" }, nil, { - light_source = core.LIGHT_MAX, - drop = "pyutest_electricity:lamp_device" -}, function(pos, node, sender_pos) - core.set_node(pos, { name = "pyutest_electricity:lamp_device" }) -end) - PyuTest.make_electricity_device("pyutest_electricity:time_device", "Time Device", { cracky = PyuTest.BLOCK_FAST }, { "pyutest-time-device.png" }, nil, nil, function(pos, node) diff --git a/mods/ITEMS/pyutest_electricity/devices/command_block.lua b/mods/ITEMS/pyutest_electricity/devices/command_block.lua index 34bb464..20cbf40 100644 --- a/mods/ITEMS/pyutest_electricity/devices/command_block.lua +++ b/mods/ITEMS/pyutest_electricity/devices/command_block.lua @@ -26,15 +26,4 @@ PyuTest.make_electricity_device("pyutest_electricity:command_block", "Command Bl local command = meta:get_string("command") PyuTest.execute_as(owner, command) - - for _, v in pairs(PyuTest.get_full_neighbours(pos)) do - local n = core.get_node(v) - - -- To prevent infinite loops - if v ~= sender_pos then - core.after(PyuTest.ELECTRICITY_TICK, function() - PyuTest.electricity_activate(v, n, pos) - end) - end - end end) diff --git a/mods/ITEMS/pyutest_electricity/devices/lamp.lua b/mods/ITEMS/pyutest_electricity/devices/lamp.lua new file mode 100644 index 0000000..a579f8d --- /dev/null +++ b/mods/ITEMS/pyutest_electricity/devices/lamp.lua @@ -0,0 +1,15 @@ +PyuTest.make_electricity_device("pyutest_electricity:lamp_device", "Lamp Device", { + cracky = PyuTest.BLOCK_FAST, +}, { "pyutest-lamp.png" }, "pyutest_blocks:light", nil, function(pos, node, sender_pos) + core.swap_node(pos, { name = "pyutest_electricity:lamp_device_on" }) +end) + +PyuTest.make_electricity_device("pyutest_electricity:lamp_device_on", "Lamp Device", { + cracky = PyuTest.BLOCK_FAST, + not_in_creative_inventory = 1 +}, { "pyutest-lamp.png" }, nil, { + light_source = core.LIGHT_MAX, + drop = "pyutest_electricity:lamp_device" +}, function(pos, node, sender_pos) + core.swap_node(pos, { name = "pyutest_electricity:lamp_device" }) +end) diff --git a/mods/ITEMS/pyutest_electricity/init.lua b/mods/ITEMS/pyutest_electricity/init.lua index fc4dfe1..63dc837 100644 --- a/mods/ITEMS/pyutest_electricity/init.lua +++ b/mods/ITEMS/pyutest_electricity/init.lua @@ -1,122 +1,8 @@ local modpath = core.get_modpath("pyutest_electricity") -PyuTest.ELECTRICITY_TICK = 1 / 1000 - -PyuTest.electricity_activate = function(pos, node, sender_pos) - local def = core.registered_nodes[node.name] - - if def.__on_electricity_activated then - def.__on_electricity_activated(pos, node, sender_pos) - end -end - -PyuTest.make_button = function(id, desc, groups, tiles) - PyuTest.make_node(id, desc, PyuTest.util.tableconcat(groups, { - electric = 1 - }), tiles, { - is_ground_content = false, - on_rightclick = function(pos, node, clicker) - core.sound_play("button", { - pos = pos, - gain = 1 - }) - - for _, v in pairs(PyuTest.get_full_neighbours(pos)) do - local n = core.get_node(v) - core.after(PyuTest.ELECTRICITY_TICK, function() - PyuTest.electricity_activate(v, n, pos) - end) - end - end - }) -end - -PyuTest.make_wire = function(id, desc, groups, color, opts, texture, delay) - local del = PyuTest.ELECTRICITY_TICK * delay - - PyuTest.make_node(id, desc, PyuTest.util.tableconcat(groups, { - electric = 1 - }), { - texture or "pyutest-wire.png", - texture or "pyutest-wire.png", - texture or "pyutest-wire.png", - texture or "pyutest-wire.png" - }, PyuTest.util.tableconcat(opts or {}, { - drawtype = "raillike", - color = color, - paramtype = "light", - sunlight_propagates = true, - walkable = false, - inventory_image = "pyutest-powder.png", - wield_image = "pyutest-powder.png", - buildable_to = true, - selection_box = { - type = "fixed", - fixed = PyuTest.NODE_BOXES.CARPET.fixed - }, - - __on_electricity_activated = function(pos, node, sender_pos) - for _, v in pairs(PyuTest.get_full_neighbours(pos)) do - local n = core.get_node(v) - - -- To prevent infinite loops - if v ~= sender_pos then - core.after(del, function() - PyuTest.electricity_activate(v, n, pos) - end) - end - end - end - })) -end - -PyuTest.make_electricity_device = function(id, desc, groups, tiles, craftitem, opts, afn) - PyuTest.make_node(id, desc, PyuTest.util.tableconcat(groups, { - electric = 1 - }), tiles, PyuTest.util.tableconcat(opts or {}, { - __on_electricity_activated = afn, - })) - - -- Dont create a recipe if it is nil - if craftitem ~= nil then - core.register_craft({ - output = id, - recipe = { - { "group:cobble", "group:cobble", "group:cobble" }, - { "group:cobble", craftitem, "group:cobble" }, - { "group:cobble", "group:cobble", "group:cobble" } - }, - }) - end -end - -PyuTest.make_button("pyutest_electricity:button", "Button", { - cracky = PyuTest.BLOCK_NORMAL, -}, { "pyutest-button.png" }) - -PyuTest.make_wire("pyutest_electricity:copper_wire", "Copper Wire", { - snappy = PyuTest.BLOCK_NORMAL -}, "darkgoldenrod", nil, nil, 1) - - -core.register_craft({ - output = "pyutest_electricity:copper_wire 4", - recipe = { - "pyutest_ores:copper_ingot" - }, - type = "shapeless" -}) - -core.register_craft({ - output = "pyutest_electricity:button", - recipe = { - { "group:cobble", "group:cobble", "group:cobble" }, - { "group:cobble", "pyutest_ores:copper_ingot", "group:cobble" }, - { "group:cobble", "group:cobble", "group:cobble" } - }, -}) - -dofile(modpath .. "/devices.lua") -dofile(modpath .. "/devices/command_block.lua") -dofile(modpath .. "/delayer.lua") +dofile(modpath .. "/wirecutter.lua") +dofile(modpath .. "/api.lua") dofile(modpath .. "/components.lua") +dofile(modpath .. "/devices.lua") +dofile(modpath .. "/devices/lamp.lua") +dofile(modpath .. "/devices/command_block.lua") diff --git a/mods/ITEMS/pyutest_electricity/mod.conf b/mods/ITEMS/pyutest_electricity/mod.conf index f103bb4..e3cefe3 100644 --- a/mods/ITEMS/pyutest_electricity/mod.conf +++ b/mods/ITEMS/pyutest_electricity/mod.conf @@ -1 +1 @@ -depends = pyutest_blocks,pyutest_cmds \ No newline at end of file +depends = pyutest_blocks,pyutest_cmds,pyutest_tools,pyutest_ores diff --git a/mods/ITEMS/pyutest_electricity/wirecutter.lua b/mods/ITEMS/pyutest_electricity/wirecutter.lua new file mode 100644 index 0000000..8b64bb0 --- /dev/null +++ b/mods/ITEMS/pyutest_electricity/wirecutter.lua @@ -0,0 +1,69 @@ +PyuTest.WIRECUTTER_META_NAME = "WIRECUTTER_TARGET" +local function wirecutter_meta(pos) + return core.serialize({ + x = pos.x, + y = pos.y, + z = pos.z + }) +end + +PyuTest.get_node_electricity_targets = function(pos) + local meta = core.get_meta(pos) + local s = meta:get_string(PyuTest.WIRECUTTER_META_NAME) + + if s ~= "" then + local positions = core.deserialize(s) + local r = {} + + for _, v in pairs(positions) do + table.insert(r, v) + end + return r + end + + return nil +end + +PyuTest.make_item("pyutest_electricity:wirecutter", "Wirecutter", {}, "pyutest-wirecutter.png", { + stack_max = 1, + + on_use = function (itemstack, user, pointed_thing) + if pointed_thing.type == "node" then + local s = wirecutter_meta(pointed_thing.under) + itemstack:get_meta():set_string(PyuTest.WIRECUTTER_META_NAME, s) + end + return itemstack + end, + + on_place = function (itemstack, placer, pointed_thing) + local s = itemstack:get_meta():get_string(PyuTest.WIRECUTTER_META_NAME) + + if s ~= "" then + local pos = pointed_thing.under + local pos2 = core.deserialize(s) + itemstack:get_meta():set_string(PyuTest.WIRECUTTER_META_NAME, "") + + local meta = core.get_meta(pos) + local oldvalue = core.deserialize(meta:get_string(PyuTest.WIRECUTTER_META_NAME)) + if oldvalue ~= nil then + table.insert(oldvalue, pos2) + meta:set_string(PyuTest.WIRECUTTER_META_NAME, core.serialize(oldvalue)) + else + core.chat_send_player(placer:get_player_name(), "Failed.") + end + else + core.chat_send_player(placer:get_player_name(), "No target set.") + end + + return itemstack + end +}) + +core.register_craft({ + output = "pyutest_electricity:wirecutter", + recipe = { + "pyutest_ores:copper_ingot", + "pyutest_ores:copper_ingot", + }, + type = "shapeless" +}) diff --git a/textures/pyutest-wirecutter.png b/textures/pyutest-wirecutter.png new file mode 100644 index 0000000..a8e308f Binary files /dev/null and b/textures/pyutest-wirecutter.png differ