minetest/minetest — pull request #528 by khonkhortisan (2013-03-06 07:03:04+00:00)
Title: Diagonal Rail

Abstract
--
This self-referencing pull request adds diagonal rails.

Proof of Concept
--
![minetestdiagonalrail8](https://f.cloud.github.com/assets/1996449/226181/69c78826-861f-11e2-8edd-21c295b12fa2.png)
[Gif](https://f.cloud.github.com/assets/1996449/226179/698502bc-861f-11e2-96fd-941008bb496c.gif)
![minetestdiagonalrail9](https://f.cloud.github.com/assets/1996449/226180/69c593e0-861f-11e2-9a62-f73643ba5dc0.png)

Images
--
They are just the same as regular rail except that they use two more images:
```
- tiles = {"default_rail.png", "default_rail_curved.png", "default_rail_t_junction.png", "default_rail_crossing.png"},
+ tiles = {"default_rail.png", "default_rail_curved.png", "default_rail_t_junction.png", "default_rail_crossing.png", "default_rail_diagonal.png", "default_rail_diagonal_end.png"},
```
If this commit is used without the supplementary images, diagonals will appear as crossings. That is why I include child pull requests in three places (minetest_game, carts, moreores)
End diagonals aren't simply rotated to turn left like curves/diagonals are, they must be flipped so the end is on the other side.
If you use raillike nodes for roofing, this probably won't affect you, unless you use unusual non-rectangular roofing.

Pseudo-rules
--
A curve will turn diagonal if there are two or more curves in the same diagonal direction (no U-turns)
A rail will end diagonal if it is between a diagonal and a non-curve – unless it is next to the end of the line, in which case _that_ will end diagonal (so non-curve includes non-rail)
Height differences don't apply, as they always create straight rail.

Intersections
--
There are no diagonal intersections. To do this, one would first have know how to keep two adjacent rail lines from intersecting. They aren't needed at this time.

How it works
--
It (a rail) reads its neighbors to know how many adjacencies there are, then based on that decides its image. Diagonals are based on more than just the immediate neighbors, so a recursive function is used. The top-level recursion is for a rail, and has its neighbors. The middle level gets its neighbors' neighbors. Using the neighbors' neighbors, a rail can decide if its neighbor is indeed curved, and become diagonal (as its neighbor does the same when the top-level function gets called at that position). But it goes one level further; there are three levels of recursion. The very end of a diagonal rail line (1) needs to know that its neighbor (2) is curved, and that _its_ neighbor (3) is also curved (so it (1) knows that its neighbor (2) would've been an end diagonal had it (1) not been the end of a line). That is the end of the recursion.

Merging
--
May not automatically merge with https://github.com/minetest/minetest/pull/473 but will merge manually.
Merge around the same time as these child pull requests: [minetest_game](https://github.com/minetest/minetest_game/pull/135), [carts](https://github.com/PilzAdam/carts/pull/8), [moreores](https://github.com/khonkhortisan/calinou_mods/pull/1)