From c92659a11ad77093b8a66a43a8fe362590774d48 Mon Sep 17 00:00:00 2001 From: cheapie Date: Fri, 13 Sep 2019 14:09:25 -0500 Subject: [PATCH] Add I/O expander --- README | 7 +- init.lua | 3 + ioexpander.lua | 176 +++++++++++++++++++++++++++++++ textures/digistuff_ioexp_top.png | Bin 0 -> 10739 bytes 4 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 ioexpander.lua create mode 100644 textures/digistuff_ioexp_top.png diff --git a/README b/README index 617705a..79f68c7 100644 --- a/README +++ b/README @@ -10,7 +10,8 @@ Textures WITH "adwaita" in the file name - These are icons by the GNOME Project, Depends: Required: digilines (base only) and mesecons (base only) -Only needed for craft recipes: default, mesecons_luacontroller, basic_materials +Optional: mesecons_noteblock (for digilines noteblock), mesecons_mvps (for digilines piston), mesecons_luacontroller (for I/O expander) +Only needed for craft recipes: default, basic_materials How to use digilines buttons: @@ -66,3 +67,7 @@ Send a number representing a time in seconds, from 0.5 to 3600. When the time ex How to use the junction box: These are just plain digilines conductors (like digimese) but can skip over one node to another junction box or certain other nodes. As in, [digiline][junction box][dirt][junction box][digiline] will work to transmit signals "through" the dirt. + +How to use the I/O expander: +After setting a channel, send a table (same format as a Luacontroller's "port" table) to set the output states. +A table in this same format will be sent back whenever an input changes or you manually poll it by sending a "GET" message. diff --git a/init.lua b/init.lua index 4f336b4..4df2e65 100644 --- a/init.lua +++ b/init.lua @@ -14,6 +14,9 @@ local components = { "piston", "timer", } + +if minetest.get_modpath("mesecons_luacontroller") then table.insert(components,"ioexpander") end + for _,name in ipairs(components) do dofile(string.format("%s%s%s.lua",minetest.get_modpath(minetest.get_current_modname()),DIR_DELIM,name)) end diff --git a/ioexpander.lua b/ioexpander.lua new file mode 100644 index 0000000..7e25772 --- /dev/null +++ b/ioexpander.lua @@ -0,0 +1,176 @@ +local explode_port_states = function(state) + local port = {} + port.a = state%2 == 1 + port.b = state%4 >= 2 + port.c = state%8 >= 4 + port.d = state%16 >= 8 + return port +end + +local implode_port_states = function(port) + local state = 0 + if port.a then state = state + 1 end + if port.b then state = state + 2 end + if port.c then state = state + 4 end + if port.d then state = state + 8 end + return state +end + +local gettiles = function(state) + tiles = { + "digistuff_ioexp_top.png", + "jeija_microcontroller_bottom.png", + "jeija_microcontroller_sides.png", + "jeija_microcontroller_sides.png", + "jeija_microcontroller_sides.png", + "jeija_microcontroller_sides.png" + } + local port = explode_port_states(state) + for p,v in pairs(port) do + if v then + tiles[1] = tiles[1].."^jeija_luacontroller_LED_"..string.upper(p)..".png" + end + end + return tiles +end + +local ioexp_get_on_rules = function(state) + local port = explode_port_states(state) + local rules = {} + if port.a then table.insert(rules,vector.new(-1,0,0)) end + if port.b then table.insert(rules,vector.new(0,0,1)) end + if port.c then table.insert(rules,vector.new(1,0,0)) end + if port.d then table.insert(rules,vector.new(0,0,-1)) end + return rules +end + +local ioexp_get_off_rules = function(state) + local port = explode_port_states(state) + local rules = {} + if not port.a then table.insert(rules,vector.new(-1,0,0)) end + if not port.b then table.insert(rules,vector.new(0,0,1)) end + if not port.c then table.insert(rules,vector.new(1,0,0)) end + if not port.d then table.insert(rules,vector.new(0,0,-1)) end + return rules +end + +local ioexp_digiline_send = function(pos) + local meta = minetest.get_meta(pos) + local channel = meta:get_string("channel") + local port = { + a = meta:get_int("aon") == 1, + b = meta:get_int("bon") == 1, + c = meta:get_int("con") == 1, + d = meta:get_int("don") == 1, + } + local outstate = explode_port_states(meta:get_int("outstate")) + for k,v in pairs(outstate) do port[k] = port[k] or v end + digiline:receptor_send(pos,digiline.rules.default,channel,port) +end + +local ioexp_handle_digilines = function(pos,node,channel,msg) + local meta = minetest.get_meta(pos) + if channel ~= meta:get_string("channel") then return end + if msg == "GET" then + ioexp_digiline_send(pos) + return + end + if type(msg) ~= "table" then return end + local state = implode_port_states(msg) + node.name = "digistuff:ioexpander_"..state + meta:set_int("outstate",state) + minetest.swap_node(pos,node) + for _,i in ipairs(ioexp_get_on_rules(state)) do + mesecon.receptor_on(pos,{i}) + end + for _,i in ipairs(ioexp_get_off_rules(state)) do + mesecon.receptor_off(pos,{i}) + end +end + +local ioexp_rule_to_port = function(rule) + if rule.x < 0 then return "a" + elseif rule.z > 0 then return "b" + elseif rule.x > 0 then return "c" + elseif rule.z < 0 then return "d" end +end + +local ioexp_handle_mesecons = function(pos,_,rule,state) + local meta = minetest.get_meta(pos) + local port = ioexp_rule_to_port(rule) + if not port then return end + local meta = minetest.get_meta(pos) + meta:set_int(port.."on",state == "on" and 1 or 0) + ioexp_digiline_send(pos) +end + +for i=0,15,1 do + local offstate = i == 0 + minetest.register_node("digistuff:ioexpander_"..i, { + description = offstate and "Digilines I/O Expander" or string.format("Digilines I/O Expander (on state %X - you hacker you!)",i), + groups = offstate and {cracky = 3,} or {cracky = 3,not_in_creative_inventory = 1,}, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec","field[channel;Channel;${channel}") + meta:set_int("aon",0) + meta:set_int("bon",0) + meta:set_int("con",0) + meta:set_int("don",0) + meta:set_int("outstate",i) + end, + tiles = gettiles(i), + inventory_image = "digistuff_ioexp_top.png", + drawtype = "nodebox", + drop = "digistuff:ioexpander_0", + selection_box = { + --From luacontroller + type = "fixed", + fixed = { -8/16, -8/16, -8/16, 8/16, -5/16, 8/16 }, + }, + node_box = { + --From Luacontroller + type = "fixed", + fixed = { + {-8/16, -8/16, -8/16, 8/16, -7/16, 8/16}, -- Bottom slab + {-5/16, -7/16, -5/16, 5/16, -6/16, 5/16}, -- Circuit board + {-3/16, -6/16, -3/16, 3/16, -5/16, 3/16}, -- IC + } + }, + paramtype = "light", + sunlight_propagates = true, + on_receive_fields = function(pos, formname, fields, sender) + local name = sender:get_player_name() + if minetest.is_protected(pos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then + minetest.record_protection_violation(pos,name) + return + end + local meta = minetest.get_meta(pos) + if fields.channel then meta:set_string("channel",fields.channel) end + end, + mesecons = { + effector = { + rules = ioexp_get_off_rules(i), + action_change = ioexp_handle_mesecons, + }, + receptor = { + state = mesecon.state.on, + rules = ioexp_get_on_rules(i), + }, + }, + digiline = { + receptor = {}, + effector = { + action = ioexp_handle_digilines, + }, + }, + }) +end + +minetest.register_craft({ + output = "digistuff:ioexpander_0", + recipe = { + {"","mesecons:wire_00000000_off","",}, + {"digilines:wire_std_00000000","basic_materials:silicon","mesecons:wire_00000000_off",}, + {"","mesecons:wire_00000000_off","",}, + } +}) diff --git a/textures/digistuff_ioexp_top.png b/textures/digistuff_ioexp_top.png new file mode 100644 index 0000000000000000000000000000000000000000..0b8ee3e5e86e03f0668db35ae0d7dc8b696908f3 GIT binary patch literal 10739 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 literal 0 HcmV?d00001