diff --git a/cannon.lua b/cannon.lua index c4acd69..b07306e 100644 --- a/cannon.lua +++ b/cannon.lua @@ -111,6 +111,17 @@ local register_spacecannon = function(def) connects_to = {"group:technic_hv_cable"}, connect_sides = {"bottom", "top", "left", "right", "front", "back"}, + digiline = { + receptor = { + rules = spacecannon.digiline_rules, + action = function() end + }, + effector = { + rules = spacecannon.digiline_rules, + action = spacecannon.digiline_effector + }, + }, + after_place_node = function(pos, placer) local meta = minetest.get_meta(pos) meta:set_string("owner", placer:get_player_name() or "") @@ -123,6 +134,9 @@ local register_spacecannon = function(def) meta:set_int("HV_EU_input", 0) meta:set_int("HV_EU_demand", 0) + -- Set default digiline channel (do before updating formspec). + meta:set_string("channel", "spacecannon") + spacecannon.update_formspec(meta) end, @@ -146,9 +160,17 @@ local register_spacecannon = function(def) end, on_receive_fields = function(pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + if fields.fire then spacecannon.fire(pos, def.color, def.speed, def.range) end + + if fields.set_digiline_channel and fields.digiline_channel then + meta:set_string("channel", fields.digiline_channel) + end + + spacecannon.update_formspec(meta) end }) diff --git a/depends.txt b/depends.txt index eeb653d..db54710 100644 --- a/depends.txt +++ b/depends.txt @@ -1,3 +1,4 @@ default technic +digilines? mesecons? diff --git a/digiline.lua b/digiline.lua new file mode 100644 index 0000000..03f1dd6 --- /dev/null +++ b/digiline.lua @@ -0,0 +1,82 @@ +spacecannon.digiline_rules = { + -- digilines.rules.default + {x= 1,y= 0,z= 0},{x=-1,y= 0,z= 0}, -- along x beside + {x= 0,y= 0,z= 1},{x= 0,y= 0,z=-1}, -- along z beside + {x= 1,y= 1,z= 0},{x=-1,y= 1,z= 0}, -- 1 node above along x diagonal + {x= 0,y= 1,z= 1},{x= 0,y= 1,z=-1}, -- 1 node above along z diagonal + {x= 1,y=-1,z= 0},{x=-1,y=-1,z= 0}, -- 1 node below along x diagonal + {x= 0,y=-1,z= 1},{x= 0,y=-1,z=-1}, -- 1 node below along z diagonal + -- added rules for digi cable + {x= 0,y= 1,z= 0},{x= 0,y=-1,z= 0}, -- along y above and below +} + +spacecannon.digiline_handler_get = function(pos, node, channel, msg) + local meta = minetest.get_meta(pos) + + local input = meta:get_int("HV_EU_input") + local demand = meta:get_int("HV_EU_demand") + local powerstorage = meta:get_int("powerstorage") + + local resp = { + ready = (demand == 0) and (powerstorage > 0), + HV_EU_input = input, + HV_EU_demand = demand, + powerstorage = powerstorage, + dir = spacecannon.facedir_to_down_dir(node.param2), + name = node.name, + origin = channel, + pos = pos + } + + digilines.receptor_send(pos, spacecannon.digiline_rules, channel, resp) +end + +spacecannon.digiline_handler_fire = function(pos, node, channel, msg) + local meta = minetest.get_meta(pos) + + -- TODO: Add ability to set "target node" in the msg, and if its within + -- 45 degree angle of where the cannon is aimed, then allow the projectile + -- to travel at a suitable angle to pass through the target node. + + -- TODO: Modify "spacecannon.fire" to return success/failure, so we can + -- return that to the digiline receptor. + -- For now, if we've consumed powerstorage, then assume success. + local powerstorage_before = meta:get_int("powerstorage") + + -- We cannot directly call "spacecannon.fire", as we don't know the + -- cannon's registered color, speed and range; we'll trampoline through + -- the mesecons effector. + local mesecons = minetest.registered_nodes[node.name]['mesecons'] + if mesecons then + mesecons.effector.action_on(pos, node) + end + + local powerstorage_after = meta:get_int("powerstorage") + + local resp = { + action = "fire", + success = (powerstorage_before > 0) and (powerstorage_after == 0), + origin = channel, + pos = pos + } + + digilines.receptor_send(pos, spacecannon.digiline_rules, channel, resp) +end + +spacecannon.digiline_effector = function(pos, node, channel, msg) + if type(msg) ~= "table" then + return + end + + local meta = minetest.get_meta(pos) + + if channel ~= meta:get_string("channel") then + return + end + + if msg.command == "get" then + spacecannon.digiline_handler_get(pos, node, channel, msg) + elseif msg.command == "fire" then + spacecannon.digiline_handler_fire(pos, node, channel, msg) + end +end diff --git a/init.lua b/init.lua index 713a367..0577546 100644 --- a/init.lua +++ b/init.lua @@ -13,7 +13,8 @@ spacecannon = { local MP = minetest.get_modpath("spacecannon") dofile(MP.."/util.lua") +dofile(MP.."/digiline.lua") dofile(MP.."/cannon.lua") dofile(MP.."/node_resilience.lua") -print("[OK] Spacecannon") \ No newline at end of file +print("[OK] Spacecannon") diff --git a/util.lua b/util.lua index fde32e9..912e58f 100644 --- a/util.lua +++ b/util.lua @@ -1,7 +1,30 @@ +local has_digilines = minetest.get_modpath("digilines") + +spacecannon.update_formspec_digilines = function(meta) + local channel = meta:get_string("channel") or "" + + local formspec = + "formspec_version[4]" .. + "size[6,4;]" .. + + -- Digiline channel + "field[0.5,0.5;3.5,1;digiline_channel;Digiline Channel;" .. + channel .. "]" .. + "button_exit[4.5,0.5;1,1;set_digiline_channel;Set]" .. + + -- Manual "fire" button + "button_exit[0.5,2.5;5,1;fire;Fire]" + + meta:set_string("formspec", formspec) +end spacecannon.update_formspec = function(meta) - meta:set_string("formspec", "size[8,2;]" .. - "button_exit[0,1;8,1;fire;Fire]") + if has_digilines then + spacecannon.update_formspec_digilines(meta) + else + meta:set_string("formspec", "size[8,2;]" .. + "button_exit[0,1;8,1;fire;Fire]") + end end spacecannon.can_shoot = function(pos)