make the json a little less verbose by having separate position types instead of a discriminator

This commit is contained in:
Adam 2022-01-09 16:33:23 +01:00
parent f41def72e2
commit b9190b1948
6 changed files with 87 additions and 21 deletions

View file

@ -14,7 +14,7 @@ interface PlayerData extends FactorioObjectData {
lastOnline: uint;
name: string;
objectName: ObjectName;
position: PositionData;
position: MapEntityPosition;
}
interface EntityData extends FactorioObjectData {
@ -24,7 +24,7 @@ interface EntityData extends FactorioObjectData {
name: string;
objectName: ObjectName;
playerIndex: uint | null;
position: PositionData;
position: MapEntityPosition;
surfaceIndex: int;
type: string;
unitNumber: uint | null;
@ -39,13 +39,14 @@ interface SurfaceData extends FactorioObjectData {
interface MapTile extends FactorioObjectData {
objectName: ObjectName;
position: PositionData;
position: MapTilePosition;
prototypeName: string;
surfaceIndex: int;
}
interface MapChunk extends FactorioObjectData {
objectName: ObjectName;
position: MapChunkPosition;
tiles: MapTile[];
}

View file

@ -22,10 +22,17 @@ interface Colour {
red: float;
}
type PositionType = "MAP" | "CHUNK" | "TILE";
interface PositionData {
type: PositionType | null;
interface MapEntityPosition {
x: double;
y: double;
}
interface MapChunkPosition {
x: int;
y: int;
}
interface MapTilePosition {
x: int;
y: int;
}

View file

@ -8,7 +8,7 @@ export namespace Converters {
name: player.name,
characterUnitNumber: player.character?.unit_number ?? null,
associatedCharactersUnitNumbers: charIds,
position: convertMapPosition(player.position),
position: mapEntityPosition(player.position),
colour: mapColour(player.color),
chatColour: mapColour(player.chat_color),
lastOnline: player.last_online
@ -30,7 +30,7 @@ export namespace Converters {
healthRatio: entity.get_health_ratio(),
surfaceIndex: entity.surface.index,
unitNumber: entity.unit_number ?? null,
position: convertMapPosition(entity.position),
position: mapEntityPosition(entity.position),
// player data
playerIndex: player?.index ?? null
@ -57,9 +57,23 @@ export namespace Converters {
}
}
export function convertMapPosition(mapPos: MapPositionTable): PositionData {
export function mapEntityPosition(mapPos: MapPositionTable): MapEntityPosition {
return {
x: mapPos.x,
y: mapPos.y,
}
}
export function mapTilePosition(mapPos: MapPositionTable): MapTilePosition {
return {
x: mapPos.x,
y: mapPos.y,
}
}
export function mapChunkPosition(mapPos: ChunkPositionTable): MapChunkPosition {
return {
type: "MAP",
x: mapPos.x,
y: mapPos.y,
}
@ -87,7 +101,7 @@ export namespace Converters {
return {
objectName: tile.object_name,
position: convertMapPosition(tile.position),
position: mapTilePosition(tile.position),
prototypeName: tile.prototype.name,
surfaceIndex: tile.surface.index
}

View file

@ -1,5 +1,6 @@
import {Converters} from "./converters"
import {emitEvent} from "./emitEvent";
import mapChunkPosition = Converters.mapChunkPosition;
export function handlePlayerUpdate(tick: uint, eventType: string, playerIndex: uint) {
let player: LuaPlayer = game.players[playerIndex]
@ -55,7 +56,7 @@ export function handleChunkUpdate(
tick: uint,
eventType: string,
surfaceIndex: uint,
position: ChunkPosition
position: ChunkPositionTable
) {
let surface = game.get_surface(surfaceIndex)
@ -77,6 +78,7 @@ export function handleChunkUpdate(
let mapChunk: MapChunk = {
objectName: "MapChunk",
tiles: convertedTiles,
position: mapChunkPosition(position)
}
emitEvent(mapChunk, tick, eventType)

View file

@ -1,18 +1,59 @@
package dev.adamko.kafkatorio.events.schema
import kotlin.math.roundToInt
import kotlinx.serialization.EncodeDefault
import kotlinx.serialization.Serializable
const val MAP_CHUNK_SIZE = 32
/**
* Coordinates of a [EntityData] on a map.
*
* A [MapEntityPosition] can be translated to a [MapChunkPosition] by dividing the `x`/`y` values
* by [32][MAP_CHUNK_SIZE].
*/
@Serializable
data class PositionData(
data class MapEntityPosition(
val x: Double,
val y: Double,
val type: PositionType?,
)
) {
fun toMapChunkPosition() = MapChunkPosition(
(x / MAP_CHUNK_SIZE).roundToInt(),
(y / MAP_CHUNK_SIZE).roundToInt(),
)
}
/** Coordinates of a chunk in a [SurfaceData] where each integer `x`/`y` represents a different
* chunk.
*
* A [MapChunkPosition] can be translated to a [MapEntityPosition] by multiplying the `x`/`y`
* values by [32][MAP_CHUNK_SIZE].
*/
@Serializable
enum class PositionType {
MAP, CHUNK, TILE,
data class MapChunkPosition(
val x: Int,
val y: Int,
) {
fun toMapEntityPosition() = MapEntityPosition(
x * MAP_CHUNK_SIZE.toDouble(),
y * MAP_CHUNK_SIZE.toDouble(),
)
}
/**
* Coordinates of a tile in a chunk on a [SurfaceData] where each integer `x`/`y` represents a
* different [MapTile].
*
* It rounds any `x`/`y` down to whole numbers.
*/
@Serializable
data class MapTilePosition(
val x: Int,
val y: Int,
) {
constructor(x: Number, y: Number) : this(x.toInt(), y.toInt())
}
/**

View file

@ -77,7 +77,7 @@ data class PlayerData(
val associatedCharactersUnitNumbers: List<UInt>,
val characterUnitNumber: UInt?,
val name: String,
val position: PositionData,
val position: MapEntityPosition,
val colour: Colour,
val chatColour: Colour,
val lastOnline: UInt,
@ -92,7 +92,7 @@ data class EntityData(
val health: Double?,
val healthRatio: Double,
val name: String,
val position: PositionData,
val position: MapEntityPosition,
val surfaceIndex: Int,
val type: String,
val unitNumber: UInt? = null,
@ -116,6 +116,7 @@ data class SurfaceData(
@Serializable
data class MapChunk(
val tiles: List<MapTile>,
val position: MapChunkPosition,
) : FactorioObjectData() {
@EncodeDefault
override val objectName = ObjectName.MapChunk
@ -124,7 +125,7 @@ data class MapChunk(
@Serializable
data class MapTile(
val prototypeName: String,
val position: PositionData,
val position: MapTilePosition,
val surfaceIndex: Int,
) : FactorioObjectData() {
@EncodeDefault