Zefram
2014-07-14 6a4cb163927026e6b0e8ce9b74e2ca8457dc55e7
Fix mesecon control of forcefield

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.
2 files modified
38 ■■■■■ changed files
technic/locale/template.txt 3 ●●●●● patch | view | raw | blame | history
technic/machines/HV/forcefield.lua 35 ●●●●● patch | view | raw | blame | history
technic/locale/template.txt
@@ -55,6 +55,9 @@
Mode: %s =
single items =
whole stacks =
Ignoring Mesecon Signal =
Controlled by Positive Mesecon Signal =
Controlled by Inverted Mesecon Signal =
## Machine names
# $1: Tier
technic/machines/HV/forcefield.lua
@@ -63,12 +63,19 @@
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").."]"
    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")).."]"
    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,1;disable;"..S("%s Enabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
        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.25,1.75;5,1;enable;"..S("%s Disabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
    else
        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 @@
    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 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 @@
        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 @@
    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)