diff --git a/server/src/assets/game/destinations-swtbahn-full.json b/server/src/assets/game/destinations-swtbahn-full.json
index f586e48d..ba756398 100644
--- a/server/src/assets/game/destinations-swtbahn-full.json
+++ b/server/src/assets/game/destinations-swtbahn-full.json
@@ -1,4 +1,4 @@
-const allPossibleDestinationsSwtbahnFull = {
+const allPossibleDestinations_swtbahn_full = {
"block1": {
"signal20": {
"route-id": 71,
diff --git a/server/src/assets/game/destinations-swtbahn-standard.json b/server/src/assets/game/destinations-swtbahn-standard.json
index c87d9eae..4f6998e4 100644
--- a/server/src/assets/game/destinations-swtbahn-standard.json
+++ b/server/src/assets/game/destinations-swtbahn-standard.json
@@ -1,232 +1,753 @@
-const allPossibleDestinationsSwtbahnStandard = {
- 'buffer': {
- "signal6": {
- "route-id": 57,
- "orientation": "anticlockwise",
- "block": "block2",
- "segment": "seg8"
- }
- },
- 'block1': {
- "signal1": {
- "route-id": 44,
- "orientation": "clockwise",
- "block": "buffer",
- "segment": "seg1"
- },
- "signal7": {
- "route-id": 47,
- "orientation": "clockwise",
- "block": "block3",
- "segment": "seg12"
- },
- "signal6": {
- "route-id": 57,
- "orientation": "anticlockwise",
- "block": "block2",
- "segment": "seg8"
- }
- },
- 'block2': {
- "signal2": {
- "route-id": 77,
- "orientation": "clockwise",
- "block": "block1",
- "segment": "seg4"
- },
- "signal9": {
- "route-id": 75,
- "orientation": "clockwise",
- "block": "block5",
- "segment": "seg28"
- },
- "signal10": {
- "route-id": 78,
- "orientation": "clockwise",
- "block": "block4",
- "segment": "seg16"
- },
- "signal8": {
- "route-id": 104,
- "orientation": "anticlockwise",
- "block": "block3",
- "segment": "seg12"
- },
- "signal11": {
- "route-id": 111,
- "orientation": "anticlockwise",
- "block": "block5",
- "segment": "seg28"
- },
- "signal14": {
- "route-id": 114,
- "orientation": "anticlockwise",
- "block": "block7",
- "segment": "seg31"
- },
- "signal15": {
- "route-id": 108,
- "orientation": "anticlockwise",
- "block": "block7",
- "segment": "seg31"
- }
- },
- 'block3': {
- "signal4": {
- "route-id": 120,
- "orientation": "clockwise",
- "block": "block2",
- "segment": "seg8"
- },
- "signal3": {
- "route-id": 6,
- "orientation": "anticlockwise",
- "block": "block1",
- "segment": "seg4"
- },
- "signal12": {
- "route-id": 23,
- "orientation": "anticlockwise",
- "block": "block4",
- "segment": "seg16"
- }
- },
- 'block4': {
- "signal7": {
- "route-id": 70,
- "orientation": "clockwise",
- "block": "block3",
- "segment": "seg12"
- },
- "signal6": {
- "route-id": 221,
- "orientation": "anticlockwise",
- "block": "block2",
- "segment": "seg8"
- }
- },
- 'block5': {
- "signal4": {
- "route-id": 33,
- "orientation": "clockwise",
- "block": "block2",
- "segment": "seg8"
- },
- "signal13": {
- "route-id": 40,
- "orientation": "clockwise",
- "block": "block6",
- "segment": "seg21"
- },
- "signal17": {
- "route-id": 39,
- "orientation": "clockwise",
- "block": "platform1",
- "segment": "seg37"
- },
- "signal19": {
- "route-id": 26,
- "orientation": "clockwise",
- "block": "platform2",
- "segment": "seg40"
- },
- "signal5": {
- "route-id": 203,
- "orientation": "anticlockwise",
- "block": "block6",
- "segment": "seg21"
- },
- "signal6": {
- "route-id": 204,
- "orientation": "anticlockwise",
- "block": "block2",
- "segment": "seg8"
- }
- },
- 'block6': {
- "signal9": {
- "route-id": 229,
- "orientation": "clockwise",
- "block": "block5",
- "segment": "seg28"
- },
- "signal11": {
- "route-id": 96,
- "orientation": "anticlockwise",
- "block": "block5",
- "segment": "seg28"
- },
- "signal14": {
- "route-id": 100,
- "orientation": "anticlockwise",
- "block": "block7",
- "segment": "seg31"
- },
- "signal15": {
- "route-id": 94,
- "orientation": "anticlockwise",
- "block": "block7",
- "segment": "seg31"
- }
- },
- 'block7': {
- "signal17": {
- "route-id": 260,
- "orientation": "clockwise",
- "block": "platform1",
- "segment": "seg37"
- },
- "signal19": {
- "route-id": 243,
- "orientation": "clockwise",
- "block": "platform2",
- "segment": "seg40"
- },
- "signal4": {
- "route-id": 255,
- "orientation": "clockwise",
- "block": "block2",
- "segment": "seg8"
- },
- "signal13": {
- "route-id": 261,
- "orientation": "clockwise",
- "block": "block6",
- "segment": "seg21"
- }
- },
- 'platform1': {
- "signal11": {
- "route-id": 152,
- "orientation": "anticlockwise",
- "block": "block5",
- "segment": "seg28"
- },
- "signal15": {
- "route-id": 151,
- "orientation": "anticlockwise",
- "block": "block7",
- "segment": "seg31"
- }
- },
- 'platform2': {
- "signal11": {
- "route-id": 187,
- "orientation": "anticlockwise",
- "block": "block5",
- "segment": "seg28"
- },
- "signal14": {
- "route-id": 193,
- "orientation": "anticlockwise",
- "block": "block7",
- "segment": "seg31"
- },
- "signal15": {
- "route-id": 185,
- "orientation": "anticlockwise",
- "block": "block7",
- "segment": "seg31"
- }
- }
-};
+const allPossibleDestinations_swtbahn_standard = {
+ "block1": {
+ "signal6": {
+ "route-id": 57,
+ "orientation": "anticlockwise",
+ "block": "block2",
+ "segment": "seg8"
+ },
+ "signal5": {
+ "route-id": 56,
+ "orientation": "anticlockwise",
+ "block": "block6",
+ "segment": "seg21"
+ },
+ "signal17": {
+ "route-id": 60,
+ "orientation": "anticlockwise",
+ "block": "platform1",
+ "segment": "seg37"
+ },
+ "signal19": {
+ "route-id": 53,
+ "orientation": "anticlockwise",
+ "block": "platform2",
+ "segment": "seg40"
+ },
+ "signal12": {
+ "route-id": 63,
+ "orientation": "anticlockwise",
+ "block": "block4",
+ "segment": "seg16"
+ },
+ "signal13": {
+ "route-id": 50,
+ "orientation": "clockwise",
+ "block": "block6",
+ "segment": "seg21"
+ },
+ "signal11": {
+ "route-id": 61,
+ "orientation": "anticlockwise",
+ "block": "block5",
+ "segment": "seg28"
+ },
+ "signal10": {
+ "route-id": 45,
+ "orientation": "clockwise",
+ "block": "block4",
+ "segment": "seg16"
+ },
+ "signal9": {
+ "route-id": 43,
+ "orientation": "clockwise",
+ "block": "block5",
+ "segment": "seg28"
+ },
+ "signal14": {
+ "route-id": 64,
+ "orientation": "anticlockwise",
+ "block": "block7",
+ "segment": "seg31"
+ },
+ "signal8": {
+ "route-id": 54,
+ "orientation": "anticlockwise",
+ "block": "block3",
+ "segment": "seg12"
+ },
+ "signal15": {
+ "route-id": 59,
+ "orientation": "anticlockwise",
+ "block": "block7",
+ "segment": "seg31"
+ },
+ "signal7": {
+ "route-id": 47,
+ "orientation": "clockwise",
+ "block": "block3",
+ "segment": "seg12"
+ },
+ "signal4": {
+ "route-id": 46,
+ "orientation": "clockwise",
+ "block": "block2",
+ "segment": "seg8"
+ }
+ },
+ "block2": {
+ "signal5": {
+ "route-id": 107,
+ "orientation": "anticlockwise",
+ "block": "block6",
+ "segment": "seg21"
+ },
+ "signal17": {
+ "route-id": 110,
+ "orientation": "anticlockwise",
+ "block": "platform1",
+ "segment": "seg37"
+ },
+ "signal19": {
+ "route-id": 102,
+ "orientation": "anticlockwise",
+ "block": "platform2",
+ "segment": "seg40"
+ },
+ "signal3": {
+ "route-id": 105,
+ "orientation": "anticlockwise",
+ "block": "block1",
+ "segment": "seg4"
+ },
+ "signal12": {
+ "route-id": 113,
+ "orientation": "anticlockwise",
+ "block": "block4",
+ "segment": "seg16"
+ },
+ "signal13": {
+ "route-id": 82,
+ "orientation": "clockwise",
+ "block": "block6",
+ "segment": "seg21"
+ },
+ "signal11": {
+ "route-id": 111,
+ "orientation": "anticlockwise",
+ "block": "block5",
+ "segment": "seg28"
+ },
+ "signal2": {
+ "route-id": 77,
+ "orientation": "clockwise",
+ "block": "block1",
+ "segment": "seg4"
+ },
+ "signal10": {
+ "route-id": 78,
+ "orientation": "clockwise",
+ "block": "block4",
+ "segment": "seg16"
+ },
+ "signal9": {
+ "route-id": 75,
+ "orientation": "clockwise",
+ "block": "block5",
+ "segment": "seg28"
+ },
+ "signal14": {
+ "route-id": 114,
+ "orientation": "anticlockwise",
+ "block": "block7",
+ "segment": "seg31"
+ },
+ "signal8": {
+ "route-id": 104,
+ "orientation": "anticlockwise",
+ "block": "block3",
+ "segment": "seg12"
+ },
+ "signal15": {
+ "route-id": 108,
+ "orientation": "anticlockwise",
+ "block": "block7",
+ "segment": "seg31"
+ },
+ "signal7": {
+ "route-id": 79,
+ "orientation": "clockwise",
+ "block": "block3",
+ "segment": "seg12"
+ }
+ },
+ "block3": {
+ "signal6": {
+ "route-id": 11,
+ "orientation": "anticlockwise",
+ "block": "block2",
+ "segment": "seg8"
+ },
+ "signal5": {
+ "route-id": 9,
+ "orientation": "anticlockwise",
+ "block": "block6",
+ "segment": "seg21"
+ },
+ "signal17": {
+ "route-id": 17,
+ "orientation": "anticlockwise",
+ "block": "platform1",
+ "segment": "seg37"
+ },
+ "signal19": {
+ "route-id": 0,
+ "orientation": "anticlockwise",
+ "block": "platform2",
+ "segment": "seg40"
+ },
+ "signal3": {
+ "route-id": 6,
+ "orientation": "anticlockwise",
+ "block": "block1",
+ "segment": "seg4"
+ },
+ "signal12": {
+ "route-id": 23,
+ "orientation": "anticlockwise",
+ "block": "block4",
+ "segment": "seg16"
+ },
+ "signal13": {
+ "route-id": 123,
+ "orientation": "clockwise",
+ "block": "block6",
+ "segment": "seg21"
+ },
+ "signal11": {
+ "route-id": 19,
+ "orientation": "anticlockwise",
+ "block": "block5",
+ "segment": "seg28"
+ },
+ "signal2": {
+ "route-id": 118,
+ "orientation": "clockwise",
+ "block": "block1",
+ "segment": "seg4"
+ },
+ "signal10": {
+ "route-id": 119,
+ "orientation": "clockwise",
+ "block": "block4",
+ "segment": "seg16"
+ },
+ "signal9": {
+ "route-id": 116,
+ "orientation": "clockwise",
+ "block": "block5",
+ "segment": "seg28"
+ },
+ "signal14": {
+ "route-id": 24,
+ "orientation": "anticlockwise",
+ "block": "block7",
+ "segment": "seg31"
+ },
+ "signal15": {
+ "route-id": 14,
+ "orientation": "anticlockwise",
+ "block": "block7",
+ "segment": "seg31"
+ },
+ "signal4": {
+ "route-id": 120,
+ "orientation": "clockwise",
+ "block": "block2",
+ "segment": "seg8"
+ }
+ },
+ "block4": {
+ "signal6": {
+ "route-id": 221,
+ "orientation": "anticlockwise",
+ "block": "block2",
+ "segment": "seg8"
+ },
+ "signal5": {
+ "route-id": 220,
+ "orientation": "anticlockwise",
+ "block": "block6",
+ "segment": "seg21"
+ },
+ "signal17": {
+ "route-id": 224,
+ "orientation": "anticlockwise",
+ "block": "platform1",
+ "segment": "seg37"
+ },
+ "signal19": {
+ "route-id": 215,
+ "orientation": "anticlockwise",
+ "block": "platform2",
+ "segment": "seg40"
+ },
+ "signal3": {
+ "route-id": 218,
+ "orientation": "anticlockwise",
+ "block": "block1",
+ "segment": "seg4"
+ },
+ "signal13": {
+ "route-id": 72,
+ "orientation": "clockwise",
+ "block": "block6",
+ "segment": "seg21"
+ },
+ "signal11": {
+ "route-id": 226,
+ "orientation": "anticlockwise",
+ "block": "block5",
+ "segment": "seg28"
+ },
+ "signal2": {
+ "route-id": 68,
+ "orientation": "clockwise",
+ "block": "block1",
+ "segment": "seg4"
+ },
+ "signal9": {
+ "route-id": 66,
+ "orientation": "clockwise",
+ "block": "block5",
+ "segment": "seg28"
+ },
+ "signal14": {
+ "route-id": 227,
+ "orientation": "anticlockwise",
+ "block": "block7",
+ "segment": "seg31"
+ },
+ "signal8": {
+ "route-id": 217,
+ "orientation": "anticlockwise",
+ "block": "block3",
+ "segment": "seg12"
+ },
+ "signal15": {
+ "route-id": 222,
+ "orientation": "anticlockwise",
+ "block": "block7",
+ "segment": "seg31"
+ },
+ "signal7": {
+ "route-id": 70,
+ "orientation": "clockwise",
+ "block": "block3",
+ "segment": "seg12"
+ },
+ "signal4": {
+ "route-id": 69,
+ "orientation": "clockwise",
+ "block": "block2",
+ "segment": "seg8"
+ }
+ },
+ "block5": {
+ "signal6": {
+ "route-id": 204,
+ "orientation": "anticlockwise",
+ "block": "block2",
+ "segment": "seg8"
+ },
+ "signal5": {
+ "route-id": 203,
+ "orientation": "anticlockwise",
+ "block": "block6",
+ "segment": "seg21"
+ },
+ "signal17": {
+ "route-id": 210,
+ "orientation": "anticlockwise",
+ "block": "platform1",
+ "segment": "seg37"
+ },
+ "signal19": {
+ "route-id": 197,
+ "orientation": "anticlockwise",
+ "block": "platform2",
+ "segment": "seg40"
+ },
+ "signal3": {
+ "route-id": 202,
+ "orientation": "anticlockwise",
+ "block": "block1",
+ "segment": "seg4"
+ },
+ "signal12": {
+ "route-id": 211,
+ "orientation": "anticlockwise",
+ "block": "block4",
+ "segment": "seg16"
+ },
+ "signal13": {
+ "route-id": 40,
+ "orientation": "clockwise",
+ "block": "block6",
+ "segment": "seg21"
+ },
+ "signal2": {
+ "route-id": 29,
+ "orientation": "clockwise",
+ "block": "block1",
+ "segment": "seg4"
+ },
+ "signal10": {
+ "route-id": 32,
+ "orientation": "clockwise",
+ "block": "block4",
+ "segment": "seg16"
+ },
+ "signal14": {
+ "route-id": 212,
+ "orientation": "anticlockwise",
+ "block": "block7",
+ "segment": "seg31"
+ },
+ "signal8": {
+ "route-id": 201,
+ "orientation": "anticlockwise",
+ "block": "block3",
+ "segment": "seg12"
+ },
+ "signal15": {
+ "route-id": 206,
+ "orientation": "anticlockwise",
+ "block": "block7",
+ "segment": "seg31"
+ },
+ "signal7": {
+ "route-id": 37,
+ "orientation": "clockwise",
+ "block": "block3",
+ "segment": "seg12"
+ },
+ "signal4": {
+ "route-id": 33,
+ "orientation": "clockwise",
+ "block": "block2",
+ "segment": "seg8"
+ }
+ },
+ "block6": {
+ "signal6": {
+ "route-id": 92,
+ "orientation": "anticlockwise",
+ "block": "block2",
+ "segment": "seg8"
+ },
+ "signal17": {
+ "route-id": 95,
+ "orientation": "anticlockwise",
+ "block": "platform1",
+ "segment": "seg37"
+ },
+ "signal19": {
+ "route-id": 85,
+ "orientation": "anticlockwise",
+ "block": "platform2",
+ "segment": "seg40"
+ },
+ "signal3": {
+ "route-id": 90,
+ "orientation": "anticlockwise",
+ "block": "block1",
+ "segment": "seg4"
+ },
+ "signal12": {
+ "route-id": 98,
+ "orientation": "anticlockwise",
+ "block": "block4",
+ "segment": "seg16"
+ },
+ "signal11": {
+ "route-id": 96,
+ "orientation": "anticlockwise",
+ "block": "block5",
+ "segment": "seg28"
+ },
+ "signal2": {
+ "route-id": 232,
+ "orientation": "clockwise",
+ "block": "block1",
+ "segment": "seg4"
+ },
+ "signal10": {
+ "route-id": 234,
+ "orientation": "clockwise",
+ "block": "block4",
+ "segment": "seg16"
+ },
+ "signal9": {
+ "route-id": 229,
+ "orientation": "clockwise",
+ "block": "block5",
+ "segment": "seg28"
+ },
+ "signal14": {
+ "route-id": 100,
+ "orientation": "anticlockwise",
+ "block": "block7",
+ "segment": "seg31"
+ },
+ "signal8": {
+ "route-id": 88,
+ "orientation": "anticlockwise",
+ "block": "block3",
+ "segment": "seg12"
+ },
+ "signal15": {
+ "route-id": 94,
+ "orientation": "anticlockwise",
+ "block": "block7",
+ "segment": "seg31"
+ },
+ "signal7": {
+ "route-id": 239,
+ "orientation": "clockwise",
+ "block": "block3",
+ "segment": "seg12"
+ },
+ "signal4": {
+ "route-id": 236,
+ "orientation": "clockwise",
+ "block": "block2",
+ "segment": "seg8"
+ }
+ },
+ "block7": {
+ "signal17": {
+ "route-id": 136,
+ "orientation": "anticlockwise",
+ "block": "platform1",
+ "segment": "seg37"
+ },
+ "signal19": {
+ "route-id": 125,
+ "orientation": "anticlockwise",
+ "block": "platform2",
+ "segment": "seg40"
+ },
+ "signal13": {
+ "route-id": 137,
+ "orientation": "anticlockwise",
+ "block": "block6",
+ "segment": "seg21"
+ },
+ "signal2": {
+ "route-id": 130,
+ "orientation": "anticlockwise",
+ "block": "block1",
+ "segment": "seg4"
+ },
+ "signal10": {
+ "route-id": 131,
+ "orientation": "anticlockwise",
+ "block": "block4",
+ "segment": "seg16"
+ },
+ "signal9": {
+ "route-id": 127,
+ "orientation": "anticlockwise",
+ "block": "block5",
+ "segment": "seg28"
+ },
+ "signal7": {
+ "route-id": 133,
+ "orientation": "anticlockwise",
+ "block": "block3",
+ "segment": "seg12"
+ },
+ "signal4": {
+ "route-id": 132,
+ "orientation": "anticlockwise",
+ "block": "block2",
+ "segment": "seg8"
+ }
+ },
+ "buffer": {},
+ "platform1": {
+ "signal6": {
+ "route-id": 148,
+ "orientation": "anticlockwise",
+ "block": "block2",
+ "segment": "seg8"
+ },
+ "signal5": {
+ "route-id": 147,
+ "orientation": "anticlockwise",
+ "block": "block6",
+ "segment": "seg21"
+ },
+ "signal19": {
+ "route-id": 138,
+ "orientation": "anticlockwise",
+ "block": "platform2",
+ "segment": "seg40"
+ },
+ "signal3": {
+ "route-id": 144,
+ "orientation": "anticlockwise",
+ "block": "block1",
+ "segment": "seg4"
+ },
+ "signal12": {
+ "route-id": 153,
+ "orientation": "anticlockwise",
+ "block": "block4",
+ "segment": "seg16"
+ },
+ "signal13": {
+ "route-id": 154,
+ "orientation": "anticlockwise",
+ "block": "block6",
+ "segment": "seg21"
+ },
+ "signal11": {
+ "route-id": 152,
+ "orientation": "anticlockwise",
+ "block": "block5",
+ "segment": "seg28"
+ },
+ "signal2": {
+ "route-id": 143,
+ "orientation": "anticlockwise",
+ "block": "block1",
+ "segment": "seg4"
+ },
+ "signal10": {
+ "route-id": 145,
+ "orientation": "anticlockwise",
+ "block": "block4",
+ "segment": "seg16"
+ },
+ "signal9": {
+ "route-id": 140,
+ "orientation": "anticlockwise",
+ "block": "block5",
+ "segment": "seg28"
+ },
+ "signal14": {
+ "route-id": 156,
+ "orientation": "anticlockwise",
+ "block": "block7",
+ "segment": "seg31"
+ },
+ "signal8": {
+ "route-id": 139,
+ "orientation": "anticlockwise",
+ "block": "block3",
+ "segment": "seg12"
+ },
+ "signal15": {
+ "route-id": 151,
+ "orientation": "anticlockwise",
+ "block": "block7",
+ "segment": "seg31"
+ },
+ "signal7": {
+ "route-id": 149,
+ "orientation": "anticlockwise",
+ "block": "block3",
+ "segment": "seg12"
+ },
+ "signal4": {
+ "route-id": 146,
+ "orientation": "anticlockwise",
+ "block": "block2",
+ "segment": "seg8"
+ }
+ },
+ "platform2": {
+ "signal6": {
+ "route-id": 178,
+ "orientation": "anticlockwise",
+ "block": "block2",
+ "segment": "seg8"
+ },
+ "signal5": {
+ "route-id": 177,
+ "orientation": "anticlockwise",
+ "block": "block6",
+ "segment": "seg21"
+ },
+ "signal17": {
+ "route-id": 186,
+ "orientation": "anticlockwise",
+ "block": "platform1",
+ "segment": "seg37"
+ },
+ "signal3": {
+ "route-id": 170,
+ "orientation": "anticlockwise",
+ "block": "block1",
+ "segment": "seg4"
+ },
+ "signal12": {
+ "route-id": 188,
+ "orientation": "anticlockwise",
+ "block": "block4",
+ "segment": "seg16"
+ },
+ "signal13": {
+ "route-id": 189,
+ "orientation": "anticlockwise",
+ "block": "block6",
+ "segment": "seg21"
+ },
+ "signal11": {
+ "route-id": 187,
+ "orientation": "anticlockwise",
+ "block": "block5",
+ "segment": "seg28"
+ },
+ "signal2": {
+ "route-id": 169,
+ "orientation": "anticlockwise",
+ "block": "block1",
+ "segment": "seg4"
+ },
+ "signal10": {
+ "route-id": 172,
+ "orientation": "anticlockwise",
+ "block": "block4",
+ "segment": "seg16"
+ },
+ "signal9": {
+ "route-id": 163,
+ "orientation": "anticlockwise",
+ "block": "block5",
+ "segment": "seg28"
+ },
+ "signal14": {
+ "route-id": 193,
+ "orientation": "anticlockwise",
+ "block": "block7",
+ "segment": "seg31"
+ },
+ "signal8": {
+ "route-id": 157,
+ "orientation": "anticlockwise",
+ "block": "block3",
+ "segment": "seg12"
+ },
+ "signal15": {
+ "route-id": 185,
+ "orientation": "anticlockwise",
+ "block": "block7",
+ "segment": "seg31"
+ },
+ "signal7": {
+ "route-id": 179,
+ "orientation": "anticlockwise",
+ "block": "block3",
+ "segment": "seg12"
+ },
+ "signal4": {
+ "route-id": 176,
+ "orientation": "anticlockwise",
+ "block": "block2",
+ "segment": "seg8"
+ }
+ }
+};
\ No newline at end of file
diff --git a/server/src/assets/game/destinations-swtbahn-ultraloop.json b/server/src/assets/game/destinations-swtbahn-ultraloop.json
deleted file mode 100644
index c5e92664..00000000
--- a/server/src/assets/game/destinations-swtbahn-ultraloop.json
+++ /dev/null
@@ -1,20 +0,0 @@
-const allPossibleDestinationsSwtbahnUltraloop = {
- 'block0': { // Source block
-
- // Route
- "signal4": { // Destination signal of route
- "route-id": 0, // Required route ID
- "orientation": "clockwise", // Route orientation
- "block": "block1", // Block ID of destination signal
- "segment": "seg29" // ID of main segment of destination block
- },
-
- // Route
- "signal6": { // Destination signal of route
- "route-id": 1, // Required route ID
- "orientation": "anticlockwise", // Route orientation
- "block": "block1", // Block ID of destination signal
- "segment": "seg17" // ID of main segment of destination block
- }
- }
-};
diff --git a/server/src/assets/game/driver-game.html b/server/src/assets/game/driver-game.html
index 7f57e190..8d08e190 100644
--- a/server/src/assets/game/driver-game.html
+++ b/server/src/assets/game/driver-game.html
@@ -15,6 +15,7 @@
+
diff --git a/server/src/assets/game/flags-swtbahn-full.json b/server/src/assets/game/flags-swtbahn-full.json
index 807ef27a..1640c326 100644
--- a/server/src/assets/game/flags-swtbahn-full.json
+++ b/server/src/assets/game/flags-swtbahn-full.json
@@ -1,4 +1,4 @@
-const signalFlagMapSwtbahnFull = {
+const signalFlagMap_swtbahn_full = {
"signal4": "flagThemeBlack flagOutline flagOne",
"signal18": "flagThemeBlack flagOutline flagTwo",
"signal51": "flagThemeBlack flagOutline flagThree",
diff --git a/server/src/assets/game/flags-swtbahn-standard.json b/server/src/assets/game/flags-swtbahn-standard.json
new file mode 100644
index 00000000..d790028e
--- /dev/null
+++ b/server/src/assets/game/flags-swtbahn-standard.json
@@ -0,0 +1,20 @@
+const signalFlagMap_swtbahn_standard = {
+ "signal6": "flagThemeGreen flagFilled flagThree",
+ "signal5": "flagThemeGreen flagFilled flagTwo",
+ "signal17": "flagThemeGreen flagFilled flagOne",
+ "signal19": "flagThemeGreen flagFilled flagZero",
+ "signal3": "flagThemeRed flagFilled flagTwo",
+ "signal12": "flagThemeRed flagFilled flagOne",
+ "signal13": "flagThemeRed flagFilled flagThree",
+ "signal11": "flagThemeRed flagFilled flagZero",
+ "signal2": "flagThemeBlue flagFilled flagOne",
+ "signal10": "flagThemeBlue flagFilled flagTwo",
+ "signal9": "flagThemeBlue flagFilled flagThree",
+ "signal14": "flagThemeBlue flagFilled flagFour",
+ "signal8": "flagThemeBlue flagFilled flagFive",
+ "signal15": "flagThemeBlack flagFilled flagZero",
+ "signal18": "flagThemeBlack flagFilled flagOne",
+ "signal16": "flagThemeBlack flagFilled flagTwo",
+ "signal7": "flagThemeBlack flagFilled flagThree",
+ "signal4": "flagThemeRed flagFilled flagFour"
+};
\ No newline at end of file
diff --git a/server/src/assets/game/script-game.js b/server/src/assets/game/script-game.js
index 0dfee03e..bf40a725 100644
--- a/server/src/assets/game/script-game.js
+++ b/server/src/assets/game/script-game.js
@@ -11,8 +11,16 @@ var isEasyMode = false; // User interface verbosity.
const numberOfDestinationsMax = 12; // Maximum destinations to display
const destinationNamePrefix = "destination"; // HTML element ID prefix of the destination buttons
-var allPossibleDestinations = null; // Platform specific lookup table for destinations
-var signalFlagMap = null; // Platform specific lookup table for signal flags
+// Initialisation of Lookup tables
+var allPossibleDestinations = null; // Global Access variable for destination lookup table
+var signalFlagMap = null; // Global access variable for signal flag mapping
+
+function getPlatformName(){
+ //TODO: Add corresponding server endpoint and error handling and make it once executable (when it succeed)
+ return "swtbahn_full";
+}
+
+
// Returns the destinations possible from a given block
function getDestinations(blockId) {
@@ -740,6 +748,7 @@ class Driver {
}
+
/*************************************************************
* UI update for client initialisation and game start and end
* (train grab and release)
@@ -796,6 +805,9 @@ function initialise() {
null // trainId
);
+ const platform = getPlatformName();
+
+
// Hide the chosen train.
$('#chosenTrain').hide();
@@ -849,13 +861,15 @@ function initialise() {
});
// Set the possible destinations for the SWTbahn platform.
- allPossibleDestinations = allPossibleDestinationsSwtbahnFull;
-// allPossibleDestinations = allPossibleDestinationsSwtbahnStandard;
-// allPossibleDestinations = allPossibleDestinationsSwtbahnUltraloop;
- disableAllDestinationButtons();
+ namedMapDes = "allPossibleDestinations_" + platform;
+ strDes = "allPossibleDestinations =" + namedMapDes;
+ eval (strDes);
+ namedMapSignal = "signalFlagMap_" + platform;
+ strSignal = "signalFlagMap =" + namedMapSignal;
+ eval (strSignal);
- // Set the signal to flag mapping.
- signalFlagMap = signalFlagMapSwtbahnFull;
+ disableAllDestinationButtons();
+
// Initialise the click handler of each destination button.
for (let i = 0; i < numberOfDestinationsMax; i++) {
diff --git a/server/src/assets/game/tableGenerator/Readme.md b/server/src/assets/game/tableGenerator/Readme.md
new file mode 100644
index 00000000..517b8c24
--- /dev/null
+++ b/server/src/assets/game/tableGenerator/Readme.md
@@ -0,0 +1,49 @@
+# Table Generator for SWTbahn Game
+
+This python script generates the configuration json files for the swtbahn game client, which are required for the signal-symbol mapping and the route suggestion mechanics.
+The script will automatically find the shortest possible route from any block of the track to any destination which is equipped with a symbol and store it for the game client in a fast readable format, it will do this action only for signals which are listed in the mapping-csv to reduce storage usage.
+There is also the option to block single route ids within the blacklist.txt
+
+
+## Requirements
+* Python3
+* Configuration files for the model railway:
+ * Interlocking table
+ * extra configuration (extra_config.yaml)
+
+## Color codes
+The color code is a coding system which descripes the dice symbol of the swtbahn within 2 to 3 characters and can be divided into two parts.
+The first part describes the coloring schema of the symbol. There are four colors:
+* **B**: Blue
+* **G**: Green
+* **R**: Red
+* **S**: Black
+In case we want to invert the colors (so instead of a symbol with red background and a red outline, we want a red outline and a white background), we append a **w** behind the color.
+
+The second part of the code descripes the dots of the dice. (Currently they can be numbers from 0 to 5, a six will currently count as 0).
+
+### Examples
+* B5:
+
+* RW5:
+
+
+## How to get started
+### Map the Signals with the Symbols
+* Create a CSV Document with the following content formatting in the flagMappings directory (the filename should match with the name of the configuration folder of the model railway): [signalId],[colorCode]
+#### Example:
+for the swtbahn-standard the filename would be `swtbahn-standard.csv`
+The content of the file would look like:
+```
+6,g3
+5,g2
+17,g1
+19,g0
+3,r2
+12,r1
+```
+* run generator.py
+* run converter.py
+* link the generated files to the game
+ * replace the return string of `getPlatformName()` of `script-game.js` to your platform name
+
diff --git a/server/src/assets/game/tableGenerator/blacklist.txt b/server/src/assets/game/tableGenerator/blacklists/swtbahn-full.txt
similarity index 100%
rename from server/src/assets/game/tableGenerator/blacklist.txt
rename to server/src/assets/game/tableGenerator/blacklists/swtbahn-full.txt
diff --git a/server/src/assets/game/tableGenerator/converter.py b/server/src/assets/game/tableGenerator/converter.py
index 8ef6c343..5c9ac9db 100644
--- a/server/src/assets/game/tableGenerator/converter.py
+++ b/server/src/assets/game/tableGenerator/converter.py
@@ -1,127 +1,185 @@
from csv import reader
-import json
-import yaml
-
-interlockingTableFile = "../../../../../configurations/swtbahn-full/interlocking_table.yml"
-configuratonBahnFile = "../../../../../configurations/swtbahn-full/extras_config.yml"
-blacklistFile = "./blacklist.txt"
-groupingFile = "./flags-swtbahn-full.csv"
-interlockingTable = json.loads(json.dumps(yaml.safe_load(open(interlockingTableFile))))
-configuratonBahn = json.loads(json.dumps(yaml.safe_load(open(configuratonBahnFile))))
-
-blacklist = []
-
-for line in open(blacklistFile):
- blacklist.append(int(line.strip()))
-
-resultData = {}
-
-blocktypes = ["blocks", "platforms"]
-
-for blockType in blocktypes:
- for block in configuratonBahn[blockType]:
- try:
- signals = block["signals"]
- except KeyError:
-# print("Block {} has no signals".format(block["id"]))
- signals = []
- routes = []
- for signal in signals:
- destinations = []
- for route in interlockingTable["interlocking-table"]:
- if route["source"] == signal:
- if route["destination"] not in destinations:
- destinations.append(route["destination"])
- for destination in destinations:
- routeID = -1
- for route in interlockingTable["interlocking-table"]:
- if route["source"] == signal and route["destination"] == destination:
- if routeID == -1:
- routeID = route["id"]
- else:
- if interlockingTable["interlocking-table"][routeID]["id"] in blacklist:
- print("Route was overriden because old was blacklisted")
- elif interlockingTable["interlocking-table"][route["id"]]["id"] in blacklist:
- print("Route Beibehalten")
- elif len(interlockingTable["interlocking-table"][route["id"]]["path"]) < len(interlockingTable["interlocking-table"][routeID]["path"]):
- routeID = route["id"]
+import json, yaml, os, copy
+
+##### META #####
+
+pathToConfig = "../../../../../configurations"
+
+
+
+interlockingTableFileName = "interlocking_table.yml"
+configurationBahnFileName = "extras_config.yml"
+
+blacklistFileDirectory = "./blacklists"
+groupingFileDirectory = "./flagMappings"
+
+configFolderItemList = os.scandir(pathToConfig)
+
- print("{} -> {} | {}".format(signal, destination, routeID))
- if routeID not in blacklist:
- routes.append(routeID)
- else:
- print("Route {} wurde ignoriert, weil diese in der Blacklist steht".format(routeID))
-
- resultData[block["id"]] = {}
- for route in routes:
- destination = interlockingTable["interlocking-table"][route]["destination"]
- routeID = route
- orientation = interlockingTable["interlocking-table"][route]["orientation"]
- lastBlock = interlockingTable["interlocking-table"][route]["sections"][-1]["id"]
- stopSegment = None
- segments = []
- isError = False
-
- for qblock in configuratonBahn["platforms"]:
- if qblock["id"] == lastBlock:
- for segment in qblock["main"]:
- segments.append(segment)
- break
- for qblock in configuratonBahn["blocks"]:
- if qblock["id"] == lastBlock:
- for segment in qblock["main"]:
- segments.append(segment)
- break
- if len(segments) == 1:
-# print("Segment: {} at Block {}".format(segments[0], lastBlock))
- stopSegment = segments[0]
- elif len(segments) == 2:
- if segments[0][0:-1] == segments[1][0:-1]:
- # print(segments)
- stopSegment = segments[0][0:-1]
-# print(stopSegment)
- else:
- print("Error Segment {} and Segment {} are not the same. Block {}".format(segments[0], segments[1], block["id"]))
- isError = True
+##### FUNCTIONS #####
+def generateJsonStructure(resultData):
+ """
+ Params:
+ ResultData
+ Json with the format
+ Includes the default structure for the endformat and handle all data
+ Returns:
+ Updated version of the ResultData Json
+
+ Doing:
+ Roll over all Blocks and search for a RouteID for the destination and insert the details based on start block, destination signal. Data were read from the interlocking table
+ """
+ newResult = {}
+
+ for block in resultData:
+ destinations = []
+ for destination in resultData[block]:
+ destinations.append(destination)
+ destinationsSorted = []
+ print(destinations)
+ with open(groupingFile, "r") as csvFile:
+ csv_reader = reader(csvFile)
+ for row in csv_reader:
+ signal = "signal" + row[0]
+ if signal in destinations:
+ destinationsSorted.append(signal)
+ signalComposite = signal + "a"
+ if signalComposite in destinations:
+ destinationsSorted.append(signal)
+
+ print(resultData["block1"])
+ for destination in destinationsSorted:
+ newResult[block] = {}
+ newResult[block][destination] = {
+ "route-id" : resultData[block][destination]["route-id"],
+ "orientation" : resultData[block][destination]["orientation"],
+ "block" : resultData[block][destination]["block"],
+ "segment" : resultData[block][destination]["segment"]
+ }
+
+ return newResult
+
+def interlockerDataExtraction(routes, resultData):
+ """
+ Filters the resultData Json for blacklisted routes and check if there are shorter routes
+ """
+
+ for route in routes:
+ destination = interlockingTable["interlocking-table"][route]["destination"]
+ routeID = route
+ orientation = interlockingTable["interlocking-table"][route]["orientation"]
+ lastBlock = interlockingTable["interlocking-table"][route]["sections"][-1]["id"]
+ stopSegment = None
+ segments = []
+ isError = False
+
+ for qblock in configuratonBahn["platforms"] or qblock in configuration["blocks"]:
+ if qblock["id"] == lastBlock:
+ for segment in qblock["main"]:
+ segments.append(segment)
+ break
+
+ if len(segments) == 1:
+ stopSegment = segments[0]
+ elif len(segments) == 2:
+ if segments[0][0:-1] == segments[1][0:-1]:
+ stopSegment = segments[0][0:-1]
else:
- print("Error with BlockID {}".format(block["id"]))
+ print("Error Segment {} and Segment {} are not the same. Block {}".format(segments[0], segments[1],
+ block["id"]))
isError = True
- if isError:
- break
- resultData[block["id"]][destination] = {}
- resultData[block["id"]][destination]["route-id"] = routeID
- resultData[block["id"]][destination]["orientation"] = orientation
- resultData[block["id"]][destination]["block"] = lastBlock
- resultData[block["id"]][destination]["segment"] = stopSegment
-
-# Sort
-originalResultData = resultData
-resultData = {}
-for block in originalResultData:
- destinations = []
- for destination in originalResultData[block]:
- destinations.append(destination)
- destinationsSorted = []
-
- with open(groupingFile, "r") as csvFile:
- csv_reader = reader(csvFile)
- for row in csv_reader:
- signal = "signal" + row[0]
- if signal in destinations:
- destinationsSorted.append(signal)
- signal = signal + "a"
- if signal in destinations:
- destinationsSorted.append(signal)
-
- resultData[block] = {}
- for destination in destinationsSorted:
- resultData[block][destination] = {}
- resultData[block][destination]["route-id"] = originalResultData[block][destination]["route-id"]
- resultData[block][destination]["orientation"] = originalResultData[block][destination]["orientation"]
- resultData[block][destination]["block"] = originalResultData[block][destination]["block"]
- resultData[block][destination]["segment"] = originalResultData[block][destination]["segment"]
-
-with open("../destinations-swtbahn-full.json", "w") as file:
- file.write("const allPossibleDestinationsSwtbahnFull = ")
- file.write(json.dumps(resultData, indent=2))
- file.write(";")
+ else:
+ print("Error with BlockID {} - Too many segments".format(block["id"]))
+ isError = True
+ if isError:
+ print("error with {}".format(route))
+ break
+ resultData[block["id"]][destination] = {
+ "route-id" : routeID,
+ "orientation": orientation,
+ "block": lastBlock,
+ "segment": stopSegment
+ }
+
+
+### Start Script ###
+
+folderList = [entry.name for entry in configFolderItemList if entry.is_dir()]
+
+for configuration in folderList: # Roll over the list of configuration possibilities and check if a mapping CSV is existing
+
+ mappingFolderContent = os.scandir(groupingFileDirectory)
+ flagMappings = []
+ for entry in mappingFolderContent:
+ if entry.is_file() and entry.name[-4:] == ".csv":
+ flagMappings.append(entry.name[:-4])
+
+ if configuration not in flagMappings: # Ignore all entries which doesnt have an equivalent Mapping-CSV
+ continue
+
+
+ blacklist = []
+
+ if os.path.exists("{}/{}.txt".format(blacklistFileDirectory, configuration)): # import the blacklists if exists
+ for line in open("{}/{}.txt".format(blacklistFileDirectory, configuration)):
+ blacklist.append(int(line.strip()))
+
+
+ interlockingTableFile = "{}/{}/{}".format(pathToConfig, configuration, interlockingTableFileName)
+ configurationBahnFile = "{}/{}/{}".format(pathToConfig, configuration, configurationBahnFileName)
+
+
+ interlockingTable = json.loads(json.dumps(yaml.safe_load(open(interlockingTableFile))))
+ configuratonBahn = json.loads(json.dumps(yaml.safe_load(open(configurationBahnFile))))
+
+ groupingFile = "{}/{}.csv".format(groupingFileDirectory, configuration)
+
+
+ resultData = {}
+
+ blocktypes = ["blocks", "platforms"]
+
+ for blockType in blocktypes: # Roll over all Blocktypes
+ for block in configuratonBahn[blockType]: # Roll over all Blocks
+ try:
+ signals = block["signals"]
+ except KeyError:
+ signals = []
+ routes = []
+ for signal in signals: # Roll over all Signals of the Block
+ destinations = []
+ for route in interlockingTable["interlocking-table"]:
+ if route["source"] == signal:
+ if route["destination"] not in destinations:
+ destinations.append(route["destination"])
+ for destination in destinations: # Roll over all Destination of the specific signal and check if a route id is there
+ routeID = -1
+ for route in interlockingTable["interlocking-table"]:
+ if route["source"] == signal and route["destination"] == destination:
+ if routeID == -1:
+ routeID = route["id"]
+ else:
+ if interlockingTable["interlocking-table"][routeID]["id"] in blacklist:
+ print("Route was overriden because old was blacklisted")
+ elif interlockingTable["interlocking-table"][route["id"]]["id"] in blacklist:
+ print("Route Beibehalten")
+ elif len(interlockingTable["interlocking-table"][route["id"]]["path"]) < len(interlockingTable["interlocking-table"][routeID]["path"]): # if new Route ID is shorter than old route id (less node points) than overwrite the routeid
+ routeID = route["id"]
+
+
+ if routeID not in blacklist:
+ routes.append(routeID)
+ else:
+ print("Route {} wurde ignoriert, weil diese in der Blacklist steht".format(routeID))
+
+ resultData[block["id"]] = {}
+ interlockerDataExtraction(routes, resultData)
+
+
+ # Group and sort based on interlocking table blocks (block -> destination)
+ jsonStructure = generateJsonStructure(resultData)
+ # Write to json file
+ with open("../destinations-{}.json".format(configuration), "w") as file:
+ file.write("const allPossibleDestinations_{} = ".format(configuration.replace("-", "_")))
+ file.write(json.dumps(jsonStructure, indent=2))
+ file.write(";")
diff --git a/server/src/assets/game/tableGenerator/docs/b5.png b/server/src/assets/game/tableGenerator/docs/b5.png
new file mode 100644
index 00000000..59f434be
Binary files /dev/null and b/server/src/assets/game/tableGenerator/docs/b5.png differ
diff --git a/server/src/assets/game/tableGenerator/docs/rw5.png b/server/src/assets/game/tableGenerator/docs/rw5.png
new file mode 100644
index 00000000..dbea6d8e
Binary files /dev/null and b/server/src/assets/game/tableGenerator/docs/rw5.png differ
diff --git a/server/src/assets/game/tableGenerator/flags-swtbahn-full.csv b/server/src/assets/game/tableGenerator/flagMappings/swtbahn-full.csv
similarity index 100%
rename from server/src/assets/game/tableGenerator/flags-swtbahn-full.csv
rename to server/src/assets/game/tableGenerator/flagMappings/swtbahn-full.csv
diff --git a/server/src/assets/game/tableGenerator/flagMappings/swtbahn-standard.csv b/server/src/assets/game/tableGenerator/flagMappings/swtbahn-standard.csv
new file mode 100644
index 00000000..0c655e10
--- /dev/null
+++ b/server/src/assets/game/tableGenerator/flagMappings/swtbahn-standard.csv
@@ -0,0 +1,18 @@
+6,g3
+5,g2
+17,g1
+19,g0
+3,r2
+12,r1
+13,r3
+11,r0
+2,b1
+10,b2
+9,b3
+14,b4
+8,b5
+15,s0
+18,s1
+16,s2
+7,s3
+4,r4
diff --git a/server/src/assets/game/tableGenerator/generator.py b/server/src/assets/game/tableGenerator/generator.py
index b5c95d97..9a10a81c 100644
--- a/server/src/assets/game/tableGenerator/generator.py
+++ b/server/src/assets/game/tableGenerator/generator.py
@@ -1,38 +1,40 @@
-import json
-import csv
+import json, csv, os
def numberToWord(number):
return ["Zero", "One", "Two", "Three", "Four", "Five", "Six"][int(number)]
def characterToColor(character):
- return {"b": "Blue", "g": "Green", "r": "Red", "s": "Black"}[character]
-
-# Load Match to Signal into File
-with open("flags-swtbahn-full.csv", "r") as f:
- reader = csv.reader(f)
- jsonString = {}
- for row in reader:
- signal = row[0]
- colorDefinition = row[1]
- number = colorDefinition[-1]
-
- endString = "flagTheme" + characterToColor(colorDefinition[0])
-
- if colorDefinition[1] == "w":
- endString += " flagOutline "
- else:
- endString += " flagFilled "
-
- if int(number) == 6:
- number = 0
-
- endString += "flag" + numberToWord(number)
- print(endString)
- signalName = "signal{}".format(str(signal))
- jsonString[signalName] = endString
-
- with open("../flags-swtbahn-full.json", "w") as file:
- file.write("const signalFlagMapSwtbahnFull = ")
- file.write(json.dumps(jsonString, indent=2))
- file.write(";")
-
+ return {"b": "Blue", "g": "Green", "r": "Red", "s": "Black"}[character.lower()]
+
+groupingFileDirectory = "./flagMappings"
+
+mappingFolderContent = os.scandir(groupingFileDirectory)
+for entry in mappingFolderContent:
+ if entry.is_file() and entry.name[-4:] == ".csv":
+ with open("{}/{}".format(groupingFileDirectory, entry.name), "r") as f:
+ reader = csv.reader(f)
+ jsonString = {}
+ for row in reader:
+ signal = row[0]
+ colorDefinition = row[1]
+ number = colorDefinition[-1]
+
+ endString = "flagTheme" + characterToColor(colorDefinition[0])
+
+ if colorDefinition[1] == "w":
+ endString += " flagOutline "
+ else:
+ endString += " flagFilled "
+
+ if int(number) == 6:
+ number = 0
+
+ endString += "flag" + numberToWord(number)
+ print(endString)
+ signalName = "signal{}".format(str(signal))
+ jsonString[signalName] = endString
+
+ with open("../flags-{}.json".format(entry.name[:-4]), "w") as file:
+ file.write("const signalFlagMap_{} = ".format(entry.name[:-4].replace("-", "_")))
+ file.write(json.dumps(jsonString, indent=2))
+ file.write(";")