From cb63b47b12900edd7b286c9a9e2730448afd69f1 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sat, 30 Mar 2024 20:12:40 +0700 Subject: [PATCH] Some sky implementation work --- .../dbotthepony/kstarbound/defs/world/Sky.kt | 37 ++- .../kstarbound/network/PacketRegistry.kt | 3 +- .../clientbound/EnvironmentUpdatePacket.kt | 22 ++ .../kstarbound/server/ServerConnection.kt | 3 +- .../kstarbound/server/world/ServerWorld.kt | 2 +- .../server/world/ServerWorldTracker.kt | 11 +- .../ru/dbotthepony/kstarbound/util/Utils.kt | 3 + .../ru/dbotthepony/kstarbound/world/Sky.kt | 244 +++++++++++++++--- .../ru/dbotthepony/kstarbound/world/World.kt | 4 +- .../world/entities/AbstractEntity.kt | 4 +- .../world/entities/DynamicEntity.kt | 2 +- .../kstarbound/world/entities/TileEntity.kt | 2 +- .../kstarbound/world/entities/WorldObject.kt | 6 +- .../world/entities/player/PlayerEntity.kt | 4 +- 14 files changed, 292 insertions(+), 55 deletions(-) create mode 100644 src/main/kotlin/ru/dbotthepony/kstarbound/network/packets/clientbound/EnvironmentUpdatePacket.kt diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/world/Sky.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/world/Sky.kt index 96a226f0..91399fb3 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/world/Sky.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/world/Sky.kt @@ -1,7 +1,6 @@ package ru.dbotthepony.kstarbound.defs.world import com.google.common.collect.ImmutableList -import com.google.gson.stream.JsonWriter import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.kommons.util.Either @@ -41,10 +40,10 @@ enum class FlyingType { } } -enum class WarpPhase(val stupidassbitch: Int) { - SLOWING_DOWN(-1), - MAINTAIN(0), - SPEEDING_UP(1) +enum class WarpPhase { + SLOWING_DOWN, + MAINTAIN, + SPEEDING_UP; } enum class SkyOrbiterType(override val jsonName: String) : IStringSerializable { @@ -168,12 +167,40 @@ data class SkyParameters( } } +@JsonFactory data class SkyGlobalConfig( val stars: Stars, + val disembarkOrigin: PathPiece, + val disembarkPath: ImmutableList, + val spaceDisembarkOrigin: PathPiece, + val spaceDisembarkPath: ImmutableList, + val arrivalOrigin: PathPiece, + val arrivalPath: ImmutableList, + val spaceArrivalOrigin: PathPiece, + val spaceArrivalPath: ImmutableList, + val correctionPower: Double = 0.0, + val speedupTime: Double = 1.0, + val hyperspaceSpeedupTime: Double = 2.4, + val slowdownTime: Double = 1.0, + val hyperspaceSlowdownTime: Double = 2.0, + val flyMaxVelocity: Double = 0.0, + val starVelocityFactor: Double = 0.0, + val flyingTimer: Double = 0.0, + val flashTimer: Double = 1.0, ) { + @JsonFactory data class Stars( val frames: Int, val list: ImmutableList, val hyperlist: ImmutableList, ) + + @JsonFactory + data class PathPiece( + val offset: Vector2d, + val rotation: Double = 0.0, + val time: Double = 0.0 + ) { + val rotationRad = Math.toDegrees(rotation) + } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/network/PacketRegistry.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/network/PacketRegistry.kt index ecaf8b95..29afdffb 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/network/PacketRegistry.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/network/PacketRegistry.kt @@ -34,6 +34,7 @@ import ru.dbotthepony.kstarbound.network.packets.StepUpdatePacket import ru.dbotthepony.kstarbound.network.packets.clientbound.CentralStructureUpdatePacket import ru.dbotthepony.kstarbound.network.packets.clientbound.ChatReceivePacket import ru.dbotthepony.kstarbound.network.packets.clientbound.ConnectFailurePacket +import ru.dbotthepony.kstarbound.network.packets.clientbound.EnvironmentUpdatePacket import ru.dbotthepony.kstarbound.network.packets.clientbound.FindUniqueEntityResponsePacket import ru.dbotthepony.kstarbound.network.packets.clientbound.LegacyTileArrayUpdatePacket import ru.dbotthepony.kstarbound.network.packets.clientbound.LegacyTileUpdatePacket @@ -419,7 +420,7 @@ class PacketRegistry(val isLegacy: Boolean) { LEGACY.add(::TileDamageUpdatePacket) LEGACY.skip("TileModificationFailure") LEGACY.skip("GiveItem") - LEGACY.skip("EnvironmentUpdate") + LEGACY.add(::EnvironmentUpdatePacket) LEGACY.skip("UpdateTileProtection") LEGACY.skip("SetDungeonGravity") LEGACY.skip("SetDungeonBreathable") diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/network/packets/clientbound/EnvironmentUpdatePacket.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/network/packets/clientbound/EnvironmentUpdatePacket.kt new file mode 100644 index 00000000..854ab44e --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/network/packets/clientbound/EnvironmentUpdatePacket.kt @@ -0,0 +1,22 @@ +package ru.dbotthepony.kstarbound.network.packets.clientbound + +import it.unimi.dsi.fastutil.bytes.ByteArrayList +import ru.dbotthepony.kommons.io.readByteArray +import ru.dbotthepony.kommons.io.writeByteArray +import ru.dbotthepony.kstarbound.client.ClientConnection +import ru.dbotthepony.kstarbound.network.IClientPacket +import java.io.DataInputStream +import java.io.DataOutputStream + +class EnvironmentUpdatePacket(val sky: ByteArrayList, val weather: ByteArrayList) : IClientPacket { + constructor(stream: DataInputStream, isLegacy: Boolean) : this(ByteArrayList.wrap(stream.readByteArray()), ByteArrayList.wrap(stream.readByteArray())) + + override fun write(stream: DataOutputStream, isLegacy: Boolean) { + stream.writeByteArray(sky.elements(), 0, sky.size) + stream.writeByteArray(weather.elements(), 0, weather.size) + } + + override fun play(connection: ClientConnection) { + TODO("Not yet implemented") + } +} diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/server/ServerConnection.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/server/ServerConnection.kt index e5dc8094..766ee4a7 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/server/ServerConnection.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/server/ServerConnection.kt @@ -9,6 +9,7 @@ import ru.dbotthepony.kommons.util.KOptional import ru.dbotthepony.kstarbound.defs.WarpAction import ru.dbotthepony.kstarbound.defs.WarpAlias import ru.dbotthepony.kstarbound.defs.WorldID +import ru.dbotthepony.kstarbound.defs.world.SkyType import ru.dbotthepony.kstarbound.network.Connection import ru.dbotthepony.kstarbound.network.ConnectionSide import ru.dbotthepony.kstarbound.network.ConnectionType @@ -23,7 +24,7 @@ import ru.dbotthepony.kstarbound.server.world.ServerWorld import java.util.HashMap import java.util.UUID import java.util.concurrent.CompletableFuture -import java.util.concurrent.ConcurrentLinkedQueue +import java.util.concurrent.TimeUnit import kotlin.properties.Delegates // serverside part of connection diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/server/world/ServerWorld.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/server/world/ServerWorld.kt index 5437234a..c5db6ce1 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/server/world/ServerWorld.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/server/world/ServerWorld.kt @@ -83,7 +83,7 @@ class ServerWorld private constructor( if (action != null) client.send(PlayerWarpResultPacket(true, action, false)) - client.tracker?.remove() + client.tracker?.remove("Transiting to new world") clients.add(ServerWorldTracker(this, client, start)) } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/server/world/ServerWorldTracker.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/server/world/ServerWorldTracker.kt index 4156ac39..d60c9076 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/server/world/ServerWorldTracker.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/server/world/ServerWorldTracker.kt @@ -20,6 +20,7 @@ import ru.dbotthepony.kstarbound.network.packets.EntityCreatePacket import ru.dbotthepony.kstarbound.network.packets.EntityDestroyPacket import ru.dbotthepony.kstarbound.network.packets.EntityUpdateSetPacket import ru.dbotthepony.kstarbound.network.packets.clientbound.CentralStructureUpdatePacket +import ru.dbotthepony.kstarbound.network.packets.clientbound.EnvironmentUpdatePacket import ru.dbotthepony.kstarbound.network.packets.clientbound.LegacyTileArrayUpdatePacket import ru.dbotthepony.kstarbound.network.packets.clientbound.LegacyTileUpdatePacket import ru.dbotthepony.kstarbound.network.packets.clientbound.TileDamageUpdatePacket @@ -141,6 +142,12 @@ class ServerWorldTracker(val world: ServerWorld, val client: ServerConnection, p return } + run { + val (data, version) = world.sky.networkedGroup.write(skyVersion, isLegacy = client.isLegacy) + skyVersion = version + send(EnvironmentUpdatePacket(data, ByteArrayList())) + } + run { var next = tasks.poll() @@ -269,7 +276,7 @@ class ServerWorldTracker(val world: ServerWorld, val client: ServerConnection, p } } - fun remove() { + fun remove(reason: String = "ServerWorldTracker got removed") { if (isRemoved.compareAndSet(false, true)) { // erase all tasks just to be sure tasks.clear() @@ -283,7 +290,7 @@ class ServerWorldTracker(val world: ServerWorld, val client: ServerConnection, p client.tracker = null client.playerEntity = null client.worldID = WorldID.Limbo - client.send(WorldStopPacket("Removed")) + client.send(WorldStopPacket(reason)) } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/util/Utils.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/util/Utils.kt index 63252cb0..1bc9c68d 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/util/Utils.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/util/Utils.kt @@ -15,6 +15,9 @@ fun String.sbIntern2(): String { return Starbound.STRINGS.intern(this.intern()) } +val JsonElement.asStringOrNull: String? + get() = if (isJsonNull) null else asString + fun traverseJsonPath(path: String?, element: JsonElement?): JsonElement? { element ?: return null path ?: return element diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/world/Sky.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/world/Sky.kt index 5e855179..373ef694 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/world/Sky.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/world/Sky.kt @@ -1,65 +1,89 @@ package ru.dbotthepony.kstarbound.world +import ru.dbotthepony.kommons.io.VarIntValueCodec +import ru.dbotthepony.kommons.io.map +import ru.dbotthepony.kommons.math.linearInterpolation import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.kommons.util.value +import ru.dbotthepony.kommons.vector.Vector2d +import ru.dbotthepony.kstarbound.GlobalDefaults +import ru.dbotthepony.kstarbound.Starbound +import ru.dbotthepony.kstarbound.defs.world.FlyingType +import ru.dbotthepony.kstarbound.defs.world.SkyGlobalConfig import ru.dbotthepony.kstarbound.defs.world.SkyParameters import ru.dbotthepony.kstarbound.defs.world.SkyType import ru.dbotthepony.kstarbound.defs.world.WarpPhase 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.networkedData import ru.dbotthepony.kstarbound.network.syncher.networkedDouble +import ru.dbotthepony.kstarbound.network.syncher.networkedEnum import ru.dbotthepony.kstarbound.network.syncher.networkedEnumStupid import ru.dbotthepony.kstarbound.network.syncher.networkedFloat import ru.dbotthepony.kstarbound.network.syncher.networkedJson -import ru.dbotthepony.kstarbound.network.syncher.networkedUnsignedInt import ru.dbotthepony.kstarbound.network.syncher.networkedVec2f +import kotlin.math.cos +import kotlin.math.pow +import kotlin.math.sin class Sky() { - private val skyParametersNetState = networkedJson(SkyParameters()) + val networkedGroup = MasterElement(NetworkedGroup()) - private val skyTypeNetState = networkedEnumStupid(SkyType.ORBITAL) - private val timeNetState = networkedDouble() - private val flyingTypeNetState = networkedUnsignedInt() - private val enterHyperspaceNetState = networkedBoolean() - private val startInWarpNetState = networkedBoolean() - private val worldMoveNetState = networkedEnumStupid(WarpPhase.MAINTAIN) - private val starMoveNetState = networkedVec2f() - private val warpPhaseNetState = networkedVec2f() - private val flyingTimerNetState = networkedFloat() + private val skyParametersNetState = networkedGroup.upstream.add(networkedJson(SkyParameters())) - var skyType by skyTypeNetState + var skyType by networkedGroup.upstream.add(networkedEnumStupid(SkyType.ORBITAL)) + var time by networkedGroup.upstream.add(networkedDouble()) private set - var time by timeNetState + var flyingType by networkedGroup.upstream.add(networkedEnum(FlyingType.NONE)) private set - var flyingType by flyingTypeNetState + var enterHyperspace by networkedGroup.upstream.add(networkedBoolean()) private set - var enterHyperspace by enterHyperspaceNetState + var startInWarp by networkedGroup.upstream.add(networkedBoolean()) private set - var startInWarp by startInWarpNetState + var warpPhase by networkedGroup.upstream.add(networkedData(WarpPhase.MAINTAIN, VarIntValueCodec.map({ WarpPhase.entries[this - 1] }, { ordinal - 1 }))) private set - var worldMove by worldMoveNetState + var worldMoveOffset by networkedGroup.upstream.add(networkedVec2f()) private set - var starMove by starMoveNetState + var starMoveOffset by networkedGroup.upstream.add(networkedVec2f()) private set - var warpPhase by warpPhaseNetState - private set - var flyingTimer by flyingTimerNetState + var flyingTimer by networkedGroup.upstream.add(networkedFloat()) private set - val networkedGroup = MasterElement(NetworkedGroup( - skyParametersNetState, - skyTypeNetState, - timeNetState, - flyingTypeNetState, - enterHyperspaceNetState, - startInWarpNetState, - worldMoveNetState, - starMoveNetState, - warpPhaseNetState, - flyingTimerNetState, - )) + var flashTimer = 0.0 + private set + + var starOffset = Vector2d.ZERO + private set + var worldOffset = Vector2d.ZERO + private set + var pathOffset = Vector2d.ZERO + private set + + var starRotation: Double = 0.0 + private set + var pathRotation: Double = 0.0 + private set + + var destination: SkyParameters? = null + private set + + val speedupTime: Double get() { + if (enterHyperspace) { + return GlobalDefaults.sky.hyperspaceSpeedupTime.coerceAtLeast(0.01) + } else { + return GlobalDefaults.sky.speedupTime.coerceAtLeast(0.01) + } + } + + val slowdownTime: Double get() { + if (enterHyperspace) { + return GlobalDefaults.sky.hyperspaceSlowdownTime.coerceAtLeast(0.01) + } else { + return GlobalDefaults.sky.slowdownTime.coerceAtLeast(0.01) + } + } constructor(parameters: SkyParameters, inOrbit: Boolean) : this() { skyParametersNetState.value = parameters.copy() @@ -70,4 +94,158 @@ class Sky() { skyType = parameters.skyType } } + + fun startFlying(enterHyperspace: Boolean, startInWarp: Boolean = false) { + if (startInWarp) + flyingType = FlyingType.WARP + else + flyingType = FlyingType.DISEMBARKING + + flyingTimer = 0.0 + this.enterHyperspace = enterHyperspace + this.startInWarp = startInWarp + } + + private var lastFlyingType = FlyingType.NONE + private var lastWarpPhase = WarpPhase.MAINTAIN + private var sentSFX = false + + private fun stateUpdate() { + if (flyingType != lastFlyingType) { + flyingTimer = 0.0 + + if (flyingType == FlyingType.WARP) { + warpPhase = WarpPhase.SPEEDING_UP + + if (startInWarp) { + if (enterHyperspace) { + warpPhase = WarpPhase.MAINTAIN + } else { + flyingTimer = speedupTime + } + + lastWarpPhase = warpPhase + } + + worldMoveOffset = Vector2d(cos(pathRotation), sin(pathRotation)) * GlobalDefaults.sky.flyMaxVelocity / 2.0 * speedupTime + starMoveOffset = Vector2d(x = GlobalDefaults.sky.flyMaxVelocity * GlobalDefaults.sky.starVelocityFactor / 2.0 * speedupTime) + } else if (flyingType == FlyingType.ARRIVING) { + sentSFX = false + worldOffset = Vector2d.ZERO + starOffset = Vector2d.ZERO + } + } + + if (warpPhase != lastWarpPhase) { + flyingTimer = 0.0 + + when (warpPhase) { + WarpPhase.SLOWING_DOWN -> { + + } + + WarpPhase.MAINTAIN -> { + flashTimer = GlobalDefaults.sky.flashTimer + skyType = SkyType.WARP + sentSFX = false + } + + WarpPhase.SPEEDING_UP -> { + flyingTimer = 0.0 + } + } + } + + lastFlyingType = flyingType + } + + + fun tick(delta: Double = Starbound.TIMESTEP) { + time += delta + flashTimer = (flashTimer - delta).coerceAtLeast(0.0) + + if (flyingType != FlyingType.NONE) { + flyingTimer += delta + + if (flyingType == FlyingType.DISEMBARKING) { + val finished = if (skyParametersNetState.value.skyType == SkyType.SPACE) + controlledMovement(GlobalDefaults.sky.spaceDisembarkPath, GlobalDefaults.sky.spaceDisembarkOrigin, flyingTimer) + else + controlledMovement(GlobalDefaults.sky.disembarkPath, GlobalDefaults.sky.disembarkOrigin, flyingTimer) + + if (finished) { + flyingType = FlyingType.WARP + } + } else if (flyingType == FlyingType.ARRIVING) { + val finished = if (skyParametersNetState.value.skyType == SkyType.SPACE) + controlledMovement(GlobalDefaults.sky.spaceArrivalPath, GlobalDefaults.sky.spaceArrivalOrigin, flyingTimer) + else + controlledMovement(GlobalDefaults.sky.arrivalPath, GlobalDefaults.sky.arrivalOrigin, flyingTimer) + + if (finished) { + flyingType = FlyingType.NONE + } + + starOffset -= starOffset * GlobalDefaults.sky.correctionPower + worldOffset -= worldOffset * GlobalDefaults.sky.correctionPower + } else if (flyingType == FlyingType.WARP) { + val percentage = when (warpPhase) { + WarpPhase.SLOWING_DOWN -> (flyingTimer / speedupTime).pow(2.0) + WarpPhase.MAINTAIN -> 1.0 + WarpPhase.SPEEDING_UP -> (1.0 - flyingTimer / speedupTime).pow(2.0) + } + + if (percentage < 1.0) { + val dir = warpPhase.ordinal - 1.0 + starOffset = (starMoveOffset * percentage * dir).rotate(-(starRotation + pathRotation)) + worldOffset = (worldMoveOffset * percentage * dir).rotate(-(starRotation + pathRotation)) + } else { + val angle = -(starRotation + pathRotation) + val angleVec = Vector2d(cos(angle), sin(angle)) + starOffset += angleVec * GlobalDefaults.sky.flyMaxVelocity * delta * GlobalDefaults.sky.starVelocityFactor + worldOffset = worldMoveOffset + } + + if (warpPhase == WarpPhase.SPEEDING_UP && flyingTimer >= speedupTime && !enterHyperspace && destination != null) { + skyParametersNetState.value = destination!! + destination = null + warpPhase = WarpPhase.SLOWING_DOWN + } else if (warpPhase == WarpPhase.SPEEDING_UP && flyingTimer >= speedupTime && enterHyperspace) { + warpPhase = WarpPhase.MAINTAIN + } else if (warpPhase == WarpPhase.MAINTAIN && flyingTimer >= GlobalDefaults.sky.flyingTimer && destination != null) { + skyParametersNetState.value = destination!! + destination = null + warpPhase = WarpPhase.SLOWING_DOWN + } else if (warpPhase == WarpPhase.SLOWING_DOWN && flyingTimer >= slowdownTime) { + flyingType = FlyingType.ARRIVING + } + } + } else { + starOffset = Vector2d.ZERO + worldOffset = Vector2d.ZERO + pathOffset = Vector2d.ZERO + } + + stateUpdate() + } + + private fun controlledMovement(path: List, origin: SkyGlobalConfig.PathPiece, timeOffset: Double): Boolean { + var previous = origin + var stepTime = 0.0 + + for (entry in path) { + stepTime += entry.time + + if (timeOffset <= stepTime) { + val percentage = (timeOffset - previous.time) / (stepTime - previous.time) + pathOffset = linearInterpolation(percentage, previous.offset, entry.offset) + pathRotation = linearInterpolation(percentage, previous.rotation, entry.rotation) + return false + } + + previous = entry + } + + return true + } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/world/World.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/world/World.kt index b6b49bfe..823fad46 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/world/World.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/world/World.kt @@ -266,11 +266,11 @@ abstract class World, ChunkType : Chunk) { } - protected open fun onRemove(world: World<*, *>) { } + protected open fun onRemove(world: World<*, *>, isDeath: Boolean) { } val networkGroup = MasterElement(NetworkedGroup()) abstract fun writeNetwork(stream: DataOutputStream, isLegacy: Boolean) @@ -116,7 +116,7 @@ abstract class AbstractEntity(path: String) : JsonDriven(path), Comparable) { + override fun onRemove(world: World<*, *>, isDeath: Boolean) { world.dynamicEntities.remove(this) movement.remove() } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/world/entities/TileEntity.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/world/entities/TileEntity.kt index e1320981..973eda28 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/world/entities/TileEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/world/entities/TileEntity.kt @@ -28,6 +28,6 @@ abstract class TileEntity(path: String) : AbstractEntity(path) { tilePosition = tilePosition } - override fun onRemove(world: World<*, *>) { + override fun onRemove(world: World<*, *>, isDeath: Boolean) { } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/world/entities/WorldObject.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/world/entities/WorldObject.kt index 94bd642a..0fc4eaf6 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/world/entities/WorldObject.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/world/entities/WorldObject.kt @@ -20,6 +20,7 @@ import ru.dbotthepony.kstarbound.server.world.ServerWorld import ru.dbotthepony.kommons.gson.get import ru.dbotthepony.kommons.gson.set import ru.dbotthepony.kstarbound.defs.EntityType +import ru.dbotthepony.kstarbound.util.asStringOrNull import ru.dbotthepony.kstarbound.world.Side import ru.dbotthepony.kstarbound.world.LightCalculator import ru.dbotthepony.kstarbound.world.PIXELS_IN_STARBOUND_UNITf @@ -35,10 +36,7 @@ open class WorldObject( orientationIndex = data.get("orientationIndex", -1) interactive = data.get("interactive", false) - data["uniqueId"]?.let { - if (!it.isJsonNull) - uniqueId = it.asString - } + uniqueId = data["uniqueId"]?.asStringOrNull for ((k, v) in data.get("parameters") { JsonObject() }.entrySet()) { properties[k] = v.deepCopy() diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/world/entities/player/PlayerEntity.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/world/entities/player/PlayerEntity.kt index 01aec673..7e9a91ca 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/world/entities/player/PlayerEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/world/entities/player/PlayerEntity.kt @@ -107,8 +107,8 @@ class PlayerEntity() : HumanoidActorEntity("/") { metaFixture = spatialEntry!!.Fixture() } - override fun onRemove(world: World<*, *>) { - super.onRemove(world) + override fun onRemove(world: World<*, *>, isDeath: Boolean) { + super.onRemove(world, isDeath) metaFixture?.remove() metaFixture = null }