22
22
-- mesecon:effector_get_rules(node) --> Returns the input rules of the effector (mesecon.rules.default if none specified)
23
23
24
24
-- SIGNALS
25
- -- mesecon:activate(pos, node, recdepth ) --> Activates the effector node at the specific pos (calls nodedef.mesecons.effector.action_on), higher recdepths are executed later
26
- -- mesecon:deactivate(pos, node, recdepth ) --> Deactivates the effector node at the specific pos (calls nodedef.mesecons.effector.action_off), "
27
- -- mesecon:changesignal(pos, node, rulename, newstate) --> Changes the effector node at the specific pos (calls nodedef.mesecons.effector.action_change), "
25
+ -- mesecon:activate(pos, node, depth ) --> Activates the effector node at the specific pos (calls nodedef.mesecons.effector.action_on), higher depths are executed later
26
+ -- mesecon:deactivate(pos, node, depth ) --> Deactivates the effector node at the specific pos (calls nodedef.mesecons.effector.action_off), higher depths are executed later
27
+ -- mesecon:changesignal(pos, node, rulename, newstate, depth ) --> Changes the effector node at the specific pos (calls nodedef.mesecons.effector.action_change), higher depths are executed later
28
28
29
29
-- CONDUCTORS
30
30
-- mesecon:is_conductor(nodename) --> Returns true if nodename is a conductor
@@ -187,14 +187,14 @@ mesecon.queue:add_function("activate", function (pos, rulename)
187
187
end
188
188
end )
189
189
190
- function mesecon :activate (pos , node , rulename , recdepth )
190
+ function mesecon :activate (pos , node , rulename , depth )
191
191
if rulename == nil then
192
192
for _ ,rule in ipairs (mesecon :effector_get_rules (node )) do
193
- mesecon :activate (pos , node , rule , recdepth + 1 )
193
+ mesecon :activate (pos , node , rule , depth + 1 )
194
194
end
195
195
return
196
196
end
197
- mesecon .queue :add_action (pos , " activate" , {rulename }, nil , rulename , 1 / recdepth )
197
+ mesecon .queue :add_action (pos , " activate" , {rulename }, nil , rulename , 1 / depth )
198
198
end
199
199
200
200
@@ -208,36 +208,36 @@ mesecon.queue:add_function("deactivate", function (pos, rulename)
208
208
end
209
209
end )
210
210
211
- function mesecon :deactivate (pos , node , rulename , recdepth )
211
+ function mesecon :deactivate (pos , node , rulename , depth )
212
212
if rulename == nil then
213
213
for _ ,rule in ipairs (mesecon :effector_get_rules (node )) do
214
- mesecon :deactivate (pos , node , rule , recdepth + 1 )
214
+ mesecon :deactivate (pos , node , rule , depth + 1 )
215
215
end
216
216
return
217
217
end
218
- mesecon .queue :add_action (pos , " deactivate" , {rulename }, nil , rulename , 1 / recdepth )
218
+ mesecon .queue :add_action (pos , " deactivate" , {rulename }, nil , rulename , 1 / depth )
219
219
end
220
220
221
221
222
222
-- Change
223
223
mesecon .queue :add_function (" change" , function (pos , rulename , changetype )
224
- node = minetest .get_node (pos )
225
- effector = mesecon :get_effector (node .name )
224
+ local node = minetest .get_node (pos )
225
+ local effector = mesecon :get_effector (node .name )
226
226
227
227
if effector and effector .action_change then
228
228
effector .action_change (pos , node , rulename , changetype )
229
229
end
230
230
end )
231
231
232
- function mesecon :changesignal (pos , node , rulename , newstate , recdepth )
232
+ function mesecon :changesignal (pos , node , rulename , newstate , depth )
233
233
if rulename == nil then
234
234
for _ ,rule in ipairs (mesecon :effector_get_rules (node )) do
235
- mesecon :changesignal (pos , node , rule , newstate , recdepth + 1 )
235
+ mesecon :changesignal (pos , node , rule , newstate , depth + 1 )
236
236
end
237
237
return
238
238
end
239
239
240
- mesecon .queue :add_action (pos , " change" , {rulename , newstate }, nil , rulename , 1 / recdepth )
240
+ mesecon .queue :add_action (pos , " change" , {rulename , newstate }, nil , rulename , 1 / depth )
241
241
end
242
242
243
243
-- Conductors
@@ -349,92 +349,95 @@ function mesecon:is_power_off(pos, rulename)
349
349
return false
350
350
end
351
351
352
- function mesecon :turnon (pos , rulename , recdepth )
353
- recdepth = recdepth or 2
354
- if (recdepth > STACK_SIZE ) then return end
355
- local node = minetest .get_node (pos )
352
+ function mesecon :turnon (pos , link )
353
+ local frontiers = {{pos = pos , link = link }}
356
354
357
- if (node .name == " ignore" ) then
358
- -- try turning on later again
359
- mesecon .queue :add_action (
360
- pos , " turnon" , {rulename , recdepth + 1 }, nil , true )
361
- end
362
-
363
- if mesecon :is_conductor_off (node , rulename ) then
364
- local rules = mesecon :conductor_get_rules (node )
355
+ local depth = 1
356
+ while frontiers [depth ] do
357
+ local f = frontiers [depth ]
358
+ local node = minetest .get_node_or_nil (f .pos )
365
359
366
- if not rulename then
367
- for _ , rule in ipairs (mesecon :flattenrules (rules )) do
368
- if mesecon :connected_to_receptor (pos , rule ) then
369
- mesecon :turnon (pos , rule , recdepth + 1 )
370
- end
371
- end
372
- return
360
+ -- area not loaded, postpone action
361
+ if not node then
362
+ mesecon .queue :add_action (f .pos , " turnon" , {link }, nil , true )
373
363
end
374
364
375
- minetest .swap_node (pos , {name = mesecon :get_conductor_on (node , rulename ), param2 = node .param2 })
365
+ if mesecon :is_conductor_off (node , f .link ) then
366
+ local rules = mesecon :conductor_get_rules (node )
376
367
377
- for _ , rule in ipairs (mesecon :rule2meta (rulename , rules )) do
378
- local np = mesecon :addPosRule (pos , rule )
379
- if (minetest .get_node (np ).name == " ignore" ) then
380
- -- try turning on later again
381
- mesecon .queue :add_action (
382
- np , " turnon" , {rulename , recdepth + 1 }, nil , true )
383
- else
384
- local rulenames = mesecon :rules_link_rule_all (pos , rule )
385
-
386
- for _ , rulename in ipairs (rulenames ) do
387
- mesecon :turnon (np , rulename , recdepth + 1 )
368
+ minetest .swap_node (f .pos , {name = mesecon :get_conductor_on (node , f .link ),
369
+ param2 = node .param2 })
370
+
371
+ -- call turnon on neighbors: normal rules
372
+ for _ , r in ipairs (mesecon :rule2meta (f .link , rules )) do
373
+ local np = mesecon :addPosRule (f .pos , r )
374
+
375
+ -- area not loaded, postpone action
376
+ if not minetest .get_node_or_nil (np ) then
377
+ mesecon .queue :add_action (np , " turnon" , {rulename },
378
+ nil , true )
379
+ else
380
+ local links = mesecon :rules_link_rule_all (f .pos , r )
381
+ for _ , l in ipairs (links ) do
382
+ table.insert (frontiers , {pos = np , link = l })
383
+ end
388
384
end
389
385
end
386
+ elseif mesecon :is_effector (node .name ) then
387
+ mesecon :changesignal (f .pos , node , f .link , mesecon .state .on , depth )
388
+ if mesecon :is_effector_off (node .name ) then
389
+ mesecon :activate (f .pos , node , f .link , depth )
390
+ end
390
391
end
391
- elseif mesecon :is_effector (node .name ) then
392
- mesecon :changesignal (pos , node , rulename , mesecon .state .on , recdepth )
393
- if mesecon :is_effector_off (node .name ) then
394
- mesecon :activate (pos , node , rulename , recdepth )
395
- end
392
+ depth = depth + 1
396
393
end
397
394
end
398
395
399
396
mesecon .queue :add_function (" turnon" , function (pos , rulename , recdepth )
400
397
mesecon :turnon (pos , rulename , recdepth )
401
398
end )
402
399
403
- function mesecon :turnoff (pos , rulename , recdepth )
404
- recdepth = recdepth or 2
405
- if (recdepth > STACK_SIZE ) then return end
406
- local node = minetest .get_node (pos )
400
+ function mesecon :turnoff (pos , link )
401
+ local frontiers = {{pos = pos , link = link }}
407
402
408
- if (node .name == " ignore" ) then
409
- -- try turning on later again
410
- mesecon .queue :add_action (
411
- pos , " turnoff" , {rulename , recdepth + 1 }, nil , true )
412
- end
403
+ local depth = 1
404
+ while frontiers [depth ] do
405
+ local f = frontiers [depth ]
406
+ local node = minetest .get_node_or_nil (f .pos )
413
407
414
- if mesecon :is_conductor_on (node , rulename ) then
415
- local rules = mesecon :conductor_get_rules (node )
416
- minetest .swap_node (pos , {name = mesecon :get_conductor_off (node , rulename ), param2 = node .param2 })
408
+ -- area not loaded, postpone action
409
+ if not node then
410
+ mesecon .queue :add_action (f .pos , " turnoff" , {link }, nil , true )
411
+ end
417
412
418
- for _ , rule in ipairs (mesecon :rule2meta (rulename , rules )) do
419
- local np = mesecon :addPosRule (pos , rule )
420
- if (minetest .get_node (np ).name == " ignore" ) then
421
- -- try turning on later again
422
- mesecon .queue :add_action (
423
- np , " turnoff" , {rulename , recdepth + 1 }, nil , true )
424
- else
425
- local rulenames = mesecon :rules_link_rule_all (pos , rule )
426
-
427
- for _ , rulename in ipairs (rulenames ) do
428
- mesecon :turnoff (np , rulename , recdepth + 1 )
413
+ if mesecon :is_conductor_on (node , f .link ) then
414
+ local rules = mesecon :conductor_get_rules (node )
415
+
416
+ minetest .swap_node (f .pos , {name = mesecon :get_conductor_off (node , f .link ),
417
+ param2 = node .param2 })
418
+
419
+ -- call turnoff on neighbors: normal rules
420
+ for _ , r in ipairs (mesecon :rule2meta (f .link , rules )) do
421
+ local np = mesecon :addPosRule (f .pos , r )
422
+
423
+ -- area not loaded, postpone action
424
+ if not minetest .get_node_or_nil (np ) then
425
+ mesecon .queue :add_action (np , " turnoff" , {rulename },
426
+ nil , true )
427
+ else
428
+ local links = mesecon :rules_link_rule_all (f .pos , r )
429
+ for _ , l in ipairs (links ) do
430
+ table.insert (frontiers , {pos = np , link = l })
431
+ end
429
432
end
430
433
end
434
+ elseif mesecon :is_effector (node .name ) then
435
+ mesecon :changesignal (f .pos , node , f .link , mesecon .state .off , depth )
436
+ if mesecon :is_effector_on (node .name ) and not mesecon :is_powered (f .pos ) then
437
+ mesecon :deactivate (f .pos , node , f .link , depth )
438
+ end
431
439
end
432
- elseif mesecon :is_effector (node .name ) then
433
- mesecon :changesignal (pos , node , rulename , mesecon .state .off , recdepth )
434
- if mesecon :is_effector_on (node .name )
435
- and not mesecon :is_powered (pos ) then
436
- mesecon :deactivate (pos , node , rulename , recdepth + 1 )
437
- end
440
+ depth = depth + 1
438
441
end
439
442
end
440
443
0 commit comments