@@ -133,6 +133,23 @@ local function set_port_states(pos, ports)
133
133
local new_name = generate_name (ports )
134
134
135
135
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
+
136
153
minetest .swap_node (pos , {name = new_name , param2 = node .param2 })
137
154
138
155
if ports .a ~= vports .a then set_port (pos , rules .a , ports .a ) end
@@ -163,6 +180,19 @@ local function overheat(pos, meta)
163
180
end
164
181
end
165
182
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
166
196
167
197
---- ---------------------
168
198
-- Parsing and running --
361
391
local function run (pos , event )
362
392
local meta = minetest .get_meta (pos )
363
393
if overheat (pos ) then return end
394
+ if ignore_event (event , meta ) then return end
364
395
365
396
-- Load code & mem from meta
366
397
local mem = load_memory (meta )
@@ -499,7 +530,7 @@ for d = 0, 1 do
499
530
rules = input_rules [cid ],
500
531
action_change = function (pos , _ , rule_name , new_state )
501
532
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 })
503
534
end ,
504
535
},
505
536
receptor = {
0 commit comments