Compare commits

...

10 Commits

59 changed files with 718 additions and 236 deletions

View File

@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m
kotlinVersion=1.9.10 kotlinVersion=1.9.10
kotlinCoroutinesVersion=1.8.0 kotlinCoroutinesVersion=1.8.0
kommonsVersion=3.0.1 kommonsVersion=3.1.0
ffiVersion=2.2.13 ffiVersion=2.2.13
lwjglVersion=3.3.0 lwjglVersion=3.3.0

View File

@ -40,7 +40,7 @@ class ResumeInfo {
if (resumable instanceof ProtectedResumable) { if (resumable instanceof ProtectedResumable) {
// top is protected, can handle the error // top is protected, can handle the error
ProtectedResumable pr = (ProtectedResumable) resumable; ProtectedResumable pr = (ProtectedResumable) resumable;
pr.resumeError(context, savedState, Conversions.toErrorObject(error)); pr.resumeError(context, savedState, error);
Dispatch.evaluateTailCalls(context); Dispatch.evaluateTailCalls(context);
return true; return true;
} else { } else {

View File

@ -4,7 +4,10 @@ import com.google.common.collect.ImmutableList
import com.google.common.collect.ImmutableMap import com.google.common.collect.ImmutableMap
import com.google.gson.GsonBuilder import com.google.gson.GsonBuilder
import com.google.gson.JsonArray import com.google.gson.JsonArray
import com.google.gson.JsonElement
import com.google.gson.JsonNull
import com.google.gson.JsonObject import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive
import com.google.gson.JsonSyntaxException import com.google.gson.JsonSyntaxException
import com.google.gson.TypeAdapterFactory import com.google.gson.TypeAdapterFactory
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
@ -14,6 +17,7 @@ import kotlinx.coroutines.future.asCompletableFuture
import kotlinx.coroutines.future.await 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.gson.contains
import ru.dbotthepony.kommons.util.KOptional import ru.dbotthepony.kommons.util.KOptional
import ru.dbotthepony.kstarbound.defs.AssetReference import ru.dbotthepony.kstarbound.defs.AssetReference
import ru.dbotthepony.kstarbound.defs.DamageKind import ru.dbotthepony.kstarbound.defs.DamageKind
@ -21,14 +25,13 @@ import ru.dbotthepony.kstarbound.defs.Json2Function
import ru.dbotthepony.kstarbound.defs.JsonConfigFunction import ru.dbotthepony.kstarbound.defs.JsonConfigFunction
import ru.dbotthepony.kstarbound.defs.JsonFunction import ru.dbotthepony.kstarbound.defs.JsonFunction
import ru.dbotthepony.kstarbound.defs.MarkovTextGenerator import ru.dbotthepony.kstarbound.defs.MarkovTextGenerator
import ru.dbotthepony.kstarbound.defs.Species import ru.dbotthepony.kstarbound.defs.actor.Species
import ru.dbotthepony.kstarbound.defs.StatusEffectDefinition import ru.dbotthepony.kstarbound.defs.StatusEffectDefinition
import ru.dbotthepony.kstarbound.defs.ThingDescription import ru.dbotthepony.kstarbound.defs.ThingDescription
import ru.dbotthepony.kstarbound.defs.item.TreasurePoolDefinition import ru.dbotthepony.kstarbound.defs.item.TreasurePoolDefinition
import ru.dbotthepony.kstarbound.defs.monster.MonsterSkillDefinition import ru.dbotthepony.kstarbound.defs.monster.MonsterSkillDefinition
import ru.dbotthepony.kstarbound.defs.monster.MonsterTypeDefinition import ru.dbotthepony.kstarbound.defs.monster.MonsterTypeDefinition
import ru.dbotthepony.kstarbound.defs.npc.NpcTypeDefinition import ru.dbotthepony.kstarbound.defs.actor.TenantDefinition
import ru.dbotthepony.kstarbound.defs.npc.TenantDefinition
import ru.dbotthepony.kstarbound.defs.`object`.ObjectDefinition import ru.dbotthepony.kstarbound.defs.`object`.ObjectDefinition
import ru.dbotthepony.kstarbound.defs.actor.player.TechDefinition import ru.dbotthepony.kstarbound.defs.actor.player.TechDefinition
import ru.dbotthepony.kstarbound.defs.animation.ParticleConfig import ru.dbotthepony.kstarbound.defs.animation.ParticleConfig
@ -54,6 +57,7 @@ import ru.dbotthepony.kstarbound.item.ItemRegistry
import ru.dbotthepony.kstarbound.json.JsonPatch import ru.dbotthepony.kstarbound.json.JsonPatch
import ru.dbotthepony.kstarbound.json.builder.JsonFactory import ru.dbotthepony.kstarbound.json.builder.JsonFactory
import ru.dbotthepony.kstarbound.json.fromJsonTreeFast import ru.dbotthepony.kstarbound.json.fromJsonTreeFast
import ru.dbotthepony.kstarbound.json.mergeJson
import ru.dbotthepony.kstarbound.world.terrain.TerrainSelectorType import ru.dbotthepony.kstarbound.world.terrain.TerrainSelectorType
import ru.dbotthepony.kstarbound.util.AssetPathStack import ru.dbotthepony.kstarbound.util.AssetPathStack
import ru.dbotthepony.kstarbound.util.random.random import ru.dbotthepony.kstarbound.util.random.random
@ -62,6 +66,7 @@ import java.util.*
import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletableFuture
import java.util.concurrent.Future import java.util.concurrent.Future
import java.util.random.RandomGenerator import java.util.random.RandomGenerator
import kotlin.NoSuchElementException
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
import kotlin.collections.HashMap import kotlin.collections.HashMap
@ -87,7 +92,6 @@ object Registries {
val jsonFunctions = Registry<JsonFunction>("json function").also(registriesInternal::add).also { adapters.add(it.adapter()) } val jsonFunctions = Registry<JsonFunction>("json function").also(registriesInternal::add).also { adapters.add(it.adapter()) }
val json2Functions = Registry<Json2Function>("json 2function").also(registriesInternal::add).also { adapters.add(it.adapter()) } val json2Functions = Registry<Json2Function>("json 2function").also(registriesInternal::add).also { adapters.add(it.adapter()) }
val jsonConfigFunctions = Registry<JsonConfigFunction>("json config function").also(registriesInternal::add).also { adapters.add(it.adapter()) } val jsonConfigFunctions = Registry<JsonConfigFunction>("json config function").also(registriesInternal::add).also { adapters.add(it.adapter()) }
val npcTypes = Registry<NpcTypeDefinition>("npc type").also(registriesInternal::add).also { adapters.add(it.adapter()) }
val projectiles = Registry<ProjectileDefinition>("projectile").also(registriesInternal::add).also { adapters.add(it.adapter()) } val projectiles = Registry<ProjectileDefinition>("projectile").also(registriesInternal::add).also { adapters.add(it.adapter()) }
val tenants = Registry<TenantDefinition>("tenant").also(registriesInternal::add).also { adapters.add(it.adapter()) } val tenants = Registry<TenantDefinition>("tenant").also(registriesInternal::add).also { adapters.add(it.adapter()) }
val treasurePools = Registry<TreasurePoolDefinition>("treasure pool").also(registriesInternal::add).also { adapters.add(it.adapter()) } val treasurePools = Registry<TreasurePoolDefinition>("treasure pool").also(registriesInternal::add).also { adapters.add(it.adapter()) }
@ -110,14 +114,14 @@ object Registries {
val damageKinds = Registry<DamageKind>("damage kind").also(registriesInternal::add).also { adapters.add(it.adapter()) } val damageKinds = Registry<DamageKind>("damage kind").also(registriesInternal::add).also { adapters.add(it.adapter()) }
private val monsterParts = HashMap<Pair<String, String>, HashMap<String, Pair<MonsterPartDefinition, IStarboundFile>>>() private val monsterParts = HashMap<Pair<String, String>, HashMap<String, Pair<MonsterPartDefinition, IStarboundFile>>>()
private val loggedMisses = Collections.synchronizedSet(ObjectOpenHashSet<Pair<String, String>>()) private val loggedMonsterPartMisses = Collections.synchronizedSet(ObjectOpenHashSet<Pair<String, String>>())
fun selectMonsterPart(category: String, type: String, random: RandomGenerator): MonsterPartDefinition? { fun selectMonsterPart(category: String, type: String, random: RandomGenerator): MonsterPartDefinition? {
val key = category to type val key = category to type
val get = monsterParts[key] val get = monsterParts[key]
if (get.isNullOrEmpty()) { if (get.isNullOrEmpty()) {
if (loggedMisses.add(key)) { if (loggedMonsterPartMisses.add(key)) {
LOGGER.error("No such monster part combination of category '$category' and type '$type'") LOGGER.error("No such monster part combination of category '$category' and type '$type'")
} }
@ -157,6 +161,49 @@ object Registries {
} }
} }
private val npcTypes = HashMap<String, Pair<IStarboundFile, JsonObject>>()
fun buildNPCConfig(type: String, overrides: JsonElement = JsonNull.INSTANCE): JsonObject {
val baseConfig = npcTypes.getOrElse(type) { throw NoSuchElementException("No such NPC type $type") }.second
val config = mergeJson(baseConfig.deepCopy(), overrides)
if ("baseType" in baseConfig) {
return buildNPCConfig(baseConfig["baseType"].asString, config)
} else {
return config
}
}
private fun loadNpcTypes(files: Collection<IStarboundFile>, patches: Map<String, Collection<IStarboundFile>>): List<Future<*>> {
return files.map { listedFile ->
Starbound.GLOBAL_SCOPE.launch {
try {
val elem = JsonPatch.applyAsync(listedFile.asyncJsonReader(), patches[listedFile.computeFullPath()]) as JsonObject
val type = elem.get("type").asString
if ("scripts" in elem) {
val fPath = listedFile.computeFullPath()
val scripts = elem["scripts"].asJsonArray
for (i in 0 until scripts.size()) {
scripts[i] = JsonPrimitive(AssetPathStack.relativeTo(fPath, scripts[i].asString))
}
}
Starbound.submit {
val existing = npcTypes.put(type, listedFile to elem)
if (existing != null) {
LOGGER.warn("Overwriting existing NPC definition '$type' (new originate from $listedFile, old originating from ${existing.first})")
}
}
} catch (err: Throwable) {
LOGGER.error("Loading NPC type definition file $listedFile", err)
}
}.asCompletableFuture()
}
}
private fun <T> key(mapper: (T) -> String): (T) -> Pair<String, KOptional<Int?>> { private fun <T> key(mapper: (T) -> String): (T) -> Pair<String, KOptional<Int?>> {
return { mapper.invoke(it) to KOptional() } return { mapper.invoke(it) to KOptional() }
} }
@ -236,7 +283,6 @@ object Registries {
tasks.addAll(loadRegistry(particles, patchTree, fileTree["particle"] ?: listOf(), { (it.kind ?: throw NullPointerException("Missing 'kind' value")) to KOptional() })) tasks.addAll(loadRegistry(particles, patchTree, fileTree["particle"] ?: listOf(), { (it.kind ?: throw NullPointerException("Missing 'kind' value")) to KOptional() }))
tasks.addAll(loadRegistry(questTemplates, patchTree, fileTree["questtemplate"] ?: listOf(), key(QuestTemplate::id))) tasks.addAll(loadRegistry(questTemplates, patchTree, fileTree["questtemplate"] ?: listOf(), key(QuestTemplate::id)))
tasks.addAll(loadRegistry(techs, patchTree, fileTree["tech"] ?: listOf(), key(TechDefinition::name))) tasks.addAll(loadRegistry(techs, patchTree, fileTree["tech"] ?: listOf(), key(TechDefinition::name)))
tasks.addAll(loadRegistry(npcTypes, patchTree, fileTree["npctype"] ?: listOf(), key(NpcTypeDefinition::type)))
tasks.addAll(loadRegistry(biomes, patchTree, fileTree["biome"] ?: listOf(), key(BiomeDefinition::name))) tasks.addAll(loadRegistry(biomes, patchTree, fileTree["biome"] ?: listOf(), key(BiomeDefinition::name)))
tasks.addAll(loadRegistry(grassVariants, patchTree, fileTree["grass"] ?: listOf(), key(GrassVariant.Data::name))) tasks.addAll(loadRegistry(grassVariants, patchTree, fileTree["grass"] ?: listOf(), key(GrassVariant.Data::name)))
tasks.addAll(loadRegistry(treeStemVariants, patchTree, fileTree["modularstem"] ?: listOf(), key(TreeVariant.StemData::name))) tasks.addAll(loadRegistry(treeStemVariants, patchTree, fileTree["modularstem"] ?: listOf(), key(TreeVariant.StemData::name)))
@ -259,6 +305,8 @@ object Registries {
// declaring game data // declaring game data
tasks.addAll(loadMixed(spawnTypes, fileTree["spawntypes"] ?: listOf(), patchTree, SpawnType::name)) tasks.addAll(loadMixed(spawnTypes, fileTree["spawntypes"] ?: listOf(), patchTree, SpawnType::name))
tasks.addAll(loadNpcTypes(fileTree["npctype"] ?: listOf(), patchTree))
return tasks return tasks
} }

View File

@ -51,6 +51,10 @@ object VersionRegistry {
return migrate(read, name) return migrate(read, name)
} }
fun load(reader: JsonElement): JsonElement {
return migrate(VersionedJson.fromJson(reader))
}
private val adapter by lazy { Starbound.gson.getAdapter(VersionedJson::class.java) } private val adapter by lazy { Starbound.gson.getAdapter(VersionedJson::class.java) }
fun load(): Future<*> { fun load(): Future<*> {

View File

@ -6,7 +6,7 @@ import com.google.gson.annotations.JsonAdapter
import com.google.gson.stream.JsonReader import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonWriter import com.google.gson.stream.JsonWriter
import kotlinx.coroutines.future.await import kotlinx.coroutines.future.await
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kommons.io.readUUID import ru.dbotthepony.kommons.io.readUUID
import ru.dbotthepony.kstarbound.io.readVector2d import ru.dbotthepony.kstarbound.io.readVector2d
import ru.dbotthepony.kstarbound.io.readVector2f import ru.dbotthepony.kstarbound.io.readVector2f

View File

@ -0,0 +1,44 @@
package ru.dbotthepony.kstarbound.defs.actor
import com.google.common.collect.ImmutableList
import com.google.gson.JsonElement
import com.google.gson.JsonNull
import ru.dbotthepony.kstarbound.Registries
import ru.dbotthepony.kstarbound.Registry
import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.defs.AssetPath
import ru.dbotthepony.kstarbound.json.builder.JsonFactory
import ru.dbotthepony.kstarbound.math.vector.Vector2d
import ru.dbotthepony.kstarbound.util.random.nextRange
import ru.dbotthepony.kstarbound.util.random.random
import java.util.random.RandomGenerator
import kotlin.math.max
data class NPCVariant(
val species: Registry.Entry<Species>,
val scripts: ImmutableList<AssetPath>,
val initialScriptDelta: Int = 5,
) {
@JsonFactory
data class SerializedData(
val levelVariance: Vector2d = Vector2d.ZERO,
val scripts: ImmutableList<AssetPath>,
val initialScriptDelta: Int = 5,
val scriptConfig: JsonElement = JsonNull.INSTANCE,
val humanoidConfig: String? = null,
)
companion object {
suspend fun create(species: Registry.Entry<Species>, type: String, level: Double, random: RandomGenerator, overrides: JsonElement = JsonNull.INSTANCE): NPCVariant {
val config = Registries.buildNPCConfig(type, overrides)
val serialized = Starbound.gson.fromJson(config, SerializedData::class.java)
val finalLevel = max(0.0, random.nextRange(serialized.levelVariance) + level)
TODO()
}
suspend fun create(species: Registry.Entry<Species>, type: String, level: Double, seed: Long, overrides: JsonElement = JsonNull.INSTANCE): NPCVariant {
return create(species, type, level, random(seed), overrides)
}
}
}

View File

@ -1,8 +1,11 @@
package ru.dbotthepony.kstarbound.defs package ru.dbotthepony.kstarbound.defs.actor
import com.google.common.collect.ImmutableList import com.google.common.collect.ImmutableList
import com.google.common.collect.ImmutableSet import com.google.common.collect.ImmutableSet
import ru.dbotthepony.kstarbound.Registry import ru.dbotthepony.kstarbound.Registry
import ru.dbotthepony.kstarbound.defs.AssetPath
import ru.dbotthepony.kstarbound.defs.ColorReplacements
import ru.dbotthepony.kstarbound.defs.StatusEffectDefinition
import ru.dbotthepony.kstarbound.defs.image.SpriteReference import ru.dbotthepony.kstarbound.defs.image.SpriteReference
import ru.dbotthepony.kstarbound.defs.actor.player.BlueprintLearnList import ru.dbotthepony.kstarbound.defs.actor.player.BlueprintLearnList
import ru.dbotthepony.kstarbound.defs.item.ItemDescriptor import ru.dbotthepony.kstarbound.defs.item.ItemDescriptor
@ -11,31 +14,36 @@ import ru.dbotthepony.kstarbound.json.builder.JsonFactory
@JsonFactory @JsonFactory
data class Species( data class Species(
val kind: String, val kind: String,
val charCreationTooltip: Tooltip, val charCreationTooltip: Tooltip = Tooltip(),
val nameGen: ImmutableList<String>, val nameGen: ImmutableList<String>,
val ouchNoises: ImmutableList<String>, val ouchNoises: ImmutableList<AssetPath>,
val charGenTextLabels: ImmutableList<String>, val charGenTextLabels: ImmutableList<String> = ImmutableList.of(),
val skull: String, val skull: AssetPath = AssetPath("/humanoid/any/dead.png"), // ваш свет угасает
val defaultBlueprints: BlueprintLearnList, val defaultBlueprints: BlueprintLearnList,
val headOptionAsHairColor: Boolean = false,
val headOptionAsFacialhair: Boolean = false, val headOptionAsFacialhair: Boolean = false,
val altOptionAsUndyColor: Boolean = false, val altOptionAsUndyColor: Boolean = false,
val altOptionAsHairColor: Boolean = false, val altOptionAsHairColor: Boolean = false,
val bodyColorAsFacialMaskSubColor: Boolean = false, val altOptionAsFacialMask: Boolean = false,
val hairColorAsBodySubColor: Boolean = false, val hairColorAsBodySubColor: Boolean = false,
val bodyColorAsFacialMaskSubColor: Boolean = false,
val altColorAsFacialMaskSubColor: Boolean = false,
val bodyColor: ImmutableList<ColorReplacements>, val bodyColor: ImmutableList<ColorReplacements>,
val undyColor: ImmutableList<ColorReplacements>, val undyColor: ImmutableList<ColorReplacements>,
val hairColor: ImmutableList<ColorReplacements>, val hairColor: ImmutableList<ColorReplacements>,
val genders: ImmutableList<Gender>, val genders: ImmutableList<GenderSettings>,
val statusEffects: ImmutableSet<Registry.Ref<StatusEffectDefinition>> = ImmutableSet.of(), val statusEffects: ImmutableSet<Registry.Ref<StatusEffectDefinition>> = ImmutableSet.of(),
) { ) {
@JsonFactory @JsonFactory
data class Tooltip(val title: String, val subTitle: String, val description: String) data class Tooltip(val title: String = "", val subTitle: String = "", val description: String = "")
@JsonFactory @JsonFactory
data class Gender( data class GenderSettings(
val name: String, val name: String = "",
val image: SpriteReference, val image: SpriteReference = SpriteReference.NEVER,
val characterImage: SpriteReference, val characterImage: SpriteReference = SpriteReference.NEVER,
val hairGroup: String? = null, val hairGroup: String? = null,
val hair: ImmutableSet<String>, val hair: ImmutableSet<String>,
val shirt: ImmutableSet<ItemDescriptor>, val shirt: ImmutableSet<ItemDescriptor>,

View File

@ -1,4 +1,4 @@
package ru.dbotthepony.kstarbound.defs.npc package ru.dbotthepony.kstarbound.defs.actor
import com.google.common.collect.ImmutableMap import com.google.common.collect.ImmutableMap
import it.unimi.dsi.fastutil.objects.Object2IntMap import it.unimi.dsi.fastutil.objects.Object2IntMap

View File

@ -11,9 +11,8 @@ import ru.dbotthepony.kstarbound.world.entities.behavior.RandomizeNode
import ru.dbotthepony.kstarbound.world.entities.behavior.SequenceNode import ru.dbotthepony.kstarbound.world.entities.behavior.SequenceNode
enum class CompositeNodeType(override val jsonName: String, val factory: (Map<String, NodeParameter>, ImmutableList<AbstractBehaviorNode>) -> AbstractBehaviorNode) : IStringSerializable { enum class CompositeNodeType(override val jsonName: String, val factory: (Map<String, NodeParameter>, ImmutableList<AbstractBehaviorNode>) -> AbstractBehaviorNode) : IStringSerializable {
SEQUENCE("Sequence", { _, c -> SequenceNode(c) }), SEQUENCE("Sequence", { _, c -> SequenceNode(c, isSelector = false) }),
// in original engine, selector and sequence nodes are identical code-wise SELECTOR("Selector", { _, c -> SequenceNode(c, isSelector = true) }),
SELECTOR("Selector", { _, c -> SequenceNode(c) }),
PARALLEL("Parallel", { p, c -> ParallelNode(p, c) }), PARALLEL("Parallel", { p, c -> ParallelNode(p, c) }),
DYNAMIC("Dynamic", { _, c -> DynamicNode(c) }), DYNAMIC("Dynamic", { _, c -> DynamicNode(c) }),
RANDOMIZE("Randomize", { _, c -> RandomizeNode(c) }); RANDOMIZE("Randomize", { _, c -> RandomizeNode(c) });

View File

@ -1,8 +1,8 @@
package ru.dbotthepony.kstarbound.defs.actor.player package ru.dbotthepony.kstarbound.defs.actor.player
import ru.dbotthepony.kommons.io.IntValueCodec import ru.dbotthepony.kstarbound.io.IntValueCodec
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kommons.io.map import ru.dbotthepony.kstarbound.io.map
import ru.dbotthepony.kstarbound.json.builder.IStringSerializable import ru.dbotthepony.kstarbound.json.builder.IStringSerializable
enum class PlayerBusyState(override val jsonName: String) : IStringSerializable { enum class PlayerBusyState(override val jsonName: String) : IStringSerializable {

View File

@ -10,7 +10,7 @@ import ru.dbotthepony.kstarbound.math.vector.Vector2d
import ru.dbotthepony.kstarbound.Registry import ru.dbotthepony.kstarbound.Registry
import ru.dbotthepony.kstarbound.defs.ActorMovementParameters import ru.dbotthepony.kstarbound.defs.ActorMovementParameters
import ru.dbotthepony.kstarbound.defs.AssetReference import ru.dbotthepony.kstarbound.defs.AssetReference
import ru.dbotthepony.kstarbound.defs.Species import ru.dbotthepony.kstarbound.defs.actor.Species
import ru.dbotthepony.kstarbound.defs.actor.StatusControllerConfig import ru.dbotthepony.kstarbound.defs.actor.StatusControllerConfig
import ru.dbotthepony.kstarbound.util.SBPattern import ru.dbotthepony.kstarbound.util.SBPattern
import ru.dbotthepony.kstarbound.defs.animation.AnimationDefinition import ru.dbotthepony.kstarbound.defs.animation.AnimationDefinition

View File

@ -1,8 +1,8 @@
package ru.dbotthepony.kstarbound.defs.actor.player package ru.dbotthepony.kstarbound.defs.actor.player
import ru.dbotthepony.kommons.io.IntValueCodec import ru.dbotthepony.kstarbound.io.IntValueCodec
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kommons.io.map import ru.dbotthepony.kstarbound.io.map
import ru.dbotthepony.kstarbound.json.builder.IStringSerializable import ru.dbotthepony.kstarbound.json.builder.IStringSerializable
enum class PlayerGamemode(override val jsonName: String) : IStringSerializable { enum class PlayerGamemode(override val jsonName: String) : IStringSerializable {

View File

@ -20,7 +20,7 @@ import org.classdump.luna.runtime.ExecutionContext
import ru.dbotthepony.kommons.gson.contains import ru.dbotthepony.kommons.gson.contains
import ru.dbotthepony.kommons.gson.get import ru.dbotthepony.kommons.gson.get
import ru.dbotthepony.kommons.gson.value import ru.dbotthepony.kommons.gson.value
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kommons.io.readVarLong import ru.dbotthepony.kommons.io.readVarLong
import ru.dbotthepony.kommons.io.writeBinaryString import ru.dbotthepony.kommons.io.writeBinaryString
import ru.dbotthepony.kommons.io.writeVarLong import ru.dbotthepony.kommons.io.writeVarLong

View File

@ -1,9 +0,0 @@
package ru.dbotthepony.kstarbound.defs.npc
import ru.dbotthepony.kstarbound.json.builder.JsonFactory
@JsonFactory
data class NpcTypeDefinition(
val type: String,
val baseType: String? = null,
)

View File

@ -5,7 +5,7 @@ import com.google.gson.JsonObject
import it.unimi.dsi.fastutil.ints.IntArrayList import it.unimi.dsi.fastutil.ints.IntArrayList
import ru.dbotthepony.kommons.gson.contains import ru.dbotthepony.kommons.gson.contains
import ru.dbotthepony.kommons.gson.get import ru.dbotthepony.kommons.gson.get
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.kstarbound.math.vector.Vector2d import ru.dbotthepony.kstarbound.math.vector.Vector2d
import ru.dbotthepony.kstarbound.math.vector.Vector2i import ru.dbotthepony.kstarbound.math.vector.Vector2i

View File

@ -0,0 +1,44 @@
package ru.dbotthepony.kstarbound.io
import java.io.Closeable
import java.sql.Connection
import java.sql.PreparedStatement
class SQLSavepoint(connection: Connection, name: String) : Closeable {
private val begin: PreparedStatement
private val finish: PreparedStatement
private val rollback: PreparedStatement
init {
check('"' !in name) { "Invalid identifier: $name" }
begin = connection.prepareStatement("""
SAVEPOINT "$name"
""".trimIndent())
finish = connection.prepareStatement("""
RELEASE SAVEPOINT "$name"
""".trimIndent())
rollback = connection. prepareStatement("""
ROLLBACK TO SAVEPOINT "$name"
""".trimIndent())
}
fun execute(block: () -> Unit) {
try {
begin.execute()
block.invoke()
finish.execute()
} catch (err: Throwable) {
rollback.execute()
throw err
}
}
override fun close() {
begin.close()
finish.close()
rollback.close()
}
}

View File

@ -1,24 +0,0 @@
package ru.dbotthepony.kstarbound.io
import java.sql.Connection
import java.sql.PreparedStatement
data class SavepointStatements(val begin: PreparedStatement, val commit: PreparedStatement, val rollback: PreparedStatement)
fun Connection.createSavepoint(name: String): SavepointStatements {
check('"' !in name) { "Invalid identifier: $name" }
val begin = prepareStatement("""
SAVEPOINT "$name"
""".trimIndent())
val commit = prepareStatement("""
RELEASE SAVEPOINT "$name"
""".trimIndent())
val rollback = prepareStatement("""
ROLLBACK TO SAVEPOINT "$name"
""".trimIndent())
return SavepointStatements(begin, commit, rollback)
}

View File

@ -0,0 +1,338 @@
package ru.dbotthepony.kstarbound.io
import ru.dbotthepony.kommons.io.readBigDecimal
import ru.dbotthepony.kommons.io.readBinaryString
import ru.dbotthepony.kommons.io.readByteArray
import ru.dbotthepony.kommons.io.readKOptional
import ru.dbotthepony.kommons.io.readMap
import ru.dbotthepony.kommons.io.readOptional
import ru.dbotthepony.kommons.io.readSignedVarInt
import ru.dbotthepony.kommons.io.readSignedVarLong
import ru.dbotthepony.kommons.io.readVarInt
import ru.dbotthepony.kommons.io.readVarLong
import ru.dbotthepony.kommons.io.writeBigDecimal
import ru.dbotthepony.kommons.io.writeBinaryString
import ru.dbotthepony.kommons.io.writeByteArray
import ru.dbotthepony.kommons.io.writeKOptional
import ru.dbotthepony.kommons.io.writeMap
import ru.dbotthepony.kommons.io.writeOptional
import ru.dbotthepony.kommons.io.writeSignedVarInt
import ru.dbotthepony.kommons.io.writeSignedVarLong
import ru.dbotthepony.kommons.io.writeVarInt
import ru.dbotthepony.kommons.io.writeVarLong
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.kommons.util.KOptional
import java.io.DataInputStream
import java.io.DataOutputStream
import java.util.*
import kotlin.reflect.KClass
/**
* Represents value which can be encoded onto or decoded from stream.
*/
interface StreamCodec<V> {
fun read(stream: DataInputStream): V
fun write(stream: DataOutputStream, value: V)
/**
* Defensive copy
*/
fun copy(value: V): V
/**
* Optional custom equality check
*/
fun compare(a: V, b: V): Boolean {
return a == b
}
class Impl<V>(
private val reader: (stream: DataInputStream) -> V,
private val writer: (stream: DataOutputStream, value: V) -> Unit,
private val copier: ((value: V) -> V) = { it },
private val comparator: ((a: V, b: V) -> Boolean) = { a, b -> a == b }
) : StreamCodec<V> {
constructor(
reader: (stream: DataInputStream) -> V,
payloadSize: Long,
writer: (stream: DataOutputStream, value: V) -> Unit,
copier: ((value: V) -> V) = { it },
comparator: ((a: V, b: V) -> Boolean) = { a, b -> a == b }
) : this({ stream -> reader.invoke(stream) }, writer, copier, comparator)
override fun read(stream: DataInputStream): V {
return reader.invoke(stream)
}
override fun write(stream: DataOutputStream, value: V) {
writer.invoke(stream, value)
}
override fun copy(value: V): V {
return copier.invoke(value)
}
override fun compare(a: V, b: V): Boolean {
return comparator.invoke(a, b)
}
}
class Nullable<V>(val parent: StreamCodec<V>) : StreamCodec<V?> {
override fun read(stream: DataInputStream): V? {
return if (stream.read() == 0) null else parent.read(stream)
}
override fun write(stream: DataOutputStream, value: V?) {
if (value === null)
stream.write(0)
else {
stream.write(1)
parent.write(stream, value)
}
}
override fun copy(value: V?): V? {
return if (value === null) null else parent.copy(value)
}
override fun compare(a: V?, b: V?): Boolean {
if (a === null && b === null) return true
if (a === null || b === null) return false
return parent.compare(a, b)
}
}
class Collection<E, C : MutableCollection<E>>(val elementCodec: StreamCodec<E>, val collectionFactory: (Int) -> C) : StreamCodec<C> {
override fun read(stream: DataInputStream): C {
val size = stream.readVarInt()
if (size <= 0) {
return collectionFactory.invoke(0)
}
val collection = collectionFactory.invoke(size)
for (i in 0 until size) {
collection.add(elementCodec.read(stream))
}
return collection
}
override fun write(stream: DataOutputStream, value: C) {
stream.writeVarInt(value.size)
value.forEach { elementCodec.write(stream, it) }
}
override fun copy(value: C): C {
val new = collectionFactory.invoke(value.size)
value.forEach { new.add(elementCodec.copy(it)) }
return new
}
}
class Map<K, V, C : MutableMap<K, V>>(val keyCodec: StreamCodec<K>, val valueCodec: StreamCodec<V>, val factory: (Int) -> C): StreamCodec<C> {
override fun read(stream: DataInputStream): C {
return stream.readMap(keyCodec::read, valueCodec::read, factory)
}
override fun write(stream: DataOutputStream, value: C) {
stream.writeMap(value, keyCodec::write, valueCodec::write)
}
override fun copy(value: C): C {
val new = factory.invoke(value.size)
for ((k, v) in value.entries) {
new[keyCodec.copy(k)] = valueCodec.copy(v)
}
return new
}
}
class Enum<V : kotlin.Enum<V>>(clazz: Class<out V>) : StreamCodec<V> {
val clazz = searchClass(clazz)
val values: List<V> = listOf(*this.clazz.enumConstants!!)
val valuesMap = values.associateBy { it.name }
override fun read(stream: DataInputStream): V {
val id = stream.readVarInt()
return values.getOrNull(id) ?: throw NoSuchElementException("No such enum with index $id")
}
override fun write(stream: DataOutputStream, value: V) {
stream.writeVarInt(value.ordinal)
}
override fun copy(value: V): V {
return value
}
override fun compare(a: V, b: V): Boolean {
return a === b
}
companion object {
/**
* FIXME: enums with abstract methods which get compiled to subclasses, whose DO NOT expose "parent's" enum constants array
*
* is there an already existing solution?
*/
fun <V : kotlin.Enum<V>> searchClass(clazz: Class<out V>): Class<out V> {
var search: Class<*> = clazz
while (search.enumConstants == null && search.superclass != null) {
search = search.superclass
}
if (search.enumConstants == null) {
throw ClassCastException("$clazz does not represent an enum or enum subclass")
}
return search as Class<out V>
}
}
}
class KOptional<V>(val codec: StreamCodec<V>) : StreamCodec<ru.dbotthepony.kommons.util.KOptional<V>> {
override fun read(stream: DataInputStream): ru.dbotthepony.kommons.util.KOptional<V> {
return stream.readKOptional(codec::read)
}
override fun write(stream: DataOutputStream, value: ru.dbotthepony.kommons.util.KOptional<V>) {
stream.writeKOptional(value, codec::write)
}
override fun copy(value: ru.dbotthepony.kommons.util.KOptional<V>): ru.dbotthepony.kommons.util.KOptional<V> {
return value.map(codec::copy)
}
}
class Optional<V : Any>(val codec: StreamCodec<V>) : StreamCodec<java.util.Optional<V>> {
override fun read(stream: DataInputStream): java.util.Optional<V> {
return stream.readOptional(codec::read)
}
override fun write(stream: DataOutputStream, value: java.util.Optional<V>) {
stream.writeOptional(value, codec::write)
}
override fun copy(value: java.util.Optional<V>): java.util.Optional<V> {
return value.map(codec::copy)
}
}
class Mapping<T, R>(private val codec: StreamCodec<T>, private val from: T.() -> R, private val to: R.() -> T, private val copy: R.() -> R = { this }) : StreamCodec<R> {
override fun read(stream: DataInputStream): R {
return from(codec.read(stream))
}
override fun write(stream: DataOutputStream, value: R) {
codec.write(stream, to(value))
}
override fun copy(value: R): R {
return copy.invoke(value)
}
}
class Pair<L, R>(private val left: StreamCodec<L>, private val right: StreamCodec<R>) : StreamCodec<kotlin.Pair<L, R>> {
override fun read(stream: DataInputStream): kotlin.Pair<L, R> {
val left = left.read(stream)
val right = right.read(stream)
return left to right
}
override fun write(stream: DataOutputStream, value: kotlin.Pair<L, R>) {
left.write(stream, value.first)
right.write(stream, value.second)
}
override fun copy(value: kotlin.Pair<L, R>): kotlin.Pair<L, R> {
val left = left.copy(value.first)
val right = right.copy(value.second)
if (left !== this.left && right !== this.right) {
return left to right
} else {
return value
}
}
}
}
fun <T, R> StreamCodec<T>.map(from: T.() -> R, to: R.() -> T): StreamCodec<R> {
return StreamCodec.Mapping(this, from, to)
}
fun <T, R> StreamCodec<T>.map(from: T.() -> R, to: R.() -> T, copy: R.() -> R): StreamCodec<R> {
return StreamCodec.Mapping(this, from, to, copy)
}
fun <T : Any> StreamCodec<T>.optional(): StreamCodec<Optional<T>> = StreamCodec.Optional(this)
fun <T> StreamCodec<T>.koptional(): StreamCodec<KOptional<T>> = StreamCodec.KOptional(this)
fun <T> StreamCodec<T>.nullable(): StreamCodec<T?> = StreamCodec.Nullable(this)
val NullValueCodec = StreamCodec.Impl({ _ -> null }, { _, _ -> })
val BooleanValueCodec = StreamCodec.Impl(DataInputStream::readBoolean, 1L, DataOutputStream::writeBoolean)
val ByteValueCodec = StreamCodec.Impl(DataInputStream::readByte, 1L, { s, v -> s.writeByte(v.toInt()) })
val ShortValueCodec = StreamCodec.Impl(DataInputStream::readShort, 2L, { s, v -> s.writeShort(v.toInt()) })
val CharValueCodec = StreamCodec.Impl(DataInputStream::readChar, 2L, { s, v -> s.writeShort(v.code) })
val IntValueCodec = StreamCodec.Impl(DataInputStream::readInt, 4L, DataOutputStream::writeInt)
val LongValueCodec = StreamCodec.Impl(DataInputStream::readLong, 8L, DataOutputStream::writeLong)
val FloatValueCodec = StreamCodec.Impl(DataInputStream::readFloat, 4L, DataOutputStream::writeFloat)
val DoubleValueCodec = StreamCodec.Impl(DataInputStream::readDouble, 8L, DataOutputStream::writeDouble)
val BigDecimalValueCodec = StreamCodec.Impl(DataInputStream::readBigDecimal, DataOutputStream::writeBigDecimal)
val UUIDValueCodec = StreamCodec.Impl({ s -> UUID(s.readLong(), s.readLong()) }, { s, v -> s.writeLong(v.mostSignificantBits); s.writeLong(v.leastSignificantBits) })
val VarIntValueCodec = StreamCodec.Impl(DataInputStream::readSignedVarInt, DataOutputStream::writeSignedVarInt)
val VarLongValueCodec = StreamCodec.Impl(DataInputStream::readSignedVarLong, DataOutputStream::writeSignedVarLong)
val BinaryStringCodec = StreamCodec.Impl(DataInputStream::readBinaryString, DataOutputStream::writeBinaryString)
val UnsignedVarLongCodec = StreamCodec.Impl(DataInputStream::readVarLong, DataOutputStream::writeVarLong)
val UnsignedVarIntCodec = StreamCodec.Impl(DataInputStream::readVarInt, DataOutputStream::writeVarInt)
val ByteArrayCodec = StreamCodec.Impl(DataInputStream::readByteArray, DataOutputStream::writeByteArray)
val RGBCodec = StreamCodec.Impl(
{ s -> RGBAColor(s.readFloat(), s.readFloat(), s.readFloat()) },
{ s, v -> s.writeFloat(v.red); s.writeFloat(v.green); s.writeFloat(v.blue) })
val RGBACodec = StreamCodec.Impl(
{ s -> RGBAColor(s.readFloat(), s.readFloat(), s.readFloat(), s.readFloat()) },
{ s, v -> s.writeFloat(v.red); s.writeFloat(v.green); s.writeFloat(v.blue); s.writeFloat(v.alpha) })
val OptionalBooleanValueCodec = StreamCodec.Optional(BooleanValueCodec)
val OptionalByteValueCodec = StreamCodec.Optional(ByteValueCodec)
val OptionalShortValueCodec = StreamCodec.Optional(ShortValueCodec)
val OptionalCharValueCodec = StreamCodec.Optional(CharValueCodec)
val OptionalIntValueCodec = StreamCodec.Optional(IntValueCodec)
val OptionalLongValueCodec = StreamCodec.Optional(LongValueCodec)
val OptionalFloatValueCodec = StreamCodec.Optional(FloatValueCodec)
val OptionalDoubleValueCodec = StreamCodec.Optional(DoubleValueCodec)
val OptionalBigDecimalValueCodec = StreamCodec.Optional(BigDecimalValueCodec)
val OptionalUUIDValueCodec = StreamCodec.Optional(UUIDValueCodec)
val OptionalVarIntValueCodec = StreamCodec.Optional(VarIntValueCodec)
val OptionalVarLongValueCodec = StreamCodec.Optional(VarLongValueCodec)
val OptionalBinaryStringCodec = StreamCodec.Optional(BinaryStringCodec)
val OptionalRGBCodec = StreamCodec.Optional(RGBCodec)
val OptionalRGBACodec = StreamCodec.Optional(RGBACodec)
val KOptionalBooleanValueCodec = StreamCodec.KOptional(BooleanValueCodec)
val KOptionalByteValueCodec = StreamCodec.KOptional(ByteValueCodec)
val KOptionalShortValueCodec = StreamCodec.KOptional(ShortValueCodec)
val KOptionalCharValueCodec = StreamCodec.KOptional(CharValueCodec)
val KOptionalIntValueCodec = StreamCodec.KOptional(IntValueCodec)
val KOptionalLongValueCodec = StreamCodec.KOptional(LongValueCodec)
val KOptionalFloatValueCodec = StreamCodec.KOptional(FloatValueCodec)
val KOptionalDoubleValueCodec = StreamCodec.KOptional(DoubleValueCodec)
val KOptionalBigDecimalValueCodec = StreamCodec.KOptional(BigDecimalValueCodec)
val KOptionalUUIDValueCodec = StreamCodec.KOptional(UUIDValueCodec)
val KOptionalVarIntValueCodec = StreamCodec.KOptional(VarIntValueCodec)
val KOptionalVarLongValueCodec = StreamCodec.KOptional(VarLongValueCodec)
val KOptionalBinaryStringCodec = StreamCodec.KOptional(BinaryStringCodec)
val KOptionalRGBCodec = StreamCodec.KOptional(RGBCodec)
val KOptionalRGBACodec = StreamCodec.KOptional(RGBACodec)
fun <E : Enum<E>> Class<E>.codec() = StreamCodec.Enum(this)
fun <E : Enum<E>> KClass<E>.codec() = StreamCodec.Enum(this.java)

View File

@ -2,8 +2,6 @@ package ru.dbotthepony.kstarbound.io
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 ru.dbotthepony.kommons.io.DelegateSyncher
import ru.dbotthepony.kommons.io.StreamCodec
import ru.dbotthepony.kommons.io.readBinaryString import ru.dbotthepony.kommons.io.readBinaryString
import ru.dbotthepony.kommons.io.readDouble import ru.dbotthepony.kommons.io.readDouble
import ru.dbotthepony.kommons.io.readFloat import ru.dbotthepony.kommons.io.readFloat
@ -263,27 +261,6 @@ val Vector4iCodec = StreamCodec.Impl(DataInputStream::readVector4i, DataOutputSt
val Vector4dCodec = StreamCodec.Impl(DataInputStream::readVector4d, DataOutputStream::writeStruct4d) val Vector4dCodec = StreamCodec.Impl(DataInputStream::readVector4d, DataOutputStream::writeStruct4d)
val Vector4fCodec = StreamCodec.Impl(DataInputStream::readVector4f, DataOutputStream::writeStruct4f) val Vector4fCodec = StreamCodec.Impl(DataInputStream::readVector4f, DataOutputStream::writeStruct4f)
fun DelegateSyncher.vec2i(value: Vector2i, setter: DelegateSetter<Vector2i> = DelegateSetter.passthrough(), getter: DelegateGetter<Vector2i> = DelegateGetter.passthrough()) = Slot(
ListenableDelegate.maskSmart(value, getter, setter), Vector2iCodec)
fun DelegateSyncher.vec2d(value: Vector2d, setter: DelegateSetter<Vector2d> = DelegateSetter.passthrough(), getter: DelegateGetter<Vector2d> = DelegateGetter.passthrough()) = Slot(
ListenableDelegate.maskSmart(value, getter, setter), Vector2dCodec)
fun DelegateSyncher.vec2f(value: Vector2f, setter: DelegateSetter<Vector2f> = DelegateSetter.passthrough(), getter: DelegateGetter<Vector2f> = DelegateGetter.passthrough()) = Slot(
ListenableDelegate.maskSmart(value, getter, setter), Vector2fCodec)
fun DelegateSyncher.vec3i(value: Vector3i, setter: DelegateSetter<Vector3i> = DelegateSetter.passthrough(), getter: DelegateGetter<Vector3i> = DelegateGetter.passthrough()) = Slot(
ListenableDelegate.maskSmart(value, getter, setter), Vector3iCodec)
fun DelegateSyncher.vec3d(value: Vector3d, setter: DelegateSetter<Vector3d> = DelegateSetter.passthrough(), getter: DelegateGetter<Vector3d> = DelegateGetter.passthrough()) = Slot(
ListenableDelegate.maskSmart(value, getter, setter), Vector3dCodec)
fun DelegateSyncher.vec3f(value: Vector3f, setter: DelegateSetter<Vector3f> = DelegateSetter.passthrough(), getter: DelegateGetter<Vector3f> = DelegateGetter.passthrough()) = Slot(
ListenableDelegate.maskSmart(value, getter, setter), Vector3fCodec)
fun DelegateSyncher.vec4i(value: Vector4i, setter: DelegateSetter<Vector4i> = DelegateSetter.passthrough(), getter: DelegateGetter<Vector4i> = DelegateGetter.passthrough()) = Slot(
ListenableDelegate.maskSmart(value, getter, setter), Vector4iCodec)
fun DelegateSyncher.vec4d(value: Vector4d, setter: DelegateSetter<Vector4d> = DelegateSetter.passthrough(), getter: DelegateGetter<Vector4d> = DelegateGetter.passthrough()) = Slot(
ListenableDelegate.maskSmart(value, getter, setter), Vector4dCodec)
fun DelegateSyncher.vec4f(value: Vector4f, setter: DelegateSetter<Vector4f> = DelegateSetter.passthrough(), getter: DelegateGetter<Vector4f> = DelegateGetter.passthrough()) = Slot(
ListenableDelegate.maskSmart(value, getter, setter), Vector4fCodec)
fun OutputStream.writeEnumStupid(index: Int, isLegacy: Boolean) { fun OutputStream.writeEnumStupid(index: Int, isLegacy: Boolean) {
if (isLegacy) writeInt(index) else write(index) if (isLegacy) writeInt(index) else write(index)
} }

View File

@ -2,7 +2,7 @@ package ru.dbotthepony.kstarbound.item
import com.google.gson.JsonNull import com.google.gson.JsonNull
import com.google.gson.JsonObject import com.google.gson.JsonObject
import ru.dbotthepony.kommons.io.koptional import ru.dbotthepony.kstarbound.io.koptional
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

View File

@ -40,5 +40,9 @@ data class VersionedJson(val id: String, val version: Int?, val content: JsonEle
companion object { companion object {
private val adapter by lazy { Starbound.gson.getAdapter<VersionedJson>() } private val adapter by lazy { Starbound.gson.getAdapter<VersionedJson>() }
fun fromJson(data: JsonElement): VersionedJson {
return adapter.fromJsonTree(data)
}
} }
} }

View File

@ -461,7 +461,7 @@ fun provideRootBindings(lua: LuaEnvironment) {
table["imageSize"] = imageSize table["imageSize"] = imageSize
table["imageSpaces"] = luaFunctionNS("imageSpaces", ::imageSpaces) table["imageSpaces"] = luaFunctionNS("imageSpaces", ::imageSpaces)
table["nonEmptyRegion"] = luaFunction(::nonEmptyRegion) table["nonEmptyRegion"] = luaFunction(::nonEmptyRegion)
table["npcConfig"] = registryDef(Registries.npcTypes) //table["npcConfig"] = registryDef(Registries.npcTypes)
table["npcVariant"] = luaStub("npcVariant") table["npcVariant"] = luaStub("npcVariant")
table["projectileGravityMultiplier"] = luaStub("projectileGravityMultiplier") table["projectileGravityMultiplier"] = luaStub("projectileGravityMultiplier")

View File

@ -13,9 +13,9 @@ import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.asCoroutineDispatcher 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.IntValueCodec import ru.dbotthepony.kstarbound.io.IntValueCodec
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kommons.io.koptional import ru.dbotthepony.kstarbound.io.koptional
import ru.dbotthepony.kstarbound.math.AABBi import ru.dbotthepony.kstarbound.math.AABBi
import ru.dbotthepony.kommons.util.KOptional import ru.dbotthepony.kommons.util.KOptional
import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.getValue

View File

@ -1,6 +1,6 @@
package ru.dbotthepony.kstarbound.network.syncher package ru.dbotthepony.kstarbound.network.syncher
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kommons.util.Listenable import ru.dbotthepony.kommons.util.Listenable
import ru.dbotthepony.kommons.util.ListenableDelegate import ru.dbotthepony.kommons.util.ListenableDelegate
import java.io.DataInputStream import java.io.DataInputStream

View File

@ -1,6 +1,6 @@
package ru.dbotthepony.kstarbound.network.syncher package ru.dbotthepony.kstarbound.network.syncher
import ru.dbotthepony.kommons.io.UnsignedVarLongCodec import ru.dbotthepony.kstarbound.io.UnsignedVarLongCodec
import java.io.DataInputStream import java.io.DataInputStream
import java.util.function.Consumer import java.util.function.Consumer

View File

@ -4,34 +4,25 @@ 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 com.google.gson.TypeAdapter import com.google.gson.TypeAdapter
import ru.dbotthepony.kommons.io.BinaryStringCodec
import ru.dbotthepony.kommons.io.BooleanValueCodec
import ru.dbotthepony.kommons.io.IntValueCodec
import ru.dbotthepony.kommons.io.RGBACodec
import ru.dbotthepony.kommons.io.StreamCodec
import ru.dbotthepony.kommons.io.UnsignedVarIntCodec
import ru.dbotthepony.kommons.io.UnsignedVarLongCodec
import ru.dbotthepony.kommons.io.VarIntValueCodec
import ru.dbotthepony.kommons.io.VarLongValueCodec
import ru.dbotthepony.kommons.io.koptional
import ru.dbotthepony.kommons.io.map
import ru.dbotthepony.kommons.io.readByteArray import ru.dbotthepony.kommons.io.readByteArray
import ru.dbotthepony.kommons.io.readVarInt
import ru.dbotthepony.kommons.io.readVarLong import ru.dbotthepony.kommons.io.readVarLong
import ru.dbotthepony.kommons.io.writeBinaryString import ru.dbotthepony.kommons.io.writeBinaryString
import ru.dbotthepony.kommons.io.writeByteArray import ru.dbotthepony.kommons.io.writeByteArray
import ru.dbotthepony.kommons.io.writeShort
import ru.dbotthepony.kommons.io.writeVarInt
import ru.dbotthepony.kommons.io.writeVarLong import ru.dbotthepony.kommons.io.writeVarLong
import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.kstarbound.math.AABB
import ru.dbotthepony.kommons.util.KOptional import ru.dbotthepony.kommons.util.KOptional
import ru.dbotthepony.kstarbound.math.vector.Vector2d
import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.defs.item.ItemDescriptor import ru.dbotthepony.kstarbound.io.IntValueCodec
import ru.dbotthepony.kstarbound.defs.world.SkyType import ru.dbotthepony.kstarbound.io.RGBACodec
import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kstarbound.io.UnsignedVarIntCodec
import ru.dbotthepony.kstarbound.io.UnsignedVarLongCodec
import ru.dbotthepony.kstarbound.io.VarIntValueCodec
import ru.dbotthepony.kstarbound.io.VarLongValueCodec
import ru.dbotthepony.kstarbound.io.Vector2dCodec import ru.dbotthepony.kstarbound.io.Vector2dCodec
import ru.dbotthepony.kstarbound.io.Vector2fCodec import ru.dbotthepony.kstarbound.io.Vector2fCodec
import ru.dbotthepony.kstarbound.io.koptional
import ru.dbotthepony.kstarbound.io.map
import ru.dbotthepony.kstarbound.io.readAABB import ru.dbotthepony.kstarbound.io.readAABB
import ru.dbotthepony.kstarbound.io.readAABBLegacy import ru.dbotthepony.kstarbound.io.readAABBLegacy
import ru.dbotthepony.kstarbound.io.readAABBLegacyOptional import ru.dbotthepony.kstarbound.io.readAABBLegacyOptional
@ -45,6 +36,8 @@ import ru.dbotthepony.kstarbound.json.readJsonElement
import ru.dbotthepony.kstarbound.json.readJsonObject import ru.dbotthepony.kstarbound.json.readJsonObject
import ru.dbotthepony.kstarbound.json.writeJsonElement import ru.dbotthepony.kstarbound.json.writeJsonElement
import ru.dbotthepony.kstarbound.json.writeJsonObject import ru.dbotthepony.kstarbound.json.writeJsonObject
import ru.dbotthepony.kstarbound.math.AABB
import ru.dbotthepony.kstarbound.math.vector.Vector2d
import ru.dbotthepony.kstarbound.world.physics.Poly import ru.dbotthepony.kstarbound.world.physics.Poly
import java.io.DataInputStream import java.io.DataInputStream
import java.io.DataOutputStream import java.io.DataOutputStream

View File

@ -3,7 +3,7 @@ package ru.dbotthepony.kstarbound.network.syncher
import com.google.gson.TypeAdapter import com.google.gson.TypeAdapter
import it.unimi.dsi.fastutil.io.FastByteArrayInputStream import it.unimi.dsi.fastutil.io.FastByteArrayInputStream
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kommons.io.readByteArray import ru.dbotthepony.kommons.io.readByteArray
import ru.dbotthepony.kommons.io.writeByteArray import ru.dbotthepony.kommons.io.writeByteArray
import ru.dbotthepony.kstarbound.json.BinaryJsonReader import ru.dbotthepony.kstarbound.json.BinaryJsonReader

View File

@ -2,7 +2,7 @@ package ru.dbotthepony.kstarbound.network.syncher
import it.unimi.dsi.fastutil.io.FastByteArrayInputStream import it.unimi.dsi.fastutil.io.FastByteArrayInputStream
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kommons.io.readByteArray import ru.dbotthepony.kommons.io.readByteArray
import ru.dbotthepony.kommons.io.readVarInt import ru.dbotthepony.kommons.io.readVarInt
import ru.dbotthepony.kommons.io.writeVarInt import ru.dbotthepony.kommons.io.writeVarInt

View File

@ -1,7 +1,7 @@
package ru.dbotthepony.kstarbound.network.syncher package ru.dbotthepony.kstarbound.network.syncher
import ru.dbotthepony.kommons.collect.ListenableMap import ru.dbotthepony.kommons.collect.ListenableMap
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kommons.io.readVarInt import ru.dbotthepony.kommons.io.readVarInt
import ru.dbotthepony.kommons.io.writeVarInt import ru.dbotthepony.kommons.io.writeVarInt
import ru.dbotthepony.kommons.util.KOptional import ru.dbotthepony.kommons.util.KOptional

View File

@ -1,6 +1,6 @@
package ru.dbotthepony.kstarbound.network.syncher package ru.dbotthepony.kstarbound.network.syncher
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kommons.io.readVarInt import ru.dbotthepony.kommons.io.readVarInt
import ru.dbotthepony.kommons.io.writeVarInt import ru.dbotthepony.kommons.io.writeVarInt
import ru.dbotthepony.kommons.util.KOptional import ru.dbotthepony.kommons.util.KOptional

View File

@ -1,5 +1,6 @@
package ru.dbotthepony.kstarbound.server.world package ru.dbotthepony.kstarbound.server.world
import com.google.gson.JsonArray
import com.google.gson.JsonObject import com.google.gson.JsonObject
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
import it.unimi.dsi.fastutil.io.FastByteArrayInputStream import it.unimi.dsi.fastutil.io.FastByteArrayInputStream
@ -15,12 +16,13 @@ import ru.dbotthepony.kommons.io.writeCollection
import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.VersionRegistry import ru.dbotthepony.kstarbound.VersionRegistry
import ru.dbotthepony.kstarbound.defs.EntityType import ru.dbotthepony.kstarbound.defs.EntityType
import ru.dbotthepony.kstarbound.io.createSavepoint import ru.dbotthepony.kstarbound.io.SQLSavepoint
import ru.dbotthepony.kstarbound.json.VersionedJson import ru.dbotthepony.kstarbound.json.VersionedJson
import ru.dbotthepony.kstarbound.json.readJsonArrayInflated
import ru.dbotthepony.kstarbound.json.readJsonElement import ru.dbotthepony.kstarbound.json.readJsonElement
import ru.dbotthepony.kstarbound.json.readJsonObjectInflated import ru.dbotthepony.kstarbound.json.readJsonObjectInflated
import ru.dbotthepony.kstarbound.json.writeJsonArrayDeflated
import ru.dbotthepony.kstarbound.json.writeJsonElement import ru.dbotthepony.kstarbound.json.writeJsonElement
import ru.dbotthepony.kstarbound.json.writeJsonObjectDeflated
import ru.dbotthepony.kstarbound.math.vector.Vector2d import ru.dbotthepony.kstarbound.math.vector.Vector2d
import ru.dbotthepony.kstarbound.math.vector.Vector2i import ru.dbotthepony.kstarbound.math.vector.Vector2i
import ru.dbotthepony.kstarbound.util.CarriedExecutor import ru.dbotthepony.kstarbound.util.CarriedExecutor
@ -39,7 +41,6 @@ import java.io.File
import java.lang.ref.Cleaner import java.lang.ref.Cleaner
import java.sql.Connection import java.sql.Connection
import java.sql.DriverManager import java.sql.DriverManager
import java.sql.PreparedStatement
import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletableFuture
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import java.util.zip.Deflater import java.util.zip.Deflater
@ -96,28 +97,26 @@ class NativeLocalWorldStorage(file: File?) : WorldStorage() {
it.execute(""" it.execute("""
CREATE TABLE IF NOT EXISTS "entities" ( CREATE TABLE IF NOT EXISTS "entities" (
"x" INTEGER NOT NULL,
"y" INTEGER NOT NULL,
"data" BLOB NOT NULL,
PRIMARY KEY ("x", "y")
)
""".trimIndent())
it.execute("""
CREATE TABLE IF NOT EXISTS "unique_entities" (
"unique_id" BLOB NOT NULL PRIMARY KEY,
-- store chunks because rules for entities belonging to specific chunk might get different over time -- store chunks because rules for entities belonging to specific chunk might get different over time
"chunkX" INTEGER NOT NULL, "chunkX" INTEGER NOT NULL,
"chunkY" INTEGER NOT NULL, "chunkY" INTEGER NOT NULL,
"x" REAL NOT NULL, "x" REAL NOT NULL,
"y" REAL NOT NULL, "y" REAL NOT NULL
"unique_id" VARCHAR,
"type" VARCHAR NOT NULL,
"version" INTEGER NOT NULL,
"data" BLOB NOT NULL
) )
""".trimIndent()) """.trimIndent())
// Enforce unique-ness of unique entity IDs
// If another entity pops-up with same unique id, then it will overwrite entity in other chunk
// (unless colliding entities are both loaded into world's memory, which will cause runtime exception to be thrown;
// and no overwrite will happen)
it.execute(""" it.execute("""
CREATE UNIQUE INDEX IF NOT EXISTS "entities_unique_id" ON "entities" ("unique_id") CREATE INDEX IF NOT EXISTS "entities_chunk_pos" ON "unique_entities" ("chunkX", "chunkY")
""".trimIndent())
it.execute("""
CREATE INDEX IF NOT EXISTS "entities_chunk_pos" ON "entities" ("chunkX", "chunkY")
""".trimIndent()) """.trimIndent())
} }
@ -167,7 +166,7 @@ class NativeLocalWorldStorage(file: File?) : WorldStorage() {
} }
private val readEntities = connection.prepareStatement(""" private val readEntities = connection.prepareStatement("""
SELECT "type", "version", "data" FROM "entities" WHERE "chunkX" = ? AND "chunkY" = ? SELECT "data" FROM "entities" WHERE "x" = ? AND "y" = ?
""".trimIndent()) """.trimIndent())
override fun loadEntities(pos: ChunkPos): CompletableFuture<Collection<AbstractEntity>> { override fun loadEntities(pos: ChunkPos): CompletableFuture<Collection<AbstractEntity>> {
@ -178,20 +177,22 @@ class NativeLocalWorldStorage(file: File?) : WorldStorage() {
val entities = ArrayList<AbstractEntity>() val entities = ArrayList<AbstractEntity>()
readEntities.executeQuery().use { readEntities.executeQuery().use {
while (it.next()) { if (it.next()) {
val rtype = it.getString(1) val data = it.getBytes(1).readJsonArrayInflated()
val version = it.getInt(2)
val type = EntityType.entries.firstOrNull { it.storeName == rtype }
if (type != null) { for (entry in data) {
try { val versioned = VersionedJson.fromJson(entry)
val data = it.getBytes(3).readJsonObjectInflated() val type = EntityType.entries.firstOrNull { it.storeName == versioned.id }
entities.add(type.fromStorage(VersionRegistry.migrate(VersionedJson(rtype, version, data)) as JsonObject))
} catch (err: Throwable) { if (type != null) {
LOGGER.error("Unable to deserialize entity in chunk $pos", err) try {
entities.add(type.fromStorage(VersionRegistry.migrate(versioned) as JsonObject))
} catch (err: Throwable) {
LOGGER.error("Unable to deserialize entity in chunk $pos", err)
}
} else {
LOGGER.error("Unknown entity type ${versioned.id} in chunk $pos")
} }
} else {
LOGGER.error("Unknown entity type $rtype in chunk $pos")
} }
} }
} }
@ -240,57 +241,53 @@ class NativeLocalWorldStorage(file: File?) : WorldStorage() {
} }
} }
private val clearEntities = connection.prepareStatement(""" private val clearUniqueEntities = connection.prepareStatement("""
DELETE FROM "entities" WHERE "chunkX" = ? AND "chunkY" = ? DELETE FROM "unique_entities" WHERE "chunkX" = ? AND "chunkY" = ?
""".trimIndent()) """.trimIndent())
private val beginSaveEntities: PreparedStatement private val entitiesSavepoint = SQLSavepoint(connection, "save_entities")
private val finishSaveEntities: PreparedStatement
private val rollbackSaveEntities: PreparedStatement
init { private val writeEntities = connection.prepareStatement("""
val (begin, commit, rollback) = connection.createSavepoint("save_entities") REPLACE INTO "entities" ("x", "y", "data")
beginSaveEntities = begin VALUES (?, ?, ?)
finishSaveEntities = commit """.trimIndent())
rollbackSaveEntities = rollback
}
private val writeEntity = connection.prepareStatement(""" private val writeUniqueEntity = connection.prepareStatement("""
REPLACE INTO "entities" ("chunkX", "chunkY", "x", "y", "unique_id", "type", "version", "data") REPLACE INTO "unique_entities" ("unique_id", "chunkX", "chunkY", "x", "y")
VALUES (?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?)
""".trimIndent()) """.trimIndent())
override fun saveEntities(pos: ChunkPos, entities: Collection<AbstractEntity>) { override fun saveEntities(pos: ChunkPos, entities: Collection<AbstractEntity>) {
executor.execute { executor.execute {
beginSaveEntities.execute() entitiesSavepoint.execute {
clearUniqueEntities.setInt(1, pos.x)
clearUniqueEntities.setInt(2, pos.y)
clearUniqueEntities.execute()
try { val storeData = JsonArray()
clearEntities.setInt(1, pos.x)
clearEntities.setInt(2, pos.y)
clearEntities.execute()
for (entity in entities) { for (entity in entities) {
Starbound.storeJson { Starbound.storeJson {
val data = JsonObject() val data = JsonObject()
entity.serialize(data) entity.serialize(data)
storeData.add(VersionRegistry.make(entity.type.storeName, data).toJson())
writeEntity.setInt(1, pos.x) if (entity.uniqueID.get() != null) {
writeEntity.setInt(2, pos.y) writeUniqueEntity.setString(1, entity.uniqueID.get())
writeEntity.setDouble(3, entity.position.x) writeUniqueEntity.setInt(2, pos.x)
writeEntity.setDouble(4, entity.position.y) writeUniqueEntity.setInt(3, pos.y)
writeEntity.setString(5, entity.uniqueID.get()) writeUniqueEntity.setDouble(4, entity.position.x)
writeEntity.setString(6, entity.type.storeName) writeUniqueEntity.setDouble(5, entity.position.y)
writeEntity.setInt(7, VersionRegistry.currentVersion(entity.type.storeName))
writeEntity.setBytes(8, data.writeJsonObjectDeflated())
writeEntity.execute() writeUniqueEntity.execute()
}
} }
} }
finishSaveEntities.execute() writeEntities.setInt(1, pos.x)
} catch (err: Throwable) { writeEntities.setInt(2, pos.y)
rollbackSaveEntities.execute() writeEntities.setBytes(3, storeData.writeJsonArrayDeflated())
throw err writeEntities.execute()
} }
} }
} }
@ -430,7 +427,7 @@ class NativeLocalWorldStorage(file: File?) : WorldStorage() {
} }
private val findUniqueEntity = connection.prepareStatement(""" private val findUniqueEntity = connection.prepareStatement("""
SELECT "chunkX", "chunkY", "x", "y" FROM "entities" WHERE "unique_id" = ? SELECT "chunkX", "chunkY", "x", "y" FROM "unique_entities" WHERE "unique_id" = ?
""".trimIndent()) """.trimIndent())
override fun findUniqueEntity(identifier: String): CompletableFuture<UniqueEntitySearchResult?> { override fun findUniqueEntity(identifier: String): CompletableFuture<UniqueEntitySearchResult?> {

View File

@ -58,6 +58,6 @@ object AssetPathStack {
if (path.isNotEmpty() && path[0] == '/') if (path.isNotEmpty() && path[0] == '/')
return path return path
return if (base.endsWith('/')) "$base$path" else "$base/$path" return if (base.endsWith('/')) "$base$path".sbIntern() else "$base/$path".sbIntern()
} }
} }

View File

@ -1,7 +1,7 @@
package ru.dbotthepony.kstarbound.util package ru.dbotthepony.kstarbound.util
import com.google.gson.JsonElement import com.google.gson.JsonElement
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.json.builder.IStringSerializable import ru.dbotthepony.kstarbound.json.builder.IStringSerializable
import java.util.* import java.util.*

View File

@ -5,6 +5,7 @@ import com.google.gson.JsonElement
import it.unimi.dsi.fastutil.bytes.ByteConsumer import it.unimi.dsi.fastutil.bytes.ByteConsumer
import org.classdump.luna.ByteString import org.classdump.luna.ByteString
import ru.dbotthepony.kommons.util.IStruct2d import ru.dbotthepony.kommons.util.IStruct2d
import ru.dbotthepony.kommons.util.IStruct2f
import ru.dbotthepony.kommons.util.IStruct2i import ru.dbotthepony.kommons.util.IStruct2i
import ru.dbotthepony.kommons.util.XXHash32 import ru.dbotthepony.kommons.util.XXHash32
import ru.dbotthepony.kommons.util.XXHash64 import ru.dbotthepony.kommons.util.XXHash64
@ -263,6 +264,10 @@ fun RandomGenerator.nextRange(range: IStruct2d): Double {
return if (range.component1() == range.component2()) return range.component1() else nextDouble(range.component1(), range.component2()) return if (range.component1() == range.component2()) return range.component1() else nextDouble(range.component1(), range.component2())
} }
fun RandomGenerator.nextRange(range: IStruct2f): Float {
return if (range.component1() == range.component2()) return range.component1() else nextFloat(range.component1(), range.component2())
}
fun <T> MutableList<T>.shuffle(random: RandomGenerator) { fun <T> MutableList<T>.shuffle(random: RandomGenerator) {
for (i in 0 until size) { for (i in 0 until size) {
val rand = random.nextInt(size) val rand = random.nextInt(size)

View File

@ -1,6 +1,6 @@
package ru.dbotthepony.kstarbound.world package ru.dbotthepony.kstarbound.world
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kstarbound.math.vector.Vector2d import ru.dbotthepony.kstarbound.math.vector.Vector2d
import ru.dbotthepony.kstarbound.json.builder.IStringSerializable import ru.dbotthepony.kstarbound.json.builder.IStringSerializable

View File

@ -1,6 +1,6 @@
package ru.dbotthepony.kstarbound.world package ru.dbotthepony.kstarbound.world
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kstarbound.math.vector.Vector2d import ru.dbotthepony.kstarbound.math.vector.Vector2d
import ru.dbotthepony.kstarbound.json.builder.IStringSerializable import ru.dbotthepony.kstarbound.json.builder.IStringSerializable

View File

@ -1,7 +1,6 @@
package ru.dbotthepony.kstarbound.world package ru.dbotthepony.kstarbound.world
import ru.dbotthepony.kommons.io.VarIntValueCodec import ru.dbotthepony.kstarbound.io.map
import ru.dbotthepony.kommons.io.map
import ru.dbotthepony.kommons.math.linearInterpolation import ru.dbotthepony.kommons.math.linearInterpolation
import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.getValue
import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.kommons.util.setValue
@ -12,6 +11,7 @@ import ru.dbotthepony.kstarbound.defs.world.SkyGlobalConfig
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.defs.world.SkyType
import ru.dbotthepony.kstarbound.defs.world.WarpPhase import ru.dbotthepony.kstarbound.defs.world.WarpPhase
import ru.dbotthepony.kstarbound.io.VarIntValueCodec
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
import ru.dbotthepony.kstarbound.network.syncher.networkedBoolean import ru.dbotthepony.kstarbound.network.syncher.networkedBoolean

View File

@ -1,7 +1,7 @@
package ru.dbotthepony.kstarbound.world package ru.dbotthepony.kstarbound.world
import com.google.gson.JsonObject import com.google.gson.JsonObject
import ru.dbotthepony.kommons.io.koptional import ru.dbotthepony.kstarbound.io.koptional
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

View File

@ -7,7 +7,6 @@ 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.ObjectArrayList import it.unimi.dsi.fastutil.objects.ObjectArrayList
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
import ru.dbotthepony.kommons.io.nullable
import ru.dbotthepony.kommons.util.Either import ru.dbotthepony.kommons.util.Either
import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.client.StarboundClient import ru.dbotthepony.kstarbound.client.StarboundClient
@ -20,6 +19,7 @@ import ru.dbotthepony.kstarbound.defs.DamageType
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.HitType import ru.dbotthepony.kstarbound.defs.HitType
import ru.dbotthepony.kstarbound.io.nullable
import ru.dbotthepony.kstarbound.math.AABB import ru.dbotthepony.kstarbound.math.AABB
import ru.dbotthepony.kstarbound.math.vector.Vector2d import ru.dbotthepony.kstarbound.math.vector.Vector2d
import ru.dbotthepony.kstarbound.network.packets.DamageNotificationPacket import ru.dbotthepony.kstarbound.network.packets.DamageNotificationPacket

View File

@ -1,6 +1,5 @@
package ru.dbotthepony.kstarbound.world.entities package ru.dbotthepony.kstarbound.world.entities
import ru.dbotthepony.kommons.io.nullable
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.Globals import ru.dbotthepony.kstarbound.Globals
@ -9,6 +8,7 @@ import ru.dbotthepony.kstarbound.math.vector.Vector2d
import ru.dbotthepony.kstarbound.defs.ActorMovementParameters import ru.dbotthepony.kstarbound.defs.ActorMovementParameters
import ru.dbotthepony.kstarbound.defs.JumpProfile import ru.dbotthepony.kstarbound.defs.JumpProfile
import ru.dbotthepony.kstarbound.defs.MovementParameters import ru.dbotthepony.kstarbound.defs.MovementParameters
import ru.dbotthepony.kstarbound.io.nullable
import ru.dbotthepony.kstarbound.json.builder.JsonFactory import ru.dbotthepony.kstarbound.json.builder.JsonFactory
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
@ -239,7 +239,7 @@ class ActorMovementController() : MovementController() {
updateParameters(calculateMovementParameters(actorMovementParameters)) updateParameters(calculateMovementParameters(actorMovementParameters))
} }
// TODO: run is unsed // TODO: run is unused
fun pathMove(position: Vector2d, run: Boolean, parameters: PathFinder.Parameters? = null): Pair<Vector2d, Boolean>? { fun pathMove(position: Vector2d, run: Boolean, parameters: PathFinder.Parameters? = null): Pair<Vector2d, Boolean>? {
// FIXME: code flow is stupid // FIXME: code flow is stupid
@ -281,6 +281,7 @@ class ActorMovementController() : MovementController() {
controlMove = null controlMove = null
controlRun = false controlRun = false
controlCrouch = false controlCrouch = false
controlDown = false
controlJump = false controlJump = false
controlJumpAnyway = false controlJumpAnyway = false
controlFly = null controlFly = null

View File

@ -9,8 +9,8 @@ import org.apache.logging.log4j.LogManager
import ru.dbotthepony.kommons.gson.contains import ru.dbotthepony.kommons.gson.contains
import ru.dbotthepony.kommons.gson.getArray import ru.dbotthepony.kommons.gson.getArray
import ru.dbotthepony.kommons.gson.set import ru.dbotthepony.kommons.gson.set
import ru.dbotthepony.kommons.io.IntValueCodec import ru.dbotthepony.kstarbound.io.IntValueCodec
import ru.dbotthepony.kommons.io.map import ru.dbotthepony.kstarbound.io.map
import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.kstarbound.math.matrix.Matrix3d import ru.dbotthepony.kstarbound.math.matrix.Matrix3d
import ru.dbotthepony.kstarbound.math.matrix.Matrix3f import ru.dbotthepony.kstarbound.math.matrix.Matrix3f

View File

@ -3,7 +3,7 @@ package ru.dbotthepony.kstarbound.world.entities
import com.google.gson.JsonArray import com.google.gson.JsonArray
import com.google.gson.JsonElement import com.google.gson.JsonElement
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.StreamCodec
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.Starbound import ru.dbotthepony.kstarbound.Starbound

View File

@ -12,10 +12,7 @@ import org.classdump.luna.ByteString
import org.classdump.luna.Table import org.classdump.luna.Table
import ru.dbotthepony.kommons.gson.get import ru.dbotthepony.kommons.gson.get
import ru.dbotthepony.kommons.gson.set import ru.dbotthepony.kommons.gson.set
import ru.dbotthepony.kommons.io.DoubleValueCodec import ru.dbotthepony.kstarbound.io.map
import ru.dbotthepony.kommons.io.FloatValueCodec
import ru.dbotthepony.kommons.io.map
import ru.dbotthepony.kommons.io.nullable
import ru.dbotthepony.kommons.util.Either import ru.dbotthepony.kommons.util.Either
import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.getValue
import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.kommons.util.setValue
@ -39,6 +36,9 @@ import ru.dbotthepony.kstarbound.defs.actor.StatusControllerConfig
import ru.dbotthepony.kstarbound.defs.item.TreasurePoolDefinition import ru.dbotthepony.kstarbound.defs.item.TreasurePoolDefinition
import ru.dbotthepony.kstarbound.defs.monster.MonsterVariant import ru.dbotthepony.kstarbound.defs.monster.MonsterVariant
import ru.dbotthepony.kstarbound.fromJsonFast import ru.dbotthepony.kstarbound.fromJsonFast
import ru.dbotthepony.kstarbound.io.DoubleValueCodec
import ru.dbotthepony.kstarbound.io.FloatValueCodec
import ru.dbotthepony.kstarbound.io.nullable
import ru.dbotthepony.kstarbound.json.builder.JsonFactory import ru.dbotthepony.kstarbound.json.builder.JsonFactory
import ru.dbotthepony.kstarbound.lua.LuaEnvironment import ru.dbotthepony.kstarbound.lua.LuaEnvironment
import ru.dbotthepony.kstarbound.lua.LuaMessageHandlerComponent import ru.dbotthepony.kstarbound.lua.LuaMessageHandlerComponent

View File

@ -1,11 +1,9 @@
package ru.dbotthepony.kstarbound.world.entities package ru.dbotthepony.kstarbound.world.entities
import it.unimi.dsi.fastutil.objects.ObjectArrayList import it.unimi.dsi.fastutil.objects.ObjectArrayList
import ru.dbotthepony.kommons.io.DoubleValueCodec import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kommons.io.FloatValueCodec import ru.dbotthepony.kstarbound.io.koptional
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.map
import ru.dbotthepony.kommons.io.koptional
import ru.dbotthepony.kommons.io.map
import ru.dbotthepony.kstarbound.math.AABB import ru.dbotthepony.kstarbound.math.AABB
import ru.dbotthepony.kommons.util.KOptional import ru.dbotthepony.kommons.util.KOptional
import ru.dbotthepony.kommons.util.Listenable import ru.dbotthepony.kommons.util.Listenable
@ -17,6 +15,8 @@ import ru.dbotthepony.kstarbound.Globals
import ru.dbotthepony.kstarbound.Registry import ru.dbotthepony.kstarbound.Registry
import ru.dbotthepony.kstarbound.defs.MovementParameters import ru.dbotthepony.kstarbound.defs.MovementParameters
import ru.dbotthepony.kstarbound.defs.tile.LiquidDefinition import ru.dbotthepony.kstarbound.defs.tile.LiquidDefinition
import ru.dbotthepony.kstarbound.io.DoubleValueCodec
import ru.dbotthepony.kstarbound.io.FloatValueCodec
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.NetworkedGroup
import ru.dbotthepony.kstarbound.network.syncher.networkedBoolean import ru.dbotthepony.kstarbound.network.syncher.networkedBoolean
@ -197,9 +197,6 @@ open class MovementController {
var movementParameters: MovementParameters = Globals.movementParameters var movementParameters: MovementParameters = Globals.movementParameters
protected set protected set
var gravityMultiplier = 1.0
var isGravityDisabled = false
open fun isAtWorldLimit(bottomOnly: Boolean = false): Boolean { open fun isAtWorldLimit(bottomOnly: Boolean = false): Boolean {
return false // TODO return false // TODO
} }
@ -212,7 +209,7 @@ open class MovementController {
} }
fun determineGravity(): Vector2d { fun determineGravity(): Vector2d {
if (isGravityDisabled) if (movementParameters.gravityEnabled == false)
return Vector2d.ZERO return Vector2d.ZERO
return world.chunkMap.gravityAt(position) return world.chunkMap.gravityAt(position)
@ -279,7 +276,7 @@ open class MovementController {
*/ */
// TODO: Ghost collisions occur, where objects trip on edges // TODO: Ghost collisions occur, where objects trip on edges
open fun move(delta: Double) { open fun move(delta: Double) {
isZeroGravity = isGravityDisabled || gravityMultiplier == 0.0 || determineGravity().lengthSquared == 0.0 isZeroGravity = movementParameters.gravityEnabled == false || (movementParameters.gravityMultiplier ?: 1.0) == 0.0 || determineGravity().lengthSquared == 0.0
val movementParameters = movementParameters val movementParameters = movementParameters

View File

@ -0,0 +1,35 @@
package ru.dbotthepony.kstarbound.world.entities
import ru.dbotthepony.kstarbound.defs.EntityType
import ru.dbotthepony.kstarbound.math.AABB
import ru.dbotthepony.kstarbound.world.entities.api.InteractiveEntity
import ru.dbotthepony.kstarbound.world.entities.api.ScriptedEntity
import java.io.DataOutputStream
class NPCEntity : ActorEntity(), InteractiveEntity, ScriptedEntity {
override val type: EntityType
get() = EntityType.NPC
override val statusController: StatusController
get() = TODO("Not yet implemented")
override val damageBarType: DamageBarType
get() = TODO("Not yet implemented")
override fun writeNetwork(stream: DataOutputStream, isLegacy: Boolean) {
TODO("Not yet implemented")
}
override val metaBoundingBox: AABB
get() = TODO("Not yet implemented")
override val name: String
get() = TODO("Not yet implemented")
override val description: String
get() = TODO("Not yet implemented")
override fun callScript(fnName: String, vararg arguments: Any?): Array<Any?> {
TODO("Not yet implemented")
}
override fun evalScript(code: String): Array<Any?> {
TODO("Not yet implemented")
}
}

View File

@ -102,6 +102,9 @@ class PathController(val controller: ActorMovementController, var edgeTimer: Dou
this.path.addAll(newPath) this.path.addAll(newPath)
} }
} }
} else if (this.path.isEmpty() && newPath.isNotEmpty()) {
merged = true
this.path.addAll(newPath)
} }
if (!merged && controller.position != this.startPosition) { if (!merged && controller.position != this.startPosition) {
@ -130,7 +133,11 @@ class PathController(val controller: ActorMovementController, var edgeTimer: Dou
} }
this.edgeTimer = newEdgeTimer this.edgeTimer = newEdgeTimer
return this.path.isEmpty()
if (this.path.isEmpty())
return true
else
return null
} else { } else {
return null return null
} }
@ -139,7 +146,7 @@ class PathController(val controller: ActorMovementController, var edgeTimer: Dou
fun findPath(target: Vector2d): Boolean? { fun findPath(target: Vector2d): Boolean? {
// reached the end of the last path and we have a new target position to move toward // reached the end of the last path and we have a new target position to move toward
if (path.isEmpty() && controller.world.geometry.diff(this.target!!, target).lengthSquared > 0.1) { if (this.target != null && path.isEmpty() && controller.world.geometry.diff(this.target!!, target).lengthSquared > 0.1) {
reset() reset()
this.target = target this.target = target
} }

View File

@ -17,9 +17,8 @@ import ru.dbotthepony.kommons.collect.ListenableMap
import ru.dbotthepony.kommons.collect.collect import ru.dbotthepony.kommons.collect.collect
import ru.dbotthepony.kommons.collect.map import ru.dbotthepony.kommons.collect.map
import ru.dbotthepony.kommons.gson.set import ru.dbotthepony.kommons.gson.set
import ru.dbotthepony.kommons.io.IntValueCodec import ru.dbotthepony.kstarbound.io.IntValueCodec
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kommons.io.nullable
import ru.dbotthepony.kommons.io.readKOptional import ru.dbotthepony.kommons.io.readKOptional
import ru.dbotthepony.kommons.io.writeBinaryString import ru.dbotthepony.kommons.io.writeBinaryString
import ru.dbotthepony.kommons.io.writeKOptional import ru.dbotthepony.kommons.io.writeKOptional
@ -40,6 +39,7 @@ import ru.dbotthepony.kstarbound.defs.actor.StatModifier
import ru.dbotthepony.kstarbound.defs.actor.StatModifierType import ru.dbotthepony.kstarbound.defs.actor.StatModifierType
import ru.dbotthepony.kstarbound.defs.actor.StatusControllerConfig import ru.dbotthepony.kstarbound.defs.actor.StatusControllerConfig
import ru.dbotthepony.kstarbound.fromJsonFast import ru.dbotthepony.kstarbound.fromJsonFast
import ru.dbotthepony.kstarbound.io.nullable
import ru.dbotthepony.kstarbound.io.readInternedString import ru.dbotthepony.kstarbound.io.readInternedString
import ru.dbotthepony.kstarbound.json.builder.JsonFactory import ru.dbotthepony.kstarbound.json.builder.JsonFactory
import ru.dbotthepony.kstarbound.lua.LuaEnvironment import ru.dbotthepony.kstarbound.lua.LuaEnvironment

View File

@ -23,6 +23,9 @@ abstract class AbstractBehaviorNode {
RUNNING(null) RUNNING(null)
} }
var calls = 0
protected set
abstract fun run(delta: Double, state: BehaviorState): Status abstract fun run(delta: Double, state: BehaviorState): Status
abstract fun reset() abstract fun reset()

View File

@ -14,6 +14,7 @@ class ActionNode(val name: String, val parameters: Map<String, NodeParameter>, v
private val nodeID = BehaviorState.NODE_GARBAGE_INDEX.getAndIncrement() private val nodeID = BehaviorState.NODE_GARBAGE_INDEX.getAndIncrement()
override fun run(delta: Double, state: BehaviorState): Status { override fun run(delta: Double, state: BehaviorState): Status {
calls++
var coroutine = coroutine var coroutine = coroutine
var firstTime = false var firstTime = false
@ -67,7 +68,7 @@ class ActionNode(val name: String, val parameters: Map<String, NodeParameter>, v
} }
override fun toString(): String { override fun toString(): String {
return "ActionNode[$name, parameters=$parameters, outputs=$outputs, coroutine=$coroutine]" return "ActionNode[$calls / $name, parameters=$parameters, outputs=$outputs, coroutine=$coroutine]"
} }
companion object { companion object {

View File

@ -15,6 +15,7 @@ class DecoratorNode(val name: String, val parameters: Map<String, NodeParameter>
private val nodeID = BehaviorState.NODE_GARBAGE_INDEX.getAndIncrement() private val nodeID = BehaviorState.NODE_GARBAGE_INDEX.getAndIncrement()
override fun run(delta: Double, state: BehaviorState): Status { override fun run(delta: Double, state: BehaviorState): Status {
calls++
var coroutine = coroutine var coroutine = coroutine
if (coroutine == null) { if (coroutine == null) {
@ -100,7 +101,7 @@ class DecoratorNode(val name: String, val parameters: Map<String, NodeParameter>
} }
override fun toString(): String { override fun toString(): String {
return "DecoratorNode[$name, coroutine=$coroutine, parameters=$parameters, children=$child]" return "DecoratorNode[$calls / $name, coroutine=$coroutine, parameters=$parameters, children=$child]"
} }
companion object { companion object {

View File

@ -8,6 +8,7 @@ class DynamicNode(val children: ImmutableList<AbstractBehaviorNode>) : AbstractB
private var index = 0 private var index = 0
override fun run(delta: Double, state: BehaviorState): Status { override fun run(delta: Double, state: BehaviorState): Status {
calls++
for ((i, node) in children.withIndex()) { for ((i, node) in children.withIndex()) {
val status = node.runAndReset(delta, state) val status = node.runAndReset(delta, state)
@ -27,7 +28,7 @@ class DynamicNode(val children: ImmutableList<AbstractBehaviorNode>) : AbstractB
} }
override fun toString(): String { override fun toString(): String {
return "DynamicNode[${children.size}, index=$index, current=${children.getOrNull(index)}]" return "DynamicNode[$calls / ${children.size}, index=$index, current=${children.getOrNull(index)}]"
} }
override fun reset() { override fun reset() {

View File

@ -34,6 +34,7 @@ class ParallelNode(parameters: Map<String, NodeParameter>, val children: Immutab
private var lastSucceeded = -1 private var lastSucceeded = -1
override fun run(delta: Double, state: BehaviorState): Status { override fun run(delta: Double, state: BehaviorState): Status {
calls++
var failed = 0 var failed = 0
var succeeded = 0 var succeeded = 0
@ -58,7 +59,7 @@ class ParallelNode(parameters: Map<String, NodeParameter>, val children: Immutab
} }
override fun toString(): String { override fun toString(): String {
return "ParallelNode[children=${children.size}, successLimit=$successLimit, failLimit=$failLimit, lastFailed=$lastFailed, lastSucceeded=$lastSucceeded]" return "ParallelNode[$calls / children=${children.size}, successLimit=$successLimit, failLimit=$failLimit, lastFailed=$lastFailed, lastSucceeded=$lastSucceeded]"
} }
override fun reset() { override fun reset() {

View File

@ -8,6 +8,8 @@ class RandomizeNode(val children: ImmutableList<AbstractBehaviorNode>) : Abstrac
var index = -1 var index = -1
override fun run(delta: Double, state: BehaviorState): Status { override fun run(delta: Double, state: BehaviorState): Status {
calls++
if (index == -1 && children.isNotEmpty()) if (index == -1 && children.isNotEmpty())
index = state.lua.random.nextInt(children.size) index = state.lua.random.nextInt(children.size)
@ -19,9 +21,9 @@ class RandomizeNode(val children: ImmutableList<AbstractBehaviorNode>) : Abstrac
override fun toString(): String { override fun toString(): String {
if (index == -1) if (index == -1)
return "RandomizeNode[${children.size}, not chosen]" return "RandomizeNode[$calls / ${children.size}, not chosen]"
else else
return "RandomizeNode[${children.size}, ${children[index]}]" return "RandomizeNode[$calls / ${children.size}, ${children[index]}]"
} }
override fun reset() { override fun reset() {

View File

@ -4,25 +4,30 @@ import com.google.common.collect.ImmutableList
import org.classdump.luna.runtime.ExecutionContext import org.classdump.luna.runtime.ExecutionContext
import ru.dbotthepony.kstarbound.lua.userdata.BehaviorState import ru.dbotthepony.kstarbound.lua.userdata.BehaviorState
class SequenceNode(val children: ImmutableList<AbstractBehaviorNode>) : AbstractBehaviorNode() { class SequenceNode(val children: ImmutableList<AbstractBehaviorNode>, val isSelector: Boolean) : AbstractBehaviorNode() {
private var index = 0 private var index = 0
override fun run(delta: Double, state: BehaviorState): Status { override fun run(delta: Double, state: BehaviorState): Status {
calls++
while (index < children.size) { while (index < children.size) {
val child = children[index] val child = children[index]
val status = child.runAndReset(delta, state) val status = child.runAndReset(delta, state)
if (status == Status.FAILURE || status == Status.RUNNING) if ((isSelector && status == Status.SUCCESS || !isSelector && status == Status.FAILURE) || status == Status.RUNNING)
return status return status
index++ index++
} }
return Status.SUCCESS return if (isSelector) Status.FAILURE else Status.SUCCESS
} }
override fun toString(): String { override fun toString(): String {
return "SequenceNode[${children.size}, index=$index, current=${children.getOrNull(index)}]" if (isSelector)
return "SelectorNode[$calls / ${children.size}, index=$index, current=${children.getOrNull(index)}]"
else
return "SequenceNode[$calls / ${children.size}, index=$index, current=${children.getOrNull(index)}]"
} }
override fun reset() { override fun reset() {

View File

@ -1,6 +1,6 @@
package ru.dbotthepony.kstarbound.world.entities.player package ru.dbotthepony.kstarbound.world.entities.player
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.StreamCodec
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
import java.io.DataInputStream import java.io.DataInputStream

View File

@ -3,8 +3,6 @@ package ru.dbotthepony.kstarbound.world.entities.player
import com.google.common.collect.ImmutableMap import com.google.common.collect.ImmutableMap
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.LongValueCodec
import ru.dbotthepony.kommons.io.UnsignedVarLongCodec
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
@ -14,6 +12,8 @@ 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.defs.item.ItemDescriptor import ru.dbotthepony.kstarbound.defs.item.ItemDescriptor
import ru.dbotthepony.kstarbound.io.LongValueCodec
import ru.dbotthepony.kstarbound.io.UnsignedVarLongCodec
import ru.dbotthepony.kstarbound.item.ItemStack import ru.dbotthepony.kstarbound.item.ItemStack
import ru.dbotthepony.kstarbound.network.syncher.NetworkedGroup import ru.dbotthepony.kstarbound.network.syncher.NetworkedGroup
import ru.dbotthepony.kstarbound.network.syncher.legacyCodec import ru.dbotthepony.kstarbound.network.syncher.legacyCodec

View File

@ -1,9 +1,9 @@
package ru.dbotthepony.kstarbound.world.entities.player package ru.dbotthepony.kstarbound.world.entities.player
import ru.dbotthepony.kommons.io.IntValueCodec import ru.dbotthepony.kstarbound.io.IntValueCodec
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kommons.io.koptional import ru.dbotthepony.kstarbound.io.koptional
import ru.dbotthepony.kommons.io.map import ru.dbotthepony.kstarbound.io.map
import ru.dbotthepony.kommons.io.readKOptional import ru.dbotthepony.kommons.io.readKOptional
import ru.dbotthepony.kommons.io.writeBinaryString import ru.dbotthepony.kommons.io.writeBinaryString
import ru.dbotthepony.kommons.io.writeKOptional import ru.dbotthepony.kommons.io.writeKOptional

View File

@ -1,6 +1,6 @@
package ru.dbotthepony.kstarbound.world.entities.tile package ru.dbotthepony.kstarbound.world.entities.tile
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kommons.io.readSignedVarInt import ru.dbotthepony.kommons.io.readSignedVarInt
import ru.dbotthepony.kommons.io.readVarInt import ru.dbotthepony.kommons.io.readVarInt
import ru.dbotthepony.kommons.io.writeSignedVarInt import ru.dbotthepony.kommons.io.writeSignedVarInt

View File

@ -26,9 +26,8 @@ import ru.dbotthepony.kstarbound.defs.`object`.ObjectOrientation
import ru.dbotthepony.kommons.gson.get import ru.dbotthepony.kommons.gson.get
import ru.dbotthepony.kommons.gson.set import ru.dbotthepony.kommons.gson.set
import ru.dbotthepony.kommons.guava.immutableSet import ru.dbotthepony.kommons.guava.immutableSet
import ru.dbotthepony.kommons.io.RGBACodec import ru.dbotthepony.kstarbound.io.StreamCodec
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kstarbound.io.map
import ru.dbotthepony.kommons.io.map
import ru.dbotthepony.kommons.io.writeBinaryString import ru.dbotthepony.kommons.io.writeBinaryString
import ru.dbotthepony.kstarbound.math.AABB import ru.dbotthepony.kstarbound.math.AABB
import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.getValue
@ -46,6 +45,7 @@ import ru.dbotthepony.kstarbound.defs.item.ItemDescriptor
import ru.dbotthepony.kstarbound.defs.`object`.ObjectType import ru.dbotthepony.kstarbound.defs.`object`.ObjectType
import ru.dbotthepony.kstarbound.defs.quest.QuestArcDescriptor import ru.dbotthepony.kstarbound.defs.quest.QuestArcDescriptor
import ru.dbotthepony.kstarbound.defs.tile.TileDamage import ru.dbotthepony.kstarbound.defs.tile.TileDamage
import ru.dbotthepony.kstarbound.io.RGBACodec
import ru.dbotthepony.kstarbound.io.Vector2iCodec import ru.dbotthepony.kstarbound.io.Vector2iCodec
import ru.dbotthepony.kstarbound.json.JsonPath import ru.dbotthepony.kstarbound.json.JsonPath
import ru.dbotthepony.kstarbound.json.jsonArrayOf import ru.dbotthepony.kstarbound.json.jsonArrayOf