Skip to content

Commit c9b8dd7

Browse files
committed
implement resolver for viaducts
1 parent 692b086 commit c9b8dd7

9 files changed

Lines changed: 239 additions & 20 deletions

src/main/scala/module/CompileAllMetarules.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ object CompileAllMetarules {
4949

5050
// Compile individually with `sbt "runMain com.sc4nam.module.CompileRhwCode"`.
5151
object CompileRhwCode extends AbstractMain {
52-
lazy val resolve: IdResolver = new MiscResolver orElse new RealRailwayResolver orElse new RhwResolver orElse new NwmResolver
52+
lazy val resolve: IdResolver = new MiscResolver orElse new RealRailwayResolver orElse new RhwResolver orElse new NwmResolver orElse new ViaductResolver
5353
val generator = new RhwRuleGenerator(_)
5454
lazy val file = new File("target/RhwMetaGenerated_MANAGED.txt")
5555
}

src/main/scala/module/CompileRealRailwayCode.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import syntax.{RuleGenerator, IdResolver, RuleTransducer}
77
*/
88
object CompileRealRailwayCode extends AbstractMain {
99

10-
lazy val resolve: IdResolver = new RealRailwayResolver orElse new SamResolver orElse new RhwResolver orElse new MiscResolver orElse new NwmResolver
10+
lazy val resolve: IdResolver = new RealRailwayResolver orElse new SamResolver orElse new RhwResolver orElse new MiscResolver orElse new NwmResolver orElse new ViaductResolver
1111
val generator = new RealRailwayRuleGenerator(_)
1212
lazy val file = new File("target/Sec11r_RRW_MANAGED.txt")
1313

src/main/scala/module/Main.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import syntax.{RuleGenerator, IdResolver, RuleTransducer, Tile}
1010
*/
1111
object Main extends AbstractMain {
1212

13-
lazy val resolve: IdResolver = new RealRailwayResolver orElse new SamResolver orElse new MiscResolver orElse new RhwResolver orElse new NwmResolver
13+
lazy val resolve: IdResolver = new RealRailwayResolver orElse new SamResolver orElse new MiscResolver orElse new RhwResolver orElse new NwmResolver orElse new ViaductResolver
1414
val generator = new RhwRuleGenerator(_)
1515
lazy val file = new File("./Controller/RUL2/07_RHW/RhwMetaGenerated_MANAGED.txt")
1616
}

src/main/scala/module/MiscResolver.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ class MiscResolver extends IdResolver {
1717
add(0x08031500, Lightrail~NS); add(0x08001a00, Lightrail~ES)
1818
add(0x0d031500, Monorail~NS); add(0x0d001a00, Monorail~ES)
1919
add(0x09004b00, Onewayroad~NS); add(0x09000a00, Onewayroad~ES)
20+
add(0x02001500, Highway~EW); add(0x02002200, Highway~ES); add(0x02002100, Highway~SharedDiagRight)
21+
add(0x0a001500, Groundhighway~EW); add(0x0a002200, Groundhighway~ES); add(0x0a002100, Groundhighway~SharedDiagRight)
2022

2123
add(0x5d300000, Str ~NS); add(0x5d302000, Str ~ES)
2224
add(0x5f880000, Glr1 ~NS); add(0x5f880600, Glr1 ~NW)

src/main/scala/module/RealRailwayResolver.scala

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -81,23 +81,17 @@ class RealRailwayResolver extends IdResolver {
8181
// -- Road --
8282
add(0x5d671100, Road~WE & L1Dtr~NS)
8383
add(0x5d771100, Road~WE & L2Dtr~NS)
84-
add(0x5c001500, L1Road~NS & Rail~WE)
8584
add(0x5d771105, L1Road~NS & L2Dtr~WE)
86-
add(0x5c031500, L2Road~NS & Rail~WE)
8785
add(0x5d67110a, L2Road~WE & L1Dtr~NS)
8886
// -- OWR --
8987
add(0x5d671200, Onewayroad~WE & L1Dtr~NS)
9088
add(0x5d771200, Onewayroad~WE & L2Dtr~NS)
91-
add(0x5c011500, L1Onewayroad~NS & Rail~WE)
9289
add(0x5d771205, L1Onewayroad~NS & L2Dtr~WE)
93-
add(0x5c041500, L2Onewayroad~NS & Rail~WE)
9490
add(0x5d67120a, L2Onewayroad~NS & L1Dtr~WE)
9591
// -- Avenue --
9692
add(0x5d671300, Avenue~EW & L1Dtr~NS)
9793
add(0x5d771300, Avenue~EW & L2Dtr~NS)
98-
add(0x5c021500, L1Avenue~NS & Rail~WE)
9994
add(0x5d771305, L1Avenue~NS & L2Dtr~WE)
100-
add(0x5c051500, L2Avenue~NS & Rail~WE)
10195
add(0x5d67130a, L2Avenue~EW & L1Dtr~NS)
10296
// -- Rail --
10397
add(0x5d671500, Rail~WE & L1Dtr~NS)
@@ -241,9 +235,7 @@ class RealRailwayResolver extends IdResolver {
241235
// -- Road --
242236
add(0x5d674100, Road~ES & L1Dtr~NS)
243237
add(0x5d774100, Road~ES & L2Dtr~NS)
244-
add(0x5c007500, L1Road~ES & Rail~WE)
245238
add(0x5d774110, L1Road~ES & L2Dtr~NS)
246-
add(0x5c037500, L2Road~ES & Rail~WE)
247239
add(0x5d67410a, L2Road~ES & L1Dtr~NS)
248240
// -- OWR --
249241
add(0x5d674200, Onewayroad~ES & L1Dtr~NS)
@@ -580,15 +572,10 @@ class RealRailwayResolver extends IdResolver {
580572
add(0x5e511b09, Sam11~NS & Str~WE) // TODO: currently the only SAM set with a SAM IID for this crossing
581573
// -- Road --
582574
add(0x5d341000, Road~NS & Str~WE)
583-
add(0x5c001505, L1Road~NS & Str~WE)
584-
add(0x5c031505, L2Road~NS & Str~WE)
585575
// -- OWR --
586576
add(0x5d342000, Onewayroad~NS & Str~WE)
587-
add(0x5c011505, L1Onewayroad~NS & Str~WE)
588577
// -- Avenue --
589578
add(0x5d343000, Avenue~NS & Str~WE)
590-
add(0x5c021505, L1Avenue~NS & Str~WE)
591-
add(0x5c051505, L2Avenue~NS & Str~WE)
592579
// ----- OxD -----
593580
// -- Street / SAM --
594581
add(0x5d360000, Street~WN & Str~NS)

src/main/scala/module/ResolverBuilder.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,10 @@ class ResolverBuilder extends scala.collection.mutable.Builder[(Tile, IdTile | (
7878
}
7979

8080
// for convenience
81-
def add(id: Int, tile: Tile): this.type = {
82-
addOne((tile, IdTile(id, R0F0)))
83-
}
81+
def add(id: Int, tile: Tile): this.type = add(tile, id)
82+
83+
// for convenience
84+
def add(id: Int, tile: Tile, when: Boolean): this.type = add(tile, id, when)
8485

8586
}
8687
object ResolverBuilder {

src/main/scala/module/ReverseResolver.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ object ReverseResolver {
9696
(new RhwResolver).tileMap,
9797
(new flexfly.FlexFlyResolver).tileMap,
9898
(new NwmResolver).tileMap,
99+
(new ViaductResolver).tileMap,
99100
)
100101

101102
val reverseTileMap = collection.mutable.Map.empty[Int, ::[Tile]]

src/main/scala/module/RhwResolver.scala

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,14 @@ object RhwResolver {
6666
def greater(a: Network, b: Network): Boolean = {
6767
if (a.isRhw != b.isRhw) {
6868
a.isRhw
69+
} else if (Viaducts.contains(a) != Viaducts.contains(b)) {
70+
Viaducts.contains(a)
6971
} else if (a.isNwm != b.isNwm) {
7072
a.isNwm
7173
} else if (a.height != b.height) {
7274
a.height > b.height
7375
} else if (a != b) {
74-
a > b // both RHW or both NWM with same height
76+
a > b // both RHW or both Viaducts or both NWM with same height
7577
} else {
7678
assert(a == b)
7779
false
@@ -181,6 +183,71 @@ class RhwResolver extends IdResolver {
181183
add(n~se & n2~ws, id + 0x9000 + off8Diag + (dir1 & msk1a | dir2 & msk2a), when = !n.isSymm && (!n2.isSymm || n2HasSharedDiag))
182184
}
183185

186+
// T intersections with viaducts
187+
// Rhw2
188+
add(0x57600110, L1Rhw2~NS & L1Road~EC)
189+
add(0x57600120, L2Rhw2~NS & L2Road~EC)
190+
add(0x57600210, L1Rhw2~NS & L1Onewayroad~EC)
191+
add(0x57600220, L2Rhw2~NS & L2Onewayroad~EC)
192+
add(0x57600310, L1Rhw2~NS & L1Avenue~EC)
193+
add(0x57600320, L2Rhw2~NS & L2Avenue~EC)
194+
add(0x57601110, L1Rhw2~CE & L1Road~NS)
195+
add(0x57601120, L2Rhw2~CE & L2Road~NS)
196+
add(0x57601210, L1Rhw2~CE & L1Onewayroad~NS)
197+
add(0x57601220, L2Rhw2~CE & L2Onewayroad~NS)
198+
add(0x57601310, L1Rhw2~CE & L1Avenue~SN)
199+
add(0x57601315, L1Rhw2~CE & L1Avenue~NS)
200+
add(0x57601320, L2Rhw2~CE & L2Avenue~SN)
201+
add(0x57601325, L2Rhw2~CE & L2Avenue~NS)
202+
// Rhw3 (incomplete)
203+
add(0x57610310, L1Rhw3~NS & L1Avenue~EC)
204+
add(0x57610320, L2Rhw3~NS & L2Avenue~EC)
205+
add(0x57610390, L1Rhw3~SN & L1Avenue~EC)
206+
add(0x576103a0, L2Rhw3~SN & L2Avenue~EC)
207+
add(0x57611310, L1Rhw3~NC & L1Avenue~EW)
208+
add(0x57611315, L1Rhw3~CE & L1Avenue~NS)
209+
add(0x57611320, L2Rhw3~NC & L2Avenue~EW)
210+
add(0x57611325, L2Rhw3~CE & L2Avenue~NS)
211+
// Mis
212+
add(0x57620110, L1Mis~NS & L1Road~EC)
213+
add(0x57620120, L2Mis~NS & L2Road~EC)
214+
add(0x57620190, L1Mis~SN & L1Road~EC)
215+
add(0x576201a0, L2Mis~SN & L2Road~EC)
216+
add(0x57620210, L1Mis~NS & L1Onewayroad~EC)
217+
add(0x57620220, L2Mis~NS & L2Onewayroad~EC)
218+
add(0x57620290, L1Mis~SN & L1Onewayroad~EC)
219+
add(0x576202a0, L2Mis~SN & L2Onewayroad~EC)
220+
// (Avenue ending at Mis is not possible due to lane math)
221+
add(0x57621110, L1Mis~EC & L1Road~NS)
222+
add(0x57621120, L2Mis~EC & L2Road~NS)
223+
add(0x57621210, L1Mis~EC & L1Onewayroad~NS)
224+
add(0x57621220, L2Mis~EC & L2Onewayroad~NS)
225+
add(0x57621310, L1Mis~EC & L1Avenue~SN)
226+
add(0x57621315, L1Mis~EC & L1Avenue~NS)
227+
add(0x57621320, L2Mis~EC & L2Avenue~SN)
228+
add(0x57621325, L2Mis~EC & L2Avenue~NS)
229+
// Rhw4
230+
add(0x57630110, L1Rhw4~NS & L1Road~EC)
231+
add(0x57630120, L2Rhw4~NS & L2Road~EC)
232+
add(0x57630190, L1Rhw4~SN & L1Road~EC)
233+
add(0x576301a0, L2Rhw4~SN & L2Road~EC)
234+
add(0x57630210, L1Rhw4~NS & L1Onewayroad~EC)
235+
add(0x57630220, L2Rhw4~NS & L2Onewayroad~EC)
236+
add(0x57630290, L1Rhw4~SN & L1Onewayroad~EC)
237+
add(0x576302a0, L2Rhw4~SN & L2Onewayroad~EC)
238+
add(0x57630310, L1Rhw4~NS & L1Avenue~EC)
239+
add(0x57630320, L2Rhw4~NS & L2Avenue~EC)
240+
add(0x57630390, L1Rhw4~SN & L1Avenue~EC)
241+
add(0x576303a0, L2Rhw4~SN & L2Avenue~EC)
242+
add(0x57631110, L1Rhw4~EC & L1Road~NS)
243+
add(0x57631120, L2Rhw4~EC & L2Road~NS)
244+
add(0x57631210, L1Rhw4~EC & L1Onewayroad~NS)
245+
add(0x57631220, L2Rhw4~EC & L2Onewayroad~NS)
246+
add(0x57631310, L1Rhw4~EC & L1Avenue~SN)
247+
add(0x57631315, L1Rhw4~EC & L1Avenue~NS)
248+
add(0x57631320, L2Rhw4~EC & L2Avenue~SN)
249+
add(0x57631325, L2Rhw4~EC & L2Avenue~NS)
250+
184251
builder.result()
185252
}
186253
}
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
package com.sc4nam.module
2+
3+
import io.github.memo33.metarules.meta._, syntax._, Network._, RotFlip._, Flags._
4+
import Implicits.segmentToTile
5+
import com.sc4nam.module.{NetworkProperties => NP}
6+
7+
object ViaductResolver {
8+
9+
val viaductRangeId = Map(
10+
L1Road -> 0x5c000000,
11+
L1Onewayroad -> 0x5c010000,
12+
L1Avenue -> 0x5c020000,
13+
L2Road -> 0x5c030000,
14+
L2Onewayroad -> 0x5c040000,
15+
L2Avenue -> 0x5c050000,
16+
)
17+
18+
val viaductPieceId =
19+
Map.from[Network, Int](Iterable(
20+
0x1000 -> Street,
21+
0x1100 -> Road, 0x1110 -> L1Road, 0x1120 -> L2Road,
22+
0x1200 -> Onewayroad, 0x1210 -> L1Onewayroad, 0x1220 -> L2Onewayroad,
23+
0x1300 -> Avenue, 0x1310 -> L1Avenue, 0x1320 -> L2Avenue,
24+
0x1400 -> Groundhighway, 0x1420 -> Highway,
25+
0x1500 -> Rail, 0x1505 -> Str,
26+
0x1700 -> Glr1, 0x1705 -> Glr3, 0x1720 -> Lightrail, // 0x1730 L4 Lightrail
27+
0x1800 -> Glr2, 0x1805 -> Glr4,
28+
0x1905 -> Hsr, 0x1925 -> L2Hsr, 0x1920 -> Monorail, // 0x1930 L4 Monorail
29+
30+
0x1a00 -> Tla3, 0x1b00 -> Ave2, 0x1c00 -> Ard3,
31+
0x1d00 -> Owr1, 0x1e00 -> Owr3, 0x1f00 -> Nrd4,
32+
0x2000 -> Tla5, 0x2100 -> Owr4, 0x2200 -> Owr5,
33+
0x2300 -> Rd4, 0x2400 -> Rd6, 0x2500 -> Ave6,
34+
0x2580 -> Tla7m, 0x2600 -> Ave8, 0x2680 -> Ave6m,
35+
// 0x2700 Tram-on-Street, 0x2800 Tram-in-Road, 0x2805 Tram-on-Road, 0x2a00 Tram-in-Avenue
36+
).map(_.swap))
37+
38+
}
39+
40+
class ViaductResolver extends IdResolver {
41+
def isDefinedAt(t: Tile): Boolean = tileMap.isDefinedAt(t)
42+
def apply(tile: Tile): IdTile = tileMap(tile)
43+
44+
val tileMap = {
45+
val builder = new ResolverBuilder
46+
import builder.add
47+
48+
// curves
49+
for (n <- Viaducts) {
50+
val id = ViaductResolver.viaductRangeId(n)
51+
52+
if (NP.isSingleTile(n)) {
53+
add(id + 0x0400, n~(0,2,0,11)) // 45 curve
54+
add(id + 0x0500, n~(0,0,1,13)) // 45 curve
55+
add(id + 0x0600, n~(0,11,0,11)) // S curve
56+
add(id + 0x0700, n~(0,11,0,13)) // boomerang
57+
add(id + 0x0800, n~(0,0,2,2)) // 90 curve
58+
} else {
59+
add(id + 0x0300, n~SharedDiagLeft)
60+
add(id + 0x0500, n~(0,-2,0,+11)) // 45 curve
61+
add(id + 0x0600, n~(0,+2,0,-11)) // 45 curve
62+
add(id + 0x0700, n~(0,-11,+3,0)) // 45 curve
63+
add(id + 0x0800, n~(-3,+11,-3,+1)) // 45 curve
64+
add(id + 0x0a00, n~(+2,0,-113,0)) // 90 curve extended
65+
add(id + 0x0b00, n~(+2,0,0,-2)) // 90 curve outside
66+
add(id + 0x0c00, n~(-2,0,0,+2)) // 90 curve inside
67+
}
68+
}
69+
70+
// crossings
71+
for {
72+
n <- Viaducts.iterator
73+
n2 <- ViaductResolver.viaductPieceId.keysIterator
74+
if !RhwResolver.greater(n2, n)
75+
if NP.intersectionAllowed(n, n2) || n.height == 2 && (n2 == Lightrail || n2 == Monorail) // Lightrail and Monorail are base network crossings, but might not actually be needed for overrides
76+
} {
77+
val pid = ViaductResolver.viaductPieceId(n2)
78+
val id = ViaductResolver.viaductRangeId(n) + pid
79+
val (rev00, rev01, rev10, rev11) = // for reversed directions of networks
80+
if (n.typ == AvenueLike) (0x00, 0x09, 0x80, 0x89)
81+
else (0x00, 0x05, 0x80, 0x85)
82+
val orientA: IntFlags => IntFlags = if (n2 == Ard3) reverseIntFlags else identity
83+
84+
// O×O
85+
add(n~NS & n2~orientA(EW), id + 0x0000)
86+
87+
// O×D
88+
if (!n2.isNwm && !Viaducts.contains(n2)) {
89+
val ne = if (n2.typ == AvenueLike) SharedDiagLeft else NE
90+
if (n.typ == AvenueLike) {
91+
add(n~NS & n2~SW, id + 0x3000 + rev00)
92+
add(n~NS & n2~NE, id + 0x3000 + rev01, when = !n2.isSymm)
93+
add(n~NS & n2~ne, id + 0x3000 + rev10, when = !n.isSymm) // TODO Monorail swaps 0x80 and 0x00 -> model issue only
94+
// add(n~??? & n2~???, id + 0x3000 + rev11, when = !n.isSymm && (n2.typ == Asymmetrical))
95+
} else {
96+
add(n~NS & n2~SW, id + 0x3000 + rev00)
97+
add(n~NS & n2~ne, id + 0x3000 + rev01, when = !n2.isSymm)
98+
}
99+
}
100+
// D×O
101+
if (!n2.isNwm && !Viaducts.contains(n2)) {
102+
if (n.typ == AvenueLike) {
103+
add(n~NE & n2~NS, id + 0x6000 + rev00)
104+
add(n~NE & n2~SN, id + 0x6000 + rev01, when = !n2.isSymm)
105+
add(n~SharedDiagLeft & n2~NS, id + 0x6000 + rev10, when = !n.isSymm)
106+
// add(n~??? & n2~???, id + 0x6000 + rev11, when = (n.typ == Asymmetrical) && !n2.isSymm)
107+
} else {
108+
add(n~ES & n2~WE, id + 0x6000 + rev00)
109+
add(n~ES & n2~EW, id + 0x6000 + rev10, when = !n2.isSymm)
110+
}
111+
}
112+
// D×D
113+
if (!n2.isNwm && !Viaducts.contains(n2)) {
114+
val se = if (n2.typ == AvenueLike) SharedDiagRight else SE
115+
if (n.typ == AvenueLike) {
116+
add(n~NE & n2~ES, id + 0x9000 + rev00)
117+
add(n~NE & n2~SharedDiagRight, id + 0x9000 + rev01, when = n2.typ == AvenueLike)
118+
add(n~SharedDiagLeft & n2~se, id + 0x9000 + rev10, when = !n.isSymm)
119+
add(n~SharedDiagLeft & n2~WN, id + 0x9000 + rev11, when = !n.isSymm && !n2.isSymm)
120+
} else {
121+
add(n~ES & n2~SW, id + 0x9000 + rev00)
122+
add(n~ES & n2~SharedDiagLeft, id + 0x9000 + rev10, when = n2.typ == AvenueLike)
123+
}
124+
}
125+
}
126+
127+
// T intersections
128+
for (n <- Viaducts) {
129+
val id = ViaductResolver.viaductRangeId(n)
130+
if (n.height == 1) {
131+
add(id + 0x3110, n~SN & L1Road~CE)
132+
add(id + 0x3115, n~SN & L1Road~WC, when = !n.isSymm)
133+
add(id + 0x3210, n~SN & L1Onewayroad~CE)
134+
add(id + 0x3215, n~SN & L1Onewayroad~WC, when = !n.isSymm)
135+
add(id + 0x3310, n~WE & L1Avenue~NC, when = n.isSymm)
136+
add(id + 0x3315, n~WE & L1Avenue~NC, when = !n.isSymm)
137+
}
138+
if (n.height == 2) {
139+
add(id + 0x3120, n~SN & L2Road~CE)
140+
add(id + 0x3125, n~SN & L2Road~WC, when = !n.isSymm)
141+
add(id + 0x3220, n~SN & L2Onewayroad~CE)
142+
add(id + 0x3225, n~SN & L2Onewayroad~WC, when = !n.isSymm)
143+
add(id + 0x3320, n~WE & L2Avenue~NC, when = n.isSymm)
144+
add(id + 0x3325, n~WE & L2Avenue~NC, when = !n.isSymm)
145+
}
146+
}
147+
148+
// Onslope transitions
149+
add(0x5c060000, L1Road~NC & Road~CS)
150+
add(0x5c060010, L2Road~NC & L1Road~CS)
151+
add(0x5c060100, L2Road~NC & Road~CS)
152+
add(0x5c070000, L1Onewayroad~NC & Onewayroad~CS)
153+
add(0x5c070010, L2Onewayroad~NC & L1Onewayroad~CS)
154+
add(0x5c070100, L2Onewayroad~NC & Onewayroad~CS)
155+
add(0x5c080000, L1Avenue~NC & Avenue~CS)
156+
add(0x5c080010, L2Avenue~NC & L1Avenue~CS)
157+
add(0x5c080100, L2Avenue~NC & Avenue~CS)
158+
159+
builder.result()
160+
}
161+
}

0 commit comments

Comments
 (0)