Fix mesecon control of forcefield
authorZefram <zefram@fysh.org>
Mon, 14 Jul 2014 13:58:59 +0000 (14:58 +0100)
committerZefram <zefram@fysh.org>
Wed, 23 Jul 2014 15:49:08 +0000 (16:49 +0100)
The code formerly attempted to make the forcefield emitter controlled
both manually and by (inverted) mesecon signal, but the two interfered
with each other.  In particular, a newly-placed emitted would be
informed that it was getting no mesecon signal, and would therefore
enable itself.  Fix this by adding explicit modes for how the emitter
will respond to mesecon signals: ignore them, obey them positively,
or obey them negatively.

The manual control could have been incorporated into this mode setting
by having two "ignore mesecon" modes: always-enabled and always-disabled.
But it seems more useful to have a separate manual master switch, so that
the emitter can be manually disabled without losing the mesecon mode.
So it is now implemented that way.

technic/locale/template.txt
technic/machines/HV/forcefield.lua

index 2735dbfc7b0e43cd7b1663846bce9a1c469e694e..d771c09c41944c42f97bb2b6154ea4e4123e5c1c 100644 (file)
@@ -55,6 +55,9 @@ Slot %d =
 Mode: %s =
 single items =
 whole stacks =
+Ignoring Mesecon Signal =
+Controlled by Positive Mesecon Signal =
+Controlled by Inverted Mesecon Signal =
 
 ## Machine names
 # $1: Tier
index beb8e45ed8bf41cf34cd25cfd7670b80d4ef2bdf..d5b5e54734c5dac661306916fbd940164655eaa6 100644 (file)
@@ -63,12 +63,19 @@ local function update_forcefield(pos, range, active)
 end
 
 local function set_forcefield_formspec(meta)
-       local formspec = "size[5,1.5]"..
-               "field[2,0.5;2,1;range;"..S("Range")..";"..meta:get_int("range").."]"
+       local formspec = "size[5.5,2.25]"..
+               "field[2.25,0.5;2,1;range;"..S("Range")..";"..meta:get_int("range").."]"
+       if meta:get_int("mesecon_mode") == 0 then
+               formspec = formspec.."button[0,1;5.5,1;mesecon_mode_1;"..S("Ignoring Mesecon Signal").."]"
+       elseif meta:get_int("mesecon_mode") == 1 then
+               formspec = formspec.."button[0,1;5.5,1;mesecon_mode_2;"..S("Controlled by Positive Mesecon Signal").."]"
+       else
+               formspec = formspec.."button[0,1;5.5,1;mesecon_mode_0;"..S("Controlled by Inverted Mesecon Signal").."]"
+       end
        if meta:get_int("enabled") == 0 then
-               formspec = formspec.."button[0,1;5,1;enable;"..S("%s Disabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
+               formspec = formspec.."button[0.25,1.75;5,1;enable;"..S("%s Disabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
        else
-               formspec = formspec.."button[0,1;5,1;disable;"..S("%s Enabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
+               formspec = formspec.."button[0.25,1.75;5,1;disable;"..S("%s Enabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
        end
        meta:set_string("formspec", formspec)
 end
@@ -89,16 +96,19 @@ local forcefield_receive_fields = function(pos, formname, fields, sender)
        end
        if fields.enable then meta:set_int("enabled", 1) end
        if fields.disable then meta:set_int("enabled", 0) end
+       if fields.mesecon_mode_0 then meta:set_int("mesecon_mode", 0) end
+       if fields.mesecon_mode_1 then meta:set_int("mesecon_mode", 1) end
+       if fields.mesecon_mode_2 then meta:set_int("mesecon_mode", 2) end
        set_forcefield_formspec(meta)
 end
 
 local mesecons = {
        effector = {
                action_on = function(pos, node)
-                       minetest.get_meta(pos):set_int("enabled", 0)
+                       minetest.get_meta(pos):set_int("mesecon_effect", 1)
                end,
                action_off = function(pos, node)
-                       minetest.get_meta(pos):set_int("enabled", 1)
+                       minetest.get_meta(pos):set_int("mesecon_effect", 0)
                end
        }
 }
@@ -107,14 +117,14 @@ local run = function(pos, node, active_object_count, active_object_count_wider)
        local meta = minetest.get_meta(pos)
        local eu_input   = meta:get_int("HV_EU_input")
        local eu_demand  = meta:get_int("HV_EU_demand")
-       local enabled    = meta:get_int("enabled")
+       local enabled = meta:get_int("enabled") ~= 0 and (meta:get_int("mesecon_mode") == 0 or (meta:get_int("mesecon_mode") == 1 and meta:get_int("mesecon_effect") ~= 0) or (meta:get_int("mesecon_mode") == 2 and meta:get_int("mesecon_effect") == 0))
        local machine_name = S("%s Forcefield Emitter"):format("HV")
 
        local power_requirement = math.floor(
                        4 * math.pi * math.pow(meta:get_int("range"), 2)
                ) * forcefield_power_drain
 
-       if meta:get_int("enabled") == 0 then
+       if not enabled then
                if node.name == "technic:forcefield_emitter_on" then
                        meta:set_int("HV_EU_demand", 0)
                        update_forcefield(pos, meta:get_int("range"), false)
@@ -149,6 +159,8 @@ minetest.register_node("technic:forcefield_emitter_off", {
                meta:set_int("HV_EU_demand", 0)
                meta:set_int("range", 10)
                meta:set_int("enabled", 0)
+               meta:set_int("mesecon_mode", 0)
+               meta:set_int("mesecon_effect", 0)
                meta:set_string("infotext", S("%s Forcefield Emitter"):format("HV"))
                set_forcefield_formspec(meta)
        end,
@@ -162,11 +174,6 @@ minetest.register_node("technic:forcefield_emitter_on", {
        groups = {cracky = 1, technic_machine = 1, not_in_creative_inventory=1},
        drop = "technic:forcefield_emitter_off",
        on_receive_fields = forcefield_receive_fields,
-       on_construct = function(pos) 
-               local meta = minetest.get_meta(pos)
-               local range = meta:get_int("range")
-               meta:set_string("formspec", get_forcefield_formspec(range))
-       end,
        on_destruct = function(pos)
                local meta = minetest.get_meta(pos)
                update_forcefield(pos, meta:get_int("range"), false)