diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a37273b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +files/ diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 0000000..9c9b438 --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,15 @@ + +globals = { + "digilines", + "digicontrol" +} + +read_globals = { + "vector", + "screwdriver", + "minetest", + "default", + "pipeworks", + "dump", + "VoxelArea", +} diff --git a/diode.lua b/diode.lua new file mode 100644 index 0000000..7bccdab --- /dev/null +++ b/diode.lua @@ -0,0 +1,37 @@ + +minetest.register_node("digicontrol:diode", { + description = "Digilines Diode", + inventory_image = "digicontrol_diode.png", + tiles = { + "digicontrol_diode.png", + "digicontrol_bottom.png", + "digicontrol_side_port.png", + "digicontrol_side_port.png", + "digicontrol_side.png", + "digicontrol_side.png" + }, + drawtype = "nodebox", + node_box = digicontrol.node_box, + selection_box = digicontrol.selection_box, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = false, + groups = {digicontrol = 1, dig_immediate = 2}, + digiline = { + semiconductor = { + rules = function(node) + return { + digicontrol.get_rule(1, node.param2) + } + end + }, + wire = { + rules = function(node) + return { + digicontrol.get_rule(1, node.param2), + digicontrol.get_rule(3, node.param2) + } + end + } + } +}) diff --git a/filter.lua b/filter.lua new file mode 100644 index 0000000..5b2ed2c --- /dev/null +++ b/filter.lua @@ -0,0 +1,46 @@ + +minetest.register_node("digicontrol:filter", { + description = "Digilines Filter", + inventory_image = "digicontrol_filter.png", + tiles = { + "digicontrol_filter.png", + "digicontrol_bottom.png", + "digicontrol_side_port.png", + "digicontrol_side_port.png", + "digicontrol_side.png", + "digicontrol_side.png" + }, + drawtype = "nodebox", + node_box = digicontrol.node_box, + selection_box = digicontrol.selection_box, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = false, + groups = {digicontrol = 1, dig_immediate = 2}, + digiline = { + semiconductor = { + rules = function(node, pos, from, channel) + local setchannel = minetest.get_meta(pos):get_string("channel") + if channel ~= setchannel then return {} end + local side = digicontrol.get_side(pos, from, node.param2) + if side == 3 then + return { + digicontrol.get_rule(1, node.param2) + } + else + return { + digicontrol.get_rule(3, node.param2) + } + end + end + }, + wire = { + rules = function(node) + return { + digicontrol.get_rule(1, node.param2), + digicontrol.get_rule(3, node.param2) + } + end + } + } +}) diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..595564f --- /dev/null +++ b/init.lua @@ -0,0 +1,49 @@ + +digicontrol = {} + +digicontrol.selection_box = { + type = "fixed", + fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 } +} + +digicontrol.node_box = { + type = "fixed", + fixed = { + { -8/16, -8/16, -8/16, 8/16, -7/16, 8/16 }, + { -6/16, -7/16, -6/16, 6/16, -6/16, 6/16 } + }, +} + +local BASE_RULES = { + {x = 0, y = 0, z = 1}, -- Up (side 0) + {x = 1, y = 0, z = 0}, -- Right (side 1) + {x = 0, y = 0, z =-1}, -- Down (side 2) + {x =-1, y = 0, z = 0} -- Left (side 3) +} + +digicontrol.all_rules = BASE_RULES + +function digicontrol.get_rule(side, param2) + if param2 >= 4 then return nil end + return BASE_RULES[((side + param2) % 4) + 1] +end + +function digicontrol.get_side(pos, from, param2) + if param2 >= 4 then return nil end + local dir = vector.subtract(from, pos) + local facedir = minetest.dir_to_facedir(dir) + return ((facedir - param2) + 4) % 4 +end + +local MP = minetest.get_modpath("digicontrol") + +-- Overrides to digilines functions +dofile(MP.."/override.lua") + +-- Nodes +dofile(MP.."/diode.lua") +dofile(MP.."/splitter.lua") +dofile(MP.."/trisplitter.lua") +dofile(MP.."/filter.lua") +--dofile(MP.."/limiter.lua") +--dofile(MP.."/router.lua") diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000..9c01ff8 --- /dev/null +++ b/mod.conf @@ -0,0 +1,5 @@ +name = digicontrol +description = Adds nodes to control the flow of digiline messages +depends = default, digilines +optional_depends = digiline_routing +min_minetest_version = 5.0 \ No newline at end of file diff --git a/override.lua b/override.lua new file mode 100644 index 0000000..c1003cc --- /dev/null +++ b/override.lua @@ -0,0 +1,81 @@ + +-- Override digilines.transmit and digilines.receptor_send to add more functionality +-- Mostly copied from https://github.com/minetest-mods/digilines/blob/master/internal.lua + + +local function queue_new() + return {nextRead = 1, nextWrite = 1} +end + +local function queue_empty(queue) + return queue.nextRead == queue.nextWrite +end + +local function queue_enqueue(queue, object) + local nextWrite = queue.nextWrite + queue[nextWrite] = object + queue.nextWrite = nextWrite + 1 +end + +local function queue_dequeue(queue) + local nextRead = queue.nextRead + local object = queue[nextRead] + queue[nextRead] = nil + queue.nextRead = nextRead + 1 + return object[1], object[2] +end + +function digilines.transmit(pos, channel, msg, checked, origin) + local checkedID = minetest.hash_node_position(pos) + if checked[checkedID] or not origin then + return + end + checked[checkedID] = true + + digilines.vm_begin() + local queue = queue_new() + queue_enqueue(queue, {pos, origin}) + while not queue_empty(queue) do + local curPos, fromPos = queue_dequeue(queue) + local node = digilines.get_node_force(curPos) + local spec = digilines.getspec(node) + if spec then + -- Effector actions --> Receive + if spec.effector then + spec.effector.action(curPos, node, channel, msg, fromPos) + end + -- Cable actions --> Transmit + local rules + -- Custom semiconductor def for digicontrol nodes + if spec.semiconductor then + rules = spec.semiconductor.rules(node, curPos, fromPos, channel) + elseif spec.wire then + rules = digilines.importrules(spec.wire.rules, node) + end + if rules then + for _, rule in ipairs(rules) do + local nextPos = digilines.addPosRule(curPos, rule) + if digilines.rules_link(curPos, nextPos) then + checkedID = minetest.hash_node_position(nextPos) + if not checked[checkedID] then + checked[checkedID] = true + queue_enqueue(queue, {nextPos, curPos}) + end + end + end + end + end + end + digilines.vm_end() +end + + +function digilines.receptor_send(pos, rules, channel, msg) + local checked = {} + checked[minetest.hash_node_position(pos)] = true -- exclude itself + for _,rule in ipairs(rules) do + if digilines.rules_link(pos, digilines.addPosRule(pos, rule)) then + digilines.transmit(digilines.addPosRule(pos, rule), channel, msg, checked, pos) + end + end +end diff --git a/splitter.lua b/splitter.lua new file mode 100644 index 0000000..623d2ef --- /dev/null +++ b/splitter.lua @@ -0,0 +1,46 @@ + +minetest.register_node("digicontrol:splitter", { + description = "Digilines Splitter", + inventory_image = "digicontrol_splitter.png", + tiles = { + "digicontrol_splitter.png", + "digicontrol_bottom.png", + "digicontrol_side.png", + "digicontrol_side_port.png", + "digicontrol_side_port.png", + "digicontrol_side_port.png" + }, + drawtype = "nodebox", + node_box = digicontrol.node_box, + selection_box = digicontrol.selection_box, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = false, + groups = {digicontrol = 1, dig_immediate = 2}, + digiline = { + semiconductor = { + rules = function(node, pos, from) + local side = digicontrol.get_side(pos, from, node.param2) + if side == 3 then + return { + digicontrol.get_rule(0, node.param2), + digicontrol.get_rule(2, node.param2) + } + elseif side == 0 or side == 2 then + return { + digicontrol.get_rule(3, node.param2) + } + end + end + }, + wire = { + rules = function(node) + return { + digicontrol.get_rule(0, node.param2), + digicontrol.get_rule(2, node.param2), + digicontrol.get_rule(3, node.param2) + } + end + } + } +}) diff --git a/textures/digicontrol_bottom.png b/textures/digicontrol_bottom.png new file mode 100644 index 0000000..7ae955c Binary files /dev/null and b/textures/digicontrol_bottom.png differ diff --git a/textures/digicontrol_diode.png b/textures/digicontrol_diode.png new file mode 100644 index 0000000..4a91d4c Binary files /dev/null and b/textures/digicontrol_diode.png differ diff --git a/textures/digicontrol_filter.png b/textures/digicontrol_filter.png new file mode 100644 index 0000000..9602d83 Binary files /dev/null and b/textures/digicontrol_filter.png differ diff --git a/textures/digicontrol_side.png b/textures/digicontrol_side.png new file mode 100644 index 0000000..4694434 Binary files /dev/null and b/textures/digicontrol_side.png differ diff --git a/textures/digicontrol_side_port.png b/textures/digicontrol_side_port.png new file mode 100644 index 0000000..449d2b3 Binary files /dev/null and b/textures/digicontrol_side_port.png differ diff --git a/textures/digicontrol_splitter.png b/textures/digicontrol_splitter.png new file mode 100644 index 0000000..967f54e Binary files /dev/null and b/textures/digicontrol_splitter.png differ diff --git a/textures/digicontrol_trisplitter.png b/textures/digicontrol_trisplitter.png new file mode 100644 index 0000000..86e338a Binary files /dev/null and b/textures/digicontrol_trisplitter.png differ diff --git a/textures/digicontrol_trisplitter2.png b/textures/digicontrol_trisplitter2.png new file mode 100644 index 0000000..3d8ff5b Binary files /dev/null and b/textures/digicontrol_trisplitter2.png differ diff --git a/trisplitter.lua b/trisplitter.lua new file mode 100644 index 0000000..e4774fd --- /dev/null +++ b/trisplitter.lua @@ -0,0 +1,44 @@ + +minetest.register_node("digicontrol:trisplitter", { + description = "Digilines Tri-Splitter", + inventory_image = "digicontrol_trisplitter.png", + tiles = { + "digicontrol_trisplitter.png", + "digicontrol_bottom.png", + "digicontrol_side_port.png", + "digicontrol_side_port.png", + "digicontrol_side_port.png", + "digicontrol_side_port.png" + }, + drawtype = "nodebox", + node_box = digicontrol.node_box, + selection_box = digicontrol.selection_box, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = false, + groups = {digicontrol = 1, dig_immediate = 2}, + digiline = { + semiconductor = { + rules = function(node, pos, from) + local side = digicontrol.get_side(pos, from, node.param2) + if side == 3 then + return { + digicontrol.get_rule(0, node.param2), + digicontrol.get_rule(1, node.param2), + digicontrol.get_rule(2, node.param2) + } + else + return { + digicontrol.get_rule(3, node.param2) + } + end + end + }, + wire = { + rules = function(node) + if node.param2 >= 4 then return {} end + return digicontrol.all_rules + end + } + } +})