@@ -133,6 +133,23 @@ local function set_port_states(pos, ports)
133133 local new_name = generate_name (ports )
134134
135135 if name ~= new_name and vports then
136+ -- Problem:
137+ -- We need to place the new node first so that when turning
138+ -- off some port, it won't stay on because the rules indicate
139+ -- there is an onstate output port there.
140+ -- When turning the output off then, it will however cause feedback
141+ -- so that the luacontroller will receive an "off" event by turning
142+ -- its output off.
143+ -- Solution / Workaround:
144+ -- Remember which output was turned off and ignore next "off" event.
145+ local meta = minetest .get_meta (pos )
146+ local ign = minetest .deserialize (meta :get_string (" ignore_offevents" )) or {}
147+ if ports .a and not vports .a and not mesecon .is_powered (pos , rules .a ) then ign .A = true end
148+ if ports .b and not vports .b and not mesecon .is_powered (pos , rules .b ) then ign .B = true end
149+ if ports .c and not vports .c and not mesecon .is_powered (pos , rules .c ) then ign .C = true end
150+ if ports .d and not vports .d and not mesecon .is_powered (pos , rules .d ) then ign .D = true end
151+ meta :set_string (" ignore_offevents" , minetest .serialize (ign ))
152+
136153 minetest .swap_node (pos , {name = new_name , param2 = node .param2 })
137154
138155 if ports .a ~= vports .a then set_port (pos , rules .a , ports .a ) end
@@ -163,6 +180,19 @@ local function overheat(pos, meta)
163180 end
164181end
165182
183+ ---- --------------------
184+ -- Ignored off events --
185+ ---- --------------------
186+
187+ local function ignore_event (event , meta )
188+ if event .type ~= " off" then return false end
189+ local ignore_offevents = minetest .deserialize (meta :get_string (" ignore_offevents" )) or {}
190+ if ignore_offevents [event .pin .name ] then
191+ ignore_offevents [event .pin .name ] = nil
192+ meta :set_string (" ignore_offevents" , minetest .serialize (ignore_offevents ))
193+ return true
194+ end
195+ end
166196
167197---- ---------------------
168198-- Parsing and running --
361391local function run (pos , event )
362392 local meta = minetest .get_meta (pos )
363393 if overheat (pos ) then return end
394+ if ignore_event (event , meta ) then return end
364395
365396 -- Load code & mem from meta
366397 local mem = load_memory (meta )
@@ -499,7 +530,7 @@ for d = 0, 1 do
499530 rules = input_rules [cid ],
500531 action_change = function (pos , _ , rule_name , new_state )
501532 update_real_port_states (pos , rule_name , new_state )
502- run (pos , {type = new_state , pin = rule_name })
533+ run (pos , {type = new_state , pin = rule_name })
503534 end ,
504535 },
505536 receptor = {
0 commit comments