SkyParameters are now finally generated

This commit is contained in:
DBotThePony 2024-04-04 10:50:46 +07:00
parent 55253f78d1
commit cb384be77a
Signed by: DBot
GPG Key ID: DCC23B5715498507
27 changed files with 548 additions and 235 deletions

View File

@ -12,6 +12,9 @@ import ru.dbotthepony.kstarbound.defs.actor.player.PlayerConfig
import ru.dbotthepony.kstarbound.defs.tile.TileDamageConfig import ru.dbotthepony.kstarbound.defs.tile.TileDamageConfig
import ru.dbotthepony.kstarbound.defs.world.TerrestrialWorldsConfig import ru.dbotthepony.kstarbound.defs.world.TerrestrialWorldsConfig
import ru.dbotthepony.kstarbound.defs.world.AsteroidWorldsConfig import ru.dbotthepony.kstarbound.defs.world.AsteroidWorldsConfig
import ru.dbotthepony.kstarbound.defs.world.CelestialBaseInformation
import ru.dbotthepony.kstarbound.defs.world.CelestialConfig
import ru.dbotthepony.kstarbound.defs.world.CelestialNames
import ru.dbotthepony.kstarbound.defs.world.DungeonWorldsConfig import ru.dbotthepony.kstarbound.defs.world.DungeonWorldsConfig
import ru.dbotthepony.kstarbound.defs.world.SkyGlobalConfig import ru.dbotthepony.kstarbound.defs.world.SkyGlobalConfig
import ru.dbotthepony.kstarbound.defs.world.SystemWorldConfig import ru.dbotthepony.kstarbound.defs.world.SystemWorldConfig
@ -24,7 +27,7 @@ import java.util.concurrent.Future
import kotlin.properties.Delegates import kotlin.properties.Delegates
import kotlin.reflect.KMutableProperty0 import kotlin.reflect.KMutableProperty0
object GlobalDefaults { object Globals {
private val LOGGER = LogManager.getLogger() private val LOGGER = LogManager.getLogger()
var player by Delegates.notNull<PlayerConfig>() var player by Delegates.notNull<PlayerConfig>()
@ -78,6 +81,15 @@ object GlobalDefaults {
var systemWorld by Delegates.notNull<SystemWorldConfig>() var systemWorld by Delegates.notNull<SystemWorldConfig>()
private set private set
var celestialBaseInformation by Delegates.notNull<CelestialBaseInformation>()
private set
var celestialConfig by Delegates.notNull<CelestialConfig>()
private set
var celestialNames by Delegates.notNull<CelestialNames>()
private set
private object EmptyTask : ForkJoinTask<Unit>() { private object EmptyTask : ForkJoinTask<Unit>() {
private fun readResolve(): Any = EmptyTask private fun readResolve(): Any = EmptyTask
override fun getRawResult() { override fun getRawResult() {
@ -128,6 +140,9 @@ object GlobalDefaults {
tasks.add(load("/universe_server.config", ::universeServer)) tasks.add(load("/universe_server.config", ::universeServer))
tasks.add(load("/player.config", ::player)) tasks.add(load("/player.config", ::player))
tasks.add(load("/systemworld.config", ::systemWorld)) tasks.add(load("/systemworld.config", ::systemWorld))
tasks.add(load("/celestial.config", ::celestialBaseInformation))
tasks.add(load("/celestial.config", ::celestialConfig))
tasks.add(load("/celestial/names.config", ::celestialNames))
tasks.add(load("/plants/grassDamage.config", ::grassDamage)) tasks.add(load("/plants/grassDamage.config", ::grassDamage))
tasks.add(load("/plants/treeDamage.config", ::treeDamage)) tasks.add(load("/plants/treeDamage.config", ::treeDamage))

View File

@ -24,17 +24,13 @@ import ru.dbotthepony.kommons.gson.Vector4iTypeAdapter
import ru.dbotthepony.kommons.util.MailboxExecutorService import ru.dbotthepony.kommons.util.MailboxExecutorService
import ru.dbotthepony.kstarbound.collect.WeightedList import ru.dbotthepony.kstarbound.collect.WeightedList
import ru.dbotthepony.kstarbound.defs.* import ru.dbotthepony.kstarbound.defs.*
import ru.dbotthepony.kstarbound.defs.actor.StatModifier
import ru.dbotthepony.kstarbound.defs.image.Image import ru.dbotthepony.kstarbound.defs.image.Image
import ru.dbotthepony.kstarbound.defs.image.SpriteReference import ru.dbotthepony.kstarbound.defs.image.SpriteReference
import ru.dbotthepony.kstarbound.defs.item.api.IArmorItemDefinition import ru.dbotthepony.kstarbound.defs.item.api.IArmorItemDefinition
import ru.dbotthepony.kstarbound.defs.item.InventoryIcon import ru.dbotthepony.kstarbound.defs.item.InventoryIcon
import ru.dbotthepony.kstarbound.defs.item.TreasurePoolDefinition import ru.dbotthepony.kstarbound.defs.item.TreasurePoolDefinition
import ru.dbotthepony.kstarbound.defs.`object`.ObjectDefinition
import ru.dbotthepony.kstarbound.defs.`object`.ObjectOrientation
import ru.dbotthepony.kstarbound.defs.actor.player.BlueprintLearnList import ru.dbotthepony.kstarbound.defs.actor.player.BlueprintLearnList
import ru.dbotthepony.kstarbound.defs.animation.Particle import ru.dbotthepony.kstarbound.defs.animation.Particle
import ru.dbotthepony.kstarbound.defs.item.ItemDescriptor
import ru.dbotthepony.kstarbound.defs.quest.QuestParameter import ru.dbotthepony.kstarbound.defs.quest.QuestParameter
import ru.dbotthepony.kstarbound.defs.world.CelestialParameters import ru.dbotthepony.kstarbound.defs.world.CelestialParameters
import ru.dbotthepony.kstarbound.defs.world.VisitableWorldParametersType import ru.dbotthepony.kstarbound.defs.world.VisitableWorldParametersType
@ -57,7 +53,6 @@ import ru.dbotthepony.kstarbound.json.factory.ImmutableCollectionAdapterFactory
import ru.dbotthepony.kstarbound.json.factory.PairAdapterFactory import ru.dbotthepony.kstarbound.json.factory.PairAdapterFactory
import ru.dbotthepony.kstarbound.json.factory.RGBAColorTypeAdapter import ru.dbotthepony.kstarbound.json.factory.RGBAColorTypeAdapter
import ru.dbotthepony.kstarbound.json.factory.SingletonTypeAdapterFactory import ru.dbotthepony.kstarbound.json.factory.SingletonTypeAdapterFactory
import ru.dbotthepony.kstarbound.math.*
import ru.dbotthepony.kstarbound.server.world.UniverseChunk import ru.dbotthepony.kstarbound.server.world.UniverseChunk
import ru.dbotthepony.kstarbound.item.ItemStack import ru.dbotthepony.kstarbound.item.ItemStack
import ru.dbotthepony.kstarbound.json.JsonAdapterTypeFactory import ru.dbotthepony.kstarbound.json.JsonAdapterTypeFactory
@ -68,7 +63,6 @@ import ru.dbotthepony.kstarbound.util.ExceptionLogger
import ru.dbotthepony.kstarbound.util.SBPattern import ru.dbotthepony.kstarbound.util.SBPattern
import ru.dbotthepony.kstarbound.util.HashTableInterner import ru.dbotthepony.kstarbound.util.HashTableInterner
import ru.dbotthepony.kstarbound.util.random.AbstractPerlinNoise import ru.dbotthepony.kstarbound.util.random.AbstractPerlinNoise
import ru.dbotthepony.kstarbound.world.UniversePos
import ru.dbotthepony.kstarbound.world.physics.Poly import ru.dbotthepony.kstarbound.world.physics.Poly
import java.io.* import java.io.*
import java.lang.ref.Cleaner import java.lang.ref.Cleaner
@ -571,7 +565,7 @@ object Starbound : ISBFileLocator {
tasks.addAll(Registries.load(ext2files)) tasks.addAll(Registries.load(ext2files))
tasks.addAll(RecipeRegistry.load(ext2files)) tasks.addAll(RecipeRegistry.load(ext2files))
tasks.addAll(GlobalDefaults.load()) tasks.addAll(Globals.load())
tasks.add(VersionRegistry.load()) tasks.add(VersionRegistry.load())
val total = tasks.size.toDouble() val total = tasks.size.toDouble()

View File

@ -3,7 +3,7 @@ package ru.dbotthepony.kstarbound.defs.tile
import com.google.common.collect.ImmutableList import com.google.common.collect.ImmutableList
import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.kommons.util.Either import ru.dbotthepony.kommons.util.Either
import ru.dbotthepony.kstarbound.GlobalDefaults import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.defs.AssetReference import ru.dbotthepony.kstarbound.defs.AssetReference
import ru.dbotthepony.kstarbound.world.physics.CollisionType import ru.dbotthepony.kstarbound.world.physics.CollisionType
import ru.dbotthepony.kstarbound.defs.IThingWithDescription import ru.dbotthepony.kstarbound.defs.IThingWithDescription
@ -27,7 +27,7 @@ data class TileDefinition(
val category: String, val category: String,
@Deprecated("", replaceWith = ReplaceWith("this.actualDamageTable")) @Deprecated("", replaceWith = ReplaceWith("this.actualDamageTable"))
val damageTable: AssetReference<TileDamageConfig> = AssetReference(GlobalDefaults::tileDamage), val damageTable: AssetReference<TileDamageConfig> = AssetReference(Globals::tileDamage),
val health: Double? = null, val health: Double? = null,
val requiredHarvestLevel: Int? = null, val requiredHarvestLevel: Int? = null,

View File

@ -1,7 +1,7 @@
package ru.dbotthepony.kstarbound.defs.tile package ru.dbotthepony.kstarbound.defs.tile
import com.google.common.collect.ImmutableList import com.google.common.collect.ImmutableList
import ru.dbotthepony.kstarbound.GlobalDefaults import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.defs.AssetReference import ru.dbotthepony.kstarbound.defs.AssetReference
import ru.dbotthepony.kstarbound.defs.IThingWithDescription import ru.dbotthepony.kstarbound.defs.IThingWithDescription
import ru.dbotthepony.kstarbound.defs.ThingDescription import ru.dbotthepony.kstarbound.defs.ThingDescription
@ -23,7 +23,7 @@ data class TileModifierDefinition(
val miningSounds: ImmutableList<String> = ImmutableList.of(), val miningSounds: ImmutableList<String> = ImmutableList.of(),
@Deprecated("", replaceWith = ReplaceWith("this.actualDamageTable")) @Deprecated("", replaceWith = ReplaceWith("this.actualDamageTable"))
val damageTable: AssetReference<TileDamageConfig> = AssetReference(GlobalDefaults::tileDamage), val damageTable: AssetReference<TileDamageConfig> = AssetReference(Globals::tileDamage),
@JsonFlat @JsonFlat
val descriptionData: ThingDescription, val descriptionData: ThingDescription,

View File

@ -7,9 +7,8 @@ import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.kommons.util.AABBi import ru.dbotthepony.kommons.util.AABBi
import ru.dbotthepony.kommons.vector.Vector2d import ru.dbotthepony.kommons.vector.Vector2d
import ru.dbotthepony.kommons.vector.Vector2i import ru.dbotthepony.kommons.vector.Vector2i
import ru.dbotthepony.kstarbound.GlobalDefaults import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.fromJson
import ru.dbotthepony.kstarbound.io.readColor import ru.dbotthepony.kstarbound.io.readColor
import ru.dbotthepony.kstarbound.io.readInternedString import ru.dbotthepony.kstarbound.io.readInternedString
import ru.dbotthepony.kstarbound.io.writeColor import ru.dbotthepony.kstarbound.io.writeColor
@ -96,7 +95,7 @@ class AsteroidsWorldParameters : VisitableWorldParameters() {
override fun createLayout(seed: Long): WorldLayout { override fun createLayout(seed: Long): WorldLayout {
val random = random(seed) val random = random(seed)
val terrain = GlobalDefaults.asteroidWorlds.terrains.random(random) val terrain = Globals.asteroidWorlds.terrains.random(random)
val layout = WorldLayout() val layout = WorldLayout()
layout.worldSize = worldSize layout.worldSize = worldSize
@ -118,12 +117,12 @@ class AsteroidsWorldParameters : VisitableWorldParameters() {
worldSize.y / 2, worldSize.y / 2,
threatLevel, threatLevel,
asteroidBiome, asteroidBiome,
GlobalDefaults.asteroidWorlds.emptyTerrain.terrainSelector, Globals.asteroidWorlds.emptyTerrain.terrainSelector,
GlobalDefaults.asteroidWorlds.emptyTerrain.caveSelector, Globals.asteroidWorlds.emptyTerrain.caveSelector,
GlobalDefaults.asteroidWorlds.emptyTerrain.bgCaveSelector, Globals.asteroidWorlds.emptyTerrain.bgCaveSelector,
GlobalDefaults.asteroidWorlds.emptyTerrain.oreSelector, Globals.asteroidWorlds.emptyTerrain.oreSelector,
GlobalDefaults.asteroidWorlds.emptyTerrain.oreSelector, Globals.asteroidWorlds.emptyTerrain.oreSelector,
GlobalDefaults.asteroidWorlds.emptyTerrain.subBlockSelector, Globals.asteroidWorlds.emptyTerrain.subBlockSelector,
WorldLayout.RegionLiquids(), WorldLayout.RegionLiquids(),
) )
@ -132,7 +131,7 @@ class AsteroidsWorldParameters : VisitableWorldParameters() {
layout.addLayer(random, asteroidTopLevel, emptyRegion) layout.addLayer(random, asteroidTopLevel, emptyRegion)
layout.regionBlending = blendSize layout.regionBlending = blendSize
layout.blockNoise = GlobalDefaults.asteroidWorlds.blockNoise?.build(random) layout.blockNoise = Globals.asteroidWorlds.blockNoise?.build(random)
layout.playerStartSearchRegions.add( layout.playerStartSearchRegions.add(
AABBi( AABBi(
@ -151,21 +150,21 @@ class AsteroidsWorldParameters : VisitableWorldParameters() {
val parameters = AsteroidsWorldParameters() val parameters = AsteroidsWorldParameters()
parameters.threatLevel = random.nextRange(GlobalDefaults.asteroidWorlds.threatRange) parameters.threatLevel = random.nextRange(Globals.asteroidWorlds.threatRange)
parameters.typeName = "asteroids" parameters.typeName = "asteroids"
parameters.worldSize = GlobalDefaults.asteroidWorlds.worldSize parameters.worldSize = Globals.asteroidWorlds.worldSize
parameters.gravity = Vector2d(y = random.nextRange(GlobalDefaults.asteroidWorlds.gravityRange)) parameters.gravity = Vector2d(y = random.nextRange(Globals.asteroidWorlds.gravityRange))
parameters.environmentStatusEffects = GlobalDefaults.asteroidWorlds.environmentStatusEffects parameters.environmentStatusEffects = Globals.asteroidWorlds.environmentStatusEffects
parameters.overrideTech = GlobalDefaults.asteroidWorlds.overrideTech parameters.overrideTech = Globals.asteroidWorlds.overrideTech
parameters.globalDirectives = GlobalDefaults.asteroidWorlds.globalDirectives parameters.globalDirectives = Globals.asteroidWorlds.globalDirectives
parameters.beamUpRule = GlobalDefaults.asteroidWorlds.beamUpRule parameters.beamUpRule = Globals.asteroidWorlds.beamUpRule
parameters.disableDeathDrops = GlobalDefaults.asteroidWorlds.disableDeathDrops parameters.disableDeathDrops = Globals.asteroidWorlds.disableDeathDrops
parameters.worldEdgeForceRegions = GlobalDefaults.asteroidWorlds.worldEdgeForceRegions parameters.worldEdgeForceRegions = Globals.asteroidWorlds.worldEdgeForceRegions
parameters.asteroidTopLevel = GlobalDefaults.asteroidWorlds.asteroidsTop parameters.asteroidTopLevel = Globals.asteroidWorlds.asteroidsTop
parameters.asteroidBottomLevel = GlobalDefaults.asteroidWorlds.asteroidsBottom parameters.asteroidBottomLevel = Globals.asteroidWorlds.asteroidsBottom
parameters.blendSize = GlobalDefaults.asteroidWorlds.blendSize parameters.blendSize = Globals.asteroidWorlds.blendSize
parameters.ambientLightLevel = GlobalDefaults.asteroidWorlds.ambientLightLevel parameters.ambientLightLevel = Globals.asteroidWorlds.ambientLightLevel
parameters.asteroidBiome = GlobalDefaults.asteroidWorlds.biome parameters.asteroidBiome = Globals.asteroidWorlds.biome
return parameters return parameters
} }

View File

@ -3,8 +3,7 @@ package ru.dbotthepony.kstarbound.defs.world
import com.google.common.collect.ImmutableList import com.google.common.collect.ImmutableList
import com.google.common.collect.ImmutableMap import com.google.common.collect.ImmutableMap
import com.google.common.collect.ImmutableSet import com.google.common.collect.ImmutableSet
import com.google.gson.JsonElement import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.GlobalDefaults
import ru.dbotthepony.kstarbound.Registries import ru.dbotthepony.kstarbound.Registries
import ru.dbotthepony.kstarbound.Registry import ru.dbotthepony.kstarbound.Registry
import ru.dbotthepony.kstarbound.defs.AssetReference import ru.dbotthepony.kstarbound.defs.AssetReference
@ -65,7 +64,7 @@ class BushVariant(
ceiling = data.value.ceiling, ceiling = data.value.ceiling,
descriptions = data.value.descriptions.fixDescription("${data.key} with $modName").toMap(), descriptions = data.value.descriptions.fixDescription("${data.key} with $modName").toMap(),
ephemeral = data.value.ephemeral, ephemeral = data.value.ephemeral,
tileDamageParameters = (data.value.damageTable?.value ?: GlobalDefaults.bushDamage).copy(totalHealth = data.value.health), tileDamageParameters = (data.value.damageTable?.value ?: Globals.bushDamage).copy(totalHealth = data.value.health),
modName = modName, modName = modName,
shapes = data.value.shapes.stream().map { Shape(it.base, it.mods[modName] ?: ImmutableList.of()) }.collect(ImmutableList.toImmutableList()) shapes = data.value.shapes.stream().map { Shape(it.base, it.mods[modName] ?: ImmutableList.of()) }.collect(ImmutableList.toImmutableList())
) )

View File

@ -4,11 +4,12 @@ import com.google.common.collect.ImmutableList
import com.google.common.collect.ImmutableMap import com.google.common.collect.ImmutableMap
import com.google.gson.JsonObject import com.google.gson.JsonObject
import ru.dbotthepony.kommons.vector.Vector2i import ru.dbotthepony.kommons.vector.Vector2i
import ru.dbotthepony.kstarbound.defs.PerlinNoiseParameters
import ru.dbotthepony.kstarbound.json.builder.JsonFactory import ru.dbotthepony.kstarbound.json.builder.JsonFactory
import ru.dbotthepony.kstarbound.util.random.AbstractPerlinNoise import ru.dbotthepony.kstarbound.util.random.AbstractPerlinNoise
@JsonFactory @JsonFactory
data class CelestialGenerationInformation( data class CelestialConfig(
val systemProbability: Double, val systemProbability: Double,
val constellationProbability: Double, val constellationProbability: Double,
val constellationLineCountRange: Vector2i, val constellationLineCountRange: Vector2i,
@ -19,11 +20,18 @@ data class CelestialGenerationInformation(
val minimumConstellationLineCloseness: Double, val minimumConstellationLineCloseness: Double,
val systemTypes: ImmutableMap<String, System>, val systemTypes: ImmutableMap<String, System>,
val systemTypePerlin: AbstractPerlinNoise, val systemTypePerlin: PerlinNoiseParameters,
val systemTypeBins: ImmutableList<Pair<Double, String>>, val systemTypeBins: ImmutableList<Pair<Double, String>>,
val planetaryTypes: ImmutableMap<String, Planet>, val planetaryTypes: ImmutableMap<String, Planet>,
val satelliteTypes: ImmutableMap<String, Satellite>, val satelliteTypes: ImmutableMap<String, Satellite>,
val terrestrialGraphics: ImmutableMap<String, JsonObject>,
val terrestrialHorizonGraphics: ImmutableMap<String, JsonObject>,
val asteroidsHorizons: String,
val floatingDungeonHorizons: ImmutableMap<String, String>,
val gasGiantGraphics: JsonObject,
) { ) {
init { init {
systemTypeBins.forEach { systemTypeBins.forEach {

View File

@ -5,10 +5,9 @@ import ru.dbotthepony.kommons.gson.set
import ru.dbotthepony.kommons.io.writeBinaryString import ru.dbotthepony.kommons.io.writeBinaryString
import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.kommons.vector.Vector2d import ru.dbotthepony.kommons.vector.Vector2d
import ru.dbotthepony.kstarbound.GlobalDefaults import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.Registries import ru.dbotthepony.kstarbound.Registries
import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.fromJson
import ru.dbotthepony.kstarbound.io.readColor import ru.dbotthepony.kstarbound.io.readColor
import ru.dbotthepony.kstarbound.io.readInternedString import ru.dbotthepony.kstarbound.io.readInternedString
import ru.dbotthepony.kstarbound.io.readNullableString import ru.dbotthepony.kstarbound.io.readNullableString
@ -144,7 +143,7 @@ class FloatingDungeonWorldParameters : VisitableWorldParameters() {
companion object { companion object {
fun generate(typeName: String): FloatingDungeonWorldParameters { fun generate(typeName: String): FloatingDungeonWorldParameters {
val config = GlobalDefaults.dungeonWorlds[typeName] ?: throw NoSuchElementException("Unknown dungeon world type $typeName!") val config = Globals.dungeonWorlds[typeName] ?: throw NoSuchElementException("Unknown dungeon world type $typeName!")
val parameters = FloatingDungeonWorldParameters() val parameters = FloatingDungeonWorldParameters()
parameters.threatLevel = config.threatLevel parameters.threatLevel = config.threatLevel

View File

@ -2,8 +2,7 @@ package ru.dbotthepony.kstarbound.defs.world
import com.google.common.collect.ImmutableMap import com.google.common.collect.ImmutableMap
import com.google.common.collect.ImmutableSet import com.google.common.collect.ImmutableSet
import com.google.gson.JsonElement import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.GlobalDefaults
import ru.dbotthepony.kstarbound.Registries import ru.dbotthepony.kstarbound.Registries
import ru.dbotthepony.kstarbound.Registry import ru.dbotthepony.kstarbound.Registry
import ru.dbotthepony.kstarbound.defs.AssetReference import ru.dbotthepony.kstarbound.defs.AssetReference
@ -54,7 +53,7 @@ data class GrassVariant(
ephemeral = data.value.ephemeral, ephemeral = data.value.ephemeral,
hueShift = hueShift, hueShift = hueShift,
descriptions = data.value.descriptions.fixDescription(data.value.name).toMap(), descriptions = data.value.descriptions.fixDescription(data.value.name).toMap(),
tileDamageParameters = (data.value.damageTable?.value ?: GlobalDefaults.grassDamage).copy(totalHealth = data.value.health) tileDamageParameters = (data.value.damageTable?.value ?: Globals.grassDamage).copy(totalHealth = data.value.health)
) )
} }
} }

View File

@ -1,15 +1,24 @@
package ru.dbotthepony.kstarbound.defs.world package ru.dbotthepony.kstarbound.defs.world
import com.google.common.collect.ImmutableList import com.google.common.collect.ImmutableList
import com.google.gson.JsonObject
import it.unimi.dsi.fastutil.ints.IntArrayList
import ru.dbotthepony.kommons.gson.contains
import ru.dbotthepony.kommons.gson.get
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kommons.io.StreamCodec
import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.kommons.util.Either
import ru.dbotthepony.kommons.vector.Vector2d import ru.dbotthepony.kommons.vector.Vector2d
import ru.dbotthepony.kommons.vector.Vector2i
import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.Registries
import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.defs.AssetPath import ru.dbotthepony.kstarbound.defs.AssetPath
import ru.dbotthepony.kstarbound.io.readColor import ru.dbotthepony.kstarbound.io.readColor
import ru.dbotthepony.kstarbound.io.writeColor import ru.dbotthepony.kstarbound.io.writeColor
import ru.dbotthepony.kstarbound.json.builder.IStringSerializable import ru.dbotthepony.kstarbound.json.builder.IStringSerializable
import ru.dbotthepony.kstarbound.json.builder.JsonFactory import ru.dbotthepony.kstarbound.json.builder.JsonFactory
import ru.dbotthepony.kstarbound.json.mergeJson
import ru.dbotthepony.kstarbound.util.random.nextRange
import ru.dbotthepony.kstarbound.util.random.random import ru.dbotthepony.kstarbound.util.random.random
import ru.dbotthepony.kstarbound.world.Universe import ru.dbotthepony.kstarbound.world.Universe
import ru.dbotthepony.kstarbound.world.UniversePos import ru.dbotthepony.kstarbound.world.UniversePos
@ -123,16 +132,17 @@ data class SkyWorldHorizon(val center: Vector2d, val scale: Double, val rotation
@JsonFactory @JsonFactory
data class SkyParameters( data class SkyParameters(
val skyType: SkyType = SkyType.BARREN, var skyType: SkyType = SkyType.BARREN,
val seed: Long = 0L, var seed: Long = 0L,
val dayLength: Double? = null, var dayLength: Double? = null,
val horizonClouds: Boolean = false, var horizonClouds: Boolean = false,
val skyColoring: Either<SkyColoring, RGBAColor> = Either.left(SkyColoring()), var skyColoring: SkyColoring? = null,
val spaceLevel: Double? = null, var ambientLightLevel: RGBAColor? = RGBAColor.BLACK,
val surfaceLevel: Double? = null, var spaceLevel: Double? = null,
val nearbyPlanet: Planet? = null, var surfaceLevel: Double? = null,
val nearbyMoons: ImmutableList<Planet> = ImmutableList.of(), var planet: Planet? = null,
val horizonImages: ImmutableList<HorizonImage> = ImmutableList.of(), var satellites: ImmutableList<Planet> = ImmutableList.of(),
var horizonImages: ImmutableList<HorizonImage> = ImmutableList.of(),
) { ) {
@JsonFactory @JsonFactory
data class HorizonImage(val left: String, val right: String) data class HorizonImage(val left: String, val right: String)
@ -144,6 +154,196 @@ data class SkyParameters(
data class Planet(val pos: Vector2d, val layers: ImmutableList<Layer>) data class Planet(val pos: Vector2d, val layers: ImmutableList<Layer>)
companion object { companion object {
private val vectors by lazy { Starbound.gson.getAdapter(Vector2i::class.java) }
fun drawWorld(parameters: CelestialParameters, shadow: CelestialParameters? = null): List<Layer> {
val layers = ArrayList<Layer>()
val random = random(parameters.seed)
// i have no clue why they added this but ok
val shadowRandom = random(shadow?.seed ?: parameters.seed)
when (parameters.parameters["worldType"]?.asString?.lowercase() ?: return emptyList()) {
"terrestrial" -> {
val visitable = parameters.visitableParameters as? TerrestrialWorldParameters ?: return emptyList()
val gfxConfig = mergeJson(Globals.celestialConfig.terrestrialGraphics["default"] ?: return emptyList(), Globals.celestialConfig.terrestrialGraphics[visitable.typeName] ?: JsonObject())
val liquidImages = gfxConfig.get("liquidImages", "")
val baseImages = gfxConfig.get("baseImages", "")
val shadowImages = gfxConfig.get("shadowImages", "")
val baseCount = gfxConfig.get("baseCount", 0)
val dynamicsImages = gfxConfig.get("dynamicsImages", "")
val imageScale = parameters.parameters.get("imageScale", 1.0)
// If the planet has water, then draw the corresponding water image as the
// base layer, otherwise use the bottom most mask image.
val surfaceLiquid = visitable.surfaceLiquid?.map({ Registries.liquid[it] }, { Registries.liquid[it] })?.key
if (surfaceLiquid != null && liquidImages.isNotBlank()) {
layers.add(Layer(liquidImages.replace("<liquid>", surfaceLiquid), imageScale))
} else {
if (baseCount > 0) {
layers.add(Layer("${baseImages.replace("<biome>", visitable.primaryBiome).replace("<num>", baseCount.toString())}?hueshift=${visitable.hueShift}", imageScale))
}
}
// Then draw all the biome layers
for (i in 0 until baseCount) {
val baseImage = baseImages.replace("<num>", (baseCount - i).toString())
var hueShift = ""
var dynamicMask = ""
if (dynamicsImages.isNotBlank())
dynamicMask = "?addmask=" + dynamicsImages.replace("<num>", random.nextRange(gfxConfig.get("dynamicsRange", vectors)).toString())
if (visitable.hueShift != 0.0)
hueShift = "?hueshift=${visitable.hueShift.toInt()}"
layers.add(Layer(baseImage + hueShift + dynamicMask, imageScale))
}
if (shadowImages.isNotBlank()) {
layers.add(Layer(shadowImages.replace("<num>", shadowRandom.nextRange(gfxConfig.get("shadowNumber", vectors)).toString()), imageScale))
}
}
"asteroids" -> {
val maskImages = parameters.parameters.get("maskImages").asString
val masks = parameters.parameters.get("masks").asInt
val dynamicsImages = parameters.parameters.get("dynamicsImages").asString
val imageScale = parameters.parameters.get("imageScale", 1.0)
val dynamicsRange = parameters.parameters.get("dynamicsRange", vectors)
for (i in 0 until masks) {
val biomeMaskBase = maskImages.replace("<num>", (masks - i).toString())
val dynamicMask = dynamicsImages.replace("<num>", random.nextRange(dynamicsRange).toString())
layers.add(Layer("$biomeMaskBase?addmask=$dynamicMask", imageScale))
}
}
"floatingdungeon" -> {
val image = parameters.parameters.get("image").asString
val imageScale = parameters.parameters.get("imageScale", 1.0)
layers.add(Layer(image, imageScale))
if ("dynamicsImages" in parameters.parameters && parameters.parameters.get("dynamicsImages").asString.isNotBlank()) {
layers.add(Layer(
parameters.parameters.get("dynamicsImages").asString
.replace("<num>", random.nextRange(parameters.parameters.get("dynamicsRange", vectors)).toString()), imageScale))
}
}
"gasgiant" -> {
val gfxConfig = Globals.celestialConfig.gasGiantGraphics
val baseImage = gfxConfig.get("baseImage", "")
val shadowImages = gfxConfig.get("shadowImages", "")
val dynamicsImages = gfxConfig.get("dynamicsImages", "")
val overlayImages = gfxConfig.get("overlayImages", "")
val overlayCount = gfxConfig.get("overlayCount", 0)
val imageScale = parameters.parameters.get("imageScale", 1.0)
val offsetRange = gfxConfig.get("hueShiftOffsetRange", vectors)
val dynamicsRange = gfxConfig.get("dynamicsRange", vectors)
var hueshift = random.nextRange(gfxConfig.get("primaryHueShiftRange", vectors))
if (baseImage.isNotBlank())
layers.add(Layer("$baseImage?hueshift=$hueshift", imageScale))
if (overlayImages.isNotBlank()) {
for (i in 0 until overlayCount) {
hueshift += random.nextRange(offsetRange)
val maskImage = dynamicsImages.replace("<num>", random.nextRange(dynamicsRange).toString())
val overlayImage = overlayImages.replace("<num>", i.toString())
layers.add(Layer("$overlayImage?hueshift=$hueshift?addmask=$maskImage", imageScale))
}
}
if (shadowImages.isNotBlank()) {
layers.add(Layer(shadowImages.replace("<num>", shadowRandom.nextRange(gfxConfig.get("shadowNumber", vectors)).toString()), imageScale))
}
}
}
return layers
}
fun horizonImages(parameters: CelestialParameters): List<HorizonImage> {
fun getLR(value: String): HorizonImage {
return HorizonImage(value.replace("<selector>", "l"), value.replace("<selector>", "r"))
}
val images = ArrayList<HorizonImage>()
when (parameters.parameters["worldType"]?.asString?.lowercase() ?: return emptyList()) {
"terrestrial" -> {
val visitable = parameters.visitableParameters as? TerrestrialWorldParameters ?: return emptyList()
val gfxConfig = mergeJson(Globals.celestialConfig.terrestrialHorizonGraphics["default"] ?: return emptyList(), Globals.celestialConfig.terrestrialHorizonGraphics[visitable.typeName] ?: JsonObject())
val baseImages = gfxConfig.get("baseImages").asString
val atmoTextures = gfxConfig.get("atmosphereTextures").asString
val shadowTextures = gfxConfig.get("shadowTextures").asString
val maskTextures = gfxConfig.get("maskTextures").asString
val liquidTextures = gfxConfig.get("liquidTextures").asString
val numMasks = gfxConfig.get("maskRange", vectors)
val maskPerPlanetRange = gfxConfig.get("maskPerPlanetRange", vectors)
val biomeHueShift = "?hueshift=${visitable.hueShift.toInt()}"
val surfaceLiquid = visitable.surfaceLiquid?.map({ Registries.liquid[it] }, { Registries.liquid[it] })?.key
if (surfaceLiquid != null) {
val random = random(parameters.seed)
for (i in 0 until 23)
random.nextInt()
images.add(getLR(liquidTextures.replace("<liquid>", surfaceLiquid)))
val masksL = ArrayList<String>()
val masksR = ArrayList<String>()
for (i in 0 until random.nextRange(maskPerPlanetRange)) {
val m = random.nextRange(numMasks)
val (l, r) = getLR(maskTextures.replace("<mask>", m.toString()))
masksL.add(l)
masksR.add(r)
}
val left = if (masksL.isNotEmpty()) "?" + masksL.joinToString("?") { "addmask=$it" } else ""
val right = if (masksR.isNotEmpty()) "?" + masksR.joinToString("?") { "addmask=$it" } else ""
val (l, r) = getLR(baseImages + biomeHueShift)
images.add(HorizonImage(l + left, r + right))
} else {
images.add(getLR(baseImages + biomeHueShift))
}
// original code uses "atmosphere" parameter, but... it seems to be a leftover?
if (!visitable.airless) {
images.add(getLR(atmoTextures))
}
images.add(getLR(shadowTextures))
}
"asteroids" -> {
images.add(getLR(Globals.celestialConfig.asteroidsHorizons))
}
"floatingdungeon" -> {
val visitable = parameters.visitableParameters as? FloatingDungeonWorldParameters ?: return emptyList()
val base = Globals.celestialConfig.floatingDungeonHorizons[visitable.typeName] ?: return emptyList()
images.add(getLR(base))
}
}
return images
}
suspend fun create(coordinate: UniversePos, universe: Universe): SkyParameters { suspend fun create(coordinate: UniversePos, universe: Universe): SkyParameters {
if (coordinate.isSystem) if (coordinate.isSystem)
throw IllegalArgumentException("$coordinate is system location") throw IllegalArgumentException("$coordinate is system location")
@ -153,13 +353,22 @@ data class SkyParameters(
val random = random(params.seed) val random = random(params.seed)
val selfPos = params.coordinate val selfPos = params.coordinate
val nearbyMoons = ArrayList<Planet>()
val sky = SkyParameters() val sky = SkyParameters()
for (i in 0 until 66)
random.nextInt()
sky.seed = random.nextLong()
if (selfPos.isSatellite) { if (selfPos.isSatellite) {
val planet = universe.parameters(selfPos.parent()) val planet = universe.parameters(selfPos.parent())
if (planet != null) { if (planet != null) {
val pos = Vector2d(random.nextDouble(), random.nextDouble()) val pos = Vector2d(random.nextDouble(), random.nextDouble())
// My parent's parent is no one.
sky.planet = Planet(pos, ImmutableList.copyOf(drawWorld(planet)))
} }
} }
@ -169,10 +378,44 @@ data class SkyParameters(
if (satellite != null) { if (satellite != null) {
val pos = Vector2d(random.nextDouble(), random.nextDouble()) val pos = Vector2d(random.nextDouble(), random.nextDouble())
nearbyMoons.add(Planet(pos, ImmutableList.copyOf(drawWorld(satellite, universe.parameters(satellitePos.parent())))))
} }
} }
} }
sky.satellites = ImmutableList.copyOf(nearbyMoons)
sky.horizonImages = ImmutableList.copyOf(horizonImages(params))
val visitable = params.visitableParameters
if (visitable is TerrestrialWorldParameters) {
sky.dayLength = visitable.dayLength
if (visitable.airless) {
sky.skyType = SkyType.ATMOSPHERELESS
sky.horizonClouds = false
} else {
sky.skyType = SkyType.ATMOSPHERIC
sky.horizonClouds = true
}
sky.skyColoring = visitable.skyColoring
sky.ambientLightLevel = null
sky.spaceLevel = visitable.spaceLayer.layerMinHeight.toDouble()
sky.surfaceLevel = visitable.surfaceLayer.layerMinHeight.toDouble()
} else {
sky.skyType = SkyType.BARREN
sky.horizonClouds = false
if (visitable is AsteroidsWorldParameters) {
sky.ambientLightLevel = visitable.ambientLightLevel
} else if (visitable is FloatingDungeonWorldParameters) {
sky.ambientLightLevel = visitable.ambientLightLevel
} else {
sky.ambientLightLevel = RGBAColor.BLACK
}
}
return sky return sky
} }
} }

View File

@ -19,11 +19,10 @@ import ru.dbotthepony.kommons.io.writeCollection
import ru.dbotthepony.kommons.util.Either import ru.dbotthepony.kommons.util.Either
import ru.dbotthepony.kommons.vector.Vector2d import ru.dbotthepony.kommons.vector.Vector2d
import ru.dbotthepony.kommons.vector.Vector2i import ru.dbotthepony.kommons.vector.Vector2i
import ru.dbotthepony.kstarbound.GlobalDefaults import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.Registries import ru.dbotthepony.kstarbound.Registries
import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.collect.WeightedList import ru.dbotthepony.kstarbound.collect.WeightedList
import ru.dbotthepony.kstarbound.defs.JsonDriven
import ru.dbotthepony.kstarbound.defs.PerlinNoiseParameters import ru.dbotthepony.kstarbound.defs.PerlinNoiseParameters
import ru.dbotthepony.kstarbound.fromJson import ru.dbotthepony.kstarbound.fromJson
import ru.dbotthepony.kstarbound.io.readInternedString import ru.dbotthepony.kstarbound.io.readInternedString
@ -405,9 +404,9 @@ class TerrestrialWorldParameters : VisitableWorldParameters() {
} }
fun generate(typeName: String, sizeName: String, random: RandomGenerator): TerrestrialWorldParameters { fun generate(typeName: String, sizeName: String, random: RandomGenerator): TerrestrialWorldParameters {
val config = GlobalDefaults.terrestrialWorlds.planetDefaults.deepCopy() val config = Globals.terrestrialWorlds.planetDefaults.deepCopy()
mergeJson(config, GlobalDefaults.terrestrialWorlds.planetSizes[sizeName] ?: throw NoSuchElementException("Unknown world size name $sizeName")) mergeJson(config, Globals.terrestrialWorlds.planetSizes[sizeName] ?: throw NoSuchElementException("Unknown world size name $sizeName"))
mergeJson(config, GlobalDefaults.terrestrialWorlds.planetTypes[typeName] ?: throw NoSuchElementException("Unknown world type name $typeName")) mergeJson(config, Globals.terrestrialWorlds.planetTypes[typeName] ?: throw NoSuchElementException("Unknown world type name $typeName"))
val params = Starbound.gson.fromJson(config, Generic::class.java) val params = Starbound.gson.fromJson(config, Generic::class.java)
@ -481,8 +480,8 @@ class TerrestrialWorldParameters : VisitableWorldParameters() {
} }
fun makeRegion(name: String, baseHeight: Int): Pair<Region, Region> { fun makeRegion(name: String, baseHeight: Int): Pair<Region, Region> {
val primaryRegionJson = GlobalDefaults.terrestrialWorlds.regionDefaults.deepCopy() val primaryRegionJson = Globals.terrestrialWorlds.regionDefaults.deepCopy()
mergeJson(primaryRegionJson, GlobalDefaults.terrestrialWorlds.regionTypes[name]!!) mergeJson(primaryRegionJson, Globals.terrestrialWorlds.regionTypes[name]!!)
val region = readRegion(primaryRegionJson, baseHeight) val region = readRegion(primaryRegionJson, baseHeight)
val subRegionList = primaryRegionJson.getArray("subRegion") val subRegionList = primaryRegionJson.getArray("subRegion")
@ -490,8 +489,8 @@ class TerrestrialWorldParameters : VisitableWorldParameters() {
val subRegion = readRegion(if (subRegionList.isEmpty) { val subRegion = readRegion(if (subRegionList.isEmpty) {
primaryRegionJson primaryRegionJson
} else { } else {
val result = GlobalDefaults.terrestrialWorlds.regionDefaults.deepCopy() val result = Globals.terrestrialWorlds.regionDefaults.deepCopy()
mergeJson(result, GlobalDefaults.terrestrialWorlds.regionTypes[subRegionList.random(random).asString]!!) mergeJson(result, Globals.terrestrialWorlds.regionTypes[subRegionList.random(random).asString]!!)
result result
}, baseHeight) }, baseHeight)

View File

@ -4,7 +4,7 @@ import com.google.common.collect.ImmutableMap
import com.google.gson.JsonElement import com.google.gson.JsonElement
import com.google.gson.JsonNull import com.google.gson.JsonNull
import com.google.gson.JsonObject import com.google.gson.JsonObject
import ru.dbotthepony.kstarbound.GlobalDefaults import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.Registries import ru.dbotthepony.kstarbound.Registries
import ru.dbotthepony.kstarbound.Registry import ru.dbotthepony.kstarbound.Registry
import ru.dbotthepony.kstarbound.defs.AssetReference import ru.dbotthepony.kstarbound.defs.AssetReference
@ -81,7 +81,7 @@ data class TreeVariant(
stemDropConfig = data.value.dropConfig.deepCopy(), stemDropConfig = data.value.dropConfig.deepCopy(),
descriptions = data.value.descriptions.fixDescription(data.key).toMap(), descriptions = data.value.descriptions.fixDescription(data.key).toMap(),
ephemeral = data.value.ephemeral, ephemeral = data.value.ephemeral,
tileDamageParameters = (data.value.damageTable?.value ?: GlobalDefaults.treeDamage).copy(totalHealth = data.value.health), tileDamageParameters = (data.value.damageTable?.value ?: Globals.treeDamage).copy(totalHealth = data.value.health),
foliageSettings = JsonNull.INSTANCE, foliageSettings = JsonNull.INSTANCE,
foliageDropConfig = JsonObject(), foliageDropConfig = JsonObject(),
@ -108,7 +108,7 @@ data class TreeVariant(
stemDropConfig = data.value.dropConfig.deepCopy(), stemDropConfig = data.value.dropConfig.deepCopy(),
descriptions = data.value.descriptions.fixDescription("${data.key} with ${fdata.key}").toMap(), descriptions = data.value.descriptions.fixDescription("${data.key} with ${fdata.key}").toMap(),
ephemeral = data.value.ephemeral, ephemeral = data.value.ephemeral,
tileDamageParameters = (data.value.damageTable?.value ?: GlobalDefaults.treeDamage).copy(totalHealth = data.value.health), tileDamageParameters = (data.value.damageTable?.value ?: Globals.treeDamage).copy(totalHealth = data.value.health),
foliageSettings = fdata.json, foliageSettings = fdata.json,
foliageDropConfig = fdata.value.dropConfig.deepCopy(), foliageDropConfig = fdata.value.dropConfig.deepCopy(),

View File

@ -20,7 +20,7 @@ import ru.dbotthepony.kommons.util.AABBi
import ru.dbotthepony.kommons.util.Either import ru.dbotthepony.kommons.util.Either
import ru.dbotthepony.kommons.vector.Vector2d import ru.dbotthepony.kommons.vector.Vector2d
import ru.dbotthepony.kommons.vector.Vector2i import ru.dbotthepony.kommons.vector.Vector2i
import ru.dbotthepony.kstarbound.GlobalDefaults import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.Registries import ru.dbotthepony.kstarbound.Registries
import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.world.terrain.AbstractTerrainSelector import ru.dbotthepony.kstarbound.world.terrain.AbstractTerrainSelector
@ -336,7 +336,7 @@ class WorldLayout {
val region = buildRegion(random, params) val region = buildRegion(random, params)
val subRegion = buildRegion(random, params) val subRegion = buildRegion(random, params)
if (!GlobalDefaults.terrestrialWorlds.useSecondaryEnvironmentBiomeIndex) { if (!Globals.terrestrialWorlds.useSecondaryEnvironmentBiomeIndex) {
region.environmentBiome = primaryEnvironment.environmentBiome region.environmentBiome = primaryEnvironment.environmentBiome
} }
@ -387,7 +387,7 @@ class WorldLayout {
} }
layer.cells.add(0, layer.cells.last()) layer.cells.add(0, layer.cells.last())
val yRange = GlobalDefaults.worldTemplate.playerStartSearchYRange val yRange = Globals.worldTemplate.playerStartSearchYRange
var i = 0 var i = 0
var lastBoundary = 0 var lastBoundary = 0

View File

@ -7,7 +7,7 @@ import org.classdump.luna.Table
import org.classdump.luna.lib.ArgumentIterator import org.classdump.luna.lib.ArgumentIterator
import org.classdump.luna.runtime.ExecutionContext import org.classdump.luna.runtime.ExecutionContext
import org.classdump.luna.runtime.LuaFunction import org.classdump.luna.runtime.LuaFunction
import ru.dbotthepony.kstarbound.GlobalDefaults import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.RecipeRegistry import ru.dbotthepony.kstarbound.RecipeRegistry
import ru.dbotthepony.kstarbound.Registries import ru.dbotthepony.kstarbound.Registries
import ru.dbotthepony.kstarbound.Registry import ru.dbotthepony.kstarbound.Registry
@ -243,7 +243,7 @@ private fun materialFootstepSound(context: ExecutionContext, arguments: Argument
return return
} }
context.returnBuffer.setTo(GlobalDefaults.client.defaultFootstepSound.map({ it }, { it.random() })) context.returnBuffer.setTo(Globals.client.defaultFootstepSound.map({ it }, { it.random() }))
} }
private fun materialHealth(context: ExecutionContext, arguments: ArgumentIterator) { private fun materialHealth(context: ExecutionContext, arguments: ArgumentIterator) {

View File

@ -8,6 +8,7 @@ import io.netty.channel.ChannelOption
import io.netty.channel.nio.NioEventLoopGroup import io.netty.channel.nio.NioEventLoopGroup
import it.unimi.dsi.fastutil.ints.IntAVLTreeSet import it.unimi.dsi.fastutil.ints.IntAVLTreeSet
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kommons.io.StreamCodec
@ -19,7 +20,7 @@ import ru.dbotthepony.kommons.util.getValue
import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.kommons.util.setValue
import ru.dbotthepony.kommons.vector.Vector2d import ru.dbotthepony.kommons.vector.Vector2d
import ru.dbotthepony.kommons.vector.Vector2i import ru.dbotthepony.kommons.vector.Vector2i
import ru.dbotthepony.kstarbound.GlobalDefaults import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.defs.WarpAction import ru.dbotthepony.kstarbound.defs.WarpAction
import ru.dbotthepony.kstarbound.defs.EntityDamageTeam import ru.dbotthepony.kstarbound.defs.EntityDamageTeam
@ -50,7 +51,8 @@ abstract class Connection(val side: ConnectionSide, val type: ConnectionType) :
var entityIDRange: IntRange by Delegates.notNull() var entityIDRange: IntRange by Delegates.notNull()
private set private set
val scope = CoroutineScope(Starbound.COROUTINE_EXECUTOR) var scope: CoroutineScope by Delegates.notNull()
private set
var connectionID: Int = -1 var connectionID: Int = -1
set(value) { set(value) {
@ -120,6 +122,8 @@ abstract class Connection(val side: ConnectionSide, val type: ConnectionType) :
} }
fun bind(channel: Channel) { fun bind(channel: Channel) {
scope = CoroutineScope(channel.eventLoop().asCoroutineDispatcher())
channel.config().setOption(ChannelOption.TCP_NODELAY, true) channel.config().setOption(ChannelOption.TCP_NODELAY, true)
this.channel = channel this.channel = channel
@ -196,8 +200,8 @@ abstract class Connection(val side: ConnectionSide, val type: ConnectionType) :
fun trackingTileRegions(): List<AABBi> { fun trackingTileRegions(): List<AABBi> {
val result = ArrayList<AABBi>() val result = ArrayList<AABBi>()
var mins = Vector2i(windowXMin - GlobalDefaults.client.windowMonitoringBorder, windowYMin - GlobalDefaults.client.windowMonitoringBorder) var mins = Vector2i(windowXMin - Globals.client.windowMonitoringBorder, windowYMin - Globals.client.windowMonitoringBorder)
var maxs = Vector2i(windowWidth + GlobalDefaults.client.windowMonitoringBorder * 2, windowHeight + GlobalDefaults.client.windowMonitoringBorder * 2) var maxs = Vector2i(windowWidth + Globals.client.windowMonitoringBorder * 2, windowHeight + Globals.client.windowMonitoringBorder * 2)
if (maxs.x - mins.x > 1000) { if (maxs.x - mins.x > 1000) {
// holy shit // holy shit

View File

@ -30,33 +30,10 @@ class CelestialRequestPacket(val requests: Collection<Either<Vector2i, Vector3i>
} }
override fun play(connection: ServerConnection) { override fun play(connection: ServerConnection) {
connection.pushCelestialRequests(requests)
connection.scope.launch { connection.scope.launch {
val responses = ArrayList<Either<CelestialResponsePacket.ChunkData, CelestialResponsePacket.SystemData>>()
for (request in requests) {
if (request.isLeft) {
val chunkPos = request.left()
responses.add(Either.left(connection.server.universe.getChunk(chunkPos)?.toNetwork() ?: continue))
} else {
val systemPos = UniversePos(request.right())
val map = HashMap<Int, CelestialResponsePacket.PlanetData>()
for (planet in connection.server.universe.children(systemPos)) {
val planetData = connection.server.universe.parameters(planet) ?: continue
val children = HashMap<Int, CelestialParameters>()
for (satellite in connection.server.universe.children(planet)) {
children[satellite.satelliteOrbit] = connection.server.universe.parameters(satellite) ?: continue
}
map[planet.planetOrbit] = CelestialResponsePacket.PlanetData(planetData, children)
}
responses.add(Either.right(CelestialResponsePacket.SystemData(systemPos.location, map)))
}
}
connection.send(CelestialResponsePacket(responses))
} }
} }
} }

View File

@ -10,24 +10,27 @@ import kotlinx.coroutines.future.await
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
import ru.dbotthepony.kommons.io.ByteKey import ru.dbotthepony.kommons.io.ByteKey
import ru.dbotthepony.kommons.util.Either
import ru.dbotthepony.kommons.util.KOptional import ru.dbotthepony.kommons.util.KOptional
import ru.dbotthepony.kommons.vector.Vector2i
import ru.dbotthepony.kommons.vector.Vector3i import ru.dbotthepony.kommons.vector.Vector3i
import ru.dbotthepony.kstarbound.GlobalDefaults import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.defs.WarpAction import ru.dbotthepony.kstarbound.defs.WarpAction
import ru.dbotthepony.kstarbound.defs.WarpAlias import ru.dbotthepony.kstarbound.defs.WarpAlias
import ru.dbotthepony.kstarbound.defs.WorldID import ru.dbotthepony.kstarbound.defs.WorldID
import ru.dbotthepony.kstarbound.defs.world.CelestialParameters
import ru.dbotthepony.kstarbound.defs.world.VisitableWorldParameters import ru.dbotthepony.kstarbound.defs.world.VisitableWorldParameters
import ru.dbotthepony.kstarbound.network.Connection import ru.dbotthepony.kstarbound.network.Connection
import ru.dbotthepony.kstarbound.network.ConnectionSide import ru.dbotthepony.kstarbound.network.ConnectionSide
import ru.dbotthepony.kstarbound.network.ConnectionType import ru.dbotthepony.kstarbound.network.ConnectionType
import ru.dbotthepony.kstarbound.network.IServerPacket import ru.dbotthepony.kstarbound.network.IServerPacket
import ru.dbotthepony.kstarbound.network.packets.ClientContextUpdatePacket import ru.dbotthepony.kstarbound.network.packets.ClientContextUpdatePacket
import ru.dbotthepony.kstarbound.network.packets.clientbound.CelestialResponsePacket
import ru.dbotthepony.kstarbound.network.packets.clientbound.PlayerWarpResultPacket import ru.dbotthepony.kstarbound.network.packets.clientbound.PlayerWarpResultPacket
import ru.dbotthepony.kstarbound.network.packets.clientbound.ServerDisconnectPacket import ru.dbotthepony.kstarbound.network.packets.clientbound.ServerDisconnectPacket
import ru.dbotthepony.kstarbound.server.world.ServerWorldTracker import ru.dbotthepony.kstarbound.server.world.ServerWorldTracker
import ru.dbotthepony.kstarbound.server.world.WorldStorage import ru.dbotthepony.kstarbound.server.world.WorldStorage
import ru.dbotthepony.kstarbound.server.world.LegacyWorldStorage import ru.dbotthepony.kstarbound.server.world.LegacyWorldStorage
import ru.dbotthepony.kstarbound.server.world.ServerSystemWorld
import ru.dbotthepony.kstarbound.server.world.ServerWorld import ru.dbotthepony.kstarbound.server.world.ServerWorld
import ru.dbotthepony.kstarbound.world.SystemWorldLocation import ru.dbotthepony.kstarbound.world.SystemWorldLocation
import ru.dbotthepony.kstarbound.world.UniversePos import ru.dbotthepony.kstarbound.world.UniversePos
@ -183,13 +186,13 @@ class ServerConnection(val server: StarboundServer, type: ConnectionType) : Conn
flyShipQueue.trySend(system to location) flyShipQueue.trySend(system to location)
} }
// coordinates ship flights between systems // coordinates ship flight
private suspend fun shipFlightEventLoop() { private suspend fun shipFlightEventLoop() {
shipWorld.sky.startFlying(true, true) shipWorld.sky.startFlying(true, true)
var visited = 0 var visited = 0
LOGGER.info("Finding starter world for ${alias()}...") LOGGER.info("Finding starter world for ${alias()}...")
val params = GlobalDefaults.universeServer.findStarterWorldParameters val params = Globals.universeServer.findStarterWorldParameters
// visit all since sparsingly trying to find specific world is not healthy performance wise // visit all since sparsingly trying to find specific world is not healthy performance wise
val found = server.universe.findRandomWorld(params.tries, params.range, visitAll = true, predicate = { val found = server.universe.findRandomWorld(params.tries, params.range, visitAll = true, predicate = {
@ -235,6 +238,15 @@ class ServerConnection(val server: StarboundServer, type: ConnectionType) : Conn
shipWorld.sky.stopFlyingAt(ship.location.skyParameters(world)) shipWorld.sky.stopFlyingAt(ship.location.skyParameters(world))
shipCoordinate = found shipCoordinate = found
run {
val action = ship.location.orbitalAction(world)
orbitalWarpAction = action
for (client in shipWorld.clients) {
client.client.orbitalWarpAction = action
}
}
var currentFlightJob: Job? = null var currentFlightJob: Job? = null
while (true) { while (true) {
@ -302,10 +314,66 @@ class ServerConnection(val server: StarboundServer, type: ConnectionType) : Conn
shipWorld.mailbox.execute { shipWorld.mailbox.execute {
shipWorld.sky.stopFlyingAt(newParams) shipWorld.sky.stopFlyingAt(newParams)
} }
// this seems to be way too big isn't it?
delay((Globals.universeServer.queuedFlightWaitTime * 1000.0).toLong())
} }
} }
} }
val celestialRequestQueue = Channel<Either<Vector2i, Vector3i>>(capacity = 100)
fun pushCelestialRequests(requests: Iterable<Either<Vector2i, Vector3i>>) {
requests.forEach {
celestialRequestQueue.trySend(it)
}
}
private suspend fun handleCelestialRequests(requests: Collection<Either<Vector2i, Vector3i>>) {
val responses = ArrayList<Either<CelestialResponsePacket.ChunkData, CelestialResponsePacket.SystemData>>()
for (request in requests) {
if (request.isLeft) {
val chunkPos = request.left()
responses.add(Either.left(server.universe.getChunk(chunkPos)?.toNetwork() ?: continue))
} else {
val systemPos = UniversePos(request.right())
val map = HashMap<Int, CelestialResponsePacket.PlanetData>()
for (planet in server.universe.children(systemPos)) {
val planetData = server.universe.parameters(planet) ?: continue
val children = HashMap<Int, CelestialParameters>()
for (satellite in server.universe.children(planet)) {
children[satellite.satelliteOrbit] = server.universe.parameters(satellite) ?: continue
}
map[planet.planetOrbit] = CelestialResponsePacket.PlanetData(planetData, children)
}
responses.add(Either.right(CelestialResponsePacket.SystemData(systemPos.location, map)))
}
}
send(CelestialResponsePacket(responses))
}
// protects from malicious actors
private suspend fun celestialRequestsHandler() {
while (true) {
val next = celestialRequestQueue.receive()
val requests = ArrayList<Either<Vector2i, Vector3i>>()
requests.add(next)
while (true) {
val tryNext = celestialRequestQueue.tryReceive().getOrNull() ?: break
requests.add(tryNext)
}
handleCelestialRequests(requests)
}
}
fun enqueueWarp(destination: WarpAction, deploy: Boolean = false) { fun enqueueWarp(destination: WarpAction, deploy: Boolean = false) {
warpQueue.trySend(destination to deploy) warpQueue.trySend(destination to deploy)
} }
@ -377,6 +445,8 @@ class ServerConnection(val server: StarboundServer, type: ConnectionType) : Conn
server.channels.incrementPlayerCount() server.channels.incrementPlayerCount()
if (isLegacy) { if (isLegacy) {
scope.launch { celestialRequestsHandler() }
ServerWorld.load(server, shipChunkSource, WorldID.ShipWorld(uuid!!)).thenAccept { ServerWorld.load(server, shipChunkSource, WorldID.ShipWorld(uuid!!)).thenAccept {
if (!isConnected || !channel.isOpen) { if (!isConnected || !channel.isOpen) {
LOGGER.warn("$this disconnected before loaded their ShipWorld") LOGGER.warn("$this disconnected before loaded their ShipWorld")

View File

@ -10,7 +10,7 @@ import kotlinx.coroutines.runBlocking
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
import ru.dbotthepony.kommons.util.MailboxExecutorService import ru.dbotthepony.kommons.util.MailboxExecutorService
import ru.dbotthepony.kommons.vector.Vector3i import ru.dbotthepony.kommons.vector.Vector3i
import ru.dbotthepony.kstarbound.GlobalDefaults import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.defs.WorldID import ru.dbotthepony.kstarbound.defs.WorldID
import ru.dbotthepony.kstarbound.network.packets.clientbound.UniverseTimeUpdatePacket import ru.dbotthepony.kstarbound.network.packets.clientbound.UniverseTimeUpdatePacket
@ -83,7 +83,7 @@ sealed class StarboundServer(val root: File) : Closeable {
init { init {
mailbox.scheduleAtFixedRate(Runnable { mailbox.scheduleAtFixedRate(Runnable {
channels.broadcast(UniverseTimeUpdatePacket(universeClock.seconds)) channels.broadcast(UniverseTimeUpdatePacket(universeClock.seconds))
}, GlobalDefaults.universeServer.clockUpdatePacketInterval, GlobalDefaults.universeServer.clockUpdatePacketInterval, TimeUnit.MILLISECONDS) }, Globals.universeServer.clockUpdatePacketInterval, Globals.universeServer.clockUpdatePacketInterval, TimeUnit.MILLISECONDS)
thread.uncaughtExceptionHandler = Thread.UncaughtExceptionHandler { t, e -> thread.uncaughtExceptionHandler = Thread.UncaughtExceptionHandler { t, e ->
LOGGER.fatal("Unexpected exception in server execution loop, shutting down", e) LOGGER.fatal("Unexpected exception in server execution loop, shutting down", e)

View File

@ -6,15 +6,13 @@ import com.google.gson.JsonObject
import it.unimi.dsi.fastutil.bytes.ByteArrayList import it.unimi.dsi.fastutil.bytes.ByteArrayList
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.cancel
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
import ru.dbotthepony.kommons.io.writeBinaryString import ru.dbotthepony.kommons.io.writeBinaryString
import ru.dbotthepony.kommons.io.writeUUID import ru.dbotthepony.kommons.io.writeUUID
import ru.dbotthepony.kommons.util.KOptional import ru.dbotthepony.kommons.util.KOptional
import ru.dbotthepony.kommons.vector.Vector2d import ru.dbotthepony.kommons.vector.Vector2d
import ru.dbotthepony.kommons.vector.Vector3i import ru.dbotthepony.kommons.vector.Vector3i
import ru.dbotthepony.kstarbound.GlobalDefaults import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.defs.world.SystemWorldObjectConfig import ru.dbotthepony.kstarbound.defs.world.SystemWorldObjectConfig
import ru.dbotthepony.kstarbound.io.writeStruct2d import ru.dbotthepony.kstarbound.io.writeStruct2d
@ -34,12 +32,10 @@ import ru.dbotthepony.kstarbound.util.random.staticRandom64
import ru.dbotthepony.kstarbound.world.SystemWorld import ru.dbotthepony.kstarbound.world.SystemWorld
import ru.dbotthepony.kstarbound.world.SystemWorldLocation import ru.dbotthepony.kstarbound.world.SystemWorldLocation
import ru.dbotthepony.kstarbound.world.UniversePos import ru.dbotthepony.kstarbound.world.UniversePos
import java.io.Closeable
import java.io.DataOutputStream import java.io.DataOutputStream
import java.util.UUID import java.util.UUID
import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletableFuture
import java.util.concurrent.ConcurrentLinkedQueue import java.util.concurrent.ConcurrentLinkedQueue
import java.util.concurrent.atomic.AtomicBoolean
import java.util.function.Supplier import java.util.function.Supplier
import kotlin.math.PI import kotlin.math.PI
import kotlin.math.cos import kotlin.math.cos
@ -118,7 +114,7 @@ class ServerSystemWorld : SystemWorld {
ships.values.forEach { it.client.send(packet) } ships.values.forEach { it.client.send(packet) }
} }
fun addClient(client: ServerConnection, shipSpeed: Double = GlobalDefaults.systemWorld.clientShip.speed, location: SystemWorldLocation = SystemWorldLocation.Transit): CompletableFuture<ServerShip> { fun addClient(client: ServerConnection, shipSpeed: Double = Globals.systemWorld.clientShip.speed, location: SystemWorldLocation = SystemWorldLocation.Transit): CompletableFuture<ServerShip> {
val task = Task { addClient0(client, shipSpeed, location) } val task = Task { addClient0(client, shipSpeed, location) }
tasks.add(task) tasks.add(task)
return task.future return task.future
@ -150,8 +146,8 @@ class ServerSystemWorld : SystemWorld {
private constructor(server: StarboundServer, location: Vector3i) : super(location, server.universeClock, server.universe) { private constructor(server: StarboundServer, location: Vector3i) : super(location, server.universeClock, server.universe) {
this.server = server this.server = server
this.lastSpawn = clock.seconds - GlobalDefaults.systemWorld.objectSpawnCycle this.lastSpawn = clock.seconds - Globals.systemWorld.objectSpawnCycle
objectSpawnTime = random.nextRange(GlobalDefaults.systemWorld.objectSpawnInterval) objectSpawnTime = random.nextRange(Globals.systemWorld.objectSpawnInterval)
} }
private constructor(server: StarboundServer, data: JsonData) : super(data.location, server.universeClock, server.universe) { private constructor(server: StarboundServer, data: JsonData) : super(data.location, server.universeClock, server.universe) {
@ -168,11 +164,11 @@ class ServerSystemWorld : SystemWorld {
private suspend fun spawnInitialObjects() { private suspend fun spawnInitialObjects() {
val random = random(staticRandom64("SystemWorldGeneration", location.toString())) val random = random(staticRandom64("SystemWorldGeneration", location.toString()))
GlobalDefaults.systemWorld.initialObjectPools.sample(random).ifPresent { Globals.systemWorld.initialObjectPools.sample(random).ifPresent {
for (i in 0 until it.first) { for (i in 0 until it.first) {
val name = it.second.sample(random).orNull() ?: return@ifPresent val name = it.second.sample(random).orNull() ?: return@ifPresent
val uuid = UUID(random.nextLong(), random.nextLong()) val uuid = UUID(random.nextLong(), random.nextLong())
val prototype = GlobalDefaults.systemObjects[name] ?: throw NullPointerException("Tried to create $name system world object, but there is no such object in /system_objects.config!") val prototype = Globals.systemObjects[name] ?: throw NullPointerException("Tried to create $name system world object, but there is no such object in /system_objects.config!")
val create = ServerEntity(prototype.create(uuid, name), uuid, randomObjectSpawnPosition(), clock.seconds) val create = ServerEntity(prototype.create(uuid, name), uuid, randomObjectSpawnPosition(), clock.seconds)
create.enterOrbit(UniversePos(location), Vector2d.ZERO, clock.seconds) // orbit center of system create.enterOrbit(UniversePos(location), Vector2d.ZERO, clock.seconds) // orbit center of system
} }
@ -180,17 +176,17 @@ class ServerSystemWorld : SystemWorld {
} }
private suspend fun spawnObjects() { private suspend fun spawnObjects() {
var diff = GlobalDefaults.systemWorld.objectSpawnCycle.coerceAtMost(clock.seconds - lastSpawn) var diff = Globals.systemWorld.objectSpawnCycle.coerceAtMost(clock.seconds - lastSpawn)
lastSpawn = clock.seconds - diff lastSpawn = clock.seconds - diff
while (diff > objectSpawnTime) { while (diff > objectSpawnTime) {
lastSpawn += objectSpawnTime lastSpawn += objectSpawnTime
objectSpawnTime = random.nextRange(GlobalDefaults.systemWorld.objectSpawnInterval) objectSpawnTime = random.nextRange(Globals.systemWorld.objectSpawnInterval)
diff = clock.seconds - lastSpawn diff = clock.seconds - lastSpawn
GlobalDefaults.systemWorld.objectSpawnPool.sample(random).ifPresent { Globals.systemWorld.objectSpawnPool.sample(random).ifPresent {
val uuid = UUID(random.nextLong(), random.nextLong()) val uuid = UUID(random.nextLong(), random.nextLong())
val config = GlobalDefaults.systemObjects[it]?.create(uuid, it) ?: throw NullPointerException("Tried to create $it system world object, but there is no such object in /system_objects.config!") val config = Globals.systemObjects[it]?.create(uuid, it) ?: throw NullPointerException("Tried to create $it system world object, but there is no such object in /system_objects.config!")
val pos = randomObjectSpawnPosition() val pos = randomObjectSpawnPosition()
if (clock.seconds > lastSpawn + objectSpawnTime && config.moving) { if (clock.seconds > lastSpawn + objectSpawnTime && config.moving) {
@ -219,8 +215,8 @@ class ServerSystemWorld : SystemWorld {
val orbits = universe.children(systemLocation) val orbits = universe.children(systemLocation)
suspend fun addSpawn(inner: UniversePos, outer: UniversePos) { suspend fun addSpawn(inner: UniversePos, outer: UniversePos) {
val min = planetOrbitDistance(inner) + clusterSize(inner) / 2.0 + GlobalDefaults.systemWorld.objectSpawnPadding val min = planetOrbitDistance(inner) + clusterSize(inner) / 2.0 + Globals.systemWorld.objectSpawnPadding
val max = planetOrbitDistance(outer) - clusterSize(outer) / 2.0 - GlobalDefaults.systemWorld.objectSpawnPadding val max = planetOrbitDistance(outer) - clusterSize(outer) / 2.0 - Globals.systemWorld.objectSpawnPadding
spawnRanges.add(Vector2d(min, max)) spawnRanges.add(Vector2d(min, max))
} }
@ -230,8 +226,8 @@ class ServerSystemWorld : SystemWorld {
addSpawn(orbits[i - 1], orbits[i]) addSpawn(orbits[i - 1], orbits[i])
val outer = orbits.last() val outer = orbits.last()
val rim = planetOrbitDistance(outer) + clusterSize(outer) / 2.0 + GlobalDefaults.systemWorld.objectSpawnPadding val rim = planetOrbitDistance(outer) + clusterSize(outer) / 2.0 + Globals.systemWorld.objectSpawnPadding
spawnRanges.add(Vector2d(rim, rim + GlobalDefaults.systemWorld.objectSpawnPadding)) spawnRanges.add(Vector2d(rim, rim + Globals.systemWorld.objectSpawnPadding))
val range = spawnRanges.random(random) val range = spawnRanges.random(random)
val angle = random.nextDouble() * PI * 2.0 val angle = random.nextDouble() * PI * 2.0
@ -308,7 +304,7 @@ class ServerSystemWorld : SystemWorld {
suspend fun nearPlanetOrbit(planet: UniversePos): Orbit { suspend fun nearPlanetOrbit(planet: UniversePos): Orbit {
val toShip = planetPosition(planet) - position val toShip = planetPosition(planet) - position
val angle = toShip.toAngle() val angle = toShip.toAngle()
return Orbit(planet, 1, clock.seconds, Vector2d(cos(angle), sin(angle)) * (planetSize(planet) / 2.0 + GlobalDefaults.systemWorld.clientShip.orbitDistance)) return Orbit(planet, 1, clock.seconds, Vector2d(cos(angle), sin(angle)) * (planetSize(planet) / 2.0 + Globals.systemWorld.clientShip.orbitDistance))
} }
if (location is SystemWorldLocation.Celestial) { if (location is SystemWorldLocation.Celestial) {
@ -390,9 +386,9 @@ class ServerSystemWorld : SystemWorld {
destinationFuture = future destinationFuture = future
if (location is SystemWorldLocation.Celestial || location is SystemWorldLocation.Entity) if (location is SystemWorldLocation.Celestial || location is SystemWorldLocation.Entity)
departTimer = GlobalDefaults.systemWorld.clientShip.departTime departTimer = Globals.systemWorld.clientShip.departTime
else if (destination == SystemWorldLocation.Transit) else if (destination == SystemWorldLocation.Transit)
departTimer = GlobalDefaults.systemWorld.clientShip.spaceDepartTime departTimer = Globals.systemWorld.clientShip.spaceDepartTime
this.destination = destination this.destination = destination
this.location = SystemWorldLocation.Transit this.location = SystemWorldLocation.Transit
@ -412,7 +408,7 @@ class ServerSystemWorld : SystemWorld {
inner class ServerEntity(data: SystemWorldObjectConfig.Data, uuid: UUID, position: Vector2d, spawnTime: Double = 0.0, parameters: JsonObject = JsonObject()) : Entity(data, uuid, position, spawnTime, parameters) { inner class ServerEntity(data: SystemWorldObjectConfig.Data, uuid: UUID, position: Vector2d, spawnTime: Double = 0.0, parameters: JsonObject = JsonObject()) : Entity(data, uuid, position, spawnTime, parameters) {
constructor(data: EntityJsonData) : this( constructor(data: EntityJsonData) : this(
GlobalDefaults.systemObjects[data.name]?.create(data.actualUUID, data.name) ?: throw NullPointerException("Tried to create ${data.name} system world object, but there is no such object in /system_objects.config!"), Globals.systemObjects[data.name]?.create(data.actualUUID, data.name) ?: throw NullPointerException("Tried to create ${data.name} system world object, but there is no such object in /system_objects.config!"),
data.actualUUID, data.actualUUID,
data.position, data.position,
data.spawnTime, data.spawnTime,

View File

@ -3,8 +3,6 @@ package ru.dbotthepony.kstarbound.server.world
import com.github.benmanes.caffeine.cache.Cache import com.github.benmanes.caffeine.cache.Cache
import com.github.benmanes.caffeine.cache.Caffeine import com.github.benmanes.caffeine.cache.Caffeine
import com.github.benmanes.caffeine.cache.Scheduler import com.github.benmanes.caffeine.cache.Scheduler
import com.google.gson.stream.JsonReader
import it.unimi.dsi.fastutil.io.FastByteArrayInputStream
import it.unimi.dsi.fastutil.objects.ObjectArrayList import it.unimi.dsi.fastutil.objects.ObjectArrayList
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
import kotlinx.coroutines.future.await import kotlinx.coroutines.future.await
@ -14,21 +12,17 @@ import ru.dbotthepony.kommons.io.BTreeDB6
import ru.dbotthepony.kommons.util.AABBi import ru.dbotthepony.kommons.util.AABBi
import ru.dbotthepony.kommons.util.KOptional import ru.dbotthepony.kommons.util.KOptional
import ru.dbotthepony.kommons.vector.Vector2i import ru.dbotthepony.kommons.vector.Vector2i
import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.defs.world.CelestialBaseInformation import ru.dbotthepony.kstarbound.defs.world.CelestialBaseInformation
import ru.dbotthepony.kstarbound.defs.world.CelestialGenerationInformation import ru.dbotthepony.kstarbound.defs.world.CelestialConfig
import ru.dbotthepony.kstarbound.defs.world.CelestialNames
import ru.dbotthepony.kstarbound.defs.world.CelestialParameters import ru.dbotthepony.kstarbound.defs.world.CelestialParameters
import ru.dbotthepony.kstarbound.fromJson
import ru.dbotthepony.kstarbound.io.BTreeDB5 import ru.dbotthepony.kstarbound.io.BTreeDB5
import ru.dbotthepony.kstarbound.util.random.nextRange import ru.dbotthepony.kstarbound.util.random.nextRange
import ru.dbotthepony.kstarbound.util.random.random import ru.dbotthepony.kstarbound.util.random.random
import ru.dbotthepony.kstarbound.util.random.staticRandom64
import ru.dbotthepony.kstarbound.world.Universe import ru.dbotthepony.kstarbound.world.Universe
import ru.dbotthepony.kstarbound.world.UniversePos import ru.dbotthepony.kstarbound.world.UniversePos
import java.io.Closeable import java.io.Closeable
import java.io.File import java.io.File
import java.io.InputStreamReader
import java.time.Duration import java.time.Duration
import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletableFuture
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
@ -63,8 +57,10 @@ class ServerUniverse private constructor(marker: Nothing?) : Universe(), Closeab
} }
override val baseInformation: CelestialBaseInformation override val baseInformation: CelestialBaseInformation
val generationInformation: CelestialGenerationInformation get() = Globals.celestialBaseInformation
val celestialNames: CelestialNames
val generationInformation: CelestialConfig
get() = Globals.celestialConfig
private val sources = ArrayList<UniverseSource>() private val sources = ArrayList<UniverseSource>()
private val closeables = ArrayList<Closeable>() private val closeables = ArrayList<Closeable>()
@ -236,23 +232,6 @@ class ServerUniverse private constructor(marker: Nothing?) : Universe(), Closeab
} }
} }
init {
val celestial = Starbound.read("/celestial.config")
val stream0 = JsonReader(InputStreamReader(FastByteArrayInputStream(celestial.array())))
val stream1 = JsonReader(InputStreamReader(FastByteArrayInputStream(celestial.array())))
stream0.isLenient = true
stream1.isLenient = true
baseInformation = Starbound.gson.fromJson(stream0)!!
generationInformation = Starbound.gson.fromJson(stream1)!!
if (!generationInformation.systemTypePerlin.hasSeedSpecified)
generationInformation.systemTypePerlin.init(staticRandom64("SystemTypePerlin"))
celestialNames = Starbound.gson.fromJson(Starbound.jsonReader("/celestial/names.config"))!!
}
override val region: AABBi = AABBi(Vector2i(baseInformation.xyCoordRange.x, baseInformation.xyCoordRange.x), Vector2i(baseInformation.xyCoordRange.y, baseInformation.xyCoordRange.y)) override val region: AABBi = AABBi(Vector2i(baseInformation.xyCoordRange.x, baseInformation.xyCoordRange.x), Vector2i(baseInformation.xyCoordRange.y, baseInformation.xyCoordRange.y))
} }

View File

@ -16,6 +16,7 @@ import ru.dbotthepony.kommons.util.IStruct2i
import ru.dbotthepony.kommons.util.KOptional import ru.dbotthepony.kommons.util.KOptional
import ru.dbotthepony.kommons.vector.Vector2i import ru.dbotthepony.kommons.vector.Vector2i
import ru.dbotthepony.kommons.vector.Vector3i import ru.dbotthepony.kommons.vector.Vector3i
import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.defs.world.CelestialParameters import ru.dbotthepony.kstarbound.defs.world.CelestialParameters
import ru.dbotthepony.kstarbound.io.BTreeDB5 import ru.dbotthepony.kstarbound.io.BTreeDB5
@ -25,6 +26,7 @@ import ru.dbotthepony.kstarbound.json.writeJsonElement
import ru.dbotthepony.kstarbound.math.Line2d import ru.dbotthepony.kstarbound.math.Line2d
import ru.dbotthepony.kstarbound.util.binnedChoice import ru.dbotthepony.kstarbound.util.binnedChoice
import ru.dbotthepony.kstarbound.util.paddedNumber import ru.dbotthepony.kstarbound.util.paddedNumber
import ru.dbotthepony.kstarbound.util.random.AbstractPerlinNoise
import ru.dbotthepony.kstarbound.util.random.random import ru.dbotthepony.kstarbound.util.random.random
import ru.dbotthepony.kstarbound.util.random.staticRandom64 import ru.dbotthepony.kstarbound.util.random.staticRandom64
import ru.dbotthepony.kstarbound.world.UniversePos import ru.dbotthepony.kstarbound.world.UniversePos
@ -163,8 +165,16 @@ class NativeUniverseSource(private val db: BTreeDB6?, private val universe: Serv
} }
} }
private val systemPerlin = AbstractPerlinNoise.of(universe.generationInformation.systemTypePerlin)
init {
if (!systemPerlin.hasSeedSpecified) {
systemPerlin.init(staticRandom64("SystemTypePerlin"))
}
}
private fun generateSystem(random: RandomGenerator, location: Vector3i): UniverseChunk.System? { private fun generateSystem(random: RandomGenerator, location: Vector3i): UniverseChunk.System? {
val typeSelector = universe.generationInformation.systemTypePerlin[location.x.toDouble(), location.y.toDouble()] val typeSelector = systemPerlin[location.x.toDouble(), location.y.toDouble()]
val type = universe.generationInformation.systemTypeBins val type = universe.generationInformation.systemTypeBins
.stream() .stream()
@ -177,9 +187,9 @@ class NativeUniverseSource(private val db: BTreeDB6?, private val universe: Serv
val systemPos = UniversePos(location) val systemPos = UniversePos(location)
val systemSeed = random.nextLong() val systemSeed = random.nextLong()
val prefix = universe.celestialNames.systemPrefixNames.sample(random).orElse("") val prefix = Globals.celestialNames.systemPrefixNames.sample(random).orElse("")
val mid = universe.celestialNames.systemNames.sample(random).orElse("missingsystemname $location") val mid = Globals.celestialNames.systemNames.sample(random).orElse("missingsystemname $location")
val suffix = universe.celestialNames.systemSuffixNames.sample(random).orElse("") val suffix = Globals.celestialNames.systemSuffixNames.sample(random).orElse("")
val systemName = "$prefix $mid $suffix".trim() val systemName = "$prefix $mid $suffix".trim()
.replace("<onedigit>", random.nextInt(0, 10).toString()) .replace("<onedigit>", random.nextInt(0, 10).toString())
@ -221,7 +231,7 @@ class NativeUniverseSource(private val db: BTreeDB6?, private val universe: Serv
val planetCoordinate = UniversePos(location, planetOrbitIndex) val planetCoordinate = UniversePos(location, planetOrbitIndex)
val planetSeed = random.nextLong() val planetSeed = random.nextLong()
val planetName = "$systemName ${universe.celestialNames.planetarySuffixes[planetOrbitIndex]}" val planetName = "$systemName ${Globals.celestialNames.planetarySuffixes[planetOrbitIndex]}"
val planetParams = CelestialParameters( val planetParams = CelestialParameters(
planetCoordinate, planetCoordinate,
@ -240,7 +250,7 @@ class NativeUniverseSource(private val db: BTreeDB6?, private val universe: Serv
if (!satelliteTypeO.isPresent) continue if (!satelliteTypeO.isPresent) continue
val satelliteType = satelliteTypeO.value val satelliteType = satelliteTypeO.value
val satelliteSeed = random.nextLong() val satelliteSeed = random.nextLong()
val satelliteName = "$planetName ${universe.celestialNames.satelliteSuffixes[satellites.size]}" val satelliteName = "$planetName ${Globals.celestialNames.satelliteSuffixes[satellites.size]}"
val satelliteCoordinate = UniversePos(location, planetOrbitIndex, satelliteOrbitIndex) val satelliteCoordinate = UniversePos(location, planetOrbitIndex, satelliteOrbitIndex)
val merge = JsonObject() val merge = JsonObject()

View File

@ -7,7 +7,7 @@ import ru.dbotthepony.kommons.util.getValue
import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.kommons.util.setValue
import ru.dbotthepony.kommons.util.value import ru.dbotthepony.kommons.util.value
import ru.dbotthepony.kommons.vector.Vector2d import ru.dbotthepony.kommons.vector.Vector2d
import ru.dbotthepony.kstarbound.GlobalDefaults import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.defs.world.FlyingType import ru.dbotthepony.kstarbound.defs.world.FlyingType
import ru.dbotthepony.kstarbound.defs.world.SkyGlobalConfig import ru.dbotthepony.kstarbound.defs.world.SkyGlobalConfig
@ -75,17 +75,17 @@ class Sky() {
val speedupTime: Double get() { val speedupTime: Double get() {
if (enterHyperspace) { if (enterHyperspace) {
return GlobalDefaults.sky.hyperspaceSpeedupTime.coerceAtLeast(0.01) return Globals.sky.hyperspaceSpeedupTime.coerceAtLeast(0.01)
} else { } else {
return GlobalDefaults.sky.speedupTime.coerceAtLeast(0.01) return Globals.sky.speedupTime.coerceAtLeast(0.01)
} }
} }
val slowdownTime: Double get() { val slowdownTime: Double get() {
if (enterHyperspace) { if (enterHyperspace) {
return GlobalDefaults.sky.hyperspaceSlowdownTime.coerceAtLeast(0.01) return Globals.sky.hyperspaceSlowdownTime.coerceAtLeast(0.01)
} else { } else {
return GlobalDefaults.sky.slowdownTime.coerceAtLeast(0.01) return Globals.sky.slowdownTime.coerceAtLeast(0.01)
} }
} }
@ -138,8 +138,8 @@ class Sky() {
lastWarpPhase = warpPhase lastWarpPhase = warpPhase
} }
worldMoveOffset = Vector2d(cos(pathRotation), sin(pathRotation)) * GlobalDefaults.sky.flyMaxVelocity / 2.0 * speedupTime worldMoveOffset = Vector2d(cos(pathRotation), sin(pathRotation)) * Globals.sky.flyMaxVelocity / 2.0 * speedupTime
starMoveOffset = Vector2d(x = GlobalDefaults.sky.flyMaxVelocity * GlobalDefaults.sky.starVelocityFactor / 2.0 * speedupTime) starMoveOffset = Vector2d(x = Globals.sky.flyMaxVelocity * Globals.sky.starVelocityFactor / 2.0 * speedupTime)
} else if (flyingType == FlyingType.ARRIVING) { } else if (flyingType == FlyingType.ARRIVING) {
sentSFX = false sentSFX = false
worldOffset = Vector2d.ZERO worldOffset = Vector2d.ZERO
@ -156,17 +156,17 @@ class Sky() {
//flashTimer = GlobalDefaults.sky.flashTimer //flashTimer = GlobalDefaults.sky.flashTimer
sentSFX = false sentSFX = false
val origin = if (skyType == SkyType.SPACE) GlobalDefaults.sky.spaceArrivalOrigin else GlobalDefaults.sky.arrivalOrigin val origin = if (skyType == SkyType.SPACE) Globals.sky.spaceArrivalOrigin else Globals.sky.arrivalOrigin
val path = if (skyType == SkyType.SPACE) GlobalDefaults.sky.spaceArrivalPath else GlobalDefaults.sky.arrivalPath val path = if (skyType == SkyType.SPACE) Globals.sky.spaceArrivalPath else Globals.sky.arrivalPath
pathOffset = origin.offset pathOffset = origin.offset
pathRotation = origin.rotationRad pathRotation = origin.rotationRad
var exitDistance = GlobalDefaults.sky.flyMaxVelocity / 2.0 * slowdownTime var exitDistance = Globals.sky.flyMaxVelocity / 2.0 * slowdownTime
worldMoveOffset = Vector2d(x = exitDistance) worldMoveOffset = Vector2d(x = exitDistance)
worldOffset = worldMoveOffset worldOffset = worldMoveOffset
exitDistance *= GlobalDefaults.sky.starVelocityFactor exitDistance *= Globals.sky.starVelocityFactor
starMoveOffset = Vector2d(x = exitDistance) starMoveOffset = Vector2d(x = exitDistance)
starOffset = starMoveOffset starOffset = starMoveOffset
@ -202,25 +202,25 @@ class Sky() {
if (flyingType == FlyingType.DISEMBARKING) { if (flyingType == FlyingType.DISEMBARKING) {
val finished = if (skyParametersNetState.value.skyType == SkyType.SPACE) val finished = if (skyParametersNetState.value.skyType == SkyType.SPACE)
controlledMovement(GlobalDefaults.sky.spaceDisembarkPath, GlobalDefaults.sky.spaceDisembarkOrigin, flyingTimer) controlledMovement(Globals.sky.spaceDisembarkPath, Globals.sky.spaceDisembarkOrigin, flyingTimer)
else else
controlledMovement(GlobalDefaults.sky.disembarkPath, GlobalDefaults.sky.disembarkOrigin, flyingTimer) controlledMovement(Globals.sky.disembarkPath, Globals.sky.disembarkOrigin, flyingTimer)
if (finished) { if (finished) {
flyingType = FlyingType.WARP flyingType = FlyingType.WARP
} }
} else if (flyingType == FlyingType.ARRIVING) { } else if (flyingType == FlyingType.ARRIVING) {
val finished = if (skyParametersNetState.value.skyType == SkyType.SPACE) val finished = if (skyParametersNetState.value.skyType == SkyType.SPACE)
controlledMovement(GlobalDefaults.sky.spaceArrivalPath, GlobalDefaults.sky.spaceArrivalOrigin, flyingTimer) controlledMovement(Globals.sky.spaceArrivalPath, Globals.sky.spaceArrivalOrigin, flyingTimer)
else else
controlledMovement(GlobalDefaults.sky.arrivalPath, GlobalDefaults.sky.arrivalOrigin, flyingTimer) controlledMovement(Globals.sky.arrivalPath, Globals.sky.arrivalOrigin, flyingTimer)
if (finished) { if (finished) {
flyingType = FlyingType.NONE flyingType = FlyingType.NONE
} }
starOffset -= starOffset * GlobalDefaults.sky.correctionPower starOffset -= starOffset * Globals.sky.correctionPower
worldOffset -= worldOffset * GlobalDefaults.sky.correctionPower worldOffset -= worldOffset * Globals.sky.correctionPower
} else if (flyingType == FlyingType.WARP) { } else if (flyingType == FlyingType.WARP) {
val percentage = when (warpPhase) { val percentage = when (warpPhase) {
WarpPhase.SLOWING_DOWN -> (flyingTimer / speedupTime).pow(2.0) WarpPhase.SLOWING_DOWN -> (flyingTimer / speedupTime).pow(2.0)
@ -235,7 +235,7 @@ class Sky() {
} else { } else {
val angle = -(starRotation + pathRotation) val angle = -(starRotation + pathRotation)
val angleVec = Vector2d(cos(angle), sin(angle)) val angleVec = Vector2d(cos(angle), sin(angle))
starOffset += angleVec * GlobalDefaults.sky.flyMaxVelocity * delta * GlobalDefaults.sky.starVelocityFactor starOffset += angleVec * Globals.sky.flyMaxVelocity * delta * Globals.sky.starVelocityFactor
worldOffset = worldMoveOffset worldOffset = worldMoveOffset
} }
@ -245,7 +245,7 @@ class Sky() {
warpPhase = WarpPhase.SLOWING_DOWN warpPhase = WarpPhase.SLOWING_DOWN
} else if (warpPhase == WarpPhase.SPEEDING_UP && flyingTimer >= speedupTime && enterHyperspace) { } else if (warpPhase == WarpPhase.SPEEDING_UP && flyingTimer >= speedupTime && enterHyperspace) {
warpPhase = WarpPhase.MAINTAIN warpPhase = WarpPhase.MAINTAIN
} else if (warpPhase == WarpPhase.MAINTAIN && flyingTimer >= GlobalDefaults.sky.flyingTimer && destination != null) { } else if (warpPhase == WarpPhase.MAINTAIN && flyingTimer >= Globals.sky.flyingTimer && destination != null) {
skyParametersNetState.value = destination!! skyParametersNetState.value = destination!!
destination = null destination = null
warpPhase = WarpPhase.SLOWING_DOWN warpPhase = WarpPhase.SLOWING_DOWN

View File

@ -1,25 +1,19 @@
package ru.dbotthepony.kstarbound.world package ru.dbotthepony.kstarbound.world
import com.google.gson.JsonObject import com.google.gson.JsonObject
import kotlinx.coroutines.CoroutineScope
import ru.dbotthepony.kommons.io.koptional import ru.dbotthepony.kommons.io.koptional
import ru.dbotthepony.kommons.io.writeBinaryString
import ru.dbotthepony.kommons.io.writeUUID
import ru.dbotthepony.kommons.util.KOptional import ru.dbotthepony.kommons.util.KOptional
import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.getValue
import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.kommons.util.setValue
import ru.dbotthepony.kommons.vector.Vector2d import ru.dbotthepony.kommons.vector.Vector2d
import ru.dbotthepony.kommons.vector.Vector3i import ru.dbotthepony.kommons.vector.Vector3i
import ru.dbotthepony.kstarbound.GlobalDefaults import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.defs.world.FloatingDungeonWorldParameters import ru.dbotthepony.kstarbound.defs.world.FloatingDungeonWorldParameters
import ru.dbotthepony.kstarbound.defs.world.SystemWorldObjectConfig import ru.dbotthepony.kstarbound.defs.world.SystemWorldObjectConfig
import ru.dbotthepony.kstarbound.io.readDouble
import ru.dbotthepony.kstarbound.io.readVector2d import ru.dbotthepony.kstarbound.io.readVector2d
import ru.dbotthepony.kstarbound.io.writeDouble
import ru.dbotthepony.kstarbound.io.writeStruct2d import ru.dbotthepony.kstarbound.io.writeStruct2d
import ru.dbotthepony.kstarbound.json.builder.JsonFactory import ru.dbotthepony.kstarbound.json.builder.JsonFactory
import ru.dbotthepony.kstarbound.json.writeJsonObject
import ru.dbotthepony.kstarbound.math.Interpolator import ru.dbotthepony.kstarbound.math.Interpolator
import ru.dbotthepony.kstarbound.network.syncher.MasterElement import ru.dbotthepony.kstarbound.network.syncher.MasterElement
import ru.dbotthepony.kstarbound.network.syncher.NetworkedGroup import ru.dbotthepony.kstarbound.network.syncher.NetworkedGroup
@ -61,9 +55,9 @@ abstract class SystemWorld(val location: Vector3i, val clock: Clock, val univers
} }
if (coordinate.isPlanet) if (coordinate.isPlanet)
distance += random.nextFloat(GlobalDefaults.systemWorld.planetaryOrbitPadding.x.toFloat(), GlobalDefaults.systemWorld.planetaryOrbitPadding.y.toFloat()) distance += random.nextFloat(Globals.systemWorld.planetaryOrbitPadding.x.toFloat(), Globals.systemWorld.planetaryOrbitPadding.y.toFloat())
else if (coordinate.isSatellite) else if (coordinate.isSatellite)
distance += random.nextFloat(GlobalDefaults.systemWorld.satelliteOrbitPadding.x.toFloat(), GlobalDefaults.systemWorld.satelliteOrbitPadding.y.toFloat()) distance += random.nextFloat(Globals.systemWorld.satelliteOrbitPadding.x.toFloat(), Globals.systemWorld.satelliteOrbitPadding.y.toFloat())
} }
distance += clusterSize(coordinate) / 2.0 distance += clusterSize(coordinate) / 2.0
@ -87,10 +81,10 @@ abstract class SystemWorld(val location: Vector3i, val clock: Clock, val univers
suspend fun planetSize(coordinate: UniversePos): Double { suspend fun planetSize(coordinate: UniversePos): Double {
if (coordinate.isSystem) if (coordinate.isSystem)
return GlobalDefaults.systemWorld.starSize return Globals.systemWorld.starSize
if (!universe.children(coordinate.parent()).any { it.orbitNumber == coordinate.orbitNumber }) if (!universe.children(coordinate.parent()).any { it.orbitNumber == coordinate.orbitNumber })
return GlobalDefaults.systemWorld.emptyOrbitSize return Globals.systemWorld.emptyOrbitSize
val parameters = universe.parameters(coordinate) val parameters = universe.parameters(coordinate)
@ -101,14 +95,14 @@ abstract class SystemWorld(val location: Vector3i, val clock: Clock, val univers
var size = 0.0 var size = 0.0
if (visitable is FloatingDungeonWorldParameters) { if (visitable is FloatingDungeonWorldParameters) {
val getSize = GlobalDefaults.systemWorld.floatingDungeonWorldSizes[visitable.typeName] val getSize = Globals.systemWorld.floatingDungeonWorldSizes[visitable.typeName]
if (getSize != null) { if (getSize != null) {
return getSize return getSize
} }
} }
for ((planetSize, orbitSize) in GlobalDefaults.systemWorld.planetSizes) { for ((planetSize, orbitSize) in Globals.systemWorld.planetSizes) {
if (visitable.worldSize.x >= planetSize) if (visitable.worldSize.x >= planetSize)
size = orbitSize size = orbitSize
else else
@ -119,11 +113,11 @@ abstract class SystemWorld(val location: Vector3i, val clock: Clock, val univers
} }
} }
return GlobalDefaults.systemWorld.unvisitablePlanetSize return Globals.systemWorld.unvisitablePlanetSize
} }
fun orbitInterval(distance: Double, isSatellite: Boolean): Double { fun orbitInterval(distance: Double, isSatellite: Boolean): Double {
val gravityConstant = if (isSatellite) GlobalDefaults.systemWorld.planetGravitationalConstant else GlobalDefaults.systemWorld.starGravitationalConstant val gravityConstant = if (isSatellite) Globals.systemWorld.planetGravitationalConstant else Globals.systemWorld.starGravitationalConstant
return distance * 2.0 * PI / sqrt(gravityConstant / distance) return distance * 2.0 * PI / sqrt(gravityConstant / distance)
} }
@ -171,7 +165,7 @@ abstract class SystemWorld(val location: Vector3i, val clock: Clock, val univers
} }
fun randomArrivalPosition(): Vector2d { fun randomArrivalPosition(): Vector2d {
val range = random.nextRange(GlobalDefaults.systemWorld.arrivalRange) val range = random.nextRange(Globals.systemWorld.arrivalRange)
val angle = random.nextDouble(0.0, PI * 2.0) val angle = random.nextDouble(0.0, PI * 2.0)
return Vector2d(cos(angle), sin(angle)) * range return Vector2d(cos(angle), sin(angle)) * range
} }
@ -210,7 +204,7 @@ abstract class SystemWorld(val location: Vector3i, val clock: Clock, val univers
} }
abstract inner class Ship(val uuid: UUID, location: SystemWorldLocation) { abstract inner class Ship(val uuid: UUID, location: SystemWorldLocation) {
var speed = GlobalDefaults.systemWorld.clientShip.speed var speed = Globals.systemWorld.clientShip.speed
var departTimer = 0.0 var departTimer = 0.0
val networkGroup = MasterElement(NetworkedGroup()) val networkGroup = MasterElement(NetworkedGroup())
@ -239,7 +233,7 @@ abstract class SystemWorld(val location: Vector3i, val clock: Clock, val univers
abstract inner class Entity(val data: SystemWorldObjectConfig.Data, val uuid: UUID, position: Vector2d, val spawnTime: Double = 0.0, val parameters: JsonObject = JsonObject()) { abstract inner class Entity(val data: SystemWorldObjectConfig.Data, val uuid: UUID, position: Vector2d, val spawnTime: Double = 0.0, val parameters: JsonObject = JsonObject()) {
constructor(data: EntityJsonData) : this( constructor(data: EntityJsonData) : this(
GlobalDefaults.systemObjects[data.name]?.create(data.actualUUID, data.name) ?: throw NullPointerException("Tried to create ${data.name} system world object, but there is no such object in /system_objects.config!"), Globals.systemObjects[data.name]?.create(data.actualUUID, data.name) ?: throw NullPointerException("Tried to create ${data.name} system world object, but there is no such object in /system_objects.config!"),
data.actualUUID, data.actualUUID,
data.position, data.position,
data.spawnTime, data.spawnTime,

View File

@ -1,21 +1,23 @@
package ru.dbotthepony.kstarbound.world package ru.dbotthepony.kstarbound.world
import com.google.common.collect.ImmutableList
import ru.dbotthepony.kommons.io.readUUID import ru.dbotthepony.kommons.io.readUUID
import ru.dbotthepony.kommons.io.writeUUID import ru.dbotthepony.kommons.io.writeUUID
import ru.dbotthepony.kommons.util.KOptional import ru.dbotthepony.kommons.util.KOptional
import ru.dbotthepony.kommons.vector.Vector2d import ru.dbotthepony.kommons.vector.Vector2d
import ru.dbotthepony.kstarbound.GlobalDefaults import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.defs.SpawnTarget import ru.dbotthepony.kstarbound.defs.SpawnTarget
import ru.dbotthepony.kstarbound.defs.WarpAction import ru.dbotthepony.kstarbound.defs.WarpAction
import ru.dbotthepony.kstarbound.defs.WarpMode import ru.dbotthepony.kstarbound.defs.WarpMode
import ru.dbotthepony.kstarbound.defs.WorldID import ru.dbotthepony.kstarbound.defs.WorldID
import ru.dbotthepony.kstarbound.defs.world.AsteroidsWorldParameters import ru.dbotthepony.kstarbound.defs.world.AsteroidsWorldParameters
import ru.dbotthepony.kstarbound.defs.world.SkyParameters import ru.dbotthepony.kstarbound.defs.world.SkyParameters
import ru.dbotthepony.kstarbound.defs.world.SkyType
import ru.dbotthepony.kstarbound.io.readVector2d import ru.dbotthepony.kstarbound.io.readVector2d
import ru.dbotthepony.kstarbound.io.writeStruct2d import ru.dbotthepony.kstarbound.io.writeStruct2d
import ru.dbotthepony.kstarbound.network.syncher.legacyCodec import ru.dbotthepony.kstarbound.network.syncher.legacyCodec
import ru.dbotthepony.kstarbound.network.syncher.nativeCodec import ru.dbotthepony.kstarbound.network.syncher.nativeCodec
import ru.dbotthepony.kstarbound.util.random.random
import ru.dbotthepony.kstarbound.util.random.staticRandom64
import java.io.DataInputStream import java.io.DataInputStream
import java.io.DataOutputStream import java.io.DataOutputStream
import java.util.UUID import java.util.UUID
@ -28,8 +30,32 @@ sealed class SystemWorldLocation {
abstract suspend fun orbitalAction(system: SystemWorld): KOptional<Pair<WarpAction, WarpMode>> abstract suspend fun orbitalAction(system: SystemWorld): KOptional<Pair<WarpAction, WarpMode>>
abstract suspend fun skyParameters(system: SystemWorld): SkyParameters abstract suspend fun skyParameters(system: SystemWorld): SkyParameters
protected suspend fun appendParameters(parameters: SkyParameters, system: SystemWorld) { protected suspend fun appendParameters(parameters: SkyParameters, system: SystemWorld, orbit: UniversePos): SkyParameters {
val planets = ArrayList<UniversePos>()
// in original code, they only append nearby planet list only if we are orbiting a planet,
// and not a satellite. So let's fix that!
if (orbit.isSatellite) {
planets.add(orbit.parent())
planets.addAll(system.universe.children(orbit.parent()))
} else if (orbit.isPlanet) {
planets.add(orbit)
planets.addAll(system.universe.children(orbit))
}
val random = random(staticRandom64(orbit.toString()))
val satellites = ArrayList(parameters.satellites)
for (body in planets) {
val pos = Vector2d(random.nextDouble(), random.nextDouble())
val bodyParams = system.universe.parameters(body) ?: continue
satellites.add(SkyParameters.Planet(pos, ImmutableList.copyOf(SkyParameters.drawWorld(bodyParams))))
}
parameters.satellites = ImmutableList.copyOf(satellites)
return parameters
} }
object Transit : SystemWorldLocation() { object Transit : SystemWorldLocation() {
@ -46,7 +72,7 @@ sealed class SystemWorldLocation {
} }
override suspend fun skyParameters(system: SystemWorld): SkyParameters { override suspend fun skyParameters(system: SystemWorld): SkyParameters {
return GlobalDefaults.systemWorld.emptySkyParameters return Globals.systemWorld.emptySkyParameters
} }
} }
@ -86,11 +112,10 @@ sealed class SystemWorldLocation {
} }
override suspend fun skyParameters(system: SystemWorld): SkyParameters { override suspend fun skyParameters(system: SystemWorld): SkyParameters {
if (position.target.isPlanet) { // original code here is different,
// since it is assumed we can't "outer" orbit satellites
} // (but that is still technically possible to outer-orbit a satellite)
return appendParameters(Globals.systemWorld.emptySkyParameters.copy(), system, position.target)
return GlobalDefaults.systemWorld.emptySkyParameters
} }
} }
@ -110,8 +135,20 @@ sealed class SystemWorldLocation {
} }
override suspend fun skyParameters(system: SystemWorld): SkyParameters { override suspend fun skyParameters(system: SystemWorld): SkyParameters {
val get = system.entities[uuid] ?: return GlobalDefaults.systemWorld.emptySkyParameters val get = system.entities[uuid] ?: return Globals.systemWorld.emptySkyParameters
return get.data.skyParameters
val orbit = get.orbit.orNull()?.target
var sky = get.data.skyParameters
// original code here is slightly different again,
// if entity is orbiting a satellite, it won't add planets and
// its satellites to sky parameters
if (orbit != null && !orbit.isSystem) {
sky = sky.copy()
appendParameters(sky, system, orbit)
}
return sky
} }
} }
@ -128,7 +165,7 @@ sealed class SystemWorldLocation {
override suspend fun orbitalAction(system: SystemWorld): KOptional<Pair<WarpAction, WarpMode>> { override suspend fun orbitalAction(system: SystemWorld): KOptional<Pair<WarpAction, WarpMode>> {
// player can beam to asteroid fields simply by being in proximity to them // player can beam to asteroid fields simply by being in proximity to them
for (child in system.universe.children(system.systemLocation)) { for (child in system.universe.children(system.systemLocation)) {
if ((system.planetPosition(child).length - position.length).absoluteValue > GlobalDefaults.systemWorld.asteroidBeamDistance) { if ((system.planetPosition(child).length - position.length).absoluteValue > Globals.systemWorld.asteroidBeamDistance) {
continue continue
} }
@ -146,7 +183,7 @@ sealed class SystemWorldLocation {
override suspend fun skyParameters(system: SystemWorld): SkyParameters { override suspend fun skyParameters(system: SystemWorld): SkyParameters {
for (child in system.universe.children(system.systemLocation)) { for (child in system.universe.children(system.systemLocation)) {
if ((system.planetPosition(child).length - position.length).absoluteValue > GlobalDefaults.systemWorld.asteroidBeamDistance) { if ((system.planetPosition(child).length - position.length).absoluteValue > Globals.systemWorld.asteroidBeamDistance) {
continue continue
} }
@ -158,7 +195,7 @@ sealed class SystemWorldLocation {
} }
} }
return GlobalDefaults.systemWorld.emptySkyParameters return Globals.systemWorld.emptySkyParameters
} }
} }

View File

@ -5,7 +5,7 @@ import ru.dbotthepony.kommons.guava.immutableMap
import ru.dbotthepony.kommons.io.readVarInt import ru.dbotthepony.kommons.io.readVarInt
import ru.dbotthepony.kommons.io.writeBinaryString import ru.dbotthepony.kommons.io.writeBinaryString
import ru.dbotthepony.kommons.io.writeVarInt import ru.dbotthepony.kommons.io.writeVarInt
import ru.dbotthepony.kstarbound.GlobalDefaults import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.defs.actor.EquipmentSlot import ru.dbotthepony.kstarbound.defs.actor.EquipmentSlot
import ru.dbotthepony.kstarbound.item.ItemStack import ru.dbotthepony.kstarbound.item.ItemStack
import ru.dbotthepony.kstarbound.io.readInternedString import ru.dbotthepony.kstarbound.io.readInternedString
@ -101,7 +101,7 @@ sealed class InventoryIndex {
companion object { companion object {
private val bagIndexCache by lazy { private val bagIndexCache by lazy {
immutableMap { immutableMap {
GlobalDefaults.player.inventory.itemBags.keys.forEach { n -> Globals.player.inventory.itemBags.keys.forEach { n ->
put(n, immutableList(256) { put(n, immutableList(256) {
BagIndex(n, it) BagIndex(n, it)
}) })

View File

@ -1,15 +1,12 @@
package ru.dbotthepony.kstarbound.world.entities.player package ru.dbotthepony.kstarbound.world.entities.player
import com.google.gson.JsonElement import com.google.gson.JsonElement
import com.google.gson.JsonObject
import it.unimi.dsi.fastutil.bytes.ByteArrayList
import ru.dbotthepony.kommons.io.writeBinaryString import ru.dbotthepony.kommons.io.writeBinaryString
import ru.dbotthepony.kommons.util.AABB
import ru.dbotthepony.kommons.util.KOptional import ru.dbotthepony.kommons.util.KOptional
import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.getValue
import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.kommons.util.setValue
import ru.dbotthepony.kommons.vector.Vector2d import ru.dbotthepony.kommons.vector.Vector2d
import ru.dbotthepony.kstarbound.GlobalDefaults import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.defs.EntityDamageTeam import ru.dbotthepony.kstarbound.defs.EntityDamageTeam
import ru.dbotthepony.kstarbound.defs.EntityType import ru.dbotthepony.kstarbound.defs.EntityType
import ru.dbotthepony.kstarbound.defs.actor.HumanoidData import ru.dbotthepony.kstarbound.defs.actor.HumanoidData
@ -19,8 +16,6 @@ import ru.dbotthepony.kstarbound.io.readInternedString
import ru.dbotthepony.kstarbound.json.JsonPath import ru.dbotthepony.kstarbound.json.JsonPath
import ru.dbotthepony.kstarbound.json.builder.IStringSerializable import ru.dbotthepony.kstarbound.json.builder.IStringSerializable
import ru.dbotthepony.kstarbound.math.Interpolator import ru.dbotthepony.kstarbound.math.Interpolator
import ru.dbotthepony.kstarbound.network.syncher.NetworkedGroup
import ru.dbotthepony.kstarbound.network.syncher.MasterElement
import ru.dbotthepony.kstarbound.network.syncher.networkedBoolean import ru.dbotthepony.kstarbound.network.syncher.networkedBoolean
import ru.dbotthepony.kstarbound.network.syncher.networkedData import ru.dbotthepony.kstarbound.network.syncher.networkedData
import ru.dbotthepony.kstarbound.network.syncher.networkedEnum import ru.dbotthepony.kstarbound.network.syncher.networkedEnum
@ -80,8 +75,8 @@ class PlayerEntity() : HumanoidActorEntity("/") {
val inventory = PlayerInventory() val inventory = PlayerInventory()
val songbook = Songbook(this) val songbook = Songbook(this)
val effectAnimator = if (GlobalDefaults.player.effectsAnimator.value == null) Animator() else Animator(GlobalDefaults.player.effectsAnimator.value!!) val effectAnimator = if (Globals.player.effectsAnimator.value == null) Animator() else Animator(Globals.player.effectsAnimator.value!!)
override val statusController = StatusController(this, GlobalDefaults.player.statusControllerSettings) override val statusController = StatusController(this, Globals.player.statusControllerSettings)
val techController = TechController(this) val techController = TechController(this)
var state by networkGroup.upstream.add(networkedEnum(State.IDLE)) var state by networkGroup.upstream.add(networkedEnum(State.IDLE))
@ -126,7 +121,7 @@ class PlayerEntity() : HumanoidActorEntity("/") {
if (fixturesChangeset != movement.fixturesChangeset) { if (fixturesChangeset != movement.fixturesChangeset) {
fixturesChangeset = movement.fixturesChangeset fixturesChangeset = movement.fixturesChangeset
metaFixture!!.move(GlobalDefaults.player.metaBoundBox + position) metaFixture!!.move(Globals.player.metaBoundBox + position)
} }
} }

View File

@ -1,20 +1,16 @@
package ru.dbotthepony.kstarbound.world.entities.player package ru.dbotthepony.kstarbound.world.entities.player
import com.google.common.collect.ImmutableMap import com.google.common.collect.ImmutableMap
import it.unimi.dsi.fastutil.objects.Object2LongAVLTreeMap
import ru.dbotthepony.kommons.arrays.Object2DArray import ru.dbotthepony.kommons.arrays.Object2DArray
import ru.dbotthepony.kommons.guava.immutableList import ru.dbotthepony.kommons.guava.immutableList
import ru.dbotthepony.kommons.io.BinaryStringCodec
import ru.dbotthepony.kommons.io.LongValueCodec import ru.dbotthepony.kommons.io.LongValueCodec
import ru.dbotthepony.kommons.io.StreamCodec
import ru.dbotthepony.kommons.io.UnsignedVarLongCodec import ru.dbotthepony.kommons.io.UnsignedVarLongCodec
import ru.dbotthepony.kommons.io.VarLongValueCodec
import ru.dbotthepony.kommons.io.readKOptional import ru.dbotthepony.kommons.io.readKOptional
import ru.dbotthepony.kommons.io.writeKOptional import ru.dbotthepony.kommons.io.writeKOptional
import ru.dbotthepony.kommons.util.KOptional import ru.dbotthepony.kommons.util.KOptional
import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.getValue
import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.kommons.util.setValue
import ru.dbotthepony.kstarbound.GlobalDefaults import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.defs.actor.EquipmentSlot import ru.dbotthepony.kstarbound.defs.actor.EquipmentSlot
import ru.dbotthepony.kstarbound.defs.actor.EssentialSlot import ru.dbotthepony.kstarbound.defs.actor.EssentialSlot
import ru.dbotthepony.kstarbound.item.ItemStack import ru.dbotthepony.kstarbound.item.ItemStack
@ -65,7 +61,7 @@ class PlayerInventory {
// if bags have same priority, PlayerInventory behavior becomes undefined // if bags have same priority, PlayerInventory behavior becomes undefined
// We, on the other hand, use stable sort provided by Java // We, on the other hand, use stable sort provided by Java
// (and if bags have the same priority they will appear in order they are defined in json) // (and if bags have the same priority they will appear in order they are defined in json)
val bags: ImmutableMap<String, Bag> = GlobalDefaults.player.inventory.itemBags.entries val bags: ImmutableMap<String, Bag> = Globals.player.inventory.itemBags.entries
.stream() .stream()
.sorted { o1, o2 -> o1.value.priority.compareTo(o2.value.priority) } .sorted { o1, o2 -> o1.value.priority.compareTo(o2.value.priority) }
.map { it.key to Bag(it.value.size) } .map { it.key to Bag(it.value.size) }
@ -88,7 +84,7 @@ class PlayerInventory {
// because otherwise // because otherwise
// it will throw "element not found" // it will throw "element not found"
// when trying to update currencies // when trying to update currencies
for (key in GlobalDefaults.currencies.keys) { for (key in Globals.currencies.keys) {
currencies[key] = 0L currencies[key] = 0L
} }
} }
@ -130,7 +126,7 @@ class PlayerInventory {
} }
var hotbarGroup by networkGroup.add(networkedUnsignedInt()) var hotbarGroup by networkGroup.add(networkedUnsignedInt())
val hotbarSlots = Object2DArray(GlobalDefaults.player.inventory.customBarIndexes, GlobalDefaults.player.inventory.customBarGroups) { _, _ -> val hotbarSlots = Object2DArray(Globals.player.inventory.customBarIndexes, Globals.player.inventory.customBarGroups) { _, _ ->
networkedData(HotbarSlot(), HotbarSlot.CODEC, HotbarSlot.LEGACY_CODEC) networkedData(HotbarSlot(), HotbarSlot.CODEC, HotbarSlot.LEGACY_CODEC)
} }