diff options
Diffstat (limited to 'digistuff')
-rw-r--r-- | digistuff/button.lua | 160 | ||||
-rw-r--r-- | digistuff/camera.lua | 98 | ||||
-rw-r--r-- | digistuff/conductors.lua | 62 | ||||
-rw-r--r-- | digistuff/depends.txt | 1 | ||||
-rw-r--r-- | digistuff/detector.lua | 63 | ||||
-rw-r--r-- | digistuff/init.lua | 1123 | ||||
-rw-r--r-- | digistuff/light.lua | 71 | ||||
-rw-r--r-- | digistuff/nic.lua | 69 | ||||
-rw-r--r-- | digistuff/noteblock.lua | 64 | ||||
-rw-r--r-- | digistuff/panel.lua | 151 | ||||
-rw-r--r-- | digistuff/piezo.lua | 80 | ||||
-rw-r--r-- | digistuff/piston.lua | 222 | ||||
-rw-r--r-- | digistuff/sounds/digistuff_piston_extend.ogg | bin | 0 -> 6301 bytes | |||
-rw-r--r-- | digistuff/sounds/digistuff_piston_retract.ogg | bin | 0 -> 6214 bytes | |||
-rw-r--r-- | digistuff/textures/digistuff_piston_sides.png | bin | 0 -> 5179 bytes | |||
-rw-r--r-- | digistuff/touchscreen.lua | 279 |
16 files changed, 1339 insertions, 1104 deletions
diff --git a/digistuff/button.lua b/digistuff/button.lua new file mode 100644 index 0000000..76022f6 --- /dev/null +++ b/digistuff/button.lua @@ -0,0 +1,160 @@ +digistuff.button_turnoff = function (pos) + local node = minetest.get_node(pos) + if node.name=="digistuff:button_on" then --has not been dug + minetest.swap_node(pos, {name = "digistuff:button_off", param2=node.param2}) + if minetest.get_modpath("mesecons") then minetest.sound_play("mesecons_button_pop", {pos=pos}) end + end +end + +minetest.register_node("digistuff:button", { + drawtype = "nodebox", + tiles = { + "digistuff_digibutton_sides.png", + "digistuff_digibutton_sides.png", + "digistuff_digibutton_sides.png", + "digistuff_digibutton_sides.png", + "digistuff_digibutton_sides.png", + "digistuff_digibutton_off.png" + }, + paramtype = "light", + paramtype2 = "facedir", + legacy_wallmounted = true, + walkable = false, + sunlight_propagates = true, + selection_box = { + type = "fixed", + fixed = { -6/16, -6/16, 5/16, 6/16, 6/16, 8/16 } + }, + node_box = { + type = "fixed", + fixed = { + { -6/16, -6/16, 6/16, 6/16, 6/16, 8/16 }, -- the thin plate behind the button + { -4/16, -2/16, 4/16, 4/16, 2/16, 6/16 } -- the button itself + } + }, + digiline = + { + receptor = {} + }, + groups = {dig_immediate=2}, + description = "Digilines Button", + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec","size[8,4;]field[1,1;6,2;channel;Channel;${channel}]field[1,2;6,2;msg;Message;${msg}]button_exit[2.25,3;3,1;submit;Save]") + end, + on_receive_fields = function(pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + if fields.channel and fields.msg and fields.channel ~= "" and fields.msg ~= "" then + meta:set_string("channel",fields.channel) + meta:set_string("msg",fields.msg) + meta:set_string("formspec","") + minetest.swap_node(pos, {name = "digistuff:button_off", param2=minetest.get_node(pos).param2}) + else + minetest.chat_send_player(sender:get_player_name(),"Channel and message must both be set!") + end + end, + sounds = default and default.node_sound_stone_defaults(), +}) + +minetest.register_node("digistuff:button_off", { + drawtype = "nodebox", + tiles = { + "digistuff_digibutton_sides.png", + "digistuff_digibutton_sides.png", + "digistuff_digibutton_sides.png", + "digistuff_digibutton_sides.png", + "digistuff_digibutton_sides.png", + "digistuff_digibutton_off.png" + }, + paramtype = "light", + paramtype2 = "facedir", + legacy_wallmounted = true, + walkable = false, + sunlight_propagates = true, + selection_box = { + type = "fixed", + fixed = { -6/16, -6/16, 5/16, 6/16, 6/16, 8/16 } + }, + node_box = { + type = "fixed", + fixed = { + { -6/16, -6/16, 6/16, 6/16, 6/16, 8/16 }, -- the thin plate behind the button + { -4/16, -2/16, 4/16, 4/16, 2/16, 6/16 } -- the button itself + } + }, + digiline = + { + receptor = {} + }, + groups = {dig_immediate=2, not_in_creative_inventory=1}, + drop = "digistuff:button", + description = "Digilines Button (off state - you hacker you!)", + on_rightclick = function (pos, node, clicker) + local meta = minetest.get_meta(pos) + digiline:receptor_send(pos, digiline.rules.default, meta:get_string("channel"), meta:get_string("msg")) + minetest.swap_node(pos, {name = "digistuff:button_on", param2=node.param2}) + if minetest.get_modpath("mesecons") then minetest.sound_play("mesecons_button_push", {pos=pos}) end + minetest.after(0.5, digistuff.button_turnoff, pos) + end, + sounds = default and default.node_sound_stone_defaults(), +}) + +minetest.register_node("digistuff:button_on", { + drawtype = "nodebox", + tiles = { + "digistuff_digibutton_sides.png", + "digistuff_digibutton_sides.png", + "digistuff_digibutton_sides.png", + "digistuff_digibutton_sides.png", + "digistuff_digibutton_sides.png", + "digistuff_digibutton_on.png" + }, + paramtype = "light", + paramtype2 = "facedir", + legacy_wallmounted = true, + walkable = false, + light_source = 7, + sunlight_propagates = true, + selection_box = { + type = "fixed", + fixed = { -6/16, -6/16, 5/16, 6/16, 6/16, 8/16 } + }, + node_box = { + type = "fixed", + fixed = { + { -6/16, -6/16, 6/16, 6/16, 6/16, 8/16 }, + { -4/16, -2/16, 11/32, 4/16, 2/16, 6/16 } + } + }, + digiline = + { + receptor = {} + }, + groups = {dig_immediate=2, not_in_creative_inventory=1}, + drop = 'digistuff:button', + on_rightclick = function (pos, node, clicker) + local meta = minetest.get_meta(pos) + digiline:receptor_send(pos, digiline.rules.default, meta:get_string("channel"), meta:get_string("msg")) + if minetest.get_modpath("mesecons") then minetest.sound_play("mesecons_button_push", {pos=pos}) end + end, + description = "Digilines Button (on state - you hacker you!)", + sounds = default and default.node_sound_stone_defaults(), +}) + +minetest.register_craft({ + output = "digistuff:digimese", + recipe = { + {"digilines:wire_std_00000000","digilines:wire_std_00000000","digilines:wire_std_00000000"}, + {"digilines:wire_std_00000000","default:mese","digilines:wire_std_00000000"}, + {"digilines:wire_std_00000000","digilines:wire_std_00000000","digilines:wire_std_00000000"} + } +}) + +minetest.register_craft({ + output = "digistuff:button", + recipe = { + {"mesecons_button:button_off"}, + {"mesecons_luacontroller:luacontroller0000"}, + {"digilines:wire_std_00000000"} + } +}) diff --git a/digistuff/camera.lua b/digistuff/camera.lua new file mode 100644 index 0000000..3a2a129 --- /dev/null +++ b/digistuff/camera.lua @@ -0,0 +1,98 @@ +minetest.register_node("digistuff:camera", { + tiles = { + "digistuff_camera_top.png", + "digistuff_camera_bottom.png", + "digistuff_camera_right.png", + "digistuff_camera_left.png", + "digistuff_camera_back.png", + "digistuff_camera_front.png", + }, + digiline = + { + receptor = {} + }, + groups = {cracky=2}, + paramtype = "light", + paramtype2 = "facedir", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.1,-0.5,-0.28,0.1,-0.3,0.3}, --Camera Body + {-0.045,-0.42,-0.34,0.045,-0.36,-0.28}, -- Lens + {-0.05,-0.9,-0.05,0.05,-0.5,0.05}, --Pole + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.1,-0.5,-0.34,0.1,-0.3,0.3}, --Camera Body + } + }, + description = "Digilines Camera", + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec","size[8,6;]field[1,1;6,2;channel;Channel;${channel}]field[1,2;6,2;radius;Radius (max 10);${radius}]field[1,3;6,2;distance;Distance (max 20);${distance}]button_exit[2.25,4;3,1;submit;Save]") + end, + 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 + if fields.distance and tonumber(fields.distance) then meta:set_int("distance",math.max(math.min(20,fields.distance),0)) end + if fields.radius and tonumber(fields.radius) then meta:set_int("radius",math.max(math.min(10,fields.radius),1)) end + end, + sounds = default and default.node_sound_stone_defaults() +}) + +minetest.register_abm({ + nodenames = {"digistuff:camera"}, + interval = 1.0, + chance = 1, + action = function(pos,node) + local meta = minetest.get_meta(pos) + local channel = meta:get_string("channel") + local radius = meta:get_int("radius") + local distance = meta:get_int("distance") + local dir = vector.multiply(minetest.facedir_to_dir(node.param2),-1) + local spot = vector.add(pos,vector.multiply(dir,distance)) + local i = 0 + while i <= 10 and minetest.get_node(spot).name == "air" do + --Downward search for ground level + spot = vector.add(spot,vector.new(0,-1,0)) + i = i + 1 + end + if minetest.get_node(spot).name == "air" or minetest.get_node(spot).name == "ignore" then + --Ground not in range + return + end + + local found_any = false + local players_found = {} + local objs = minetest.get_objects_inside_radius(spot,radius) + if objs then + local _,obj + for _,obj in ipairs(objs) do + if obj:is_player() then + table.insert(players_found,obj:get_player_name()) + found_any = true + end + end + if found_any then + digiline:receptor_send({x=pos.x,y=pos.y-1,z=pos.z}, digiline.rules.default, channel, players_found) + end + end + end +}) + +minetest.register_craft({ + output = "digistuff:camera", + recipe = { + {"homedecor:plastic_sheeting","homedecor:plastic_sheeting","homedecor:plastic_sheeting"}, + {"default:glass","homedecor:ic","mesecons_luacontroller:luacontroller0000"}, + {"homedecor:plastic_sheeting","homedecor:plastic_sheeting","homedecor:plastic_sheeting"}, + } +}) diff --git a/digistuff/conductors.lua b/digistuff/conductors.lua new file mode 100644 index 0000000..77229e2 --- /dev/null +++ b/digistuff/conductors.lua @@ -0,0 +1,62 @@ +minetest.register_node("digistuff:digimese", { + description = "Digimese", + tiles = {"digistuff_digimese.png"}, + paramtype = "light", + light_source = 3, + groups = {cracky = 3, level = 2}, + is_ground_content = false, + sounds = default and default.node_sound_stone_defaults(), + digiline = { wire = { rules = { + {x = 1, y = 0, z = 0}, + {x =-1, y = 0, z = 0}, + {x = 0, y = 1, z = 0}, + {x = 0, y =-1, z = 0}, + {x = 0, y = 0, z = 1}, + {x = 0, y = 0, z =-1}}}} +}) + +minetest.register_node("digistuff:junctionbox", { + description = "Digilines Junction Box", + tiles = {"digistuff_junctionbox.png"}, + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky = 3}, + is_ground_content = false, + paramtype = "light", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.1,-0.15,0.35,0.1,0.15,0.5}, + } + }, + sounds = default and default.node_sound_stone_defaults(), + digiline = { + receptor = {}, + wire = { + rules = { + {x = 1,y = 0,z = 0}, + {x = -1,y = 0,z = 0}, + {x = 0,y = 0,z = 1}, + {x = 0,y = 0,z = -1}, + {x = 0,y = 1,z = 0}, + {x = 0,y = -1,z = 0}, + {x = 0,y = -2,z = 0}, + {x = 0,y = 2,z = 0}, + {x = -2,y = 0,z = 0}, + {x = 2,y = 0,z = 0}, + {x = 0,y = 0,z = -2}, + {x = 0,y = 0,z = 2}, + } + }, + }, +}) + +minetest.register_craft({ + output = "digistuff:junctionbox", + recipe = { + {"homedecor:plastic_sheeting","digilines:wire_std_00000000","homedecor:plastic_sheeting",}, + {"digilines:wire_std_00000000","digilines:wire_std_00000000","digilines:wire_std_00000000",}, + {"homedecor:plastic_sheeting","digilines:wire_std_00000000","homedecor:plastic_sheeting",}, + } +}) diff --git a/digistuff/depends.txt b/digistuff/depends.txt index a581a9b..cfb8465 100644 --- a/digistuff/depends.txt +++ b/digistuff/depends.txt @@ -1,3 +1,4 @@ default? digilines mesecons? +mesecons_mvps? diff --git a/digistuff/detector.lua b/digistuff/detector.lua new file mode 100644 index 0000000..f6542da --- /dev/null +++ b/digistuff/detector.lua @@ -0,0 +1,63 @@ +minetest.register_node("digistuff:detector", { + tiles = { + "digistuff_digidetector.png" + }, + digiline = + { + receptor = {} + }, + groups = {cracky=2}, + description = "Digilines Player Detector", + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec","size[8,4;]field[1,1;6,2;channel;Channel;${channel}]field[1,2;6,2;radius;Radius;${radius}]button_exit[2.25,3;3,1;submit;Save]") + end, + 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 + if fields.msg then meta:set_string("msg",fields.msg) end + if fields.radius then meta:set_string("radius",fields.radius) end + end, + sounds = default and default.node_sound_stone_defaults() +}) + +minetest.register_abm({ + nodenames = {"digistuff:detector"}, + interval = 1.0, + chance = 1, + action = function(pos) + local meta = minetest.get_meta(pos) + local channel = meta:get_string("channel") + local radius = meta:get_string("radius") + local found_any = false + local players_found = {} + if not radius or not tonumber(radius) or tonumber(radius) < 1 or tonumber(radius) > 10 then radius = 6 end + local objs = minetest.get_objects_inside_radius(pos, radius) + if objs then + local _,obj + for _,obj in ipairs(objs) do + if obj:is_player() then + table.insert(players_found,obj:get_player_name()) + found_any = true + end + end + if found_any then + digiline:receptor_send(pos, digiline.rules.default, channel, players_found) + end + end + end +}) + +minetest.register_craft({ + output = "digistuff:detector", + recipe = { + {"mesecons_detector:object_detector_off"}, + {"mesecons_luacontroller:luacontroller0000"}, + {"digilines:wire_std_00000000"} + } +}) diff --git a/digistuff/init.lua b/digistuff/init.lua index 33b5936..1deefe1 100644 --- a/digistuff/init.lua +++ b/digistuff/init.lua @@ -1,1110 +1,25 @@ digistuff = {} -digistuff.sounds_playing = {} -digistuff.update_panel_formspec = function (pos,dispstr) - local meta = minetest.get_meta(pos) - local locked = meta:get_int("locked") == 1 - local fs = "size[10,8]".. - "background[0,0;0,0;digistuff_panel_bg.png;true]".. - "label[0,0;%s]".. - (locked and "image_button[9,3;1,1;digistuff_panel_locked.png;unlock;]" or "image_button[9,3;1,1;digistuff_panel_unlocked.png;lock;]").. - "image_button[2,4.5;1,1;digistuff_adwaita_go-up.png;up;]".. - "image_button[1,5;1,1;digistuff_adwaita_go-previous.png;left;]".. - "image_button[3,5;1,1;digistuff_adwaita_go-next.png;right;]".. - "image_button[2,5.5;1,1;digistuff_adwaita_go-down.png;down;]".. - "image_button[1,6.5;1,1;digistuff_adwaita_edit-undo.png;back;]".. - "image_button[3,6.5;1,1;digistuff_adwaita_emblem-default.png;enter;]".. - "field[6,5.75;2,1;channel;Channel;${channel}]".. - "button[8,5.5;1,1;savechan;Set]" - fs = fs:format(minetest.formspec_escape(dispstr)):gsub("|","\n") - meta:set_string("formspec",fs) - meta:set_string("text",dispstr) +local components = { + "touchscreen", + "light", + "noteblock", + "camera", + "button", + "panel", + "piezo", + "detector", + "conductors", + "piston", +} +for _,name in ipairs(components) do + dofile(string.format("%s%s%s.lua",minetest.get_modpath(minetest.get_current_modname()),DIR_DELIM,name)) end -digistuff.update_ts_formspec = function (pos) - local meta = minetest.get_meta(pos) - local fs = "size[10,8]".. - "background[0,0;0,0;digistuff_ts_bg.png;true]" - if meta:get_int("init") == 0 then - fs = fs.."field[3.75,3;3,1;channel;Channel;]".. - "button_exit[4,3.75;2,1;save;Save]" - else - local data = minetest.deserialize(meta:get_string("data")) or {} - for _,field in pairs(data) do - if field.type == "image" then - fs = fs..string.format("image[%s,%s;%s,%s;%s]",field.X,field.Y,field.W,field.H,field.texture_name) - elseif field.type == "field" then - fs = fs..string.format("field[%s,%s;%s,%s;%s;%s;%s]",field.X,field.Y,field.W,field.H,field.name,field.label,field.default) - elseif field.type == "pwdfield" then - fs = fs..string.format("pwdfield[%s,%s;%s,%s;%s;%s]",field.X,field.Y,field.W,field.H,field.name,field.label) - elseif field.type == "textarea" then - fs = fs..string.format("textarea[%s,%s;%s,%s;%s;%s;%s]",field.X,field.Y,field.W,field.H,field.name,field.label,field.default) - elseif field.type == "label" then - fs = fs..string.format("label[%s,%s;%s]",field.X,field.Y,field.label) - elseif field.type == "vertlabel" then - fs = fs..string.format("vertlabel[%s,%s;%s]",field.X,field.Y,field.label) - elseif field.type == "button" then - fs = fs..string.format("button[%s,%s;%s,%s;%s;%s]",field.X,field.Y,field.W,field.H,field.name,field.label) - elseif field.type == "button_exit" then - fs = fs..string.format("button_exit[%s,%s;%s,%s;%s;%s]",field.X,field.Y,field.W,field.H,field.name,field.label) - elseif field.type == "image_button" then - fs = fs..string.format("image_button[%s,%s;%s,%s;%s;%s;%s]",field.X,field.Y,field.W,field.H,field.image,field.name,field.label) - elseif field.type == "image_button_exit" then - fs = fs..string.format("image_button_exit[%s,%s;%s,%s;%s;%s;%s]",field.X,field.Y,field.W,field.H,field.image,field.name,field.label) - elseif field.type == "dropdown" then - local choices = "" - for _,i in ipairs(field.choices) do - if type(i) == "string" then - choices = choices..minetest.formspec_escape(i).."," - end - end - choices = string.sub(choices,1,-2) - fs = fs..string.format("dropdown[%s,%s;%s,%s;%s;%s;%s]",field.X,field.Y,field.W,field.H,field.name,choices,field.selected_id) - end - end - end - meta:set_string("formspec",fs) -end - -digistuff.ts_on_receive_fields = function (pos, formname, fields, sender) - local meta = minetest.get_meta(pos) - local setchan = meta:get_string("channel") - local playername = sender:get_player_name() - local locked = meta:get_int("locked") == 1 - local can_bypass = minetest.check_player_privs(playername,{protection_bypass=true}) - local is_protected = minetest.is_protected(pos,playername) - if (locked and is_protected) and not can_bypass then - minetest.record_protection_violation(pos,playername) - minetest.chat_send_player(playername,"You are not authorized to use this screen.") - return - end - local init = meta:get_int("init") == 1 - if not init then - if fields.save then - meta:set_string("channel",fields.channel) - meta:set_int("init",1) - digistuff.update_ts_formspec(pos) - end - else - fields.clicker = sender:get_player_name() - digiline:receptor_send(pos, digiline.rules.default, setchan, fields) - end -end - -digistuff.process_command = function (meta, data, msg) - if msg.command == "clear" then - data = {} - elseif msg.command == "addimage" then - for _,i in pairs({"X","Y","W","H"}) do - if not msg[i] or type(msg[i]) ~= "number" then - return - end - end - if not msg.texture_name or type(msg.texture_name) ~= "string" then - return - end - local field = {type="image",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,texture_name=minetest.formspec_escape(msg.texture_name)} - table.insert(data,field) - elseif msg.command == "addfield" then - for _,i in pairs({"X","Y","W","H"}) do - if not msg[i] or type(msg[i]) ~= "number" then - return - end - end - for _,i in pairs({"name","label","default"}) do - if not msg[i] or type(msg[i]) ~= "string" then - return - end - end - local field = {type="field",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label),default=minetest.formspec_escape(msg.default)} - table.insert(data,field) - elseif msg.command == "addpwdfield" then - for _,i in pairs({"X","Y","W","H"}) do - if not msg[i] or type(msg[i]) ~= "number" then - return - end - end - for _,i in pairs({"name","label"}) do - if not msg[i] or type(msg[i]) ~= "string" then - return - end - end - local field = {type="pwdfield",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label)} - table.insert(data,field) - elseif msg.command == "addtextarea" then - for _,i in pairs({"X","Y","W","H"}) do - if not msg[i] or type(msg[i]) ~= "number" then - return - end - end - for _,i in pairs({"name","label","default"}) do - if not msg[i] or type(msg[i]) ~= "string" then - return - end - end - local field = {type="textarea",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label),default=minetest.formspec_escape(msg.default)} - table.insert(data,field) - elseif msg.command == "addlabel" then - for _,i in pairs({"X","Y"}) do - if not msg[i] or type(msg[i]) ~= "number" then - return - end - end - if not msg.label or type(msg.label) ~= "string" then - return - end - local field = {type="label",X=msg.X,Y=msg.Y,label=minetest.formspec_escape(msg.label)} - table.insert(data,field) - elseif msg.command == "addvertlabel" then - for _,i in pairs({"X","Y"}) do - if not msg[i] or type(msg[i]) ~= "number" then - return - end - end - if not msg.label or type(msg.label) ~= "string" then - return - end - local field = {type="vertlabel",X=msg.X,Y=msg.Y,label=minetest.formspec_escape(msg.label)} - table.insert(data,field) - elseif msg.command == "addbutton" then - for _,i in pairs({"X","Y","W","H"}) do - if not msg[i] or type(msg[i]) ~= "number" then - return - end - end - for _,i in pairs({"name","label"}) do - if not msg[i] or type(msg[i]) ~= "string" then - return - end - end - local field = {type="button",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label)} - table.insert(data,field) - elseif msg.command == "addbutton_exit" then - for _,i in pairs({"X","Y","W","H"}) do - if not msg[i] or type(msg[i]) ~= "number" then - return - end - end - for _,i in pairs({"name","label"}) do - if not msg[i] or type(msg[i]) ~= "string" then - return - end - end - local field = {type="button_exit",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label)} - table.insert(data,field) - elseif msg.command == "addimage_button" then - for _,i in pairs({"X","Y","W","H"}) do - if not msg[i] or type(msg[i]) ~= "number" then - return - end - end - for _,i in pairs({"image","name","label"}) do - if not msg[i] or type(msg[i]) ~= "string" then - return - end - end - local field = {type="image_button",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,image=minetest.formspec_escape(msg.image),name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label)} - table.insert(data,field) - elseif msg.command == "addimage_button_exit" then - for _,i in pairs({"X","Y","W","H"}) do - if not msg[i] or type(msg[i]) ~= "number" then - return - end - end - for _,i in pairs({"image","name","label"}) do - if not msg[i] or type(msg[i]) ~= "string" then - return - end - end - local field = {type="image_button_exit",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,image=minetest.formspec_escape(msg.image),name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label)} - table.insert(data,field) - elseif msg.command == "adddropdown" then - for _,i in pairs({"X","Y","W","H","selected_id"}) do - if not msg[i] or type(msg[i]) ~= "number" then - return - end - end - if not msg.name or type(msg.name) ~= "string" then - return - end - if not msg.choices or type(msg.choices) ~= "table" or #msg.choices < 1 then - return - end - local field = {type="dropdown",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,name=msg.name,selected_id=msg.selected_id,choices=msg.choices} - table.insert(data,field) - elseif msg.command == "lock" then - meta:set_int("locked",1) - elseif msg.command == "unlock" then - meta:set_int("locked",0) - end - return data -end - -digistuff.ts_on_digiline_receive = function (pos, node, channel, msg) - local meta = minetest.get_meta(pos) - local setchan = meta:get_string("channel") - if channel ~= setchan then return end - if type(msg) ~= "table" then return end - local data = minetest.deserialize(meta:get_string("data")) or {} - if msg.command then - data = digistuff.process_command(meta,data,msg) - else - for _,i in ipairs(msg) do - if i.command then - data = digistuff.process_command(meta,data,i) or data - end - end - end - meta:set_string("data",minetest.serialize(data)) - digistuff.update_ts_formspec(pos) -end - -digistuff.panel_on_digiline_receive = function (pos, node, channel, msg) - local meta = minetest.get_meta(pos) - local setchan = meta:get_string("channel") - if channel ~= setchan then return end - if type(msg) ~= "string" then return end - digistuff.update_panel_formspec(pos,msg) -end - -digistuff.panel_on_receive_fields = function(pos, formname, fields, sender) - local meta = minetest.get_meta(pos) - local setchan = meta:get_string("channel") - local playername = sender:get_player_name() - local locked = meta:get_int("locked") == 1 - local can_bypass = minetest.check_player_privs(playername,{protection_bypass=true}) - local is_protected = minetest.is_protected(pos,playername) - if fields.savechan then - if can_bypass or not is_protected then - meta:set_string("channel",fields.channel) - local helpmsg = "Channel has been set. Waiting for data..." - digistuff.update_panel_formspec(pos,helpmsg) - else - minetest.record_protection_violation(pos,playername) - minetest.chat_send_player(playername,"You are not authorized to change the channel of this panel.") - end - elseif fields.up then - if can_bypass or not is_protected or not locked then - digiline:receptor_send(pos, digiline.rules.default, setchan, "up") - else - minetest.record_protection_violation(pos,playername) - minetest.chat_send_player(playername,"You are not authorized to use this panel.") - end - elseif fields.down then - if can_bypass or not is_protected or not locked then - digiline:receptor_send(pos, digiline.rules.default, setchan, "down") - else - minetest.record_protection_violation(pos,playername) - minetest.chat_send_player(playername,"You are not authorized to use this panel.") - end - elseif fields.left then - if can_bypass or not is_protected or not locked then - digiline:receptor_send(pos, digiline.rules.default, setchan, "left") - else - minetest.record_protection_violation(pos,playername) - minetest.chat_send_player(playername,"You are not authorized to use this panel.") - end - elseif fields.right then - if can_bypass or not is_protected or not locked then - digiline:receptor_send(pos, digiline.rules.default, setchan, "right") - else - minetest.record_protection_violation(pos,playername) - minetest.chat_send_player(playername,"You are not authorized to use this panel.") - end - elseif fields.back then - if can_bypass or not is_protected or not locked then - digiline:receptor_send(pos, digiline.rules.default, setchan, "back") - else - minetest.record_protection_violation(pos,playername) - minetest.chat_send_player(playername,"You are not authorized to use this panel.") - end - elseif fields.enter then - if can_bypass or not is_protected or not locked then - digiline:receptor_send(pos, digiline.rules.default, setchan, "enter") - else - minetest.record_protection_violation(pos,playername) - minetest.chat_send_player(playername,"You are not authorized to use this panel.") - end - elseif fields.lock then - if can_bypass or not is_protected then - meta:set_int("locked",1) - minetest.chat_send_player(playername,"This panel has been locked. Access will now be controlled according to area protection.") - digistuff.update_panel_formspec(pos,meta:get_string("text")) - else - minetest.record_protection_violation(pos,playername) - minetest.chat_send_player(playername,"You are not authorized to lock this panel.") - end - elseif fields.unlock then - if can_bypass or not is_protected then - meta:set_int("locked",0) - minetest.chat_send_player(playername,"This panel has been unlocked. It can now be used (but not locked or have the channel changed) by anyone.") - digistuff.update_panel_formspec(pos,meta:get_string("text")) - else - minetest.record_protection_violation(pos,playername) - minetest.chat_send_player(playername,"You are not authorized to unlock this panel.") - end - end -end - -digistuff.button_turnoff = function (pos) - local node = minetest.get_node(pos) - if node.name=="digistuff:button_on" then --has not been dug - minetest.swap_node(pos, {name = "digistuff:button_off", param2=node.param2}) - if minetest.get_modpath("mesecons") then minetest.sound_play("mesecons_button_pop", {pos=pos}) end - end -end - -minetest.register_node("digistuff:digimese", { - description = "Digimese", - tiles = {"digistuff_digimese.png"}, - paramtype = "light", - light_source = 3, - groups = {cracky = 3, level = 2}, - is_ground_content = false, - sounds = default and default.node_sound_stone_defaults(), - digiline = { wire = { rules = { - {x = 1, y = 0, z = 0}, - {x =-1, y = 0, z = 0}, - {x = 0, y = 1, z = 0}, - {x = 0, y =-1, z = 0}, - {x = 0, y = 0, z = 1}, - {x = 0, y = 0, z =-1}}}} -}) - -minetest.register_node("digistuff:button", { - drawtype = "nodebox", - tiles = { - "digistuff_digibutton_sides.png", - "digistuff_digibutton_sides.png", - "digistuff_digibutton_sides.png", - "digistuff_digibutton_sides.png", - "digistuff_digibutton_sides.png", - "digistuff_digibutton_off.png" - }, - paramtype = "light", - paramtype2 = "facedir", - legacy_wallmounted = true, - walkable = false, - sunlight_propagates = true, - selection_box = { - type = "fixed", - fixed = { -6/16, -6/16, 5/16, 6/16, 6/16, 8/16 } - }, - node_box = { - type = "fixed", - fixed = { - { -6/16, -6/16, 6/16, 6/16, 6/16, 8/16 }, -- the thin plate behind the button - { -4/16, -2/16, 4/16, 4/16, 2/16, 6/16 } -- the button itself - } - }, - digiline = - { - receptor = {} - }, - groups = {dig_immediate=2}, - description = "Digilines Button", - on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:set_string("formspec","size[8,4;]field[1,1;6,2;channel;Channel;${channel}]field[1,2;6,2;msg;Message;${msg}]button_exit[2.25,3;3,1;submit;Save]") - end, - on_receive_fields = function(pos, formname, fields, sender) - local meta = minetest.get_meta(pos) - if fields.channel and fields.msg and fields.channel ~= "" and fields.msg ~= "" then - meta:set_string("channel",fields.channel) - meta:set_string("msg",fields.msg) - meta:set_string("formspec","") - minetest.swap_node(pos, {name = "digibutton:button_off", param2=minetest.get_node(pos).param2}) - else - minetest.chat_send_player(sender:get_player_name(),"Channel and message must both be set!") - end - end, - sounds = default and default.node_sound_stone_defaults(), -}) - -minetest.register_node("digistuff:button_off", { - drawtype = "nodebox", - tiles = { - "digistuff_digibutton_sides.png", - "digistuff_digibutton_sides.png", - "digistuff_digibutton_sides.png", - "digistuff_digibutton_sides.png", - "digistuff_digibutton_sides.png", - "digistuff_digibutton_off.png" - }, - paramtype = "light", - paramtype2 = "facedir", - legacy_wallmounted = true, - walkable = false, - sunlight_propagates = true, - selection_box = { - type = "fixed", - fixed = { -6/16, -6/16, 5/16, 6/16, 6/16, 8/16 } - }, - node_box = { - type = "fixed", - fixed = { - { -6/16, -6/16, 6/16, 6/16, 6/16, 8/16 }, -- the thin plate behind the button - { -4/16, -2/16, 4/16, 4/16, 2/16, 6/16 } -- the button itself - } - }, - digiline = - { - receptor = {} - }, - groups = {dig_immediate=2, not_in_creative_inventory=1}, - drop = "digistuff:button", - description = "Digilines Button (off state - you hacker you!)", - on_rightclick = function (pos, node, clicker) - local meta = minetest.get_meta(pos) - digiline:receptor_send(pos, digiline.rules.default, meta:get_string("channel"), meta:get_string("msg")) - minetest.swap_node(pos, {name = "digistuff:button_on", param2=node.param2}) - if minetest.get_modpath("mesecons") then minetest.sound_play("mesecons_button_push", {pos=pos}) end - minetest.after(0.5, digistuff.button_turnoff, pos) - end, - sounds = default and default.node_sound_stone_defaults(), -}) - -minetest.register_node("digistuff:button_on", { - drawtype = "nodebox", - tiles = { - "digistuff_digibutton_sides.png", - "digistuff_digibutton_sides.png", - "digistuff_digibutton_sides.png", - "digistuff_digibutton_sides.png", - "digistuff_digibutton_sides.png", - "digistuff_digibutton_on.png" - }, - paramtype = "light", - paramtype2 = "facedir", - legacy_wallmounted = true, - walkable = false, - light_source = 7, - sunlight_propagates = true, - selection_box = { - type = "fixed", - fixed = { -6/16, -6/16, 5/16, 6/16, 6/16, 8/16 } - }, - node_box = { - type = "fixed", - fixed = { - { -6/16, -6/16, 6/16, 6/16, 6/16, 8/16 }, - { -4/16, -2/16, 11/32, 4/16, 2/16, 6/16 } - } - }, - digiline = - { - receptor = {} - }, - groups = {dig_immediate=2, not_in_creative_inventory=1}, - drop = 'digistuff:button', - on_rightclick = function (pos, node, clicker) - local meta = minetest.get_meta(pos) - digiline:receptor_send(pos, digiline.rules.default, meta:get_string("channel"), meta:get_string("msg")) - if minetest.get_modpath("mesecons") then minetest.sound_play("mesecons_button_push", {pos=pos}) end - end, - description = "Digilines Button (on state - you hacker you!)", - sounds = default and default.node_sound_stone_defaults(), -}) - -minetest.register_craft({ - output = "digistuff:digimese", - recipe = { - {"digilines:wire_std_00000000","digilines:wire_std_00000000","digilines:wire_std_00000000"}, - {"digilines:wire_std_00000000","default:mese","digilines:wire_std_00000000"}, - {"digilines:wire_std_00000000","digilines:wire_std_00000000","digilines:wire_std_00000000"} - } -}) - -minetest.register_craft({ - output = "digistuff:button", - recipe = { - {"mesecons_button:button_off"}, - {"mesecons_luacontroller:luacontroller0000"}, - {"digilines:wire_std_00000000"} - } -}) - -minetest.register_alias("digibutton:button","digistuff:button") -minetest.register_alias("digibutton:button_off","digistuff:button_off") -minetest.register_alias("digibutton:button_on","digistuff:button_on") -minetest.register_alias("digibutton:digimese","digistuff:digimese") - -minetest.register_node("digistuff:detector", { - tiles = { - "digistuff_digidetector.png" - }, - digiline = - { - receptor = {} - }, - groups = {cracky=2}, - description = "Digilines Player Detector", - on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:set_string("formspec","size[8,4;]field[1,1;6,2;channel;Channel;${channel}]field[1,2;6,2;radius;Radius;${radius}]button_exit[2.25,3;3,1;submit;Save]") - end, - 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 - if fields.msg then meta:set_string("msg",fields.msg) end - if fields.radius then meta:set_string("radius",fields.radius) end - end, - sounds = default and default.node_sound_stone_defaults() -}) - -minetest.register_abm({ - nodenames = {"digistuff:detector"}, - interval = 1.0, - chance = 1, - action = function(pos) - local meta = minetest.get_meta(pos) - local channel = meta:get_string("channel") - local radius = meta:get_string("radius") - local found_any = false - local players_found = {} - if not radius or not tonumber(radius) or tonumber(radius) < 1 or tonumber(radius) > 10 then radius = 6 end - local objs = minetest.get_objects_inside_radius(pos, radius) - if objs then - local _,obj - for _,obj in ipairs(objs) do - if obj:is_player() then - table.insert(players_found,obj:get_player_name()) - found_any = true - end - end - if found_any then - digiline:receptor_send(pos, digiline.rules.default, channel, players_found) - end - end - end -}) - -minetest.register_node("digistuff:panel", { - description = "Digilines Control Panel", - groups = {cracky=3}, - on_construct = function(pos) - local helpmsg = "Please set a channel." - digistuff.update_panel_formspec(pos,helpmsg) - minetest.get_meta(pos):set_int("locked",0) - end, - drawtype = "nodebox", - tiles = { - "digistuff_panel_back.png", - "digistuff_panel_back.png", - "digistuff_panel_back.png", - "digistuff_panel_back.png", - "digistuff_panel_back.png", - "digistuff_panel_front.png" - }, - paramtype = "light", - paramtype2 = "facedir", - node_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, 0.4, 0.5, 0.5, 0.5 } - } - }, - on_receive_fields = digistuff.panel_on_receive_fields, - digiline = - { - receptor = {}, - effector = { - action = digistuff.panel_on_digiline_receive - }, - }, -}) - -minetest.register_craft({ - output = "digistuff:detector", - recipe = { - {"mesecons_detector:object_detector_off"}, - {"mesecons_luacontroller:luacontroller0000"}, - {"digilines:wire_std_00000000"} - } -}) - -minetest.register_craft({ - output = "digistuff:panel", - recipe = { - {"","digistuff:button",""}, - {"digistuff:button","digilines:lcd","digistuff:button"}, - {"","digistuff:button",""} - } -}) - -minetest.register_craft({ - output = "digistuff:touchscreen", - recipe = { - {"mesecons_luacontroller:luacontroller0000","default:glass","default:glass"}, - {"default:glass","digilines:lcd","default:glass"}, - {"default:glass","default:glass","default:glass"} - } -}) - -minetest.register_node("digistuff:touchscreen", { - description = "Digilines Touchscreen", - groups = {cracky=3}, - on_construct = function(pos) - digistuff.update_ts_formspec(pos,true) - end, - drawtype = "nodebox", - tiles = { - "digistuff_panel_back.png", - "digistuff_panel_back.png", - "digistuff_panel_back.png", - "digistuff_panel_back.png", - "digistuff_panel_back.png", - "digistuff_ts_front.png" - }, - paramtype = "light", - paramtype2 = "facedir", - node_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, 0.4, 0.5, 0.5, 0.5 } - } - }, - on_receive_fields = digistuff.ts_on_receive_fields, - digiline = - { - receptor = {}, - effector = { - action = digistuff.ts_on_digiline_receive - }, - }, -}) - -minetest.register_node("digistuff:piezo", { - description = "Digilines Piezoelectric Beeper", - groups = {cracky=3}, - on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:set_string("formspec","field[channel;Channel;${channel}") - end, - on_destruct = function(pos) - local pos_hash = minetest.hash_node_position(pos) - if digistuff.sounds_playing[pos_hash] then - minetest.sound_stop(digistuff.sounds_playing[pos_hash]) - digistuff.sounds_playing[pos_hash] = nil - end - end, - tiles = { - "digistuff_piezo_top.png", - "digistuff_piezo_sides.png", - "digistuff_piezo_sides.png", - "digistuff_piezo_sides.png", - "digistuff_piezo_sides.png", - "digistuff_piezo_sides.png" - }, - 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, - digiline = - { - receptor = {}, - effector = { - action = function(pos,node,channel,msg) - local meta = minetest.get_meta(pos) - local setchan = meta:get_string("channel") - if channel ~= setchan then return end - if msg == "shortbeep" then - local pos_hash = minetest.hash_node_position(pos) - if digistuff.sounds_playing[pos_hash] then - minetest.sound_stop(digistuff.sounds_playing[pos_hash]) - digistuff.sounds_playing[pos_hash] = nil - end - minetest.sound_play({name = "digistuff_piezo_short_single",gain = 0.2},{pos = pos,max_hear_distance = 16}) - elseif msg == "longbeep" then - local pos_hash = minetest.hash_node_position(pos) - if digistuff.sounds_playing[pos_hash] then - minetest.sound_stop(digistuff.sounds_playing[pos_hash]) - digistuff.sounds_playing[pos_hash] = nil - end - minetest.sound_play({name = "digistuff_piezo_long_single",gain = 0.2},{pos = pos,max_hear_distance = 16}) - elseif msg == "fastrepeat" then - local pos_hash = minetest.hash_node_position(pos) - if digistuff.sounds_playing[pos_hash] then - minetest.sound_stop(digistuff.sounds_playing[pos_hash]) - digistuff.sounds_playing[pos_hash] = nil - end - digistuff.sounds_playing[pos_hash] = minetest.sound_play({name = "digistuff_piezo_fast_repeat",gain = 0.2},{pos = pos,max_hear_distance = 16,loop = true}) - elseif msg == "slowrepeat" then - local pos_hash = minetest.hash_node_position(pos) - if digistuff.sounds_playing[pos_hash] then - minetest.sound_stop(digistuff.sounds_playing[pos_hash]) - digistuff.sounds_playing[pos_hash] = nil - end - digistuff.sounds_playing[pos_hash] = minetest.sound_play({name = "digistuff_piezo_slow_repeat",gain = 0.2},{pos = pos,max_hear_distance = 16,loop = true}) - elseif msg == "stop" then - local pos_hash = minetest.hash_node_position(pos) - if digistuff.sounds_playing[pos_hash] then - minetest.sound_stop(digistuff.sounds_playing[pos_hash]) - digistuff.sounds_playing[pos_hash] = nil - end - end - end - }, - }, -}) - local http = minetest.request_http_api() - -if http then - minetest.register_node("digistuff:nic", { - description = "Digilines NIC", - groups = {cracky=3}, - on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:set_string("formspec","field[channel;Channel;${channel}") - end, - tiles = { - "digistuff_nic_top.png", - "jeija_microcontroller_bottom.png", - "jeija_microcontroller_sides.png", - "jeija_microcontroller_sides.png", - "jeija_microcontroller_sides.png", - "jeija_microcontroller_sides.png" - }, - drawtype = "nodebox", - 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, - digiline = - { - receptor = {}, - effector = { - action = function(pos,node,channel,msg) - local meta = minetest.get_meta(pos) - if meta:get_string("channel") ~= channel then return end - if type(msg) ~= "string" then return end - http.fetch({ - url = msg, - timeout = 5, - user_agent = "Minetest Digilines Modem", - }, - function(res) - digiline:receptor_send(pos, digiline.rules.default, channel, res) - end) - end - }, - }, - }) - minetest.register_craft({ - output = "digistuff:nic", - recipe = { - {"","","mesecons:wire_00000000_off"}, - {"digilines:wire_std_00000000","mesecons_luacontroller:luacontroller0000","mesecons:wire_00000000_off"} - } - }) -end - -minetest.register_node("digistuff:camera", { - tiles = { - "digistuff_camera_top.png", - "digistuff_camera_bottom.png", - "digistuff_camera_right.png", - "digistuff_camera_left.png", - "digistuff_camera_back.png", - "digistuff_camera_front.png", - }, - digiline = - { - receptor = {} - }, - groups = {cracky=2}, - paramtype = "light", - paramtype2 = "facedir", - drawtype = "nodebox", - node_box = { - type = "fixed", - fixed = { - {-0.1,-0.5,-0.28,0.1,-0.3,0.3}, --Camera Body - {-0.045,-0.42,-0.34,0.045,-0.36,-0.28}, -- Lens - {-0.05,-0.9,-0.05,0.05,-0.5,0.05}, --Pole - } - }, - selection_box = { - type = "fixed", - fixed = { - {-0.1,-0.5,-0.34,0.1,-0.3,0.3}, --Camera Body - } - }, - description = "Digilines Camera", - on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:set_string("formspec","size[8,6;]field[1,1;6,2;channel;Channel;${channel}]field[1,2;6,2;radius;Radius (max 10);${radius}]field[1,3;6,2;distance;Distance (max 20);${distance}]button_exit[2.25,4;3,1;submit;Save]") - end, - 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 - if fields.distance and tonumber(fields.distance) then meta:set_int("distance",math.max(math.min(20,fields.distance),0)) end - if fields.radius and tonumber(fields.radius) then meta:set_int("radius",math.max(math.min(10,fields.radius),1)) end - end, - sounds = default and default.node_sound_stone_defaults() -}) - -minetest.register_abm({ - nodenames = {"digistuff:camera"}, - interval = 1.0, - chance = 1, - action = function(pos,node) - local meta = minetest.get_meta(pos) - local channel = meta:get_string("channel") - local radius = meta:get_int("radius") - local distance = meta:get_int("distance") - local dir = vector.multiply(minetest.facedir_to_dir(node.param2),-1) - local spot = vector.add(pos,vector.multiply(dir,distance)) - local i = 0 - while i <= 10 and minetest.get_node(spot).name == "air" do - --Downward search for ground level - spot = vector.add(spot,vector.new(0,-1,0)) - i = i + 1 - end - if minetest.get_node(spot).name == "air" or minetest.get_node(spot).name == "ignore" then - --Ground not in range - return - end - - local found_any = false - local players_found = {} - local objs = minetest.get_objects_inside_radius(spot,radius) - if objs then - local _,obj - for _,obj in ipairs(objs) do - if obj:is_player() then - table.insert(players_found,obj:get_player_name()) - found_any = true - end - end - if found_any then - digiline:receptor_send({x=pos.x,y=pos.y-1,z=pos.z}, digiline.rules.default, channel, players_found) - end - end - end -}) - -minetest.register_craft({ - output = "digistuff:camera", - recipe = { - {"homedecor:plastic_sheeting","homedecor:plastic_sheeting","homedecor:plastic_sheeting"}, - {"default:glass","homedecor:ic","mesecons_luacontroller:luacontroller0000"}, - {"homedecor:plastic_sheeting","homedecor:plastic_sheeting","homedecor:plastic_sheeting"}, - } -}) - -if minetest.get_modpath("mesecons_noteblock") then - local validnbsounds = dofile(minetest.get_modpath("digistuff")..DIR_DELIM.."nbsounds.lua") - minetest.register_node("digistuff:noteblock", { - description = "Digilines Noteblock", - groups = {cracky=3}, - on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:set_string("formspec","field[channel;Channel;${channel}") - end, - on_destruct = function(pos) - local pos_hash = minetest.hash_node_position(pos) - if digistuff.sounds_playing[pos_hash] then - minetest.sound_stop(digistuff.sounds_playing[pos_hash]) - digistuff.sounds_playing[pos_hash] = nil - end - end, - tiles = { - "mesecons_noteblock.png" - }, - 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, - digiline = - { - receptor = {}, - effector = { - action = function(pos,node,channel,msg) - if msg == "get_sounds" then - local soundnames = {} - for i in pairs(validnbsounds) do - table.insert(soundnames,i) - end - digiline:receptor_send(pos, digiline.rules.default, channel, soundnames) - end - local meta = minetest.get_meta(pos) - local setchan = meta:get_string("channel") - if channel ~= setchan then return end - if type(msg) == "string" then - local sound = validnbsounds[msg] - if sound then minetest.sound_play(sound,{pos=pos}) end - elseif type(msg) == "table" then - if type(msg.sound) ~= "string" then return end - local sound = validnbsounds[msg.sound] - local volume = 1 - if type(msg.volume) == "number" then - volume = math.max(0,math.min(1,msg.volume)) - end - if sound then minetest.sound_play({name=sound,gain=volume},{pos=pos}) end - end - end - }, - }, - }) +if not http then + minetest.log("error","digistuff is not allowed to use the HTTP API - digilines NIC will not be available!") + minetest.log("error","If this functionality is desired, please add digistuff to your secure.http_mods setting") +else + loadfile(string.format("%s%s%s.lua",minetest.get_modpath(minetest.get_current_modname()),DIR_DELIM,"nic"))(http) end - -for i=0,14,1 do - local mult = 255 - ((14-i)*12) - minetest.register_node("digistuff:light_"..i, { - drop = "digistuff:light_0", - description = "Digilines Dimmable Light"..(i > 0 and " (on state - you hacker you!)" or ""), - tiles = {"digistuff_light.png"}, - paramtype = "light", - paramtype2 = "facedir", - drawtype = "nodebox", - node_box = { - type = "fixed", - fixed = { - {-0.25,0.4,-0.25,0.25,0.5,0.25}, - } - }, - groups = i > 0 and {cracky = 1, not_in_creative_inventory = 1} or {cracky = 1}, - is_ground_content = false, - light_source = i, - color = {r = mult,g = mult,b = mult}, - sounds = default and default.node_sound_glass_defaults(), - on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:set_string("formspec","field[channel;Channel;${channel}") - end, - 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, - digiline = { - receptor = {}, - wire = { - rules = { - {x = 1,y = 0,z = 0}, - {x = -1,y = 0,z = 0}, - {x = 0,y = 0,z = 1}, - {x = 0,y = 0,z = -1}, - {x = 0,y = 1,z = 0}, - {x = 0,y = -1,z = 0}, - {x = 2,y = 0,z = 0}, - {x = -2,y = 0,z = 0}, - {x = 0,y = 0,z = 2}, - {x = 0,y = 0,z = -2}, - {x = 0,y = 2,z = 0}, - {x = 0,y = -2,z = 0}, - } - }, - effector = { - action = function(pos,node,channel,msg) - local meta = minetest.get_meta(pos) - if meta:get_string("channel") ~= channel then return end - local value = tonumber(msg) - if (not value) or value > 14 or value < 0 then return end - node.name = "digistuff:light_"..math.floor(value) - minetest.swap_node(pos,node) - end - }, - }, - }) -end - -minetest.register_node("digistuff:junctionbox", { - description = "Digilines Junction Box", - tiles = {"digistuff_junctionbox.png"}, - paramtype = "light", - paramtype2 = "facedir", - groups = {cracky = 3}, - is_ground_content = false, - paramtype = "light", - drawtype = "nodebox", - node_box = { - type = "fixed", - fixed = { - {-0.1,-0.15,0.35,0.1,0.15,0.5}, - } - }, - sounds = default and default.node_sound_stone_defaults(), - digiline = { - receptor = {}, - wire = { - rules = { - {x = 1,y = 0,z = 0}, - {x = -1,y = 0,z = 0}, - {x = 0,y = 0,z = 1}, - {x = 0,y = 0,z = -1}, - {x = 0,y = 1,z = 0}, - {x = 0,y = -1,z = 0}, - {x = 0,y = -2,z = 0}, - {x = 0,y = 2,z = 0}, - {x = -2,y = 0,z = 0}, - {x = 2,y = 0,z = 0}, - {x = 0,y = 0,z = -2}, - {x = 0,y = 0,z = 2}, - } - }, - }, -}) - -minetest.register_craft({ - output = "digistuff:light_0", - recipe = { - {"digilines:wire_std_00000000","mesecons_lamp:lamp_off",}, - } -}) - -minetest.register_craft({ - output = "digistuff:junctionbox", - recipe = { - {"homedecor:plastic_sheeting","digilines:wire_std_00000000","homedecor:plastic_sheeting",}, - {"digilines:wire_std_00000000","digilines:wire_std_00000000","digilines:wire_std_00000000",}, - {"homedecor:plastic_sheeting","digilines:wire_std_00000000","homedecor:plastic_sheeting",}, - } -}) diff --git a/digistuff/light.lua b/digistuff/light.lua new file mode 100644 index 0000000..aeca08d --- /dev/null +++ b/digistuff/light.lua @@ -0,0 +1,71 @@ +for i=0,14,1 do + local mult = 255 - ((14-i)*12) + minetest.register_node("digistuff:light_"..i, { + drop = "digistuff:light_0", + description = "Digilines Dimmable Light"..(i > 0 and " (on state - you hacker you!)" or ""), + tiles = {"digistuff_light.png"}, + paramtype = "light", + paramtype2 = "facedir", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.25,0.4,-0.25,0.25,0.5,0.25}, + } + }, + groups = i > 0 and {cracky = 1, not_in_creative_inventory = 1} or {cracky = 1}, + is_ground_content = false, + light_source = i, + color = {r = mult,g = mult,b = mult}, + sounds = default and default.node_sound_glass_defaults(), + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec","field[channel;Channel;${channel}") + end, + 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, + digiline = { + receptor = {}, + wire = { + rules = { + {x = 1,y = 0,z = 0}, + {x = -1,y = 0,z = 0}, + {x = 0,y = 0,z = 1}, + {x = 0,y = 0,z = -1}, + {x = 0,y = 1,z = 0}, + {x = 0,y = -1,z = 0}, + {x = 2,y = 0,z = 0}, + {x = -2,y = 0,z = 0}, + {x = 0,y = 0,z = 2}, + {x = 0,y = 0,z = -2}, + {x = 0,y = 2,z = 0}, + {x = 0,y = -2,z = 0}, + } + }, + effector = { + action = function(pos,node,channel,msg) + local meta = minetest.get_meta(pos) + if meta:get_string("channel") ~= channel then return end + local value = tonumber(msg) + if (not value) or value > 14 or value < 0 then return end + node.name = "digistuff:light_"..math.floor(value) + minetest.swap_node(pos,node) + end + }, + }, + }) +end + +minetest.register_craft({ + output = "digistuff:light_0", + recipe = { + {"digilines:wire_std_00000000","mesecons_lamp:lamp_off",}, + } +}) diff --git a/digistuff/nic.lua b/digistuff/nic.lua new file mode 100644 index 0000000..8760bdf --- /dev/null +++ b/digistuff/nic.lua @@ -0,0 +1,69 @@ +local http = ... +minetest.register_node("digistuff:nic", { + description = "Digilines NIC", + groups = {cracky=3}, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec","field[channel;Channel;${channel}") + end, + tiles = { + "digistuff_nic_top.png", + "jeija_microcontroller_bottom.png", + "jeija_microcontroller_sides.png", + "jeija_microcontroller_sides.png", + "jeija_microcontroller_sides.png", + "jeija_microcontroller_sides.png" + }, + drawtype = "nodebox", + 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, + digiline = + { + receptor = {}, + effector = { + action = function(pos,node,channel,msg) + local meta = minetest.get_meta(pos) + if meta:get_string("channel") ~= channel then return end + if type(msg) ~= "string" then return end + http.fetch({ + url = msg, + timeout = 5, + user_agent = "Minetest Digilines Modem", + }, + function(res) + digiline:receptor_send(pos, digiline.rules.default, channel, res) + end) + end + }, + }, +}) +minetest.register_craft({ + output = "digistuff:nic", + recipe = { + {"","","mesecons:wire_00000000_off"}, + {"digilines:wire_std_00000000","mesecons_luacontroller:luacontroller0000","mesecons:wire_00000000_off"} + } +}) diff --git a/digistuff/noteblock.lua b/digistuff/noteblock.lua new file mode 100644 index 0000000..f2e9c89 --- /dev/null +++ b/digistuff/noteblock.lua @@ -0,0 +1,64 @@ +if not minetest.get_modpath("mesecons_noteblock") then + minetest.log("error","mesecons_noteblock is not installed - digilines noteblock will not be available!") + return +end + +local validnbsounds = dofile(minetest.get_modpath(minetest.get_current_modname())..DIR_DELIM.."nbsounds.lua") +minetest.register_node("digistuff:noteblock", { + description = "Digilines Noteblock", + groups = {cracky=3}, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec","field[channel;Channel;${channel}") + end, + on_destruct = function(pos) + local pos_hash = minetest.hash_node_position(pos) + if digistuff.sounds_playing[pos_hash] then + minetest.sound_stop(digistuff.sounds_playing[pos_hash]) + digistuff.sounds_playing[pos_hash] = nil + end + end, + tiles = { + "mesecons_noteblock.png" + }, + 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, + digiline = + { + receptor = {}, + effector = { + action = function(pos,node,channel,msg) + local meta = minetest.get_meta(pos) + local setchan = meta:get_string("channel") + if channel ~= setchan then return end + if msg == "get_sounds" then + local soundnames = {} + for i in pairs(validnbsounds) do + table.insert(soundnames,i) + end + digiline:receptor_send(pos, digiline.rules.default, channel, soundnames) + return + end + if type(msg) == "string" then + local sound = validnbsounds[msg] + if sound then minetest.sound_play(sound,{pos=pos}) end + elseif type(msg) == "table" then + if type(msg.sound) ~= "string" then return end + local sound = validnbsounds[msg.sound] + local volume = 1 + if type(msg.volume) == "number" then + volume = math.max(0,math.min(1,msg.volume)) + end + if sound then minetest.sound_play({name=sound,gain=volume},{pos=pos}) end + end + end + }, + }, +}) diff --git a/digistuff/panel.lua b/digistuff/panel.lua new file mode 100644 index 0000000..d543af1 --- /dev/null +++ b/digistuff/panel.lua @@ -0,0 +1,151 @@ +digistuff.update_panel_formspec = function (pos,dispstr) + local meta = minetest.get_meta(pos) + local locked = meta:get_int("locked") == 1 + local fs = "size[10,8]".. + "background[0,0;0,0;digistuff_panel_bg.png;true]".. + "label[0,0;%s]".. + (locked and "image_button[9,3;1,1;digistuff_panel_locked.png;unlock;]" or "image_button[9,3;1,1;digistuff_panel_unlocked.png;lock;]").. + "image_button[2,4.5;1,1;digistuff_adwaita_go-up.png;up;]".. + "image_button[1,5;1,1;digistuff_adwaita_go-previous.png;left;]".. + "image_button[3,5;1,1;digistuff_adwaita_go-next.png;right;]".. + "image_button[2,5.5;1,1;digistuff_adwaita_go-down.png;down;]".. + "image_button[1,6.5;1,1;digistuff_adwaita_edit-undo.png;back;]".. + "image_button[3,6.5;1,1;digistuff_adwaita_emblem-default.png;enter;]".. + "field[6,5.75;2,1;channel;Channel;${channel}]".. + "button[8,5.5;1,1;savechan;Set]" + fs = fs:format(minetest.formspec_escape(dispstr)):gsub("|","\n") + meta:set_string("formspec",fs) + meta:set_string("text",dispstr) +end + +digistuff.panel_on_digiline_receive = function (pos, node, channel, msg) + local meta = minetest.get_meta(pos) + local setchan = meta:get_string("channel") + if channel ~= setchan then return end + if type(msg) ~= "string" then return end + digistuff.update_panel_formspec(pos,msg) +end + +digistuff.panel_on_receive_fields = function(pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + local setchan = meta:get_string("channel") + local playername = sender:get_player_name() + local locked = meta:get_int("locked") == 1 + local can_bypass = minetest.check_player_privs(playername,{protection_bypass=true}) + local is_protected = minetest.is_protected(pos,playername) + if fields.savechan then + if can_bypass or not is_protected then + meta:set_string("channel",fields.channel) + local helpmsg = "Channel has been set. Waiting for data..." + digistuff.update_panel_formspec(pos,helpmsg) + else + minetest.record_protection_violation(pos,playername) + minetest.chat_send_player(playername,"You are not authorized to change the channel of this panel.") + end + elseif fields.up then + if can_bypass or not is_protected or not locked then + digiline:receptor_send(pos, digiline.rules.default, setchan, "up") + else + minetest.record_protection_violation(pos,playername) + minetest.chat_send_player(playername,"You are not authorized to use this panel.") + end + elseif fields.down then + if can_bypass or not is_protected or not locked then + digiline:receptor_send(pos, digiline.rules.default, setchan, "down") + else + minetest.record_protection_violation(pos,playername) + minetest.chat_send_player(playername,"You are not authorized to use this panel.") + end + elseif fields.left then + if can_bypass or not is_protected or not locked then + digiline:receptor_send(pos, digiline.rules.default, setchan, "left") + else + minetest.record_protection_violation(pos,playername) + minetest.chat_send_player(playername,"You are not authorized to use this panel.") + end + elseif fields.right then + if can_bypass or not is_protected or not locked then + digiline:receptor_send(pos, digiline.rules.default, setchan, "right") + else + minetest.record_protection_violation(pos,playername) + minetest.chat_send_player(playername,"You are not authorized to use this panel.") + end + elseif fields.back then + if can_bypass or not is_protected or not locked then + digiline:receptor_send(pos, digiline.rules.default, setchan, "back") + else + minetest.record_protection_violation(pos,playername) + minetest.chat_send_player(playername,"You are not authorized to use this panel.") + end + elseif fields.enter then + if can_bypass or not is_protected or not locked then + digiline:receptor_send(pos, digiline.rules.default, setchan, "enter") + else + minetest.record_protection_violation(pos,playername) + minetest.chat_send_player(playername,"You are not authorized to use this panel.") + end + elseif fields.lock then + if can_bypass or not is_protected then + meta:set_int("locked",1) + minetest.chat_send_player(playername,"This panel has been locked. Access will now be controlled according to area protection.") + digistuff.update_panel_formspec(pos,meta:get_string("text")) + else + minetest.record_protection_violation(pos,playername) + minetest.chat_send_player(playername,"You are not authorized to lock this panel.") + end + elseif fields.unlock then + if can_bypass or not is_protected then + meta:set_int("locked",0) + minetest.chat_send_player(playername,"This panel has been unlocked. It can now be used (but not locked or have the channel changed) by anyone.") + digistuff.update_panel_formspec(pos,meta:get_string("text")) + else + minetest.record_protection_violation(pos,playername) + minetest.chat_send_player(playername,"You are not authorized to unlock this panel.") + end + end +end + + +minetest.register_node("digistuff:panel", { + description = "Digilines Control Panel", + groups = {cracky=3}, + on_construct = function(pos) + local helpmsg = "Please set a channel." + digistuff.update_panel_formspec(pos,helpmsg) + minetest.get_meta(pos):set_int("locked",0) + end, + drawtype = "nodebox", + tiles = { + "digistuff_panel_back.png", + "digistuff_panel_back.png", + "digistuff_panel_back.png", + "digistuff_panel_back.png", + "digistuff_panel_back.png", + "digistuff_panel_front.png" + }, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + { -0.5, -0.5, 0.4, 0.5, 0.5, 0.5 } + } + }, + on_receive_fields = digistuff.panel_on_receive_fields, + digiline = + { + receptor = {}, + effector = { + action = digistuff.panel_on_digiline_receive + }, + }, +}) + +minetest.register_craft({ + output = "digistuff:panel", + recipe = { + {"","digistuff:button",""}, + {"digistuff:button","digilines:lcd","digistuff:button"}, + {"","digistuff:button",""} + } +}) diff --git a/digistuff/piezo.lua b/digistuff/piezo.lua new file mode 100644 index 0000000..f96e4a1 --- /dev/null +++ b/digistuff/piezo.lua @@ -0,0 +1,80 @@ +digistuff.sounds_playing = {} + +minetest.register_node("digistuff:piezo", { + description = "Digilines Piezoelectric Beeper", + groups = {cracky=3}, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec","field[channel;Channel;${channel}") + end, + on_destruct = function(pos) + local pos_hash = minetest.hash_node_position(pos) + if digistuff.sounds_playing[pos_hash] then + minetest.sound_stop(digistuff.sounds_playing[pos_hash]) + digistuff.sounds_playing[pos_hash] = nil + end + end, + tiles = { + "digistuff_piezo_top.png", + "digistuff_piezo_sides.png", + "digistuff_piezo_sides.png", + "digistuff_piezo_sides.png", + "digistuff_piezo_sides.png", + "digistuff_piezo_sides.png" + }, + 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, + digiline = + { + receptor = {}, + effector = { + action = function(pos,node,channel,msg) + local meta = minetest.get_meta(pos) + local setchan = meta:get_string("channel") + if channel ~= setchan then return end + if msg == "shortbeep" then + local pos_hash = minetest.hash_node_position(pos) + if digistuff.sounds_playing[pos_hash] then + minetest.sound_stop(digistuff.sounds_playing[pos_hash]) + digistuff.sounds_playing[pos_hash] = nil + end + minetest.sound_play({name = "digistuff_piezo_short_single",gain = 0.2},{pos = pos,max_hear_distance = 16}) + elseif msg == "longbeep" then + local pos_hash = minetest.hash_node_position(pos) + if digistuff.sounds_playing[pos_hash] then + minetest.sound_stop(digistuff.sounds_playing[pos_hash]) + digistuff.sounds_playing[pos_hash] = nil + end + minetest.sound_play({name = "digistuff_piezo_long_single",gain = 0.2},{pos = pos,max_hear_distance = 16}) + elseif msg == "fastrepeat" then + local pos_hash = minetest.hash_node_position(pos) + if digistuff.sounds_playing[pos_hash] then + minetest.sound_stop(digistuff.sounds_playing[pos_hash]) + digistuff.sounds_playing[pos_hash] = nil + end + digistuff.sounds_playing[pos_hash] = minetest.sound_play({name = "digistuff_piezo_fast_repeat",gain = 0.2},{pos = pos,max_hear_distance = 16,loop = true}) + elseif msg == "slowrepeat" then + local pos_hash = minetest.hash_node_position(pos) + if digistuff.sounds_playing[pos_hash] then + minetest.sound_stop(digistuff.sounds_playing[pos_hash]) + digistuff.sounds_playing[pos_hash] = nil + end + digistuff.sounds_playing[pos_hash] = minetest.sound_play({name = "digistuff_piezo_slow_repeat",gain = 0.2},{pos = pos,max_hear_distance = 16,loop = true}) + elseif msg == "stop" then + local pos_hash = minetest.hash_node_position(pos) + if digistuff.sounds_playing[pos_hash] then + minetest.sound_stop(digistuff.sounds_playing[pos_hash]) + digistuff.sounds_playing[pos_hash] = nil + end + end + end + }, + }, +}) diff --git a/digistuff/piston.lua b/digistuff/piston.lua new file mode 100644 index 0000000..b4ed655 --- /dev/null +++ b/digistuff/piston.lua @@ -0,0 +1,222 @@ +if not minetest.get_modpath("mesecons_mvps") then + minetest.log("error","mesecons_mvps is not installed - digilines piston will not be available!") + return +end + +local function extend(pos,node,max) + local meta = minetest.get_meta(pos):to_table() + local facedir = minetest.facedir_to_dir(node.param2) + local actiondir = vector.multiply(facedir,-1) + local ppos = vector.add(pos,actiondir) + local success,stack,oldstack = mesecon.mvps_push(ppos,actiondir,max) + if not success then return end + minetest.sound_play("digistuff_piston_extend",{pos = pos,max_hear_distance = 20,gain = 0.6}) + minetest.swap_node(pos,{name = "digistuff:piston_ext",param2 = node.param2}) + minetest.swap_node(ppos,{name = "digistuff:piston_pusher",param2 = node.param2}) + mesecon.mvps_process_stack(stack) + mesecon.mvps_move_objects(ppos,actiondir,oldstack) + minetest.get_meta(pos):from_table(meta) +end + +local function retract(pos,node,max,allsticky) + local facedir = minetest.facedir_to_dir(node.param2) + local actiondir = vector.multiply(facedir,-1) + local ppos = vector.add(pos,actiondir) + minetest.swap_node(pos,{name = "digistuff:piston",param2 = node.param2}) + if minetest.get_node(ppos).name == "digistuff:piston_pusher" then + minetest.remove_node(ppos) + end + minetest.sound_play("digistuff_piston_retract",{pos = pos,max_hear_distance = 20,gain = 0.6}) + minetest.check_for_falling(ppos) + if type(max) ~= "number" or max <= 0 then return end + local pullpos = vector.add(pos,vector.multiply(actiondir,2)) + local success,stack,oldstack + if allsticky then + success,stack,oldstack = mesecon.mvps_pull_all(pullpos,facedir,max) + else + success,stack,oldstack = mesecon.mvps_pull_single(pullpos,facedir,max) + end + if success then + mesecon.mvps_move_objects(pullpos,actiondir,oldstack,-1) + end +end + +minetest.register_node("digistuff:piston", { + description = "Digilines Piston", + groups = {cracky=3}, + paramtype2 = "facedir", + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec","field[channel;Channel;${channel}") + end, + tiles = { + "digistuff_piston_sides.png^[transformR180", + "digistuff_piston_sides.png", + "digistuff_piston_sides.png^[transformR90", + "digistuff_piston_sides.png^[transformR270", + "digistuff_camera_pole.png", + "digistuff_camera_pole.png", + }, + 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, + digiline = { + wire = { + rules = { + {x = 1, y = 0, z = 0}, + {x =-1, y = 0, z = 0}, + {x = 0, y = 1, z = 0}, + {x = 0, y =-1, z = 0}, + {x = 0, y = 0, z = 1}, + {x = 0, y = 0, z =-1}, + }, + }, + receptor = {}, + effector = { + action = function(pos,node,channel,msg) + local meta = minetest.get_meta(pos) + local setchan = meta:get_string("channel") + if channel ~= setchan then return end + if msg == "extend" then + extend(pos,node,16) + elseif type(msg) == "table" and msg.action == "extend" then + local max = 16 + if type(msg.max) == "number" then + max = math.max(0,math.min(16,math.floor(msg.max))) + end + extend(pos,node,max) + end + end + }, + }, +}) + +minetest.register_node("digistuff:piston_ext", { + description = "Digilines Piston (extended state - you hacker you!)", + groups = {cracky = 3,not_in_creative_inventory = 1}, + paramtype2 = "facedir", + tiles = { + "digistuff_piston_sides.png^[transformR180", + "digistuff_piston_sides.png", + "digistuff_piston_sides.png^[transformR90", + "digistuff_piston_sides.png^[transformR270", + "digistuff_camera_pole.png", + "digistuff_camera_pole.png", + }, + drop = "digistuff:piston", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.5,-0.5,-0.3,0.5,0.5,0.5}, + {-0.2,-0.2,-0.5,0.2,0.2,-0.3}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5,-0.5,-1.5,0.5,0.5,0.5}, + } + }, + on_rotate = function() return false end, + 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, + after_dig_node = function(pos,node) + local pdir = vector.multiply(minetest.facedir_to_dir(node.param2),-1) + local ppos = vector.add(pos,pdir) + if minetest.get_node(ppos).name == "digistuff:piston_pusher" then + minetest.remove_node(ppos) + end + end, + digiline = { + wire = { + rules = { + {x = 1, y = 0, z = 0}, + {x =-1, y = 0, z = 0}, + {x = 0, y = 1, z = 0}, + {x = 0, y =-1, z = 0}, + {x = 0, y = 0, z = 1}, + {x = 0, y = 0, z =-1}, + }, + }, + receptor = {}, + effector = { + action = function(pos,node,channel,msg) + local meta = minetest.get_meta(pos) + local setchan = meta:get_string("channel") + if channel ~= setchan then return end + if msg == "retract" then + retract(pos,node) + elseif msg == "retract_sticky" then + retract(pos,node,16) + elseif type(msg) == "table" and msg.action == "retract" then + local max = 16 + if type(msg.max) == "number" then + max = math.max(0,math.min(16,math.floor(msg.max))) + elseif msg.max == nil then + max = 0 + end + retract(pos,node,max,msg.allsticky) + end + end + }, + }, +}) + +minetest.register_node("digistuff:piston_pusher", { + description = "Digilines Piston Pusher (you hacker you!)", + groups = {not_in_creative_inventory=1}, + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "facedir", + tiles = { + "digistuff_piston_sides.png^[transformR180", + "digistuff_piston_sides.png", + "digistuff_piston_sides.png^[transformR90", + "digistuff_piston_sides.png^[transformR270", + "digistuff_camera_pole.png", + "digistuff_camera_pole.png", + }, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.5,-0.5,-0.5,0.5,0.5,-0.3}, + {-0.2,-0.2,-0.3,0.2,0.2,0.5}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {0,0,0,0,0,0}, + } + }, + digiline = { + wire = { + rules = { + {x = 1, y = 0, z = 0}, + {x =-1, y = 0, z = 0}, + {x = 0, y = 1, z = 0}, + {x = 0, y =-1, z = 0}, + {x = 0, y = 0, z = 1}, + {x = 0, y = 0, z =-1}, + }, + }, + }, +}) + +mesecon.register_mvps_stopper("digistuff:piston_ext") +mesecon.register_mvps_stopper("digistuff:piston_pusher") diff --git a/digistuff/sounds/digistuff_piston_extend.ogg b/digistuff/sounds/digistuff_piston_extend.ogg Binary files differnew file mode 100644 index 0000000..2a855df --- /dev/null +++ b/digistuff/sounds/digistuff_piston_extend.ogg diff --git a/digistuff/sounds/digistuff_piston_retract.ogg b/digistuff/sounds/digistuff_piston_retract.ogg Binary files differnew file mode 100644 index 0000000..57f9342 --- /dev/null +++ b/digistuff/sounds/digistuff_piston_retract.ogg diff --git a/digistuff/textures/digistuff_piston_sides.png b/digistuff/textures/digistuff_piston_sides.png Binary files differnew file mode 100644 index 0000000..5475f50 --- /dev/null +++ b/digistuff/textures/digistuff_piston_sides.png diff --git a/digistuff/touchscreen.lua b/digistuff/touchscreen.lua new file mode 100644 index 0000000..5b3c5b7 --- /dev/null +++ b/digistuff/touchscreen.lua @@ -0,0 +1,279 @@ +digistuff.update_ts_formspec = function (pos) + local meta = minetest.get_meta(pos) + local fs = "size[10,8]".. + "background[0,0;0,0;digistuff_ts_bg.png;true]" + if meta:get_int("init") == 0 then + fs = fs.."field[3.75,3;3,1;channel;Channel;]".. + "button_exit[4,3.75;2,1;save;Save]" + else + local data = minetest.deserialize(meta:get_string("data")) or {} + for _,field in pairs(data) do + if field.type == "image" then + fs = fs..string.format("image[%s,%s;%s,%s;%s]",field.X,field.Y,field.W,field.H,field.texture_name) + elseif field.type == "field" then + fs = fs..string.format("field[%s,%s;%s,%s;%s;%s;%s]",field.X,field.Y,field.W,field.H,field.name,field.label,field.default) + elseif field.type == "pwdfield" then + fs = fs..string.format("pwdfield[%s,%s;%s,%s;%s;%s]",field.X,field.Y,field.W,field.H,field.name,field.label) + elseif field.type == "textarea" then + fs = fs..string.format("textarea[%s,%s;%s,%s;%s;%s;%s]",field.X,field.Y,field.W,field.H,field.name,field.label,field.default) + elseif field.type == "label" then + fs = fs..string.format("label[%s,%s;%s]",field.X,field.Y,field.label) + elseif field.type == "vertlabel" then + fs = fs..string.format("vertlabel[%s,%s;%s]",field.X,field.Y,field.label) + elseif field.type == "button" then + fs = fs..string.format("button[%s,%s;%s,%s;%s;%s]",field.X,field.Y,field.W,field.H,field.name,field.label) + elseif field.type == "button_exit" then + fs = fs..string.format("button_exit[%s,%s;%s,%s;%s;%s]",field.X,field.Y,field.W,field.H,field.name,field.label) + elseif field.type == "image_button" then + fs = fs..string.format("image_button[%s,%s;%s,%s;%s;%s;%s]",field.X,field.Y,field.W,field.H,field.image,field.name,field.label) + elseif field.type == "image_button_exit" then + fs = fs..string.format("image_button_exit[%s,%s;%s,%s;%s;%s;%s]",field.X,field.Y,field.W,field.H,field.image,field.name,field.label) + elseif field.type == "dropdown" then + local choices = "" + for _,i in ipairs(field.choices) do + if type(i) == "string" then + choices = choices..minetest.formspec_escape(i).."," + end + end + choices = string.sub(choices,1,-2) + fs = fs..string.format("dropdown[%s,%s;%s,%s;%s;%s;%s]",field.X,field.Y,field.W,field.H,field.name,choices,field.selected_id) + end + end + end + meta:set_string("formspec",fs) +end + +digistuff.ts_on_receive_fields = function (pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + local setchan = meta:get_string("channel") + local playername = sender:get_player_name() + local locked = meta:get_int("locked") == 1 + local can_bypass = minetest.check_player_privs(playername,{protection_bypass=true}) + local is_protected = minetest.is_protected(pos,playername) + if (locked and is_protected) and not can_bypass then + minetest.record_protection_violation(pos,playername) + minetest.chat_send_player(playername,"You are not authorized to use this screen.") + return + end + local init = meta:get_int("init") == 1 + if not init then + if fields.save then + meta:set_string("channel",fields.channel) + meta:set_int("init",1) + digistuff.update_ts_formspec(pos) + end + else + fields.clicker = sender:get_player_name() + digiline:receptor_send(pos, digiline.rules.default, setchan, fields) + end +end + +digistuff.process_command = function (meta, data, msg) + if msg.command == "clear" then + data = {} + elseif msg.command == "addimage" then + for _,i in pairs({"X","Y","W","H"}) do + if not msg[i] or type(msg[i]) ~= "number" then + return + end + end + if not msg.texture_name or type(msg.texture_name) ~= "string" then + return + end + local field = {type="image",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,texture_name=minetest.formspec_escape(msg.texture_name)} + table.insert(data,field) + elseif msg.command == "addfield" then + for _,i in pairs({"X","Y","W","H"}) do + if not msg[i] or type(msg[i]) ~= "number" then + return + end + end + for _,i in pairs({"name","label","default"}) do + if not msg[i] or type(msg[i]) ~= "string" then + return + end + end + local field = {type="field",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label),default=minetest.formspec_escape(msg.default)} + table.insert(data,field) + elseif msg.command == "addpwdfield" then + for _,i in pairs({"X","Y","W","H"}) do + if not msg[i] or type(msg[i]) ~= "number" then + return + end + end + for _,i in pairs({"name","label"}) do + if not msg[i] or type(msg[i]) ~= "string" then + return + end + end + local field = {type="pwdfield",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label)} + table.insert(data,field) + elseif msg.command == "addtextarea" then + for _,i in pairs({"X","Y","W","H"}) do + if not msg[i] or type(msg[i]) ~= "number" then + return + end + end + for _,i in pairs({"name","label","default"}) do + if not msg[i] or type(msg[i]) ~= "string" then + return + end + end + local field = {type="textarea",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label),default=minetest.formspec_escape(msg.default)} + table.insert(data,field) + elseif msg.command == "addlabel" then + for _,i in pairs({"X","Y"}) do + if not msg[i] or type(msg[i]) ~= "number" then + return + end + end + if not msg.label or type(msg.label) ~= "string" then + return + end + local field = {type="label",X=msg.X,Y=msg.Y,label=minetest.formspec_escape(msg.label)} + table.insert(data,field) + elseif msg.command == "addvertlabel" then + for _,i in pairs({"X","Y"}) do + if not msg[i] or type(msg[i]) ~= "number" then + return + end + end + if not msg.label or type(msg.label) ~= "string" then + return + end + local field = {type="vertlabel",X=msg.X,Y=msg.Y,label=minetest.formspec_escape(msg.label)} + table.insert(data,field) + elseif msg.command == "addbutton" then + for _,i in pairs({"X","Y","W","H"}) do + if not msg[i] or type(msg[i]) ~= "number" then + return + end + end + for _,i in pairs({"name","label"}) do + if not msg[i] or type(msg[i]) ~= "string" then + return + end + end + local field = {type="button",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label)} + table.insert(data,field) + elseif msg.command == "addbutton_exit" then + for _,i in pairs({"X","Y","W","H"}) do + if not msg[i] or type(msg[i]) ~= "number" then + return + end + end + for _,i in pairs({"name","label"}) do + if not msg[i] or type(msg[i]) ~= "string" then + return + end + end + local field = {type="button_exit",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label)} + table.insert(data,field) + elseif msg.command == "addimage_button" then + for _,i in pairs({"X","Y","W","H"}) do + if not msg[i] or type(msg[i]) ~= "number" then + return + end + end + for _,i in pairs({"image","name","label"}) do + if not msg[i] or type(msg[i]) ~= "string" then + return + end + end + local field = {type="image_button",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,image=minetest.formspec_escape(msg.image),name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label)} + table.insert(data,field) + elseif msg.command == "addimage_button_exit" then + for _,i in pairs({"X","Y","W","H"}) do + if not msg[i] or type(msg[i]) ~= "number" then + return + end + end + for _,i in pairs({"image","name","label"}) do + if not msg[i] or type(msg[i]) ~= "string" then + return + end + end + local field = {type="image_button_exit",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,image=minetest.formspec_escape(msg.image),name=minetest.formspec_escape(msg.name),label=minetest.formspec_escape(msg.label)} + table.insert(data,field) + elseif msg.command == "adddropdown" then + for _,i in pairs({"X","Y","W","H","selected_id"}) do + if not msg[i] or type(msg[i]) ~= "number" then + return + end + end + if not msg.name or type(msg.name) ~= "string" then + return + end + if not msg.choices or type(msg.choices) ~= "table" or #msg.choices < 1 then + return + end + local field = {type="dropdown",X=msg.X,Y=msg.Y,W=msg.W,H=msg.H,name=msg.name,selected_id=msg.selected_id,choices=msg.choices} + table.insert(data,field) + elseif msg.command == "lock" then + meta:set_int("locked",1) + elseif msg.command == "unlock" then + meta:set_int("locked",0) + end + return data +end + +digistuff.ts_on_digiline_receive = function (pos, node, channel, msg) + local meta = minetest.get_meta(pos) + local setchan = meta:get_string("channel") + if channel ~= setchan then return end + if type(msg) ~= "table" then return end + local data = minetest.deserialize(meta:get_string("data")) or {} + if msg.command then + data = digistuff.process_command(meta,data,msg) + else + for _,i in ipairs(msg) do + if i.command then + data = digistuff.process_command(meta,data,i) or data + end + end + end + meta:set_string("data",minetest.serialize(data)) + digistuff.update_ts_formspec(pos) +end + +minetest.register_node("digistuff:touchscreen", { + description = "Digilines Touchscreen", + groups = {cracky=3}, + on_construct = function(pos) + digistuff.update_ts_formspec(pos,true) + end, + drawtype = "nodebox", + tiles = { + "digistuff_panel_back.png", + "digistuff_panel_back.png", + "digistuff_panel_back.png", + "digistuff_panel_back.png", + "digistuff_panel_back.png", + "digistuff_ts_front.png" + }, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + { -0.5, -0.5, 0.4, 0.5, 0.5, 0.5 } + } + }, + on_receive_fields = digistuff.ts_on_receive_fields, + digiline = + { + receptor = {}, + effector = { + action = digistuff.ts_on_digiline_receive + }, + }, +}) + +minetest.register_craft({ + output = "digistuff:touchscreen", + recipe = { + {"mesecons_luacontroller:luacontroller0000","default:glass","default:glass"}, + {"default:glass","digilines:lcd","default:glass"}, + {"default:glass","default:glass","default:glass"} + } +}) |