massive refactor to export entities (buildings and resources)

- minor version bumps
- new Factorio version
- use both prototype name and type to identify a prototype
- kxs-ts-gen: use BrandTyping, but exclude some identifiers
- kxs-ts-gen: manually create zip dist, so it can run after the project compiles
- mod: use typed-factorio strict types
- mod: refactor event handlers to be a little more consistent and object-oriented
This commit is contained in:
Adam 2022-07-05 23:44:23 +02:00
parent 88982d818a
commit 90dc520d22
62 changed files with 2629 additions and 713 deletions

View file

@ -1,6 +1,9 @@
import dev.adamko.kafkatorio.gradle.asProvider
import dev.adamko.kafkatorio.gradle.typescriptAttributes
import dev.adamko.kafkatorio.task.GenerateTypeScriptTask
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
@ -36,6 +39,7 @@ kotlin {
all {
languageSettings.apply {
optIn("kotlin.ExperimentalStdlibApi")
optIn("kotlin.ExperimentalUnsignedTypes")
optIn("kotlin.RequiresOptIn")
optIn("kotlin.js.ExperimentalJsExport")
optIn("kotlin.time.ExperimentalTime")
@ -51,7 +55,7 @@ kotlin {
implementation(project.dependencies.platform(libs.kotlinx.serialization.bom))
implementation(libs.kotlinx.serialization.core)
implementation(libs.kotlinx.serialization.json)
api("dev.adamko.kxstsgen:kxs-ts-gen-core:0.1.3")
api(libs.kxs.kxsTsGen)
implementation(dependencies.platform(libs.okio.bom))
implementation(libs.okio.core)
@ -96,16 +100,34 @@ kotlin {
}
val kotlinJvmMainCompilation: NamedDomainObjectProvider<KotlinJvmCompilation> =
kotlin.jvm().compilations.named(KotlinCompilation.MAIN_COMPILATION_NAME)
val jvmJar: TaskProvider<Jar> = tasks.named<Jar>(kotlin.jvm().artifactsTaskName)
val mainCompilation: Provider<FileCollection> =
kotlin.jvm().compilations.named("main").map { it.runtimeDependencyFiles }
val kotlinMainRuntimeDependencies: Provider<FileCollection> =
kotlinJvmMainCompilation.map { it.runtimeDependencyFiles }
val kotlinMainCompileDependencies: Provider<FileCollection> =
kotlinJvmMainCompilation.map { it.compileDependencyFiles }
val kotlinMainCompileTask: Provider<KotlinCompile> =
kotlinJvmMainCompilation.map { it.compileKotlinTask }
val generateTypeScript by tasks.registering(GenerateTypeScriptTask::class) {
dependsOn(jvmJar)
// dependsOn(kotlinMainCompileTask)
// inputs.files(jvmJar.map { it.outputs.files })
// inputs.files(kotlinMainCompileTask.map { it.javaSources })
classpath(
jvmJar,
mainCompilation,
kotlinMainRuntimeDependencies,
// kotlinMainCompileTask.map { it.libraries }
// kotlinMainDependencies,
)
output.set(layout.buildDirectory.dir("generated/typescript"))
mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2ts2Kt")
@ -122,16 +144,26 @@ val generateTypeScriptOutputFiles: Provider<FileTree> =
generateTypeScript.map { it.outputs.files.asFileTree }
val schemaTs by distributions.registering {
distributionBaseName.set(schemaTsDistributionName)
contents {
from(generateTypeScriptOutputFiles)
}
//val schemaTs by distributions.registering {
// distributionBaseName.set(schemaTsDistributionName)
// contents {
// from(generateTypeScriptOutputFiles)
// }
//}
//val schemaTsZipTask: TaskProvider<Zip> = tasks.named<Zip>("${schemaTs.name}DistZip")
//val schemaTsZipTaskArchiveFile: Provider<RegularFile> = schemaTsZipTask.flatMap { it.archiveFile }
val schemaTsZip by tasks.registering(Zip::class) {
group = "kt2ts"
archiveBaseName.set("schema-ts")
from(generateTypeScriptOutputFiles)
destinationDirectory.set(layout.buildDirectory.dir("distributions/kt2ts"))
}
val schemaTsZipTask: TaskProvider<Zip> = tasks.named<Zip>("${schemaTs.name}DistZip")
val schemaTsZipTaskArchiveFile: Provider<RegularFile> = schemaTsZipTask.flatMap { it.archiveFile }
val schemaTsZipTaskArchiveFile: Provider<RegularFile> = schemaTsZip.flatMap { it.archiveFile }
val typeScriptModelGenerated: Configuration by configurations.creating {
@ -139,4 +171,5 @@ val typeScriptModelGenerated: Configuration by configurations.creating {
typescriptAttributes(objects)
outgoing.artifact(schemaTsZipTaskArchiveFile)
// outgoing.artifact(schemaTsZipTaskArchiveFile)
}

View file

@ -5,6 +5,7 @@ import kotlin.math.roundToInt
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Red, green, blue and alpha values, all in range `[0, 1]` or all in range `[0, 255]` if any
* value is > 1.

View file

@ -0,0 +1,191 @@
package dev.adamko.kafkatorio.schema.common
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
@SerialName("kafkatorio.entity.FactorioEntityData")
sealed interface FactorioEntityData {
val protoId: PrototypeId
val status: Status?
val position: MapEntityPosition
/** Non-specific entity data */
@Serializable
@SerialName("kafkatorio.entity.FactorioEntityData.Standard")
data class Standard(
override val protoId: PrototypeId,
override val status: Status? = null,
override val position: MapEntityPosition,
val graphicsVariation: UByte? = null,
val health: Float? = null,
val isActive: Boolean? = null,
val isRotatable: Boolean? = null,
val lastUser: UInt? = null,
val localisedDescription: String? = null,
val localisedName: String? = null,
) : FactorioEntityData
@Serializable
@SerialName("kafkatorio.entity.FactorioEntityData.Resource")
data class Resource(
override val protoId: PrototypeId,
override val status: Status? = null,
override val position: MapEntityPosition,
val amount: UInt,
/** Count of initial resource units contained. `null` if resource is not infinite. */
val initialAmount: UInt? = null,
) : FactorioEntityData
@Serializable
@SerialName("kafkatorio.entity.FactorioEntityData.EntityStatus")
enum class Status {
CANT_DIVIDE_SEGMENTS,
CHARGING,
CLOSED_BY_CIRCUIT_NETWORK,
DISABLED,
DISABLED_BY_CONTROL_BEHAVIOR,
DISABLED_BY_SCRIPT,
DISCHARGING,
FLUID_INGREDIENT_SHORTAGE,
FULLY_CHARGED,
FULL_OUTPUT,
ITEM_INGREDIENT_SHORTAGE,
LAUNCHING_ROCKET,
LOW_INPUT_FLUID,
LOW_POWER,
LOW_TEMPERATURE,
MARKED_FOR_DECONSTRUCTION,
MISSING_REQUIRED_FLUID,
MISSING_SCIENCE_PACKS,
NETWORKS_CONNECTED,
NETWORKS_DISCONNECTED,
NORMAL,
NOT_CONNECTED_TO_RAIL,
NOT_PLUGGED_IN_ELECTRIC_NETWORK,
NO_AMMO,
NO_FUEL,
NO_INGREDIENTS,
NO_INPUT_FLUID,
NO_MINABLE_RESOURCES,
NO_MODULES_TO_TRANSMIT,
NO_POWER,
NO_RECIPE,
NO_RESEARCH_IN_PROGRESS,
OPENED_BY_CIRCUIT_NETWORK,
OUT_OF_LOGISTIC_NETWORK,
PREPARING_ROCKET_FOR_LAUNCH,
RECHARGING_AFTER_POWER_OUTAGE,
TURNED_OFF_DURING_DAYTIME,
WAITING_FOR_SOURCE_ITEMS,
WAITING_FOR_SPACE_IN_DESTINATION,
WAITING_FOR_TARGET_TO_BE_BUILT,
WAITING_FOR_TRAIN,
WAITING_TO_LAUNCH_ROCKET,
WORKING,
}
}
/*
enum entity_status {
working,
normal,
no_power,
low_power,
no_fuel,
disabled_by_control_behavior,
opened_by_circuit_network,
closed_by_circuit_network,
disabled_by_script,
marked_for_deconstruction,
not_plugged_in_electric_network,
networks_connected,
networks_disconnected,
charging,
discharging,
fully_charged,
out_of_logistic_network,
no_recipe,
no_ingredients,
no_input_fluid,
no_research_in_progress,
no_minable_resources,
low_input_fluid,
fluid_ingredient_shortage,
full_output,
item_ingredient_shortage,
missing_required_fluid,
missing_science_packs,
waiting_for_source_items,
waiting_for_space_in_destination,
preparing_rocket_for_launch,
waiting_to_launch_rocket,
launching_rocket,
no_modules_to_transmit,
recharging_after_power_outage,
waiting_for_target_to_be_built,
waiting_for_train,
no_ammo,
low_temperature,
disabled,
turned_off_during_daytime,
not_connected_to_rail,
cant_divide_segments,
}
*/
/*
AssemblingMachine
Beam
Car
Character
CharacterCorpse
CraftingMachine
ElectricEnergyInterface
ElectricPole
EntityGhost
EntityWithHealth
EntityWithOwner
FlyingText
Furnace
Gate
Generator
Ghost
HeatInterface
HighlightBox
InfinityContainer
InfinityPipe
Inserter
ItemEntity
LandMine
LinkedBelt
Loader
Market
MiningDrill
ProgrammableSpeaker
Pump
Radar
Rail
RailChainSignal
RailSignal
Reactor
ResourceEntity
RocketSilo
SmokeWithTrigger
SpiderVehicle
Splitter
TrainStop
TransportBeltConnectable
TransportBeltToGround
Turret
Unit
Vehicle
*/

View file

@ -1,10 +1,12 @@
package dev.adamko.kafkatorio.schema.common
import kotlin.jvm.JvmInline
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
@SerialName("kafkatorio.id.Tick")
@JvmInline
value class Tick(val value: UInt)
@ -17,6 +19,7 @@ val UInt.tick
* See [`LuaSurface.index`](https://lua-api.factorio.com/latest/LuaSurface.html#LuaSurface.index)
*/
@Serializable
@SerialName("kafkatorio.id.SurfaceIndex")
@JvmInline
value class SurfaceIndex(private val id: UInt) {
override fun toString(): String = "$id"
@ -24,6 +27,7 @@ value class SurfaceIndex(private val id: UInt) {
@Serializable
@SerialName("kafkatorio.id.ForceIndex")
@JvmInline
value class ForceIndex(private val id: UInt) {
override fun toString(): String = "$id"
@ -32,6 +36,7 @@ value class ForceIndex(private val id: UInt) {
/** The player's index in `LuaGameScript::players` */
@Serializable
@SerialName("kafkatorio.id.PlayerIndex")
@JvmInline
value class PlayerIndex(private val id: UInt) {
override fun toString(): String = "$id"
@ -40,6 +45,7 @@ value class PlayerIndex(private val id: UInt) {
/** > This is universally unique for every entity that has one, for the lifetime of a whole game. */
@Serializable
@SerialName("kafkatorio.id.UnitNumber")
@JvmInline
value class UnitNumber(private val id: UInt) {
override fun toString(): String = "$id"
@ -47,13 +53,7 @@ value class UnitNumber(private val id: UInt) {
@Serializable
@JvmInline
value class PrototypeName(private val id: String) {
override fun toString(): String = id
}
@Serializable
@SerialName("kafkatorio.id.EventName")
@JvmInline
value class EventName(private val name: String) {
override fun toString(): String = name
@ -62,23 +62,23 @@ value class EventName(private val name: String) {
interface EntityIdentifiers {
val unitNumber: UnitNumber?
val name: String
/** The prototype-type of the entity. */
val protoType: String
/** The 'prototype type' and 'prototype name' of the entity. */
val protoId: PrototypeId
}
// instant of EntityIdentifiers, because kxs needs a concrete instance
@Serializable
@SerialName("kafkatorio.id.EntityIdentifiersData")
data class EntityIdentifiersData(
override val unitNumber: UnitNumber? = null,
override val name: String,
override val protoType: String,
override val protoId: PrototypeId,
) : EntityIdentifiers
@JvmInline
@Serializable
@SerialName("kafkatorio.id.FactorioServerId")
@JvmInline
value class FactorioServerId(private val id: String) {
override fun toString() = id
}

View file

@ -8,13 +8,14 @@ import kotlinx.serialization.Serializable
@Serializable
@SerialName("kafkatorio.prototype.FactorioPrototype")
sealed interface FactorioPrototype {
val name: PrototypeName
val protoId: PrototypeId
val mapColour: Colour
@SerialName("kafkatorio.prototype.MapTile")
@Serializable
data class MapTile(
override val name: PrototypeName,
override val protoId: PrototypeId,
override val mapColour: Colour,
val layer: UInt,
@ -29,7 +30,7 @@ sealed interface FactorioPrototype {
@SerialName("kafkatorio.prototype.Entity")
@Serializable
data class Entity(
override val name: PrototypeName,
override val protoId: PrototypeId,
override val mapColour: Colour,
val protoType: String,

View file

@ -12,16 +12,16 @@ const val MAP_CHUNK_SIZE = 32
data class MapTile(
val x: Int,
val y: Int,
val proto: PrototypeName,
val protoId: PrototypeId,
)
/**
* 2D map of x/y tile positions and prototype-name, optimised for JSON size.
*
* [protos] is a one-to-one map between a [PrototypeName] and [PrototypeKey].
* [protos] is a one-to-one map between a prototype[PrototypeId] and [PrototypeKey].
*
* [PrototypeKey] is an arbitrary integer value, which maps to one [PrototypeName] only for a
* [PrototypeKey] is an arbitrary integer value, which maps to one [PrototypeId] only for a
* specific instance of [MapTileDictionary].
*
* Each X/Y coordinate in [tilesXY] maps to a [PrototypeKey].
@ -30,9 +30,10 @@ data class MapTile(
data class MapTileDictionary(
/** Map an X,Y coordinate a prototype name */
val tilesXY: Map<String, Map<String, PrototypeKey>>,
val protos: Map<PrototypeName, PrototypeKey>,
val protos: Map<PrototypeId, PrototypeKey>,
) {
private val protosIndexToName: Map<PrototypeKey, PrototypeName> by lazy {
private val protosIndexToId: Map<PrototypeKey, PrototypeId> by lazy {
protos.entries.associate { (name, key) -> key to name }
}
@ -41,11 +42,11 @@ data class MapTileDictionary(
row.forEach { (yString, protoIndex) ->
val x = xString.toIntOrNull()
val y = yString.toIntOrNull()
val protoName = protosIndexToName[protoIndex]
val protoName = protosIndexToId[protoIndex]
if (x != null && y != null && protoName != null) {
add(MapTile(x, y, protoName))
} else if (protoName == null) {
println("warning: no prototype name found for index:$protoIndex. $protosIndexToName")
println("warning: no prototype name found for index:$protoIndex. $protosIndexToId")
}
}
}

View file

@ -0,0 +1,817 @@
package dev.adamko.kafkatorio.schema.common
import kotlin.jvm.JvmInline
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Both a [name] and [type] are required to unique identify a [prototype][FactorioPrototype].
*
*
* @property[name] The name of the prototype, which is unique per specific Prototype [type]
*/
// * Each subclass of [PrototypeId] is equivalent to a Prototype `type`.
//sealed interface PrototypeId {
//
// val name: String
//
// @Serializable
// @JvmInline
// @SerialName("kafkatorio.prototype.id.PrototypeIdMapTile")
// value class MapTile(override val name: String) : PrototypeId {
// override fun toString(): String = name
// }
//
// @Serializable
// @JvmInline
// @SerialName("kafkatorio.prototype.id.PrototypeIdEntity")
// value class Entity(override val name: String) : PrototypeId {
// override fun toString(): String = name
// }
//
// @Serializable
// @JvmInline
// @SerialName("kafkatorio.prototype.id.PrototypeIdResourceEntity")
// value class ResourceEntity(override val name: String) : PrototypeId {
// override fun toString(): String = name
// }
//
// @Serializable
// @JvmInline
// @SerialName("kafkatorio.prototype.id.PrototypeIdFluid")
// value class Fluid(override val name: String) : PrototypeId {
// override fun toString(): String = name
// }
//
// @Serializable
// @JvmInline
// @SerialName("kafkatorio.prototype.id.PrototypeIdItem")
// value class Item(override val name: String) : PrototypeId {
// override fun toString(): String = name
// }
//
//}
@Serializable
@JvmInline
@SerialName("kafkatorio.id.PrototypeId")
value class PrototypeId private constructor(
private val typeNameConcat: String,
) {
val type: Type get() = Type(typeNameConcat.substringBefore(delim, ""))
val name: Name get() = Name(typeNameConcat.substringAfter(delim, ""))
operator fun component1(): Type = type
operator fun component2(): Name = name
constructor(
type: String,
name: String,
) : this("${type}${delim}${name}")
/** Denotes the class of the Prototype */
@Serializable
@JvmInline
@SerialName("kafkatorio.id.PrototypeIdType")
value class Type(private val id: String) {
override fun toString(): String = id
}
/** A specific implementation of a [type]. Unique per prototype 'super class' */
@Serializable
@JvmInline
@SerialName("kafkatorio.id.PrototypeIdName")
value class Name(private val name: String) {
override fun toString(): String = name
}
companion object {
private const val delim = '/'
}
}
//@Suppress("unused")
//enum class PrototypeTypeId(
// val id: String
//) {
// AmbientSound("ambient-sound"),
// Animation("animation"),
// EditorController("editor-controller"),
// Font("font"),
// GodController("god-controller"),
// MapGenPresets("map-gen-presets"),
// MapSettings("map-settings"),
// MouseCursor("mouse-cursor"),
// Sound("sound"),
// SpectatorController("spectator-controller"),
// Sprite("sprite"),
// TileEffect("tile-effect"),
// TipsAndTricksItemCategory("tips-and-tricks-item-category"),
// TriggerTargetType("trigger-target-type"),
// WindSound("wind-sound"),
// Achievement("achievement"),
// BuildEntityAchievement("build-entity-achievement"),
// CombatRobotCountAchievement("combat-robot-count"),
// ConstructWithRobotsAchievement("construct-with-robots-achievement"),
// DeconstructWithRobotsAchievement("deconstruct-with-robots-achievement"),
// DeliverByRobotsAchievement("deliver-by-robots-achievement"),
// DontBuildEntityAchievement("dont-build-entity-achievement"),
// DontCraftManuallyAchievement("dont-craft-manually-achievement"),
// DontUseEntityInEnergyProductionAchievement("dont-use-entity-in-energy-production-achievement"),
// FinishTheGameAchievement("finish-the-game-achievement"),
// GroupAttackAchievement("group-attack-achievement"),
// KillAchievement("kill-achievement"),
// PlayerDamagedAchievement("player-damaged-achievement"),
// ProduceAchievement("produce-achievement"),
// ProducePerHourAchievement("produce-per-hour-achievement"),
// ResearchAchievement("research-achievement"),
// TrainPathAchievement("train-path-achievement"),
// AmmoCategory("ammo-category"),
// AutoplaceControl("autoplace-control"),
// CustomInput("custom-input"),
// DamageType("damage-type"),
// Decorative("optimized-decorative"),
// Entity("<abstract>"),
// Arrow("arrow"),
// ArtilleryFlare("artillery-flare"),
// ArtilleryProjectile("artillery-projectile"),
// Beam("beam"),
// CharacterCorpse("character-corpse"),
// Cliff("cliff"),
// Corpse("corpse"),
// RailRemnants("rail-remnants"),
// DeconstructibleTileProxy("deconstructible-tile-proxy"),
// EntityGhost("entity-ghost"),
// /** for migration, cannot be used */
// EntityParticle("particle"),
// /** for migration, cannot be used */
// LeafParticle("leaf-particle"),
// EntityWithHealth("<abstract>"),
// EntityWithOwner("<abstract>"),
// Accumulator("accumulator"),
// ArtilleryTurret("artillery-turret"),
// Beacon("beacon"),
// Boiler("boiler"),
// BurnerGenerator("burner-generator"),
// Character("character"),
// Combinator("<abstract>"),
// ArithmeticCombinator("arithmetic-combinator"),
// DeciderCombinator("decider-combinator"),
// ConstantCombinator("constant-combinator"),
// Container("container"),
// LogisticContainer("logistic-container"),
// InfinityContainer("infinity-container"),
// CraftingMachine("<abstract>"),
// AssemblingMachine("assembling-machine"),
// RocketSilo("rocket-silo"),
// Furnace("furnace"),
// ElectricEnergyInterface("electric-energy-interface"),
// ElectricPole("electric-pole"),
// EnemySpawner("unit-spawner"),
// FlyingRobot("<abstract>"),
// CombatRobot("combat-robot"),
// RobotWithLogisticInterface("<abstract>"),
// ConstructionRobot("construction-robot"),
// LogisticRobot("logistic-robot"),
// Gate("gate"),
// Generator("generator"),
// HeatInterface("heat-interface"),
// HeatPipe("heat-pipe"),
// Inserter("inserter"),
// Lab("lab"),
// Lamp("lamp"),
// LandMine("land-mine"),
// LinkedContainer("linked-container"),
// Market("market"),
// MiningDrill("mining-drill"),
// OffshorePump("offshore-pump"),
// Pipe("pipe"),
// InfinityPipe("infinity-pipe"),
// PipeToGround("pipe-to-ground"),
// PlayerPort("player-port"),
// PowerSwitch("power-switch"),
// ProgrammableSpeaker("programmable-speaker"),
// Pump("pump"),
// Radar("radar"),
// Rail("<abstract>"),
// CurvedRail("curved-rail"),
// StraightRail("straight-rail"),
// RailSignalBase("<abstract>"),
// RailChainSignal("rail-chain-signal"),
// RailSignal("rail-signal"),
// Reactor("reactor"),
// Roboport("roboport"),
// SimpleEntityWithOwner("simple-entity-with-owner"),
// SimpleEntityWithForce("simple-entity-with-force"),
// SolarPanel("solar-panel"),
// StorageTank("storage-tank"),
// TrainStop("train-stop"),
// TransportBeltConnectable("<abstract>"),
// LinkedBelt("linked-belt"),
// Loader1x1("loader-1x1"),
// Loader1x2("loader"),
// Splitter("splitter"),
// TransportBelt("transport-belt"),
// UndergroundBelt("underground-belt"),
// Turret("turret"),
// AmmoTurret("ammo-turret"),
// ElectricTurret("electric-turret"),
// FluidTurret("fluid-turret"),
// Unit("unit"),
// Vehicle("<abstract>"),
// Car("car"),
// RollingStock("<abstract>"),
// ArtilleryWagon("artillery-wagon"),
// CargoWagon("cargo-wagon"),
// FluidWagon("fluid-wagon"),
// Locomotive("locomotive"),
// SpiderVehicle("spider-vehicle"),
// Wall("wall"),
// Fish("fish"),
// SimpleEntity("simple-entity"),
// SpiderLeg("spider-leg"),
// Tree("tree"),
// Explosion("explosion"),
// FlameThrowerExplosion("flame-thrower-explosion"),
// FireFlame("fire"),
// FluidStream("stream"),
// FlyingText("flying-text"),
// HighlightBoxEntity("highlight-box"),
// ItemEntity("item-entity"),
// ItemRequestProxy("item-request-proxy"),
// ParticleSource("particle-source"),
// Projectile("projectile"),
// ResourceEntity("resource"),
// RocketSiloRocket("rocket-silo-rocket"),
// RocketSiloRocketShadow("rocket-silo-rocket-shadow"),
// Smoke("<abstract>"),
// /** for migration, cannot be used */
// SimpleSmoke("smoke"),
// SmokeWithTrigger("smoke-with-trigger"),
// SpeechBubble("speech-bubble"),
// Sticker("sticker"),
// TileGhost("tile-ghost"),
// Equipment("<abstract>"),
// ActiveDefenseEquipment("active-defense-equipment"),
// BatteryEquipment("battery-equipment"),
// BeltImmunityEquipment("belt-immunity-equipment"),
// EnergyShieldEquipment("energy-shield-equipment"),
// GeneratorEquipment("generator-equipment"),
// MovementBonusEquipment("movement-bonus-equipment"),
// NightVisionEquipment("night-vision-equipment"),
// RoboportEquipment("roboport-equipment"),
// SolarPanelEquipment("solar-panel-equipment"),
// EquipmentCategory("equipment-category"),
// EquipmentGrid("equipment-grid"),
// Fluid("fluid"),
// FuelCategory("fuel-category"),
// GuiStyle("gui-style"),
// Item("item"),
// AmmoItem("ammo"),
// Capsule("capsule"),
// Gun("gun"),
// ItemWithEntityData("item-with-entity-data"),
// ItemWithLabel("item-with-label"),
// ItemWithInventory("item-with-inventory"),
// BlueprintBook("blueprint-book"),
// ItemWithTags("item-with-tags"),
// SelectionTool("selection-tool"),
// BlueprintItem("blueprint"),
// CopyPasteTool("copy-paste-tool"),
// DeconstructionItem("deconstruction-item"),
// UpgradeItem("upgrade-item"),
// Module("module"),
// RailPlanner("rail-planner"),
// SpidertronRemote("spidertron-remote"),
// Tool("tool"),
// Armor("armor"),
// /** for migration, cannot be used */
// MiningTool("mining-tool"),
// RepairTool("repair-tool"),
// ItemGroup("item-group"),
// ItemSubGroup("item-subgroup"),
// ModuleCategory("module-category"),
// NamedNoiseExpression("noise-expression"),
// NoiseLayer("noise-layer"),
// Particle("optimized-particle"),
// Recipe("recipe"),
// RecipeCategory("recipe-category"),
// ResourceCategory("resource-category"),
// Shortcut("shortcut"),
// Technology("technology"),
// Tile("tile"),
// TipsAndTricksItem("tips-and-tricks-item"),
// TrivialSmoke("trivial-smoke"),
// Tutorial("tutorial"),
// UtilityConstants("utility-constants"),
// UtilitySounds("utility-sounds"),
// UtilitySprites("utility-sprites"),
// VirtualSignal("virtual-signal"),
// ;
//
// fun named(protoName: String): PrototypeId = PrototypeId(this, protoName)
//
// companion object {
// val entries: Set<PrototypeTypeId> = values().toSet()
// }
//
//}
//@Suppress("unused")
//sealed class PrototypeType(
// val id: String
//) {
//
// object AmbientSound : PrototypeType("ambient-sound")
// object Animation : PrototypeType("animation")
// object EditorController : PrototypeType("editor-controller")
// object Font : PrototypeType("font")
// object GodController : PrototypeType("god-controller")
// object MapGenPresets : PrototypeType("map-gen-presets")
// object MapSettings : PrototypeType("map-settings")
// object MouseCursor : PrototypeType("mouse-cursor")
// object Sound : PrototypeType("sound")
// object SpectatorController : PrototypeType("spectator-controller")
// object Sprite : PrototypeType("sprite")
// object TileEffect : PrototypeType("tile-effect")
// object TipsAndTricksItemCategory : PrototypeType("tips-and-tricks-item-category")
// object TriggerTargetType : PrototypeType("trigger-target-type")
// object WindSound : PrototypeType("wind-sound")
//
//
// object Achievement : PrototypeType("achievement")
// object BuildEntityAchievement : PrototypeType("build-entity-achievement")
// object CombatRobotCountAchievement : PrototypeType("combat-robot-count")
// object ConstructWithRobotsAchievement : PrototypeType("construct-with-robots-achievement")
// object DeconstructWithRobotsAchievement : PrototypeType("deconstruct-with-robots-achievement")
// object DeliverByRobotsAchievement : PrototypeType("deliver-by-robots-achievement")
// object DontBuildEntityAchievement : PrototypeType("dont-build-entity-achievement")
// object DontCraftManuallyAchievement : PrototypeType("dont-craft-manually-achievement")
// object DontUseEntityInEnergyProductionAchievement : PrototypeType("dont-use-entity-in-energy-production-achievement")
//
//
// object FinishTheGameAchievement : PrototypeType("finish-the-game-achievement")
// object GroupAttackAchievement : PrototypeType("group-attack-achievement")
// object KillAchievement : PrototypeType("kill-achievement")
// object PlayerDamagedAchievement : PrototypeType("player-damaged-achievement")
// object ProduceAchievement : PrototypeType("produce-achievement")
// object ProducePerHourAchievement : PrototypeType("produce-per-hour-achievement")
// object ResearchAchievement : PrototypeType("research-achievement")
// object TrainPathAchievement : PrototypeType("train-path-achievement")
// object AmmoCategory : PrototypeType("ammo-category")
// object AutoplaceControl : PrototypeType("autoplace-control")
// object CustomInput : PrototypeType("custom-input")
// object DamageType : PrototypeType("damage-type")
// object Decorative : PrototypeType("optimized-decorative")
//
//
// object Entity : PrototypeType("stract>")
// object Arrow : PrototypeType("arrow")
// object ArtilleryFlare : PrototypeType("artillery-flare")
// object ArtilleryProjectile : PrototypeType("artillery-projectile")
// object Beam : PrototypeType("beam")
// object CharacterCorpse : PrototypeType("character-corpse")
// object Cliff : PrototypeType("cliff")
// object Corpse : PrototypeType("corpse")
// object RailRemnants : PrototypeType("rail-remnants")
// object DeconstructibleTileProxy : PrototypeType("deconstructible-tile-proxy")
// object EntityGhost : PrototypeType("entity-ghost")
// /** for migration, cannot be used */
// object EntityParticle : PrototypeType("particle")
// /** for migration, cannot be used */
// object LeafParticle : PrototypeType("leaf-particle")
//
//
// object EntityWithOwner : PrototypeType("stract>")
// object Accumulator : PrototypeType("accumulator")
// object ArtilleryTurret : PrototypeType("artillery-turret")
// object Beacon : PrototypeType("beacon")
// object Boiler : PrototypeType("boiler")
// object BurnerGenerator : PrototypeType("burner-generator")
// object Character : PrototypeType("character")
//
//
// object Combinator : PrototypeType("stract>")
// object ArithmeticCombinator : PrototypeType("arithmetic-combinator")
// object DeciderCombinator : PrototypeType("decider-combinator")
// object ConstantCombinator : PrototypeType("constant-combinator")
// object Container : PrototypeType("container")
// object LogisticContainer : PrototypeType("logistic-container")
// object InfinityContainer : PrototypeType("infinity-container")
//
//
// object CraftingMachine : PrototypeType("stract>")
// object AssemblingMachine : PrototypeType("assembling-machine")
// object RocketSilo : PrototypeType("rocket-silo")
// object Furnace : PrototypeType("furnace")
// object ElectricEnergyInterface : PrototypeType("electric-energy-interface")
// object ElectricPole : PrototypeType("electric-pole")
// object EnemySpawner : PrototypeType("unit-spawner")
//
//
// object FlyingRobot : PrototypeType("stract>")
// object CombatRobot : PrototypeType("combat-robot") , PrototypeAbstract.FlyingRobot
//
//
// object RobotWithLogisticInterface : PrototypeType("stract>")
// object ConstructionRobot : PrototypeType("construction-robot")
// object LogisticRobot : PrototypeType("logistic-robot")
// object Gate : PrototypeType("gate")
// object Generator : PrototypeType("generator")
// object HeatInterface : PrototypeType("heat-interface")
// object HeatPipe : PrototypeType("heat-pipe")
// object Inserter : PrototypeType("inserter")
// object Lab : PrototypeType("lab")
// object Lamp : PrototypeType("lamp")
// object LandMine : PrototypeType("land-mine")
// object LinkedContainer : PrototypeType("linked-container")
// object Market : PrototypeType("market")
// object MiningDrill : PrototypeType("mining-drill")
// object OffshorePump : PrototypeType("offshore-pump")
// object Pipe : PrototypeType("pipe")
// object InfinityPipe : PrototypeType("infinity-pipe")
// object PipeToGround : PrototypeType("pipe-to-ground")
// object PlayerPort : PrototypeType("player-port")
// object PowerSwitch : PrototypeType("power-switch")
// object ProgrammableSpeaker : PrototypeType("programmable-speaker")
// object Pump : PrototypeType("pump")
// object Radar : PrototypeType("radar")
//
// object CurvedRail : PrototypeType("curved-rail"), PrototypeAbstract.Rail
// object StraightRail : PrototypeType("straight-rail"), PrototypeAbstract.Rail
//
// object RailSignalBase : PrototypeType("stract>")
// object RailChainSignal : PrototypeType("rail-chain-signal")
// object RailSignal : PrototypeType("rail-signal")
// object Reactor : PrototypeType("reactor")
// object Roboport : PrototypeType("roboport")
// object SimpleEntityWithOwner : PrototypeType("simple-entity-with-owner")
// object SimpleEntityWithForce : PrototypeType("simple-entity-with-force")
// object SolarPanel : PrototypeType("solar-panel")
// object StorageTank : PrototypeType("storage-tank")
// object TrainStop : PrototypeType("train-stop")
//
//
// object TransportBeltConnectable : PrototypeType("stract>")
// object LinkedBelt : PrototypeType("linked-belt")
// object Loader1x1 : PrototypeType("loader-1x1")
// object Loader1x2 : PrototypeType("loader")
// object Splitter : PrototypeType("splitter")
// object TransportBelt : PrototypeType("transport-belt")
// object UndergroundBelt : PrototypeType("underground-belt")
// object Turret : PrototypeType("turret")
// object AmmoTurret : PrototypeType("ammo-turret")
// object ElectricTurret : PrototypeType("electric-turret")
// object FluidTurret : PrototypeType("fluid-turret")
// object Unit : PrototypeType("unit")
//
//
// object Car : PrototypeType("car>"), PrototypeAbstract.Vehicle
// object SpiderVehicle : PrototypeType("spider-vehicle"), PrototypeAbstract.Vehicle
//
//
// object ArtilleryWagon : PrototypeType("artillery-wagon"), PrototypeAbstract.RollingStock
// object CargoWagon : PrototypeType("cargo-wagon"), PrototypeAbstract.RollingStock
// object FluidWagon : PrototypeType("fluid-wagon"), PrototypeAbstract.RollingStock
// object Locomotive : PrototypeType("locomotive"), PrototypeAbstract.RollingStock
//
// object Wall : PrototypeType("wall")
//
//
// object Fish : PrototypeType("fish"), PrototypeAbstract.EntityWithHealth
// object SimpleEntity : PrototypeType("simple-entity"), PrototypeAbstract.EntityWithHealth
// object SpiderLeg : PrototypeType("spider-leg"), PrototypeAbstract.EntityWithHealth
// object Tree : PrototypeType("tree"), PrototypeAbstract.EntityWithHealth
//
//
// object Explosion : PrototypeType("explosion"),
// object FlameThrowerExplosion : PrototypeType("flame-thrower-explosion"),
// object FireFlame : PrototypeType("fire"),
// object FluidStream : PrototypeType("stream"),
// object FlyingText : PrototypeType("flying-text"),
// object HighlightBoxEntity : PrototypeType("highlight-box"),
// object ItemEntity : PrototypeType("item-entity"),
// object ItemRequestProxy : PrototypeType("item-request-proxy"),
// object ParticleSource : PrototypeType("particle-source"),
// object Projectile : PrototypeType("projectile"),
// object ResourceEntity : PrototypeType("resource"),
// object RocketSiloRocket : PrototypeType("rocket-silo-rocket"),
// object RocketSiloRocketShadow : PrototypeType("rocket-silo-rocket-shadow"),
//
// /** for migration, cannot be used */
// object SimpleSmoke : PrototypeType("smoke"), PrototypeAbstract.Smoke
// object SmokeWithTrigger : PrototypeType("smoke-with-trigger"), PrototypeAbstract.Smoke
// object SpeechBubble : PrototypeType("speech-bubble"), PrototypeAbstract.Smoke
// object Sticker : PrototypeType("sticker"), PrototypeAbstract.Smoke
// object TileGhost : PrototypeType("tile-ghost"), PrototypeAbstract.Smoke
//
// object Equipment : PrototypeType("abstract>")
// object ActiveDefenseEquipment : PrototypeType("active-defense-equipment")
// object BatteryEquipment : PrototypeType("battery-equipment")
// object BeltImmunityEquipment : PrototypeType("belt-immunity-equipment")
// object EnergyShieldEquipment : PrototypeType("energy-shield-equipment")
// object GeneratorEquipment : PrototypeType("generator-equipment")
// object MovementBonusEquipment : PrototypeType("movement-bonus-equipment")
// object NightVisionEquipment : PrototypeType("night-vision-equipment")
// object RoboportEquipment : PrototypeType("roboport-equipment")
// object SolarPanelEquipment : PrototypeType("solar-panel-equipment")
// object EquipmentCategory : PrototypeType("equipment-category")
// object EquipmentGrid : PrototypeType("equipment-grid")
// object Fluid : PrototypeType("fluid")
// object FuelCategory : PrototypeType("fuel-category")
// object GuiStyle : PrototypeType("gui-style")
// object Item : PrototypeType("item")
// object AmmoItem : PrototypeType("ammo")
// object Capsule : PrototypeType("capsule")
// object Gun : PrototypeType("gun")
// object ItemWithEntityData : PrototypeType("item-with-entity-data")
// object ItemWithLabel : PrototypeType("item-with-label")
// object ItemWithInventory : PrototypeType("item-with-inventory")
// object BlueprintBook : PrototypeType("blueprint-book")
// object ItemWithTags : PrototypeType("item-with-tags")
// object SelectionTool : PrototypeType("selection-tool")
// object BlueprintItem : PrototypeType("blueprint")
// object CopyPasteTool : PrototypeType("copy-paste-tool")
// object DeconstructionItem : PrototypeType("deconstruction-item")
// object UpgradeItem : PrototypeType("upgrade-item")
// object Module : PrototypeType("module")
// object RailPlanner : PrototypeType("rail-planner")
// object SpidertronRemote : PrototypeType("spidertron-remote")
// object Tool : PrototypeType("tool")
// object Armor : PrototypeType("armor")
// /** for migration, cannot be used */
// object MiningTool : PrototypeType("mining-tool")
// object RepairTool : PrototypeType("repair-tool")
// object ItemGroup : PrototypeType("item-group")
// object ItemSubGroup : PrototypeType("item-subgroup")
// object ModuleCategory : PrototypeType("module-category")
// object NamedNoiseExpression : PrototypeType("noise-expression")
// object NoiseLayer : PrototypeType("noise-layer")
// object Particle : PrototypeType("optimized-particle")
// object Recipe : PrototypeType("recipe")
// object RecipeCategory : PrototypeType("recipe-category")
// object ResourceCategory : PrototypeType("resource-category")
// object Shortcut : PrototypeType("shortcut")
// object Technology : PrototypeType("technology")
// object Tile : PrototypeType("tile")
// object TipsAndTricksItem : PrototypeType("tips-and-tricks-item")
// object TrivialSmoke : PrototypeType("trivial-smoke")
// object Tutorial : PrototypeType("tutorial")
// object UtilityConstants : PrototypeType("utility-constants")
// object UtilitySounds : PrototypeType("utility-sounds")
// object UtilitySprites : PrototypeType("utility-sprites")
// object VirtualSignal : PrototypeType("virtual-signal")
//
//}
//
//@Suppress("unused")
//sealed interface PrototypeAbstract {
// //@formatter:off
// sealed interface PrototypeBase : PrototypeAbstract
// sealed interface Entity : PrototypeAbstract
// sealed interface EntityWithHealth : Entity
//
// sealed interface EntityWithOwner : EntityWithHealth
//
// sealed interface Combinator : EntityWithOwner
// sealed interface CraftingMachine : EntityWithOwner
// sealed interface FlyingRobot : EntityWithOwner
//
// sealed interface RobotWithLogisticInterface : FlyingRobot
//
// sealed interface Rail : EntityWithOwner
//
// sealed interface RailSignalBase : EntityWithOwner
// sealed interface TransportBeltConnectable : EntityWithOwner
// sealed interface Vehicle : EntityWithOwner
// sealed interface RollingStock : Vehicle
// sealed interface Smoke : Entity
// sealed interface Equipment : PrototypeAbstract
// //@formatter:on
//}
/*
* [[Prototype/AmbientSound]] '''ambient-sound'''
* [[Prototype/Animation]] '''animation'''
* [[Prototype/EditorController]] '''editor-controller'''
* [[Prototype/Font]] '''font'''
* [[Prototype/GodController]] '''god-controller'''
* [[Prototype/MapGenPresets]] '''map-gen-presets'''
* [[Prototype/MapSettings]] '''map-settings'''
* [[Prototype/MouseCursor]] '''mouse-cursor'''
* [[Prototype/Sound]] '''sound'''
* [[Prototype/SpectatorController]] '''spectator-controller'''
* [[Prototype/Sprite]] '''sprite'''
* [[Prototype/TileEffect]] '''tile-effect'''
* [[Prototype/TipsAndTricksItemCategory]] '''tips-and-tricks-item-category'''
* [[Prototype/TriggerTargetType]] '''trigger-target-type'''
* [[Prototype/WindSound]] '''wind-sound'''
* [[PrototypeBase]] <abstract>
</div><div class="prototype-tree">
* [[Prototype/Achievement]] '''achievement'''
** [[Prototype/BuildEntityAchievement]] '''build-entity-achievement'''
** [[Prototype/CombatRobotCountAchievement]] '''combat-robot-count'''
** [[Prototype/ConstructWithRobotsAchievement]] '''construct-with-robots-achievement'''
** [[Prototype/DeconstructWithRobotsAchievement]] '''deconstruct-with-robots-achievement'''
** [[Prototype/DeliverByRobotsAchievement]] '''deliver-by-robots-achievement'''
** [[Prototype/DontBuildEntityAchievement]] '''dont-build-entity-achievement'''
** [[Prototype/DontCraftManuallyAchievement]] '''dont-craft-manually-achievement'''
** [[Prototype/DontUseEntityInEnergyProductionAchievement]] '''dont-use-entity-in-energy-production-achievement'''
** [[Prototype/FinishTheGameAchievement]] '''finish-the-game-achievement'''
** [[Prototype/GroupAttackAchievement]] '''group-attack-achievement'''
** [[Prototype/KillAchievement]] '''kill-achievement'''
** [[Prototype/PlayerDamagedAchievement]] '''player-damaged-achievement'''
** [[Prototype/ProduceAchievement]] '''produce-achievement'''
** [[Prototype/ProducePerHourAchievement]] '''produce-per-hour-achievement'''
** [[Prototype/ResearchAchievement]] '''research-achievement'''
** [[Prototype/TrainPathAchievement]] '''train-path-achievement'''
* [[Prototype/AmmoCategory]] '''ammo-category'''
* [[Prototype/AutoplaceControl]] '''autoplace-control'''
* [[Prototype/CustomInput]] '''custom-input'''
* [[Prototype/DamageType]] '''damage-type'''
* [[Prototype/Decorative]] '''optimized-decorative'''
* [[Prototype/Entity]] <abstract>
** [[Prototype/Arrow]] '''arrow'''
** [[Prototype/ArtilleryFlare]] '''artillery-flare'''
** [[Prototype/ArtilleryProjectile]] '''artillery-projectile'''
** [[Prototype/Beam]] '''beam'''
** [[Prototype/CharacterCorpse]] '''character-corpse'''
** [[Prototype/Cliff]] '''cliff'''
** [[Prototype/Corpse]] '''corpse'''
*** [[Prototype/RailRemnants]] '''rail-remnants'''
** [[Prototype/DeconstructibleTileProxy]] '''deconstructible-tile-proxy'''
** [[Prototype/EntityGhost]] '''entity-ghost'''
** [[Prototype/EntityParticle]] '''particle''' (for migration, cannot be used)
*** [[Prototype/LeafParticle]] '''leaf-particle''' (for migration, cannot be used)
** [[Prototype/EntityWithHealth]] <abstract>
*** [[Prototype/EntityWithOwner]] <abstract>
**** [[Prototype/Accumulator]] '''accumulator'''
**** [[Prototype/ArtilleryTurret]] '''artillery-turret'''
**** [[Prototype/Beacon]] '''beacon'''
**** [[Prototype/Boiler]] '''boiler'''
**** [[Prototype/BurnerGenerator]] '''burner-generator'''
**** [[Prototype/Character]] '''character'''
**** [[Prototype/Combinator]] <abstract>
***** [[Prototype/ArithmeticCombinator]] '''arithmetic-combinator'''
***** [[Prototype/DeciderCombinator]] '''decider-combinator'''
**** [[Prototype/ConstantCombinator]] '''constant-combinator'''
**** [[Prototype/Container]] '''container'''
***** [[Prototype/LogisticContainer]] '''logistic-container'''
****** [[Prototype/InfinityContainer]] '''infinity-container'''
**** [[Prototype/CraftingMachine]] <abstract>
***** [[Prototype/AssemblingMachine]] '''assembling-machine'''
****** [[Prototype/RocketSilo]] '''rocket-silo'''
***** [[Prototype/Furnace]] '''furnace'''
**** [[Prototype/ElectricEnergyInterface]] '''electric-energy-interface'''
**** [[Prototype/ElectricPole]] '''electric-pole'''
**** [[Prototype/EnemySpawner]] '''unit-spawner'''
**** [[Prototype/FlyingRobot]] <abstract>
***** [[Prototype/CombatRobot]] '''combat-robot'''
***** [[Prototype/RobotWithLogisticInterface]] <abstract>
****** [[Prototype/ConstructionRobot]] '''construction-robot'''
****** [[Prototype/LogisticRobot]] '''logistic-robot'''
**** [[Prototype/Gate]] '''gate'''
**** [[Prototype/Generator]] '''generator'''
**** [[Prototype/HeatInterface]] '''heat-interface'''
**** [[Prototype/HeatPipe]] '''heat-pipe'''
**** [[Prototype/Inserter]] '''inserter'''
**** [[Prototype/Lab]] '''lab'''
**** [[Prototype/Lamp]] '''lamp'''
**** [[Prototype/LandMine]] '''land-mine'''
**** [[Prototype/LinkedContainer]] '''linked-container'''
**** [[Prototype/Market]] '''market'''
**** [[Prototype/MiningDrill]] '''mining-drill'''
**** [[Prototype/OffshorePump]] '''offshore-pump'''
**** [[Prototype/Pipe]] '''pipe'''
***** [[Prototype/InfinityPipe]] '''infinity-pipe'''
**** [[Prototype/PipeToGround]] '''pipe-to-ground'''
**** [[Prototype/PlayerPort]] '''player-port'''
**** [[Prototype/PowerSwitch]] '''power-switch'''
**** [[Prototype/ProgrammableSpeaker]] '''programmable-speaker'''
**** [[Prototype/Pump]] '''pump'''
**** [[Prototype/Radar]] '''radar'''
**** [[Prototype/Rail]] <abstract>
***** [[Prototype/CurvedRail]] '''curved-rail'''
***** [[Prototype/StraightRail]] '''straight-rail'''
**** [[Prototype/RailSignalBase]] <abstract>
***** [[Prototype/RailChainSignal]] '''rail-chain-signal'''
***** [[Prototype/RailSignal]] '''rail-signal'''
**** [[Prototype/Reactor]] '''reactor'''
**** [[Prototype/Roboport]] '''roboport'''
**** [[Prototype/SimpleEntityWithOwner]] '''simple-entity-with-owner'''
***** [[Prototype/SimpleEntityWithForce]] '''simple-entity-with-force'''
**** [[Prototype/SolarPanel]] '''solar-panel'''
**** [[Prototype/StorageTank]] '''storage-tank'''
**** [[Prototype/TrainStop]] '''train-stop'''
**** [[Prototype/TransportBeltConnectable]] <abstract>
***** [[Prototype/LinkedBelt]] '''linked-belt'''
***** [[Prototype/Loader1x1]] '''loader-1x1'''
***** [[Prototype/Loader1x2]] '''loader'''
***** [[Prototype/Splitter]] '''splitter'''
***** [[Prototype/TransportBelt]] '''transport-belt'''
***** [[Prototype/UndergroundBelt]] '''underground-belt'''
**** [[Prototype/Turret]] '''turret'''
***** [[Prototype/AmmoTurret]] '''ammo-turret'''
***** [[Prototype/ElectricTurret]] '''electric-turret'''
***** [[Prototype/FluidTurret]] '''fluid-turret'''
**** [[Prototype/Unit]] '''unit'''
**** [[Prototype/Vehicle]] <abstract>
***** [[Prototype/Car]] '''car'''
***** [[Prototype/RollingStock]] <abstract>
****** [[Prototype/ArtilleryWagon]] '''artillery-wagon'''
****** [[Prototype/CargoWagon]] '''cargo-wagon'''
****** [[Prototype/FluidWagon]] '''fluid-wagon'''
****** [[Prototype/Locomotive]] '''locomotive'''
***** [[Prototype/SpiderVehicle]] '''spider-vehicle'''
**** [[Prototype/Wall]] '''wall'''
*** [[Prototype/Fish]] '''fish'''
*** [[Prototype/SimpleEntity]] '''simple-entity'''
*** [[Prototype/SpiderLeg]] '''spider-leg'''
*** [[Prototype/Tree]] '''tree'''
** [[Prototype/Explosion]] '''explosion'''
*** [[Prototype/FlameThrowerExplosion]] '''flame-thrower-explosion'''
** [[Prototype/FireFlame]] '''fire'''
** [[Prototype/FluidStream]] '''stream'''
** [[Prototype/FlyingText]] '''flying-text'''
** [[Prototype/HighlightBoxEntity]] '''highlight-box'''
** [[Prototype/ItemEntity]] '''item-entity'''
** [[Prototype/ItemRequestProxy]] '''item-request-proxy'''
** [[Prototype/ParticleSource]] '''particle-source'''
** [[Prototype/Projectile]] '''projectile'''
** [[Prototype/ResourceEntity]] '''resource'''
** [[Prototype/RocketSiloRocket]] '''rocket-silo-rocket'''
** [[Prototype/RocketSiloRocketShadow]] '''rocket-silo-rocket-shadow'''
** [[Prototype/Smoke]] <abstract>
*** [[Prototype/SimpleSmoke]] '''smoke''' (for migration, cannot be used)
*** [[Prototype/SmokeWithTrigger]] '''smoke-with-trigger'''
** [[Prototype/SpeechBubble]] '''speech-bubble'''
** [[Prototype/Sticker]] '''sticker'''
** [[Prototype/TileGhost]] '''tile-ghost'''
* [[Prototype/Equipment]] <abstract>
** [[Prototype/ActiveDefenseEquipment]] '''active-defense-equipment'''
** [[Prototype/BatteryEquipment]] '''battery-equipment'''
** [[Prototype/BeltImmunityEquipment]] '''belt-immunity-equipment'''
** [[Prototype/EnergyShieldEquipment]] '''energy-shield-equipment'''
** [[Prototype/GeneratorEquipment]] '''generator-equipment'''
** [[Prototype/MovementBonusEquipment]] '''movement-bonus-equipment'''
** [[Prototype/NightVisionEquipment]] '''night-vision-equipment'''
** [[Prototype/RoboportEquipment]] '''roboport-equipment'''
** [[Prototype/SolarPanelEquipment]] '''solar-panel-equipment'''
* [[Prototype/EquipmentCategory]] '''equipment-category'''
* [[Prototype/EquipmentGrid]] '''equipment-grid'''
* [[Prototype/Fluid]] '''fluid'''
* [[Prototype/FuelCategory]] '''fuel-category'''
* [[Prototype/GuiStyle]] '''gui-style'''
* [[Prototype/Item]] '''item'''
** [[Prototype/AmmoItem]] '''ammo'''
** [[Prototype/Capsule]] '''capsule'''
** [[Prototype/Gun]] '''gun'''
** [[Prototype/ItemWithEntityData]] '''item-with-entity-data'''
** [[Prototype/ItemWithLabel]] '''item-with-label'''
*** [[Prototype/ItemWithInventory]] '''item-with-inventory'''
**** [[Prototype/BlueprintBook]] '''blueprint-book'''
*** [[Prototype/ItemWithTags]] '''item-with-tags'''
*** [[Prototype/SelectionTool]] '''selection-tool'''
**** [[Prototype/BlueprintItem]] '''blueprint'''
**** [[Prototype/CopyPasteTool]] '''copy-paste-tool'''
**** [[Prototype/DeconstructionItem]] '''deconstruction-item'''
**** [[Prototype/UpgradeItem]] '''upgrade-item'''
** [[Prototype/Module]] '''module'''
** [[Prototype/RailPlanner]] '''rail-planner'''
** [[Prototype/SpidertronRemote]] '''spidertron-remote'''
** [[Prototype/Tool]] '''tool'''
*** [[Prototype/Armor]] '''armor'''
*** [[Prototype/MiningTool]] '''mining-tool''' (for migration, cannot be used)
*** [[Prototype/RepairTool]] '''repair-tool'''
* [[Prototype/ItemGroup]] '''item-group'''
* [[Prototype/ItemSubGroup]] '''item-subgroup'''
* [[Prototype/ModuleCategory]] '''module-category'''
* [[Prototype/NamedNoiseExpression]] '''noise-expression'''
* [[Prototype/NoiseLayer]] '''noise-layer'''
* [[Prototype/Particle]] '''optimized-particle'''
* [[Prototype/Recipe]] '''recipe'''
* [[Prototype/RecipeCategory]] '''recipe-category'''
* [[Prototype/ResourceCategory]] '''resource-category'''
* [[Prototype/Shortcut]] '''shortcut'''
* [[Prototype/Technology]] '''technology'''
* [[Prototype/Tile]] '''tile'''
* [[Prototype/TipsAndTricksItem]] '''tips-and-tricks-item'''
* [[Prototype/TrivialSmoke]] '''trivial-smoke'''
* [[Prototype/Tutorial]] '''tutorial'''
* [[Prototype/UtilityConstants]] '''utility-constants'''
* [[Prototype/UtilitySounds]] '''utility-sounds'''
* [[Prototype/UtilitySprites]] '''utility-sprites'''
* [[Prototype/VirtualSignal]] '''virtual-signal'''
*/

View file

@ -6,16 +6,11 @@ import kotlinx.serialization.Serializable
@Serializable
@SerialName("kafkatorio.resource.MinedProduct")
data class MinedProduct(
/** `item` or `fluid`. */
val type: Type,
sealed interface MinedProduct {
/** Prototype name of the result. */
@SerialName("name")
val resultPrototype: PrototypeName,
//Amount of the item or fluid to give. If not specified, amount_min, amount_max and probability must all be specified.
val amount: Double?,
val resultProtoId: PrototypeId
//Amount of the item or fluid to give. If not specified, amount_min, amount_max and probability must all be specified.
val amount: Double?
//Minimal amount of the item or fluid to give. Has no effect when amount is specified.
//amount_min : Uint or double?,
@ -26,17 +21,24 @@ data class MinedProduct(
//A value in range [0, 1]. Item or fluid is only given with this probability; otherwise no product is produced.
//probability : Double?,
//How much of this product is a catalyst.
//How much of this product is a catalyst.
//catalyst_amount : Uint or double?,
) {
@Serializable
@SerialName("kafkatorio.resource.MinedProductType")
enum class Type {
@SerialName("item")
ITEM,
@SerialName("fluid")
FLUID,
}
@SerialName("kafkatorio.resource.MinedProduct.MinedProductFluid")
data class Fluid(
override val amount: Double? = null,
override val resultProtoId: PrototypeId,
) : MinedProduct
@Serializable
@SerialName("kafkatorio.resource.MinedProduct.MinedProductItem")
data class Item(
override val amount: Double? = null,
override val resultProtoId: PrototypeId,
) : MinedProduct
}

View file

@ -4,12 +4,13 @@ import dev.adamko.kafkatorio.schema.common.Colour
import dev.adamko.kafkatorio.schema.common.EntityIdentifiers
import dev.adamko.kafkatorio.schema.common.EntityIdentifiersData
import dev.adamko.kafkatorio.schema.common.EventName
import dev.adamko.kafkatorio.schema.common.FactorioEntityData
import dev.adamko.kafkatorio.schema.common.ForceIndex
import dev.adamko.kafkatorio.schema.common.MapChunkPosition
import dev.adamko.kafkatorio.schema.common.MapEntityPosition
import dev.adamko.kafkatorio.schema.common.MapTileDictionary
import dev.adamko.kafkatorio.schema.common.PlayerIndex
import dev.adamko.kafkatorio.schema.common.PrototypeName
import dev.adamko.kafkatorio.schema.common.PrototypeId
import dev.adamko.kafkatorio.schema.common.SurfaceIndex
import dev.adamko.kafkatorio.schema.common.Tick
import dev.adamko.kafkatorio.schema.common.UnitNumber
@ -23,6 +24,8 @@ import kotlinx.serialization.Serializable
sealed class KafkatorioKeyedPacketData : KafkatorioPacketData() {
abstract val key: KafkatorioKeyedPacketKey
/** A list of all events that have been aggregated into this packet. */
// Maybe change to be Map<EventName, Tick>, where Tick is the most recent event?
// A complete event timeline isn't necessary. The most recent tick of an event is good enough, and requires less space.
abstract val events: Map<EventName, List<Tick>>?
}
@ -40,8 +43,7 @@ sealed class KafkatorioKeyedPacketKey
data class EntityUpdateKey(
/** While normally optional, here a [unitNumber] is required for caching */
override val unitNumber: UnitNumber,
override val name: String,
override val protoType: String,
override val protoId: PrototypeId,
) : EntityIdentifiers, KafkatorioKeyedPacketKey()
@ -60,7 +62,6 @@ data class EntityUpdate(
val lastUser: UInt? = null,
val localisedDescription: String? = null,
val localisedName: String? = null,
val prototype: PrototypeName? = null,
) : KafkatorioKeyedPacketData()
@ -68,17 +69,18 @@ data class EntityUpdate(
@Serializable
@SerialName("kafkatorio.packet.keyed.MapChunkUpdateKey")
data class MapChunkUpdateKey(
@SerialName("kafkatorio.packet.keyed.MapChunkTileUpdateKey")
data class MapChunkTileUpdateKey(
// val index: PlayerIndex, // maybe add player/robot key, to allow metrics like 'player x mined y tiles'
val chunkPosition: MapChunkPosition,
val surfaceIndex: SurfaceIndex,
) : KafkatorioKeyedPacketKey()
@Serializable
@SerialName("kafkatorio.packet.keyed.MapChunkUpdate")
data class MapChunkUpdate(
override val key: MapChunkUpdateKey,
@SerialName("kafkatorio.packet.keyed.MapChunkTileUpdate")
data class MapChunkTileUpdate(
override val key: MapChunkTileUpdateKey,
override val events: Map<EventName, List<Tick>>? = null,
@ -93,6 +95,7 @@ data class MapChunkUpdate(
/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
@Serializable
@SerialName("kafkatorio.packet.keyed.PlayerUpdateKey")
data class PlayerUpdateKey(
@ -134,4 +137,32 @@ data class PlayerUpdate(
) : KafkatorioKeyedPacketData()
/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
@Serializable
@SerialName("kafkatorio.packet.keyed.MapChunkEntityUpdateKey")
data class MapChunkEntityUpdateKey(
val protoId: PrototypeId,
val surfaceIndex: SurfaceIndex,
val chunkPosition: MapChunkPosition,
) : KafkatorioKeyedPacketKey()
/**
* @property[distinctEntities] Distinct entities. The key is arbitrary and is only used
* for de-duplicating updates. It should only contain data that can be obtained from
* [the value][FactorioEntityData].
*/
@Serializable
@SerialName("kafkatorio.packet.keyed.MapChunkEntityUpdate")
data class MapChunkEntityUpdate(
override val key: MapChunkEntityUpdateKey,
override val events: Map<EventName, List<Tick>>? = null,
val distinctEntities: Map<String, FactorioEntityData>? = null,
) : KafkatorioKeyedPacketData()
/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */

View file

@ -4,12 +4,12 @@ import dev.adamko.kafkatorio.library.jsonMapperKafkatorio
import dev.adamko.kafkatorio.schema.common.EventName
import dev.adamko.kafkatorio.schema.common.MapChunkPosition
import dev.adamko.kafkatorio.schema.common.MapTileDictionary
import dev.adamko.kafkatorio.schema.common.PrototypeName
import dev.adamko.kafkatorio.schema.common.PrototypeId
import dev.adamko.kafkatorio.schema.common.SurfaceIndex
import dev.adamko.kafkatorio.schema.common.tick
import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket
import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate
import dev.adamko.kafkatorio.schema.packets.MapChunkUpdateKey
import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdate
import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdateKey
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import kotlinx.serialization.decodeFromString
@ -59,8 +59,8 @@ class MapChunkUpdateTest : FunSpec({
val expected = KafkatorioPacket(
tick = 36u.tick,
modVersion = "0.4.0",
data = MapChunkUpdate(
key = MapChunkUpdateKey(
data = MapChunkTileUpdate(
key = MapChunkTileUpdateKey(
MapChunkPosition(-6, -3),
SurfaceIndex(1u),
),
@ -78,9 +78,9 @@ class MapChunkUpdateTest : FunSpec({
),
),
protos = mapOf(
PrototypeName("water") to MapTileDictionary.PrototypeKey(1),
PrototypeName("grass-4") to MapTileDictionary.PrototypeKey(2),
PrototypeName("grass-3") to MapTileDictionary.PrototypeKey(32),
PrototypeId("tile", "water") to MapTileDictionary.PrototypeKey(1),
PrototypeId("tile", "grass-4") to MapTileDictionary.PrototypeKey(2),
PrototypeId("tile", "grass-3") to MapTileDictionary.PrototypeKey(32),
)
)
)

View file

@ -3,7 +3,7 @@ package dev.adamko.kafkatorio.events.schema
import dev.adamko.kafkatorio.library.jsonMapperKafkatorio
import dev.adamko.kafkatorio.schema.common.Colour
import dev.adamko.kafkatorio.schema.common.FactorioPrototype
import dev.adamko.kafkatorio.schema.common.PrototypeName
import dev.adamko.kafkatorio.schema.common.PrototypeId
import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket
import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate
import io.kotest.core.spec.style.BehaviorSpec
@ -12,6 +12,7 @@ import io.kotest.matchers.shouldBe
import io.kotest.matchers.types.shouldBeInstanceOf
import kotlinx.serialization.decodeFromString
class PrototypesTest : BehaviorSpec({
Given("Prototypes Json") {
// language=JSON
@ -669,7 +670,7 @@ class PrototypesTest : BehaviorSpec({
.prototypes
.forOne {
it.shouldBeInstanceOf<FactorioPrototype.MapTile>()
it.name shouldBe PrototypeName("tutorial-grid")
it.protoId shouldBe PrototypeId.MapTile("tutorial-grid")
it.order shouldBe "z[other]-c[tutorial]-a[tutorial-grid]"
it.layer shouldBe 55u
it.collisionMasks shouldBe listOf("ground-tile")

View file

@ -7,6 +7,7 @@ import dev.adamko.kafkatorio.schema.common.EventName
import dev.adamko.kafkatorio.schema.common.ForceIndex
import dev.adamko.kafkatorio.schema.common.MapEntityPosition
import dev.adamko.kafkatorio.schema.common.PlayerIndex
import dev.adamko.kafkatorio.schema.common.PrototypeId
import dev.adamko.kafkatorio.schema.common.SurfaceIndex
import dev.adamko.kafkatorio.schema.common.Tick
import dev.adamko.kafkatorio.schema.common.UnitNumber
@ -190,8 +191,7 @@ class UpdatePacketsTest : FunSpec({
colour = null,
diedCause = EntityIdentifiersData(
unitNumber = UnitNumber(66u),
name = "small-biter",
protoType = "unit",
protoId = PrototypeId("unit/small-biter"),
),
disconnectReason = null,
events = mapOf(

View file

@ -20,22 +20,22 @@ class MapTileDictionaryTest : FunSpec({
"44" to mapOf("1" to MapTileDictionary.PrototypeKey(44)),
),
protos = mapOf(
PrototypeName("water") to MapTileDictionary.PrototypeKey(1),
PrototypeName("grass-4") to MapTileDictionary.PrototypeKey(2),
PrototypeName("grass-3") to MapTileDictionary.PrototypeKey(32),
PrototypeId.MapTile("water") to MapTileDictionary.PrototypeKey(1),
PrototypeId.MapTile("grass-4") to MapTileDictionary.PrototypeKey(2),
PrototypeId.MapTile("grass-3") to MapTileDictionary.PrototypeKey(32),
PrototypeName("not-used") to MapTileDictionary.PrototypeKey(99),
PrototypeId.MapTile("not-used") to MapTileDictionary.PrototypeKey(99),
)
)
test("toMapTileList") {
actual.toMapTileList() shouldContainAll listOf(
MapTile(-192, -65, PrototypeName("grass-4")),
MapTile(-192, -65, PrototypeId.MapTile("grass-4")),
MapTile(161, -96, PrototypeName("water")),
MapTile(161, -95, PrototypeName("grass-4")),
MapTile(161, 94, PrototypeName("grass-4")),
MapTile(161, 93, PrototypeName("grass-3")),
MapTile(161, -96, PrototypeId.MapTile("water")),
MapTile(161, -95, PrototypeId.MapTile("grass-4")),
MapTile(161, 94, PrototypeId.MapTile("grass-4")),
MapTile(161, 93, PrototypeId.MapTile("grass-3")),
)
}
}

View file

@ -1,11 +1,16 @@
package dev.adamko.kafkatorio.events.schema
import dev.adamko.kafkatorio.schema.common.PlayerIndex
import dev.adamko.kafkatorio.schema.common.SurfaceIndex
import dev.adamko.kafkatorio.schema.common.UnitNumber
import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket
import dev.adamko.kxstsgen.KxsTsConfig
import dev.adamko.kxstsgen.KxsTsConfig.TypeAliasTypingConfig.BrandTyping
import dev.adamko.kxstsgen.KxsTsGenerator
import dev.adamko.kxstsgen.core.TsDeclaration.TsTypeAlias
import dev.adamko.kxstsgen.core.TsElementId
import dev.adamko.kxstsgen.core.TsLiteral
import dev.adamko.kxstsgen.core.TsSourceCodeGenerator
import dev.adamko.kxstsgen.core.TsTypeRef
import kotlin.io.path.Path
import kotlin.io.path.createDirectories
@ -13,14 +18,24 @@ import kotlinx.serialization.builtins.serializer
import org.intellij.lang.annotations.Language
@ExperimentalUnsignedTypes
fun main(args: Array<String>) {
val config = KxsTsConfig(
// typeAliasTyping = BrandTyping
typeAliasTyping = BrandTyping
)
val gen2 = KxsTsGenerator(config)
val gen2 = KxsTsGenerator(
config = config,
sourceCodeGenerator = MySourceCodeGenerator(config),
)
// gen2.serializerDescriptorOverrides += mapOf(
////@formatter:off
// SurfaceIndex.serializer() to emptySet(),
// PlayerIndex.serializer() to emptySet(),
// UnitNumber.serializer() to emptySet(),
////@formatter:on
// )
gen2.descriptorOverrides += mapOf(
//@formatter:off
@ -32,6 +47,10 @@ fun main(args: Array<String>) {
UByte .serializer().descriptor to TsTypeAlias(TsElementId("kotlin.UByte" ), TsTypeRef.Literal(TsLiteral.Custom("uint8" ), false)),
UShort.serializer().descriptor to TsTypeAlias(TsElementId("kotlin.UShort"), TsTypeRef.Literal(TsLiteral.Custom("uint16"), false)),
ULong .serializer().descriptor to TsTypeAlias(TsElementId("kotlin.ULong" ), TsTypeRef.Literal(TsLiteral.Custom("uint64"), false)),
PlayerIndex.serializer().descriptor to TsTypeAlias(TsElementId("PlayerIndex" ), TsTypeRef.Literal(TsLiteral.Custom("PlayerIndex"), false)),
SurfaceIndex.serializer().descriptor to TsTypeAlias(TsElementId("SurfaceIndex" ), TsTypeRef.Literal(TsLiteral.Custom("SurfaceIndex"), false)),
UnitNumber.serializer().descriptor to TsTypeAlias(TsElementId("UnitNumber" ), TsTypeRef.Literal(TsLiteral.Custom("UnitNumber"), false)),
//@formatter:on
)
@ -60,3 +79,26 @@ val kt2tsHeader = """
|// Generated by kxs-ts-gen - do not edit this file manually
|
""".trimMargin()
class MySourceCodeGenerator(
config: KxsTsConfig,
) : TsSourceCodeGenerator.Default(config) {
override fun generateTypeAlias(element: TsTypeAlias): String {
return if (element.id.name in listOf("PlayerIndex", "SurfaceIndex", "UnitNumber")) {
""
} else if (
(element.typeRef as? TsTypeRef.Literal)?.element is TsLiteral.Custom
|| element.id.name == "Tick"
) {
val aliasedRef = generateTypeReference(element.typeRef)
"""
|export type ${element.id.name} = ${aliasedRef};
""".trimMargin()
} else {
super.generateTypeAlias(element)
}
}
}