}
}
+fun WarpLane.withData(cluster: StarClusterView): WarpLaneWithData? =
+ systemA.resolve(cluster)?.let { a ->
+ systemB.resolve(cluster)?.let { b ->
+ WarpLaneWithData(StarSystemWithId(systemA, a), StarSystemWithId(systemB, b))
+ }
+ }
+
@Serializable
data class WarpLaneData(
val systemA: StarSystem,
val systemB: StarSystem,
)
+@Serializable
+data class WarpLaneWithData(
+ val systemA: StarSystemWithId,
+ val systemB: StarSystemWithId,
+) {
+ val lane: WarpLane
+ get() = WarpLane(systemA.id, systemB.id)
+
+ val data: WarpLaneData
+ get() = WarpLaneData(systemA.starSystem, systemB.starSystem)
+}
+
fun Id<StarSystem>.resolve(cluster: StarClusterView): StarSystem? = cluster.systems[this]
@Serializable
private lateinit var starSystem: CustomRenderFactory<StarSystemWithId>
- private lateinit var warpLane: CustomRenderFactory<WarpLaneData>
+ private lateinit var warpLane: CustomRenderFactory<WarpLaneWithData>
+ private lateinit var warpLanes: CustomRenderFactory<StarClusterView>
lateinit var starCluster: CustomRenderFactory<StarClusterView>
private set
suspend fun load() {
- warpLane = CustomRenderFactory { (systemA, systemB) ->
+ warpLane = CustomRenderFactory { laneWithData ->
+ val (systemA, systemB) = laneWithData.data
+
val warpLaneMaterial = MeshBasicMaterial(configure { color = Color("#FFFFFF") })
val aToBCenter = systemB.position - systemA.position
false
)
- Mesh(warpLaneGeometry, warpLaneMaterial)
+ Mesh(warpLaneGeometry, warpLaneMaterial).apply {
+ userData = WarpLaneRender(laneWithData.lane)
+ }
+ }
+
+ warpLanes = CustomRenderFactory { cluster ->
+ Group().apply {
+ for (lane in cluster.lanes)
+ add(warpLane.generate(lane.withData(cluster) ?: continue))
+
+ userData = WARP_LANES_UD
+ }
}
coroutineScope {
for (systemFleets in systemsFleets)
add(systemFleets)
- userData = "fleet counters"
+ userData = CLUSTER_FLEETS_UD
}
}
}
for ((id, system) in cluster.systems)
add(starSystem.generate(StarSystemWithId(id, system)))
- for (lane in cluster.lanes)
- add(warpLane.generate(lane.resolve(cluster) ?: continue))
-
+ add(warpLanes.generate(cluster))
add(fleetCountersInCluster.generate(cluster))
- userData = "star cluster"
+ userData = STAR_CLUSTER_UD
}
}
}
else
parent?.fleetPresenceRender
+external interface WarpLaneRender {
+ var isWarpLane: Boolean
+ var systemAId: String
+ var systemBId: String
+}
+
+fun WarpLaneRender(lane: WarpLane) = configure<WarpLaneRender> {
+ isWarpLane = true
+ systemAId = lane.systemA.id
+ systemBId = lane.systemB.id
+}
+
+val WarpLaneRender.warpLane: WarpLane
+ get() = WarpLane(Id(systemAId), Id(systemBId))
+
+val Object3D.warpLaneRender: WarpLane?
+ get() = if (userData.isWarpLane == true)
+ userData.unsafeCast<WarpLaneRender>().warpLane
+ else
+ null
+
val StarClusterBackground.ambientColor: IntColor
get() = when (this) {
StarClusterBackground.BLUE -> IntColor(34, 51, 85)
StarClusterBackground.RED -> IntColor(85, 0, 0)
}
+const val STAR_CLUSTER_UD = "star cluster"
val Object3D.isStarCluster: Boolean
- get() = userData == "star cluster"
+ get() = userData == STAR_CLUSTER_UD
+
+const val WARP_LANES_UD = "warp lanes"
+val Object3D.isStarClusterWarpLanes: Boolean
+ get() = userData == WARP_LANES_UD
+const val CLUSTER_FLEETS_UD = "fleet counters"
val Object3D.isStarClusterFleets: Boolean
- get() = userData == "fleet counters"
+ get() = userData == CLUSTER_FLEETS_UD
fun Object3D.isStarSystemFleets(system: Id<StarSystem>) = (parent?.isStarClusterFleets == true) && userData == system.id