Add ship faction flavors (these will be useful for the campaign)
authorTheSaminator <TheSaminator@users.noreply.github.com>
Wed, 15 Jun 2022 16:52:24 +0000 (12:52 -0400)
committerTheSaminator <TheSaminator@users.noreply.github.com>
Wed, 15 Jun 2022 16:52:24 +0000 (12:52 -0400)
59 files changed:
src/commonMain/kotlin/net/starshipfights/game/ai/ai_optimization.kt
src/commonMain/kotlin/net/starshipfights/game/ship.kt
src/commonMain/kotlin/net/starshipfights/game/ship_faction_flavors.kt [new file with mode: 0644]
src/jsMain/kotlin/externals/threejs/UniformsUtils.module_three.kt
src/jsMain/kotlin/net/starshipfights/game/game_render.kt
src/jsMain/kotlin/net/starshipfights/game/game_resources.kt
src/jsMain/kotlin/net/starshipfights/game/ship_faction_flavors_js.kt [new file with mode: 0644]
src/jsMain/resources/meshes/fulkreykk-1-gannan-class.diff.png
src/jsMain/resources/meshes/fulkreykk-1-gannan-class.spec.png
src/jsMain/resources/meshes/fulkreykk-1-lodovik-class.diff.png
src/jsMain/resources/meshes/fulkreykk-1-lodovik-class.spec.png
src/jsMain/resources/meshes/fulkreykk-2-karnas-class.diff.png
src/jsMain/resources/meshes/fulkreykk-2-karnas-class.spec.png
src/jsMain/resources/meshes/fulkreykk-2-pertona-class.diff.png
src/jsMain/resources/meshes/fulkreykk-2-pertona-class.spec.png
src/jsMain/resources/meshes/fulkreykk-2-voss-class.diff.png
src/jsMain/resources/meshes/fulkreykk-2-voss-class.spec.png
src/jsMain/resources/meshes/fulkreykk-3-brekoryn-class.diff.png
src/jsMain/resources/meshes/fulkreykk-3-brekoryn-class.spec.png
src/jsMain/resources/meshes/fulkreykk-3-falk-class.diff.png
src/jsMain/resources/meshes/fulkreykk-3-falk-class.spec.png
src/jsMain/resources/meshes/fulkreykk-3-lorus-class.diff.png
src/jsMain/resources/meshes/fulkreykk-3-lorus-class.spec.png
src/jsMain/resources/meshes/fulkreykk-3-orsh-class.diff.png
src/jsMain/resources/meshes/fulkreykk-3-orsh-class.spec.png
src/jsMain/resources/meshes/fulkreykk-3-tefran-class.diff.png
src/jsMain/resources/meshes/fulkreykk-3-tefran-class.spec.png
src/jsMain/resources/meshes/fulkreykk-4-kassck-class.diff.png
src/jsMain/resources/meshes/fulkreykk-4-kassck-class.spec.png
src/jsMain/resources/meshes/fulkreykk-4-khorr-class.diff.png
src/jsMain/resources/meshes/fulkreykk-4-khorr-class.spec.png
src/jsMain/resources/meshes/usa-1-coleman-class.diff.png
src/jsMain/resources/meshes/usa-1-coleman-class.spec.png
src/jsMain/resources/meshes/usa-1-jefferson-class.diff.png
src/jsMain/resources/meshes/usa-1-jefferson-class.spec.png
src/jsMain/resources/meshes/usa-1-quenney-class.diff.png
src/jsMain/resources/meshes/usa-1-quenney-class.spec.png
src/jsMain/resources/meshes/usa-1-roosevelt-class.diff.png
src/jsMain/resources/meshes/usa-1-roosevelt-class.spec.png
src/jsMain/resources/meshes/usa-1-washington-class.diff.png
src/jsMain/resources/meshes/usa-1-washington-class.spec.png
src/jsMain/resources/meshes/usa-3-arlington-class.diff.png
src/jsMain/resources/meshes/usa-3-arlington-class.spec.png
src/jsMain/resources/meshes/usa-3-concord-class.diff.png
src/jsMain/resources/meshes/usa-3-concord-class.spec.png
src/jsMain/resources/meshes/usa-3-lexington-class.diff.png
src/jsMain/resources/meshes/usa-3-lexington-class.spec.png
src/jsMain/resources/meshes/usa-3-raven-rock-class.diff.png
src/jsMain/resources/meshes/usa-3-raven-rock-class.spec.png
src/jsMain/resources/meshes/usa-5-iowa-class.diff.png
src/jsMain/resources/meshes/usa-5-iowa-class.spec.png
src/jsMain/resources/meshes/usa-5-maryland-class.diff.png
src/jsMain/resources/meshes/usa-5-maryland-class.spec.png
src/jsMain/resources/meshes/usa-5-new-york-class.diff.png
src/jsMain/resources/meshes/usa-5-new-york-class.spec.png
src/jsMain/resources/meshes/usa-5-ohio-class.diff.png
src/jsMain/resources/meshes/usa-5-ohio-class.spec.png
src/jvmMain/kotlin/net/starshipfights/data/admiralty/admirals.kt
src/jvmMain/kotlin/net/starshipfights/game/game_start_jvm.kt

index 37b07173dc6e0c8e6fed51cb5f44d7cb49ec3b84..60aea4e40ecedba4ebad9824e6fdc92e00a56c80 100644 (file)
@@ -174,10 +174,12 @@ fun generateFleet(faction: Faction, rank: AdmiralRank, side: GlobalSide): Map<Id
                var shipCount = 0
                shipTypes.map { st ->
                        val name = "${side}_${++shipCount}"
+                       val flavor = FactionFlavor.defaultForFaction(faction)
                        Ship(
                                id = Id(name),
                                name = name,
                                shipType = st,
+                               shipFlavor = flavor
                        )
                }.associateBy { it.id }
        }
index a1eaf9ba638071100e275fd27ae4b5644783c175..85ef04fe77fc9d6522eba02fdb9ac14d93d87ddf 100644 (file)
@@ -9,7 +9,8 @@ data class Ship(
        val id: Id<Ship>,
        
        val name: String,
-       val shipType: ShipType
+       val shipType: ShipType,
+       val shipFlavor: FactionFlavor
 ) {
        val fullName: String
                get() = "${shipType.faction.shipPrefix}$name"
diff --git a/src/commonMain/kotlin/net/starshipfights/game/ship_faction_flavors.kt b/src/commonMain/kotlin/net/starshipfights/game/ship_faction_flavors.kt
new file mode 100644 (file)
index 0000000..7daeee6
--- /dev/null
@@ -0,0 +1,89 @@
+package net.starshipfights.game
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class IntColor(val red: Int, val green: Int, val blue: Int) {
+       init {
+               require(red in 0..255) { "Invalid RGB value: red = $red" }
+               require(green in 0..255) { "Invalid RGB value: green = $green" }
+               require(blue in 0..255) { "Invalid RGB value: blue = $blue" }
+       }
+       
+       override fun toString(): String {
+               val redHex = red.toString(16).padStart(2, '0')
+               val greenHex = green.toString(16).padStart(2, '0')
+               val blueHex = blue.toString(16).padStart(2, '0')
+               
+               return "#$redHex$greenHex$blueHex"
+       }
+}
+
+val IntColor.highlight: IntColor
+       get() = let { (r, g, b) ->
+               IntColor(
+                       255 - (255 - r) * 2 / 3,
+                       255 - (255 - g) * 2 / 3,
+                       255 - (255 - b) * 2 / 3,
+               )
+       }
+
+val Faction.trimColor: IntColor?
+       get() = when (this) {
+               Faction.MECHYRDIA -> IntColor(255, 204, 51)
+               Faction.NDRC -> IntColor(255, 153, 51)
+               Faction.MASRA_DRAETSEN -> IntColor(34, 85, 170)
+               Faction.FELINAE_FELICES -> IntColor(255, 119, 187)
+               Faction.ISARNAREYKK -> null
+               Faction.VESTIGIUM -> IntColor(108, 96, 153)
+       }
+
+enum class FactionFlavor(val nativeName: String?, val translatedName: String, val colorReplacement: IntColor) {
+       MECHYRDIA("Štelflót Ciarstuos Mehurdiasi", "Imperial Star Fleet of Mechyrdia", IntColor(255, 204, 51)),
+       TYLA("Helasram Laevashtam Moashtas Tulasras", "Stellar Navy of the Tylan Republic", IntColor(51, 102, 204)),
+       OLYMPIA("Classis Nautica Rei Publicae Olympicae", "Naval Fleet of the Olympia Commonwealth", IntColor(204, 51, 51)),
+       TEXANDRIA("Texandrische Sternenmarine der Volkswehr", "Texandrian Star Navy of the Public Defense", IntColor(255, 221, 119)),
+       
+       NDRC("Sterrenvloot der NdRC", "NdRC Stellar Fleet", IntColor(255, 153, 51)),
+       CCC("Collegium Comitatum Caeleste", "Celestial Caravan Company", IntColor(255, 204, 51)),
+       MJOLNIR_ENERGY("Mjolniri Energia", "Mjölnir Energy", IntColor(34, 68, 136)),
+       
+       MASRA_DRAETSEN(null, "Diadochus Masra Draetsen", IntColor(34, 85, 170)),
+       AEDON_CULTISTS(null, "Aedon Cultists", IntColor(136, 68, 204)),
+       FERTHLON_EXILES(null, "Ferthlon Exiles", IntColor(51, 204, 68)),
+       
+       RES_NOSTRA(null, "Res Nostra", IntColor(153, 17, 85)),
+       CORSAIRS(null, "Corsairs' Commune", IntColor(34, 34, 34)),
+       FELINAE_FELICES(null, "Felinae Felices", IntColor(255, 119, 187)),
+       
+       ISARNAREYKK(null, "Isarnareyksk Federation", IntColor(255, 255, 255)),
+       SWARTAREYKK(null, "Swartareyksk Totalitariat", IntColor(255, 170, 170)),
+       THEUDAREYKK(null, "Theudareyksk Kingdom", IntColor(153, 204, 255)),
+       STAHLAREYKK(null, "Stahlareyksk Binding", IntColor(204, 153, 102)),
+       LYUDAREYKK(null, "Lyudareyksk Baurginassus", IntColor(153, 204, 153)),
+       NEUIA_FULKREYKK(null, "Neuia Fulkreykk Rebellion", IntColor(153, 153, 153)),
+       
+       CORVUS_CLUSTER_VESTIGIUM(null, "Vestigium Sect in the Corvus Cluster", IntColor(108, 96, 153)),
+       COLEMAN_SF_BASE_VESTIGIUM(null, "Vestigium Sect at Coleman Space Force Base", IntColor(153, 102, 102)),
+       ;
+       
+       companion object {
+               fun defaultForFaction(playerFaction: Faction): FactionFlavor = when (playerFaction) {
+                       Faction.MECHYRDIA -> MECHYRDIA
+                       Faction.NDRC -> NDRC
+                       Faction.MASRA_DRAETSEN -> MASRA_DRAETSEN
+                       Faction.FELINAE_FELICES -> FELINAE_FELICES
+                       Faction.ISARNAREYKK -> ISARNAREYKK
+                       Faction.VESTIGIUM -> CORVUS_CLUSTER_VESTIGIUM
+               }
+               
+               fun optionsForAiEnemy(computerFaction: Faction): Set<FactionFlavor> = when (computerFaction) {
+                       Faction.MECHYRDIA -> setOf(MECHYRDIA, TYLA, OLYMPIA, TEXANDRIA, NDRC, CORSAIRS, RES_NOSTRA)
+                       Faction.NDRC -> setOf(NDRC, CCC, MJOLNIR_ENERGY, RES_NOSTRA, CORSAIRS)
+                       Faction.MASRA_DRAETSEN -> setOf(MASRA_DRAETSEN, AEDON_CULTISTS, FERTHLON_EXILES)
+                       Faction.FELINAE_FELICES -> setOf(FELINAE_FELICES, RES_NOSTRA, CORSAIRS)
+                       Faction.ISARNAREYKK -> setOf(ISARNAREYKK, SWARTAREYKK, THEUDAREYKK, STAHLAREYKK, LYUDAREYKK, NEUIA_FULKREYKK)
+                       Faction.VESTIGIUM -> setOf(CORVUS_CLUSTER_VESTIGIUM, COLEMAN_SF_BASE_VESTIGIUM)
+               }
+       }
+}
index d845a292724b6848095b7237f38ae910c111187e..62aa3bd6d103c24b3a1bd8970a3a8333b0a34924 100644 (file)
@@ -3,6 +3,7 @@
 
 package externals.threejs
 
-external fun cloneUniforms(uniforms_src: Any): Any
-
-external fun mergeUniforms(uniforms: Array<Any>): Any
+external object UniformsUtils {
+       fun clone(uniforms_src: Any): Any
+       fun merge(uniforms: Array<Any>): Any
+}
index d0ff67f8a62d62d28eb455ce16ca56054ce55393..306ebab84b82e459b3ec140023850693f4abe731 100644 (file)
@@ -1,8 +1,11 @@
 package net.starshipfights.game
 
 import externals.threejs.*
+import net.starshipfights.data.Id
 
 object GameRender {
+       private val shipMeshCache = mutableMapOf<Id<ShipInstance>, Mesh>()
+       
        fun renderGameState(scene: Scene, state: GameState) {
                scene.background = RenderResources.spaceboxes.getValue(state.battleInfo.bg)
                scene.getObjectByName("light")?.removeFromParent()
@@ -16,7 +19,10 @@ object GameRender {
                        when (state.renderShipAs(ship, mySide)) {
                                ShipRenderMode.NONE -> {}
                                ShipRenderMode.SIGNAL -> shipGroup.add(RenderResources.enemySignal.generate(ship.position.location))
-                               ShipRenderMode.FULL -> shipGroup.add(RenderResources.shipMesh.generate(ship))
+                               ShipRenderMode.FULL -> shipGroup.add(shipMeshCache[ship.id]?.also { render ->
+                                       RenderScaling.toWorldRotation(ship.position.facing, render)
+                                       render.position.copy(RenderScaling.toWorldPosition(ship.position.location))
+                               } ?: RenderResources.shipMesh.generate(ship))
                        }
                }
        }
@@ -27,7 +33,7 @@ object RenderScaling {
        const val METERS_PER_3D_MESH_UNIT = 6.9
        
        fun toWorldRotation(facing: Double, obj: Object3D) {
-               obj.rotateY(-facing)
+               obj.rotation.y = -facing
        }
        
        fun toBattleLength(length3js: Double) = length3js * METERS_PER_THREEJS_UNIT
index 0d73b67e9af2f7ccb5dc423f874d75e7135468cd..908df1c9582ecd892ee59d73c592b499f9be0db7 100644 (file)
@@ -249,6 +249,8 @@ object RenderResources {
                                        outlineRed.material = redOutlineMaterial
                                        
                                        CustomRenderFactory { ship ->
+                                               val faction = ship.ship.shipType.faction
+                                               val flavor = ship.ship.shipFlavor
                                                val side = ship.owner.relativeTo(mySide)
                                                
                                                ShipRender(
@@ -257,6 +259,7 @@ object RenderResources {
                                                        mesh.clone(true).unsafeCast<Mesh>().apply {
                                                                receiveShadow = true
                                                                castShadow = true
+                                                               material = material.unsafeCast<MeshPhongMaterial>().forShip(faction, flavor)
                                                        },
                                                        when (side) {
                                                                LocalSide.GREEN -> outlineGreen
diff --git a/src/jsMain/kotlin/net/starshipfights/game/ship_faction_flavors_js.kt b/src/jsMain/kotlin/net/starshipfights/game/ship_faction_flavors_js.kt
new file mode 100644 (file)
index 0000000..0c4bbc7
--- /dev/null
@@ -0,0 +1,169 @@
+package net.starshipfights.game
+
+import externals.threejs.*
+
+fun IntColor.to3JS() = Color(this.toString())
+
+private val black = Color("#000000")
+private val white = Color("#FFFFFF")
+
+private val shipShaderMaterial: ShaderMaterial by lazy {
+       val customFragmentShader = """
+               |#define PHONG
+               |
+               |uniform vec3 diffuse;
+               |uniform vec3 emissive;
+               |uniform vec3 specular;
+               |uniform float shininess;
+               |uniform float opacity;
+               |
+               |#include <common>
+               |#include <packing>
+               |#include <dithering_pars_fragment>
+               |#include <color_pars_fragment>
+               |#include <uv_pars_fragment>
+               |#include <uv2_pars_fragment>
+               |#include <map_pars_fragment>
+               |#include <alphamap_pars_fragment>
+               |#include <alphatest_pars_fragment>
+               |#include <aomap_pars_fragment>
+               |#include <lightmap_pars_fragment>
+               |#include <emissivemap_pars_fragment>
+               |#include <envmap_common_pars_fragment>
+               |#include <envmap_pars_fragment>
+               |#include <cube_uv_reflection_fragment>
+               |#include <fog_pars_fragment>
+               |#include <bsdfs>
+               |#include <lights_pars_begin>
+               |#include <normal_pars_fragment>
+               |#include <lights_phong_pars_fragment>
+               |#include <shadowmap_pars_fragment>
+               |#include <bumpmap_pars_fragment>
+               |#include <normalmap_pars_fragment>
+               |#include <specularmap_pars_fragment>
+               |#include <logdepthbuf_pars_fragment>
+               |#include <clipping_planes_pars_fragment>
+               |
+               |uniform vec3 oldColorDiff;
+               |uniform vec3 oldColorSpec;
+               |uniform vec3 newColorDiff;
+               |uniform vec3 newColorSpec;
+               |uniform vec3 tintColor;
+               |
+               |// Add the mapTexelToLinear function manually
+               |vec4 mapTexelToLinear( vec4 value ) {
+               |       return LinearToLinear( value );
+               |}
+               |
+               |void main() {
+               |       #include <clipping_planes_fragment>
+               |
+               |       vec4 diffuseColor = vec4( diffuse, opacity );
+               |       ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
+               |       vec3 totalEmissiveRadiance = emissive;
+               |
+               |       #include <logdepthbuf_fragment>
+               |
+               |       // Replaces the include of map_fragment
+               |#ifdef USE_MAP
+               |       vec4 texelColor = texture2D( map, vUv );
+               |       if (texelColor.rgb == oldColorDiff) {
+               |               texelColor = vec4(newColorDiff, texelColor.a);
+               |       }
+               |       texelColor = mapTexelToLinear( texelColor );
+               |       diffuseColor *= texelColor;
+               |#endif
+               |
+               |       #include <color_fragment>
+               |       #include <alphamap_fragment>
+               |       #include <alphatest_fragment>
+               |
+               |       // Replaces the include of specularmap_fragment
+               |       vec3 specularStrength;
+               |#ifdef USE_SPECULARMAP
+               |       vec4 texelSpecular = texture2D( specularMap, vUv );
+               |       if (texelSpecular.rgb == oldColorSpec) {
+               |               texelSpecular = vec4(oldColorSpec, texelSpecular.a);
+               |       }
+               |       specularStrength = texelSpecular.rgb;
+               |#else
+               |       specularStrength = vec3( 1.0, 1.0, 1.0 );
+               |#endif
+               |
+               |       #include <normal_fragment_begin>
+               |       #include <normal_fragment_maps>
+               |       #include <emissivemap_fragment>
+               |
+               |       // accumulation
+               |       #include <lights_phong_fragment>
+               |       #include <lights_fragment_begin>
+               |       #include <lights_fragment_maps>
+               |       #include <lights_fragment_end>
+               |
+               |       // modulation
+               |       #include <aomap_fragment>
+               |       vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;
+               |
+               |       #include <envmap_fragment>
+               |       #include <output_fragment>
+               |
+               |       // Inserted custom code
+               |       gl_FragColor = vec4(gl_FragColor.rgb * tintColor, gl_FragColor.a);
+               |       // End of custom code
+               |
+               |       #include <tonemapping_fragment>
+               |       #include <encodings_fragment>
+               |       #include <fog_fragment>
+               |       #include <premultiplied_alpha_fragment>
+               |       #include <dithering_fragment>
+               |}
+       """.trimMargin()
+       
+       ShaderMaterial(
+               configure {
+                       uniforms = UniformsUtils.merge(
+                               arrayOf(
+                                       ShaderLib.phong.uniforms,
+                                       configure<AnonymousStruct8> {
+                                               this["oldColorDiff"] = configure { value = black }
+                                               this["oldColorSpec"] = configure { value = black }
+                                               this["newColorDiff"] = configure { value = black }
+                                               this["newColorSpec"] = configure { value = black }
+                                               this["tintColor"] = configure { value = white }
+                                       }
+                               )
+                       ).unsafeCast<AnonymousStruct8>()
+                       defines = configure<StringDict<Any>> {
+                               this["USE_UV"] = ""
+                               this["USE_MAP"] = ""
+                               this["USE_SPECULARMAP"] = ""
+                       }
+                       vertexShader = ShaderLib.phong.vertexShader
+                       fragmentShader = customFragmentShader
+                       lights = true
+               }
+       )
+}
+
+fun MeshPhongMaterial.forShip(faction: Faction, flavor: FactionFlavor): ShaderMaterial {
+       return shipShaderMaterial.clone().unsafeCast<ShaderMaterial>().also { material ->
+               material.uniforms["diffuse"]?.value?.unsafeCast<Color>()?.copy(color)
+               material.uniforms["specular"]?.value?.unsafeCast<Color>()?.copy(specular)
+               material.uniforms["shininess"]?.value = shininess.toDouble().coerceAtLeast(EPSILON)
+               
+               map?.let { material.uniforms["map"]?.value = it }
+               specularMap?.let { material.uniforms["specularMap"]?.value = it }
+               
+               faction.trimColor?.let { oldColorDiff ->
+                       val newColorDiff = flavor.colorReplacement
+                       
+                       val oldColorSpec = oldColorDiff.highlight
+                       val newColorSpec = newColorDiff.highlight
+                       
+                       material.uniforms["oldColorDiff"]?.value?.unsafeCast<Color>()?.copy(oldColorDiff.to3JS())
+                       material.uniforms["oldColorSpec"]?.value?.unsafeCast<Color>()?.copy(oldColorSpec.to3JS())
+                       material.uniforms["newColorDiff"]?.value?.unsafeCast<Color>()?.copy(newColorDiff.to3JS())
+                       material.uniforms["newColorSpec"]?.value?.unsafeCast<Color>()?.copy(newColorSpec.to3JS())
+               } ?: material.uniforms["tintColor"]?.value?.unsafeCast<Color>()?.copy(flavor.colorReplacement.to3JS())
+       }
+}
index 89a96a9290ad56b0a5cd26772d888460751363c3..7122902848b80a2324eab97b27955f3516c01255 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-1-gannan-class.diff.png and b/src/jsMain/resources/meshes/fulkreykk-1-gannan-class.diff.png differ
index ba419154dd8d8dfb10a833a26e78b9b2bf7f78fa..02d329763c082e2beac144abbdab7c8ab3714b8c 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-1-gannan-class.spec.png and b/src/jsMain/resources/meshes/fulkreykk-1-gannan-class.spec.png differ
index 3e9589488cd23c7fe09fedf8e61e8f3e4c453754..db5d130eabcf1aa1f1329cca943857b21d4ffa4c 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-1-lodovik-class.diff.png and b/src/jsMain/resources/meshes/fulkreykk-1-lodovik-class.diff.png differ
index 621e4bd2318d20ca2ed279d1cf36d2f9bf10f9e4..a9a204177b071ecb8161b7d60d22ae2e18bf7fec 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-1-lodovik-class.spec.png and b/src/jsMain/resources/meshes/fulkreykk-1-lodovik-class.spec.png differ
index 522b9ce6fc7735a45b399358c3bfbae14d3b7b8b..8c6cf1ee0fd57565cf332a93c87f497ac6b5924f 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-2-karnas-class.diff.png and b/src/jsMain/resources/meshes/fulkreykk-2-karnas-class.diff.png differ
index 754c1051f3fa0189c68139dc633f2eb3507029ef..b25ae7bed7f67812329f22bbcef1c1a8743335cb 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-2-karnas-class.spec.png and b/src/jsMain/resources/meshes/fulkreykk-2-karnas-class.spec.png differ
index 522b9ce6fc7735a45b399358c3bfbae14d3b7b8b..8c6cf1ee0fd57565cf332a93c87f497ac6b5924f 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-2-pertona-class.diff.png and b/src/jsMain/resources/meshes/fulkreykk-2-pertona-class.diff.png differ
index 754c1051f3fa0189c68139dc633f2eb3507029ef..b25ae7bed7f67812329f22bbcef1c1a8743335cb 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-2-pertona-class.spec.png and b/src/jsMain/resources/meshes/fulkreykk-2-pertona-class.spec.png differ
index e6865b38d6c734ee993c8e809606b65ff7217ee7..fc5c53eadaee31a2db9ae91bee99cd14f3c5bc72 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-2-voss-class.diff.png and b/src/jsMain/resources/meshes/fulkreykk-2-voss-class.diff.png differ
index 31b52423802bbbd30ffe2d1a8f55b25941b14ff6..fb61f01309acfb1852068042aa11fe3f8f2ddc68 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-2-voss-class.spec.png and b/src/jsMain/resources/meshes/fulkreykk-2-voss-class.spec.png differ
index 522b9ce6fc7735a45b399358c3bfbae14d3b7b8b..8c6cf1ee0fd57565cf332a93c87f497ac6b5924f 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-3-brekoryn-class.diff.png and b/src/jsMain/resources/meshes/fulkreykk-3-brekoryn-class.diff.png differ
index 754c1051f3fa0189c68139dc633f2eb3507029ef..b25ae7bed7f67812329f22bbcef1c1a8743335cb 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-3-brekoryn-class.spec.png and b/src/jsMain/resources/meshes/fulkreykk-3-brekoryn-class.spec.png differ
index 522b9ce6fc7735a45b399358c3bfbae14d3b7b8b..8c6cf1ee0fd57565cf332a93c87f497ac6b5924f 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-3-falk-class.diff.png and b/src/jsMain/resources/meshes/fulkreykk-3-falk-class.diff.png differ
index 754c1051f3fa0189c68139dc633f2eb3507029ef..b25ae7bed7f67812329f22bbcef1c1a8743335cb 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-3-falk-class.spec.png and b/src/jsMain/resources/meshes/fulkreykk-3-falk-class.spec.png differ
index 522b9ce6fc7735a45b399358c3bfbae14d3b7b8b..8c6cf1ee0fd57565cf332a93c87f497ac6b5924f 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-3-lorus-class.diff.png and b/src/jsMain/resources/meshes/fulkreykk-3-lorus-class.diff.png differ
index 754c1051f3fa0189c68139dc633f2eb3507029ef..b25ae7bed7f67812329f22bbcef1c1a8743335cb 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-3-lorus-class.spec.png and b/src/jsMain/resources/meshes/fulkreykk-3-lorus-class.spec.png differ
index e6865b38d6c734ee993c8e809606b65ff7217ee7..fc5c53eadaee31a2db9ae91bee99cd14f3c5bc72 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-3-orsh-class.diff.png and b/src/jsMain/resources/meshes/fulkreykk-3-orsh-class.diff.png differ
index 31b52423802bbbd30ffe2d1a8f55b25941b14ff6..fb61f01309acfb1852068042aa11fe3f8f2ddc68 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-3-orsh-class.spec.png and b/src/jsMain/resources/meshes/fulkreykk-3-orsh-class.spec.png differ
index 522b9ce6fc7735a45b399358c3bfbae14d3b7b8b..8c6cf1ee0fd57565cf332a93c87f497ac6b5924f 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-3-tefran-class.diff.png and b/src/jsMain/resources/meshes/fulkreykk-3-tefran-class.diff.png differ
index 754c1051f3fa0189c68139dc633f2eb3507029ef..b25ae7bed7f67812329f22bbcef1c1a8743335cb 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-3-tefran-class.spec.png and b/src/jsMain/resources/meshes/fulkreykk-3-tefran-class.spec.png differ
index 522b9ce6fc7735a45b399358c3bfbae14d3b7b8b..8c6cf1ee0fd57565cf332a93c87f497ac6b5924f 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-4-kassck-class.diff.png and b/src/jsMain/resources/meshes/fulkreykk-4-kassck-class.diff.png differ
index 754c1051f3fa0189c68139dc633f2eb3507029ef..b25ae7bed7f67812329f22bbcef1c1a8743335cb 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-4-kassck-class.spec.png and b/src/jsMain/resources/meshes/fulkreykk-4-kassck-class.spec.png differ
index 522b9ce6fc7735a45b399358c3bfbae14d3b7b8b..8c6cf1ee0fd57565cf332a93c87f497ac6b5924f 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-4-khorr-class.diff.png and b/src/jsMain/resources/meshes/fulkreykk-4-khorr-class.diff.png differ
index 754c1051f3fa0189c68139dc633f2eb3507029ef..b25ae7bed7f67812329f22bbcef1c1a8743335cb 100644 (file)
Binary files a/src/jsMain/resources/meshes/fulkreykk-4-khorr-class.spec.png and b/src/jsMain/resources/meshes/fulkreykk-4-khorr-class.spec.png differ
index f6e42f10c4e01a54e7b9d0ade8cc38d6626d2d89..4fce63f01007f780a32f596853188648b8a7a485 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-1-coleman-class.diff.png and b/src/jsMain/resources/meshes/usa-1-coleman-class.diff.png differ
index bc531418dc404fba7972739ed72080542aba95d4..2940bffd7db215944832b63619c972de4bda645f 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-1-coleman-class.spec.png and b/src/jsMain/resources/meshes/usa-1-coleman-class.spec.png differ
index f6e42f10c4e01a54e7b9d0ade8cc38d6626d2d89..4fce63f01007f780a32f596853188648b8a7a485 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-1-jefferson-class.diff.png and b/src/jsMain/resources/meshes/usa-1-jefferson-class.diff.png differ
index bc531418dc404fba7972739ed72080542aba95d4..2940bffd7db215944832b63619c972de4bda645f 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-1-jefferson-class.spec.png and b/src/jsMain/resources/meshes/usa-1-jefferson-class.spec.png differ
index f6e42f10c4e01a54e7b9d0ade8cc38d6626d2d89..4fce63f01007f780a32f596853188648b8a7a485 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-1-quenney-class.diff.png and b/src/jsMain/resources/meshes/usa-1-quenney-class.diff.png differ
index bc531418dc404fba7972739ed72080542aba95d4..2940bffd7db215944832b63619c972de4bda645f 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-1-quenney-class.spec.png and b/src/jsMain/resources/meshes/usa-1-quenney-class.spec.png differ
index f6e42f10c4e01a54e7b9d0ade8cc38d6626d2d89..4fce63f01007f780a32f596853188648b8a7a485 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-1-roosevelt-class.diff.png and b/src/jsMain/resources/meshes/usa-1-roosevelt-class.diff.png differ
index bc531418dc404fba7972739ed72080542aba95d4..2940bffd7db215944832b63619c972de4bda645f 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-1-roosevelt-class.spec.png and b/src/jsMain/resources/meshes/usa-1-roosevelt-class.spec.png differ
index f6e42f10c4e01a54e7b9d0ade8cc38d6626d2d89..4fce63f01007f780a32f596853188648b8a7a485 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-1-washington-class.diff.png and b/src/jsMain/resources/meshes/usa-1-washington-class.diff.png differ
index bc531418dc404fba7972739ed72080542aba95d4..2940bffd7db215944832b63619c972de4bda645f 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-1-washington-class.spec.png and b/src/jsMain/resources/meshes/usa-1-washington-class.spec.png differ
index f6e42f10c4e01a54e7b9d0ade8cc38d6626d2d89..4fce63f01007f780a32f596853188648b8a7a485 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-3-arlington-class.diff.png and b/src/jsMain/resources/meshes/usa-3-arlington-class.diff.png differ
index bc531418dc404fba7972739ed72080542aba95d4..2940bffd7db215944832b63619c972de4bda645f 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-3-arlington-class.spec.png and b/src/jsMain/resources/meshes/usa-3-arlington-class.spec.png differ
index f6e42f10c4e01a54e7b9d0ade8cc38d6626d2d89..4fce63f01007f780a32f596853188648b8a7a485 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-3-concord-class.diff.png and b/src/jsMain/resources/meshes/usa-3-concord-class.diff.png differ
index bc531418dc404fba7972739ed72080542aba95d4..2940bffd7db215944832b63619c972de4bda645f 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-3-concord-class.spec.png and b/src/jsMain/resources/meshes/usa-3-concord-class.spec.png differ
index f6e42f10c4e01a54e7b9d0ade8cc38d6626d2d89..4fce63f01007f780a32f596853188648b8a7a485 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-3-lexington-class.diff.png and b/src/jsMain/resources/meshes/usa-3-lexington-class.diff.png differ
index bc531418dc404fba7972739ed72080542aba95d4..2940bffd7db215944832b63619c972de4bda645f 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-3-lexington-class.spec.png and b/src/jsMain/resources/meshes/usa-3-lexington-class.spec.png differ
index f6e42f10c4e01a54e7b9d0ade8cc38d6626d2d89..4fce63f01007f780a32f596853188648b8a7a485 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-3-raven-rock-class.diff.png and b/src/jsMain/resources/meshes/usa-3-raven-rock-class.diff.png differ
index bc531418dc404fba7972739ed72080542aba95d4..2940bffd7db215944832b63619c972de4bda645f 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-3-raven-rock-class.spec.png and b/src/jsMain/resources/meshes/usa-3-raven-rock-class.spec.png differ
index f6e42f10c4e01a54e7b9d0ade8cc38d6626d2d89..4fce63f01007f780a32f596853188648b8a7a485 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-5-iowa-class.diff.png and b/src/jsMain/resources/meshes/usa-5-iowa-class.diff.png differ
index bc531418dc404fba7972739ed72080542aba95d4..2940bffd7db215944832b63619c972de4bda645f 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-5-iowa-class.spec.png and b/src/jsMain/resources/meshes/usa-5-iowa-class.spec.png differ
index f6e42f10c4e01a54e7b9d0ade8cc38d6626d2d89..4fce63f01007f780a32f596853188648b8a7a485 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-5-maryland-class.diff.png and b/src/jsMain/resources/meshes/usa-5-maryland-class.diff.png differ
index bc531418dc404fba7972739ed72080542aba95d4..2940bffd7db215944832b63619c972de4bda645f 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-5-maryland-class.spec.png and b/src/jsMain/resources/meshes/usa-5-maryland-class.spec.png differ
index f6e42f10c4e01a54e7b9d0ade8cc38d6626d2d89..4fce63f01007f780a32f596853188648b8a7a485 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-5-new-york-class.diff.png and b/src/jsMain/resources/meshes/usa-5-new-york-class.diff.png differ
index bc531418dc404fba7972739ed72080542aba95d4..2940bffd7db215944832b63619c972de4bda645f 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-5-new-york-class.spec.png and b/src/jsMain/resources/meshes/usa-5-new-york-class.spec.png differ
index f6e42f10c4e01a54e7b9d0ade8cc38d6626d2d89..4fce63f01007f780a32f596853188648b8a7a485 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-5-ohio-class.diff.png and b/src/jsMain/resources/meshes/usa-5-ohio-class.diff.png differ
index bc531418dc404fba7972739ed72080542aba95d4..2940bffd7db215944832b63619c972de4bda645f 100644 (file)
Binary files a/src/jsMain/resources/meshes/usa-5-ohio-class.spec.png and b/src/jsMain/resources/meshes/usa-5-ohio-class.spec.png differ
index ae3a2480a4a5fa94c1e5ca715d0413e692b8e56e..01f3be2af0f2462fc04912dbad204c2511363c5d 100644 (file)
@@ -67,11 +67,12 @@ data class ShipInDrydock(
        override val id: Id<ShipInDrydock> = Id(),
        val name: String,
        val shipType: ShipType,
+       val shipFlavor: FactionFlavor = FactionFlavor.defaultForFaction(shipType.faction),
        val readyAt: @Contextual Instant,
        val owningAdmiral: Id<Admiral>
 ) : DataDocument<ShipInDrydock> {
        val shipData: Ship
-               get() = Ship(id.reinterpret(), name, shipType)
+               get() = Ship(id.reinterpret(), name, shipType, shipFlavor)
        
        val fullName: String
                get() = shipData.fullName
@@ -132,7 +133,7 @@ suspend fun getAdmiralsShips(admiralId: Id<Admiral>): Map<Id<Ship>, Ship> {
                .associate { it.shipData.id to it.shipData }
 }
 
-fun generateFleet(admiral: Admiral): List<ShipInDrydock> = ShipWeightClass.values()
+fun generateFleet(admiral: Admiral, flavor: FactionFlavor = FactionFlavor.defaultForFaction(admiral.faction)): List<ShipInDrydock> = ShipWeightClass.values()
        .flatMap { swc ->
                val shipTypes = ShipType.values().filter { st ->
                        st.weightClass == swc && st.faction == admiral.faction
@@ -155,6 +156,7 @@ fun generateFleet(admiral: Admiral): List<ShipInDrydock> = ShipWeightClass.value
                                        id = Id(),
                                        name = name,
                                        shipType = st,
+                                       shipFlavor = flavor,
                                        readyAt = now,
                                        owningAdmiral = admiral.id
                                )
index a6d573338c79c249ba5fe020c8e34fc509e32622..89c84b48a217c468388e29ca3e7c80de5162bc5b 100644 (file)
@@ -47,6 +47,7 @@ suspend fun generateTrainingInitialState(playerInfo: InGameAdmiral, enemyFaction
        val guestDeployCenter = Position(Vec2(0.0, (battleLength / 2) - deployLength2))
        
        val aiAdmiral = genAI(enemyFaction, battleInfo.size)
+       val aiFlavor = FactionFlavor.optionsForAiEnemy(enemyFaction).random()
        
        return GameState(
                start = GameStart(
@@ -66,7 +67,7 @@ suspend fun generateTrainingInitialState(playerInfo: InGameAdmiral, enemyFaction
                                -PI / 2,
                                PickBoundary.Rectangle(guestDeployCenter, deployWidth2, deployLength2),
                                -PI / 2,
-                               generateFleet(aiAdmiral)
+                               generateFleet(aiAdmiral, aiFlavor)
                                        .associate { it.shipData.id to it.shipData }
                                        .filterValues { it.shipType.weightClass.tier <= battleInfo.size.maxTier }
                        )