+ * N (0, 0)
+ * / \
+ * (1, 0) W E (0, 1)
+ * \ /
+ * S (1, 1)
+ *
+ *
+ * @param transformation The transformation.
+ * @return Offset to new location of northern corner.
+ *
+ * @see TileIndexTransformations
+ */
+static inline TileIndexDiffC TransformedNorthCornerDiffC(DirTransformation transformation)
+{
+ /* lookup tables (bit arrays)
+ * N E S W E S W N */
+ static const uint8 DIFF_X = 0 << DTR_IDENTITY | 0 << DTR_ROTATE_90_R | 1 << DTR_ROTATE_180 | 1 << DTR_ROTATE_90_L | 0 << DTR_REFLECT_NE_SW | 1 << DTR_REFLECT_W_E | 1 << DTR_REFLECT_NW_SE | 0 << DTR_REFLECT_N_S;
+ static const uint8 DIFF_Y = 0 << DTR_IDENTITY | 1 << DTR_ROTATE_90_R | 1 << DTR_ROTATE_180 | 0 << DTR_ROTATE_90_L | 1 << DTR_REFLECT_NE_SW | 1 << DTR_REFLECT_W_E | 0 << DTR_REFLECT_NW_SE | 0 << DTR_REFLECT_N_S;
+
+ assert(IsValidDirTransform(transformation));
+
+ TileIndexDiffC ret = { (int16)GB(DIFF_X, transformation, 1), (int16)GB(DIFF_Y, transformation, 1) };
+ return ret;
+}
+
/* Functions to calculate distances */
uint DistanceManhattan(TileIndex, TileIndex); ///< also known as L1-Norm. Is the shortest distance one could go over diagonal tracks (or roads)
uint DistanceSquare(TileIndex, TileIndex); ///< euclidian- or L2-Norm squared
@@ -337,15 +686,32 @@ uint DistanceFromEdgeDir(TileIndex, DiagDirection); ///< distance from the map e
* Convert a DiagDirection to a TileIndexDiff
*
* @param dir The DiagDirection
+ * @param map The tile map (result will be valid only there)
* @return The resulting TileIndexDiff
+ *
+ * @pre Tgeneric || map == &_main_map
+ *
* @see TileIndexDiffCByDiagDir
*/
-static inline TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
+template