@@ -90,6 +90,16 @@ function mesecon.get_any_rules(node)
9090 mesecon .get_any_outputrules (node ))
9191end
9292
93+ local function get_rules_from_ndef (ndef , node )
94+ local rules = ndef and ndef .rules
95+ if type (rules ) == ' function' then
96+ return rules (node )
97+ elseif rules then
98+ return rules
99+ end
100+ return mesecon .rules .default
101+ end
102+
93103-- Receptors
94104-- Nodes that can power mesecons
95105function mesecon .is_receptor_on (nodename )
@@ -117,17 +127,7 @@ function mesecon.is_receptor(nodename)
117127end
118128
119129function mesecon .receptor_get_rules (node )
120- local receptor = mesecon .get_receptor (node .name )
121- if receptor then
122- local rules = receptor .rules
123- if type (rules ) == ' function' then
124- return rules (node )
125- elseif rules then
126- return rules
127- end
128- end
129-
130- return mesecon .rules .default
130+ return get_rules_from_ndef (mesecon .get_receptor (node .name ), node )
131131end
132132
133133-- Effectors
@@ -157,16 +157,7 @@ function mesecon.is_effector(nodename)
157157end
158158
159159function mesecon .effector_get_rules (node )
160- local effector = mesecon .get_effector (node .name )
161- if effector then
162- local rules = effector .rules
163- if type (rules ) == ' function' then
164- return rules (node )
165- elseif rules then
166- return rules
167- end
168- end
169- return mesecon .rules .default
160+ return get_rules_from_ndef (mesecon .get_effector (node .name ), node )
170161end
171162
172163-- #######################
@@ -330,16 +321,7 @@ function mesecon.get_conductor_off(node_on, rulename)
330321end
331322
332323function mesecon .conductor_get_rules (node )
333- local conductor = mesecon .get_conductor (node .name )
334- if conductor then
335- local rules = conductor .rules
336- if type (rules ) == ' function' then
337- return rules (node )
338- elseif rules then
339- return rules
340- end
341- end
342- return mesecon .rules .default
324+ return get_rules_from_ndef (mesecon .get_conductor (node .name ), node )
343325end
344326
345327-- some more general high-level stuff
@@ -545,46 +527,42 @@ function mesecon.turnoff(pos, link)
545527 return true
546528end
547529
548- -- Get all linking inputrules of inputnode (effector or conductor) that is connected to
549- -- outputnode (receptor or conductor) at position `output` and has an output in direction `rule `
550- function mesecon . rules_link_rule_all ( output , rule )
551- local input = vector .add (output , rule )
552- local inputnode = mesecon .get_node_force (input )
553- local inputrules = mesecon . get_any_inputrules ( inputnode )
554- if not inputrules then
555- return {}
530+ -- @ param getter_function Function that returns nested rules (vectors)
531+ -- @ return The matching rule or `nil `
532+ local function find_rule_in_rules ( pos , rule , getter_function )
533+ local r_pos = vector .add (pos , rule )
534+ local r_node = mesecon .get_node_force (r_pos )
535+ local r_rules = getter_function ( r_node )
536+ if not r_rules then
537+ return
556538 end
557- local rules = {}
558539
559- for _ , inputrule in ipairs (mesecon .flattenrules (inputrules )) do
560- -- Check if input accepts from output
561- if vector .equals (vector .add (input , inputrule ), output ) then
562- table.insert (rules , inputrule )
540+ local dir = vector .subtract (pos , r_pos )
541+ for _ , r_rule in ipairs (mesecon .flattenrules (r_rules )) do
542+ if vector .equals (dir , r_rule ) then
543+ -- Other matches are duplicates
544+ return r_rule
563545 end
564546 end
547+ end
565548
566- return rules
549+ -- Get all linking inputrules of inputnode (effector or conductor) that is connected to
550+ -- outputnode (receptor or conductor) at position `output` and has an output in direction `rule`
551+ function mesecon .rules_link_rule_all (output , rule )
552+ local match = find_rule_in_rules (output , rule , mesecon .get_any_inputrules )
553+ return { match }
567554end
568555
569556-- Get all linking outputnodes of outputnode (receptor or conductor) that is connected to
570557-- inputnode (effector or conductor) at position `input` and has an input in direction `rule`
571558function mesecon .rules_link_rule_all_inverted (input , rule )
572- local output = vector .add (input , rule )
573- local outputnode = mesecon .get_node_force (output )
574- local outputrules = mesecon .get_any_outputrules (outputnode )
575- if not outputrules then
576- return {}
577- end
578- local rules = {}
579-
580- for _ , outputrule in ipairs (mesecon .flattenrules (outputrules )) do
581- if vector .equals (vector .add (output , outputrule ), input ) then
582- table.insert (rules , mesecon .invertRule (outputrule ))
583- end
584- end
585- return rules
559+ local match = find_rule_in_rules (input , rule , mesecon .get_any_outputrules )
560+ return { match and mesecon .invertRule (match ) }
586561end
587562
563+ -- @param pos Node position (a vector) to check
564+ -- @param rule Optional. Specific rule (i.e. node side) to check.
565+ -- @return Returns a list of vectors that power `pos`, or `false` if unpowered.
588566function mesecon .is_powered (pos , rule )
589567 local node = mesecon .get_node_force (pos )
590568 local rules = mesecon .get_any_inputrules (node )
@@ -593,26 +571,15 @@ function mesecon.is_powered(pos, rule)
593571 -- List of nodes that send out power to pos
594572 local sourcepos = {}
595573
596- if not rule then
597- for _ , rule in ipairs (mesecon .flattenrules (rules )) do
598- local rulenames = mesecon .rules_link_rule_all_inverted (pos , rule )
599- for _ , rname in ipairs (rulenames ) do
600- local np = vector .add (pos , rname )
601- local nn = mesecon .get_node_force (np )
602-
603- if (mesecon .is_conductor_on (nn , mesecon .invertRule (rname ))
604- or mesecon .is_receptor_on (nn .name )) then
605- table.insert (sourcepos , np )
606- end
607- end
608- end
609- else
574+ local rules_flat = rule and { rule } or mesecon .flattenrules (rules )
575+ for _ , rule in ipairs (rules_flat ) do
610576 local rulenames = mesecon .rules_link_rule_all_inverted (pos , rule )
611577 for _ , rname in ipairs (rulenames ) do
612578 local np = vector .add (pos , rname )
613579 local nn = mesecon .get_node_force (np )
614- if (mesecon .is_conductor_on (nn , mesecon .invertRule (rname ))
615- or mesecon .is_receptor_on (nn .name )) then
580+
581+ if (mesecon .is_conductor_on (nn , mesecon .invertRule (rname ))
582+ or mesecon .is_receptor_on (nn .name )) then
616583 table.insert (sourcepos , np )
617584 end
618585 end
0 commit comments