diff --git a/init.lua b/init.lua index c5d1a9c..fcece74 100644 --- a/init.lua +++ b/init.lua @@ -8,4 +8,6 @@ local MODNAME = "digiline_routing" local MODPATH = minetest.get_modpath(MODNAME) dofile(MODPATH.."/overheating.lua") +dofile(MODPATH.."/multiblock.lua") dofile(MODPATH.."/diode.lua") +dofile(MODPATH.."/splitter.lua") diff --git a/multiblock.lua b/multiblock.lua new file mode 100644 index 0000000..42a1649 --- /dev/null +++ b/multiblock.lua @@ -0,0 +1,51 @@ +-- © 2017 numberZero +-- License: GNU Lesser General Public License, version 2 (or any later version) + +digiline_routing.multiblock = {} + +digiline_routing.multiblock.build2 = function(node1, node2, itemstack, placer, pointed_thing) + local under = pointed_thing.under + local pos + if minetest.registered_items[minetest.get_node(under).name].buildable_to then + pos = under + else + pos = pointed_thing.above + end + + if minetest.is_protected(pos, placer:get_player_name()) and not minetest.check_player_privs(placer, "protection_bypass") then + minetest.record_protection_violation(pos, placer:get_player_name()) + return itemstack, false + end + + local dir = minetest.dir_to_facedir(placer:get_look_dir()) + local botpos = vector.add(pos, minetest.facedir_to_dir(dir)) + + if minetest.is_protected(botpos, placer:get_player_name()) and not minetest.check_player_privs(placer, "protection_bypass") then + minetest.record_protection_violation(botpos, placer:get_player_name()) + return itemstack, false + end + + if not minetest.registered_nodes[minetest.get_node(botpos).name].buildable_to then + return itemstack, false + end + + minetest.set_node(pos, {name = node1, param2 = dir}) + minetest.set_node(botpos, {name = node2, param2 = dir}) + + if not minetest.setting_getbool("creative_mode") then + itemstack:take_item() + end + return itemstack, true +end + +digiline_routing.multiblock.dig2 = function(pos, node) + local dir = minetest.facedir_to_dir(node.param2) + local tail = vector.add(pos, dir) + minetest.swap_node(tail, {name = "air"}) -- not remove_node +end + +digiline_routing.multiblock.dig2b = function(pos, node) + local dir = minetest.facedir_to_dir(node.param2) + local head = vector.subtract(pos, dir) + minetest.remove_node(head) +end diff --git a/splitter.lua b/splitter.lua new file mode 100644 index 0000000..b9ebf06 --- /dev/null +++ b/splitter.lua @@ -0,0 +1,125 @@ +-- © 2017 numberZero +-- License: GNU Lesser General Public License, version 2 (or any later version) + +local OVERLOAD_THRESHOLD = 20.0 + +local BASE_RULES = { + [0] = {x = -1, y = 0, z = 0}, + [1] = {x = 0, y = 0, z = 1}, + [2] = {x = 1, y = 0, z = 0}, + [3] = {x = 0, y = 0, z = -1}, +} + +local rules_in = {} +local rules_out = {} + +for k = 0,3 do + rules_in[k] = {} + rules_out[k] = {} +-- for m = 0,2 do +-- table.insert(rules_in[k], BASE_RULES[(k + m + 3) % 4]) +-- table.insert(rules_out[k], BASE_RULES[(k + m + 1) % 4]) +-- end + table.insert(rules_in[k], BASE_RULES[(k) % 4]) + table.insert(rules_in[k], BASE_RULES[(k + 2) % 4]) + table.insert(rules_out[k], BASE_RULES[(k + 1) % 4]) +end + +local function splitter_rules_in(node) + return rules_in[node.param2] +end + +local function splitter_rules_out(node) + return rules_out[node.param2] +end + +local function splitter_place(...) + return (digiline_routing.multiblock.build2("digiline_routing:splitter", "digiline_routing:splitter_b", ...)) -- adjust to 1 value +end + +local function splitter_cleanup(pos, node) + digiline_routing.overheat.forget(pos) + digiline_routing.multiblock.dig2(pos, node) +end + +local function splitter_in_action(pos, node, channel, msg) +-- if digiline_routing.overheat.heat(pos) > OVERLOAD_THRESHOLD then +-- digiline_routing.overheat.forget(pos) +-- minetest.dig_node(pos) +-- minetest.add_item(pos, node.name) +-- return +-- end +-- digiline:receptor_send(pos, diode_rules_out(node), channel, msg) +end + +local function splitter_out_action(pos, node, channel, msg) +-- if digiline_routing.overheat.heat(pos) > OVERLOAD_THRESHOLD then +-- digiline_routing.overheat.forget(pos) +-- minetest.dig_node(pos) +-- minetest.add_item(pos, node.name) +-- return +-- end +-- digiline:receptor_send(pos, diode_rules_out(node), channel, msg) +end + +minetest.register_node("digiline_routing:splitter", { + description = "Digiline Splitter", + drawtype = "nodebox", + tiles = { + "digiline_routing_metal.png" + }, + paramtype = "light", + paramtype2 = "facedir", + groups = {dig_immediate=2}, + node_box = { + type = "fixed", + fixed = { +-- { -8/16, -8/16, -1/16, 24/16, -7/16, 1/16 }, +-- { -1/16, -8/16, -8/16, 1/16, -7/16, 8/16 }, +-- { -4/16, -8/16, -2/16, 4/16, -6/16, 2/16 }, +-- { -3/16, -8/16, -3/16, 3/16, -6/16, 3/16 }, +-- { -2/16, -8/16, -4/16, 2/16, -6/16, 4/16 }, + { -1/16, -8/16, 4/16, 1/16, -7/16, 24/16 }, + { -8/16, -8/16, -1/16, 8/16, -7/16, 1/16 }, + { -4/16, -8/16, -2/16, 4/16, -6/16, 2/16 }, + { -3/16, -8/16, -3/16, 3/16, -6/16, 3/16 }, + { -2/16, -8/16, -4/16, 2/16, -6/16, 4/16 }, + }, + }, + on_place = splitter_place, + after_destruct = splitter_cleanup, + digiline = { + effector = { + action = splitter_in_action, + rules = splitter_rules_in, + }, + receptor = { + rules = splitter_rules_in, + }, + }, +}) + +minetest.register_node("digiline_routing:splitter_b", { + description = "<> Digiline Splitter (Part B)", + drawtype = "nodebox", + tiles = { + "digiline_routing_metal.png" + }, + paramtype = "light", + paramtype2 = "facedir", + groups = {dig_immediate=2, not_in_creative_inventory=1}, + node_box = { + type = "fixed", + fixed = {{ -1/32, -31/64, -7/16, 1/32, -29/64, 7/16 }}, -- hidden, but nonempty for the case of some bug + }, + after_destruct = digiline_routing.multiblock.dig2b, + digiline = { + effector = { + action = splitter_out_action, + rules = splitter_rules_out, + }, + receptor = { + rules = splitter_rules_out, + }, + }, +})