Jeija/minetest-mod-mesecons — pull request #112 by khonkhortisan (2013-06-19 21:38:20+00:00)
Title: Multi rules

I'm confused how these other commits got into my branch, they don't seem to be from master.
![screenshot_1582198720](https://f.cloud.github.com/assets/1996449/677898/da0793ce-d926-11e2-8adf-cd8f0333df6c.png)

The wire crossing is back, as a crossover supported by actual mesecons code, instead of microcontroller-like functions.
There are now two types of rules: The old and still-functional style,
```
rules = {
{xyz},
{xyz},
{xyz},
{xyz},
}
state = mesecon.state.off,
```
and the new and experimental style.
```
rules = {
{
{xyz},
{xyz},
},
{
{xyz},
{xyz},
}
}
states = {
"mesecons_extrawires:crossover_off",
"mesecons_extrawires:crossover_01",
"mesecons_extrawires:crossover_10",
"mesecons_extrawires:crossover_on",
},
```
In the first style of rules, each rule contributes to the node being on or off, and each one spreads the power when it turns on.
In the second style of rules, each individual rule is separated by a table I shall call a "metarule". Each metarule can independently be on or off. Each rule in that metarule contributes to the metarule being on or off, and only the rules in a metarule spread power when it turns on.
Because this conductor isn't a two-state wire, but multiple wires in one node, I couldn't use state = mesecon.state.on/off. Instead, I used states = {} and listed all the nodes that node could turn into (by conducting), whether it could get there by changing only one metarule, or many.
"states" is a list of nodenames, sorted by what metarules are on, in binary order. So it would start with CompletelyOff, then FirstMetaRuleOn, then SecondMetaRuleOn, …, then CompletelyOn. (you can choose the endianness if you write the binary directly into the nodename, but internally it's big-endian) If there were more than two metarules, there would be more states.

When it needs to search all the rules of a node (for example, when placing it) it collapses the metarules into just rules using mesecon:flattenrules(allrules).
When it's following the path of power, it has the rule it got to the node with, it needs the rules in the metarule that rule was from to go to the nodes that are actually connected (not just adjacent), so it uses mesecon:rule2meta(findrule, allrules).
But before it goes to the next node, it has to turn the current one on. Using the same rule, it uses mesecon:rule2bit(findrule, allrules) which returns a number for which metarule it is (but not the metarule itself).
It then finds the nodename in the states to find out what the state currently is - mesecon:getstate(nodename, states) or mesecon:getbinstate(nodename, states) - With the binary state specifically it can check/set any bit/metarule/wire, then add_node whichever state that turns into - get_bit, set_bit, conductor.states[state]
There's also dec2bin and dec = tonuber(bin,2).
I added a mesecon:invertRule(r) because direction actually matters - it's not just checking if pos1, rule1 links to pos2 (which then finds rule2, dropping it when it returns true), then going to pos2. I have to invert rule1 to still have rule2 when I go to pos2. There might be two 90° wires stuck together, who knows?

This is unstable code. Now that I give it to you, the names of the functions may change (again), states may be turned from a complete list to only the nodes that node can change into in one jump, effectors and receptors might get multi_rules like conductors have, or anything else that makes the code sane.
Obviously dirt and stone aren't going to be the final textures.
Placing mesecons_extrawires:crossover_on in the middle of four off wires only makes it turn off half the way. This may or may not be a problem, depending on you hacker you.