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.
This commit is contained in:
Zefram 2014-07-14 14:58:59 +01:00
parent 1bf52c2d5a
commit 6a4cb16392
2 changed files with 24 additions and 14 deletions

@ -55,6 +55,9 @@ Slot %d =
Mode: %s = Mode: %s =
single items = single items =
whole stacks = whole stacks =
Ignoring Mesecon Signal =
Controlled by Positive Mesecon Signal =
Controlled by Inverted Mesecon Signal =
## Machine names ## Machine names
# $1: Tier # $1: Tier

@ -63,12 +63,19 @@ local function update_forcefield(pos, range, active)
end end
local function set_forcefield_formspec(meta) local function set_forcefield_formspec(meta)
local formspec = "size[5,1.5]".. local formspec = "size[5.5,2.25]"..
"field[2,0.5;2,1;range;"..S("Range")..";"..meta:get_int("range").."]" "field[2.25,0.5;2,1;range;"..S("Range")..";"..meta:get_int("range").."]"
if meta:get_int("enabled") == 0 then if meta:get_int("mesecon_mode") == 0 then
formspec = formspec.."button[0,1;5,1;enable;"..S("%s Disabled"):format(S("%s Forcefield Emitter"):format("HV")).."]" 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 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 end
meta:set_string("formspec", formspec) meta:set_string("formspec", formspec)
end end
@ -89,16 +96,19 @@ local forcefield_receive_fields = function(pos, formname, fields, sender)
end end
if fields.enable then meta:set_int("enabled", 1) end if fields.enable then meta:set_int("enabled", 1) end
if fields.disable then meta:set_int("enabled", 0) 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) set_forcefield_formspec(meta)
end end
local mesecons = { local mesecons = {
effector = { effector = {
action_on = function(pos, node) action_on = function(pos, node)
minetest.get_meta(pos):set_int("enabled", 0) minetest.get_meta(pos):set_int("mesecon_effect", 1)
end, end,
action_off = function(pos, node) action_off = function(pos, node)
minetest.get_meta(pos):set_int("enabled", 1) minetest.get_meta(pos):set_int("mesecon_effect", 0)
end end
} }
} }
@ -107,14 +117,14 @@ local run = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local eu_input = meta:get_int("HV_EU_input") local eu_input = meta:get_int("HV_EU_input")
local eu_demand = meta:get_int("HV_EU_demand") 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 machine_name = S("%s Forcefield Emitter"):format("HV")
local power_requirement = math.floor( local power_requirement = math.floor(
4 * math.pi * math.pow(meta:get_int("range"), 2) 4 * math.pi * math.pow(meta:get_int("range"), 2)
) * forcefield_power_drain ) * forcefield_power_drain
if meta:get_int("enabled") == 0 then if not enabled then
if node.name == "technic:forcefield_emitter_on" then if node.name == "technic:forcefield_emitter_on" then
meta:set_int("HV_EU_demand", 0) meta:set_int("HV_EU_demand", 0)
update_forcefield(pos, meta:get_int("range"), false) 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("HV_EU_demand", 0)
meta:set_int("range", 10) meta:set_int("range", 10)
meta:set_int("enabled", 0) 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")) meta:set_string("infotext", S("%s Forcefield Emitter"):format("HV"))
set_forcefield_formspec(meta) set_forcefield_formspec(meta)
end, end,
@ -162,11 +174,6 @@ minetest.register_node("technic:forcefield_emitter_on", {
groups = {cracky = 1, technic_machine = 1, not_in_creative_inventory=1}, groups = {cracky = 1, technic_machine = 1, not_in_creative_inventory=1},
drop = "technic:forcefield_emitter_off", drop = "technic:forcefield_emitter_off",
on_receive_fields = forcefield_receive_fields, 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) on_destruct = function(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
update_forcefield(pos, meta:get_int("range"), false) update_forcefield(pos, meta:get_int("range"), false)