chunk pngs almost working...
- rm yarn lock, it should be in ./gradle/kotlin-js-store - move kafka extensions to another project, kotka-streams - move prototypes to their own package - create a Factorio command for emitting prototypes - add bounding box to chunk updates - bump typed-factorio version - fix MapEntityPosition -> MapChunkPosition x/y rounding - lots of work on the Kafka Streams topology
This commit is contained in:
parent
49ad3654a3
commit
8533be0af8
47 changed files with 1097 additions and 4179 deletions
|
|
@ -20,7 +20,7 @@ kotlin {
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("UnstableApiUsage") // enforcedPlatform is incubating
|
||||
@Suppress("UnstableApiUsage") // platform + version catalogs is incubating
|
||||
sourceSets {
|
||||
|
||||
all {
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ data class MapEntityPosition(
|
|||
) {
|
||||
|
||||
fun toMapChunkPosition() = MapChunkPosition(
|
||||
(x / MAP_CHUNK_SIZE).roundToInt(),
|
||||
(y / MAP_CHUNK_SIZE).roundToInt(),
|
||||
(x / MAP_CHUNK_SIZE).toInt(),
|
||||
(y / MAP_CHUNK_SIZE).toInt(),
|
||||
)
|
||||
|
||||
}
|
||||
|
|
@ -36,10 +36,17 @@ data class MapChunkPosition(
|
|||
val x: Int,
|
||||
val y: Int,
|
||||
) {
|
||||
|
||||
fun toMapEntityPosition() = MapEntityPosition(
|
||||
x * MAP_CHUNK_SIZE.toDouble(),
|
||||
y * MAP_CHUNK_SIZE.toDouble(),
|
||||
)
|
||||
|
||||
fun toMapTilePosition() = MapChunkPosition(
|
||||
x * MAP_CHUNK_SIZE,
|
||||
y * MAP_CHUNK_SIZE,
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -62,6 +69,14 @@ data class MapTilePosition(
|
|||
|
||||
}
|
||||
|
||||
|
||||
@Serializable
|
||||
data class MapBoundingBox(
|
||||
val topLeft: MapTilePosition,
|
||||
val bottomRight: MapTilePosition,
|
||||
)
|
||||
|
||||
|
||||
/**
|
||||
* Red, green, blue and alpha values, all in range `[0, 1]` or all in range `[0, 255]` if any
|
||||
* value is > 1.
|
||||
|
|
@ -81,7 +96,7 @@ data class Colour(
|
|||
) {
|
||||
|
||||
/** True if any value is greater than 1, so the values are hexadecimal. */
|
||||
fun isDecimal(): Boolean {
|
||||
fun isHexadecimal(): Boolean {
|
||||
return red > 1f
|
||||
|| green > 1f
|
||||
|| blue > 1f
|
||||
|
|
@ -89,9 +104,9 @@ data class Colour(
|
|||
}
|
||||
|
||||
/** True if all values are between `[0..1]`. */
|
||||
fun isPercentage(): Boolean = !isDecimal()
|
||||
fun isPercentage(): Boolean = !isHexadecimal()
|
||||
|
||||
fun asDecimal() = if (isPercentage()) {
|
||||
fun asHexadecimal() = if (isPercentage()) {
|
||||
Colour(
|
||||
(red * 255).coerceIn(0f..255f),
|
||||
(green * 255).coerceIn(0f..255f),
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
package dev.adamko.kafkatorio.events.schema
|
||||
|
||||
import kotlinx.serialization.EncodeDefault
|
||||
import kotlinx.serialization.Required
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Transient
|
||||
|
||||
|
||||
@Serializable
|
||||
|
|
@ -12,10 +9,9 @@ data class FactorioConfigurationUpdate(
|
|||
override val modVersion: String,
|
||||
val factorioData: FactorioGameDataUpdate,
|
||||
val allMods: List<FactorioModInfo>,
|
||||
val prototypes: List<FactorioPrototype>,
|
||||
) : KafkatorioPacket() {
|
||||
@EncodeDefault
|
||||
override val packetType = PacketType.CONFIG
|
||||
override val packetType = PacketType.CONFIG
|
||||
}
|
||||
|
||||
@Serializable
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ data class SurfaceData(
|
|||
data class MapChunk(
|
||||
val tiles: MapTiles,
|
||||
val position: MapChunkPosition,
|
||||
val area: MapBoundingBox,
|
||||
) : FactorioObjectData() {
|
||||
@EncodeDefault
|
||||
override val objectName = ObjectName.MapChunk
|
||||
|
|
|
|||
|
|
@ -10,6 +10,16 @@ import kotlinx.serialization.json.jsonObject
|
|||
import kotlinx.serialization.json.jsonPrimitive
|
||||
|
||||
|
||||
@Serializable
|
||||
data class FactorioPrototypes(
|
||||
override val modVersion: String,
|
||||
val prototypes: List<FactorioPrototype>,
|
||||
) : KafkatorioPacket() {
|
||||
@EncodeDefault
|
||||
override val packetType = PacketType.PROTOTYPES
|
||||
}
|
||||
|
||||
|
||||
@Serializable(with = FactorioPrototypeSerializer::class)
|
||||
sealed class FactorioPrototype {
|
||||
@EncodeDefault
|
||||
|
|
@ -49,6 +59,7 @@ data class MapTilePrototype(
|
|||
val name: String,
|
||||
val layer: UInt,
|
||||
val mapColour: Colour,
|
||||
@Serializable(with = FactorioJsonListSerializer::class)
|
||||
val collisionMasks: List<String>,
|
||||
val order: String,
|
||||
/** Can the tile be mined for resources? */
|
||||
|
|
|
|||
|
|
@ -10,8 +10,17 @@ import kotlinx.serialization.json.JsonTransformingSerializer
|
|||
import kotlinx.serialization.json.jsonArray
|
||||
import kotlinx.serialization.json.jsonObject
|
||||
|
||||
val jsonMapperKafkatorio = Json {
|
||||
prettyPrint = true
|
||||
prettyPrintIndent = " "
|
||||
// serializersModule = FactorioEvent.kxsModule
|
||||
// serializersModule = KafkatorioPacket.kxsModule + FactorioEvent.kxsModule
|
||||
// serializersModule = SerializersModule { }
|
||||
}
|
||||
|
||||
|
||||
/** Factorio outputs lists as Json objects - this serializer converts an object back to a list. */
|
||||
// actually I'm not sure that it does - I think *empty* lists get encoded as *empty* objects
|
||||
internal class ListAsObjectSerializer<T>(dataSerializer: KSerializer<T>) :
|
||||
JsonTransformingSerializer<List<T>>(ListSerializer(dataSerializer)) {
|
||||
|
||||
|
|
@ -26,10 +35,18 @@ internal class ListAsObjectSerializer<T>(dataSerializer: KSerializer<T>) :
|
|||
)
|
||||
}
|
||||
|
||||
val jsonMapperKafkatorio = Json {
|
||||
prettyPrint = true
|
||||
prettyPrintIndent = " "
|
||||
// serializersModule = FactorioEvent.kxsModule
|
||||
// serializersModule = KafkatorioPacket.kxsModule + FactorioEvent.kxsModule
|
||||
// serializersModule = SerializersModule { }
|
||||
|
||||
/** Factorio outputs lists as Json objects - this serializer converts an object back to a list. */
|
||||
// actually I'm not sure that it does - I think *empty* lists get encoded as *empty* objects
|
||||
internal class FactorioJsonListSerializer<T>(dataSerializer: KSerializer<T>) :
|
||||
JsonTransformingSerializer<List<T>>(ListSerializer(dataSerializer)) {
|
||||
|
||||
override fun transformDeserialize(element: JsonElement): JsonElement {
|
||||
return if (element is JsonObject) {
|
||||
JsonArray(emptyList())
|
||||
} else {
|
||||
element
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ sealed class KafkatorioPacket {
|
|||
enum class PacketType {
|
||||
EVENT,
|
||||
CONFIG,
|
||||
PROTOTYPES,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -41,6 +42,7 @@ object KafkatorioPacketSerializer : JsonContentPolymorphicSerializer<KafkatorioP
|
|||
return when (type) {
|
||||
KafkatorioPacket.PacketType.EVENT -> FactorioEvent.serializer()
|
||||
KafkatorioPacket.PacketType.CONFIG -> FactorioConfigurationUpdate.serializer()
|
||||
KafkatorioPacket.PacketType.PROTOTYPES -> FactorioPrototypes.serializer()
|
||||
null ->
|
||||
throw Exception("Unknown KafkatorioPacket ${key}: '$type' ")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
package dev.adamko.kafkatorio.events.schema
|
||||
|
||||
import io.kotest.core.spec.style.BehaviorSpec
|
||||
import kotlinx.serialization.decodeFromString
|
||||
|
||||
class PrototypesTest : BehaviorSpec(
|
||||
{
|
||||
Given("Prototypes Json") {
|
||||
//Language=JSON
|
||||
val raw = """
|
||||
{
|
||||
"modVersion":"0.2.4",
|
||||
"packetType":"PROTOTYPES",
|
||||
"prototypes":[
|
||||
{
|
||||
"prototypeObjectName":"LuaTilePrototype",
|
||||
"name":"tile-unknown",
|
||||
"order":"z-a",
|
||||
"layer":0,
|
||||
"collisionMasks":{
|
||||
|
||||
},
|
||||
"mapColour":{
|
||||
"red":0,
|
||||
"green":0,
|
||||
"blue":0,
|
||||
"alpha":255
|
||||
},
|
||||
"canBeMined":false
|
||||
}
|
||||
]
|
||||
}
|
||||
""".trimIndent()
|
||||
|
||||
Then("expect can be parsed") {
|
||||
val data = jsonMapperKafkatorio.decodeFromString<KafkatorioPacket>(raw)
|
||||
println(data)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
) {
|
||||
companion object {
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,8 @@ fun main(args: Array<String>) {
|
|||
addAll(KafkatorioPacket::class.sealedSubclasses)
|
||||
addAll(FactorioObjectData::class.sealedSubclasses)
|
||||
addAll(FactorioPrototype::class.sealedSubclasses)
|
||||
add(FactorioPrototypes::class)
|
||||
add(FactorioConfigurationUpdate::class)
|
||||
},
|
||||
mappings = mapOf(
|
||||
// builtin Factorio numeric types > `typed-factorio/generated/builtin-types.d.ts`
|
||||
|
|
@ -40,7 +42,6 @@ fun main(args: Array<String>) {
|
|||
println(definitions)
|
||||
}
|
||||
else -> {
|
||||
|
||||
val outPath = Path(filename)
|
||||
outPath.createDirectories()
|
||||
|
||||
|
|
@ -64,17 +65,18 @@ private fun splitDefinitions(definitions: String): Map<String, String> {
|
|||
.split("\n\n")
|
||||
.groupBy { def ->
|
||||
when {
|
||||
"extends FactorioObjectData" in def ||
|
||||
"interface FactorioObjectData" in def ||
|
||||
"type ObjectName" in def -> "object-data.d.ts"
|
||||
"extends FactorioPrototype" in def ||
|
||||
"interface FactorioPrototype" in def ||
|
||||
"type PrototypeObjectName" in def -> "prototype.d.ts"
|
||||
"extends FactorioConfigurationUpdate" in def ||
|
||||
"interface FactorioConfigurationUpdate" in def ||
|
||||
"FactorioGameDataUpdate" in def ||
|
||||
"FactorioModInfo" in def -> "config-update.d.ts"
|
||||
else -> "schema.d.ts"
|
||||
"extends FactorioObjectData " in def ||
|
||||
"interface FactorioObjectData " in def ||
|
||||
"type ObjectName " in def -> "object-data.d.ts"
|
||||
"extends FactorioPrototype " in def ||
|
||||
"interface FactorioPrototypes " in def ||
|
||||
"interface FactorioPrototype " in def ||
|
||||
"type PrototypeObjectName " in def -> "prototype.d.ts"
|
||||
"extends FactorioConfigurationUpdate " in def ||
|
||||
"interface FactorioConfigurationUpdate " in def ||
|
||||
"FactorioGameDataUpdate " in def ||
|
||||
"FactorioModInfo " in def -> "config-update.d.ts"
|
||||
else -> "schema.d.ts"
|
||||
}
|
||||
}
|
||||
.mapValues { (_, def) ->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue