Some sky implementation work

This commit is contained in:
DBotThePony 2024-03-30 20:12:40 +07:00
parent ff746f43ae
commit cb63b47b12
Signed by: DBot
GPG Key ID: DCC23B5715498507
14 changed files with 292 additions and 55 deletions

View File

@ -1,7 +1,6 @@
package ru.dbotthepony.kstarbound.defs.world package ru.dbotthepony.kstarbound.defs.world
import com.google.common.collect.ImmutableList import com.google.common.collect.ImmutableList
import com.google.gson.stream.JsonWriter
import ru.dbotthepony.kommons.io.StreamCodec import ru.dbotthepony.kommons.io.StreamCodec
import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.kommons.util.Either import ru.dbotthepony.kommons.util.Either
@ -41,10 +40,10 @@ enum class FlyingType {
} }
} }
enum class WarpPhase(val stupidassbitch: Int) { enum class WarpPhase {
SLOWING_DOWN(-1), SLOWING_DOWN,
MAINTAIN(0), MAINTAIN,
SPEEDING_UP(1) SPEEDING_UP;
} }
enum class SkyOrbiterType(override val jsonName: String) : IStringSerializable { enum class SkyOrbiterType(override val jsonName: String) : IStringSerializable {
@ -168,12 +167,40 @@ data class SkyParameters(
} }
} }
@JsonFactory
data class SkyGlobalConfig( data class SkyGlobalConfig(
val stars: Stars, val stars: Stars,
val disembarkOrigin: PathPiece,
val disembarkPath: ImmutableList<PathPiece>,
val spaceDisembarkOrigin: PathPiece,
val spaceDisembarkPath: ImmutableList<PathPiece>,
val arrivalOrigin: PathPiece,
val arrivalPath: ImmutableList<PathPiece>,
val spaceArrivalOrigin: PathPiece,
val spaceArrivalPath: ImmutableList<PathPiece>,
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( data class Stars(
val frames: Int, val frames: Int,
val list: ImmutableList<AssetPath>, val list: ImmutableList<AssetPath>,
val hyperlist: ImmutableList<AssetPath>, val hyperlist: ImmutableList<AssetPath>,
) )
@JsonFactory
data class PathPiece(
val offset: Vector2d,
val rotation: Double = 0.0,
val time: Double = 0.0
) {
val rotationRad = Math.toDegrees(rotation)
}
} }

View File

@ -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.CentralStructureUpdatePacket
import ru.dbotthepony.kstarbound.network.packets.clientbound.ChatReceivePacket import ru.dbotthepony.kstarbound.network.packets.clientbound.ChatReceivePacket
import ru.dbotthepony.kstarbound.network.packets.clientbound.ConnectFailurePacket 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.FindUniqueEntityResponsePacket
import ru.dbotthepony.kstarbound.network.packets.clientbound.LegacyTileArrayUpdatePacket import ru.dbotthepony.kstarbound.network.packets.clientbound.LegacyTileArrayUpdatePacket
import ru.dbotthepony.kstarbound.network.packets.clientbound.LegacyTileUpdatePacket import ru.dbotthepony.kstarbound.network.packets.clientbound.LegacyTileUpdatePacket
@ -419,7 +420,7 @@ class PacketRegistry(val isLegacy: Boolean) {
LEGACY.add(::TileDamageUpdatePacket) LEGACY.add(::TileDamageUpdatePacket)
LEGACY.skip("TileModificationFailure") LEGACY.skip("TileModificationFailure")
LEGACY.skip("GiveItem") LEGACY.skip("GiveItem")
LEGACY.skip("EnvironmentUpdate") LEGACY.add(::EnvironmentUpdatePacket)
LEGACY.skip("UpdateTileProtection") LEGACY.skip("UpdateTileProtection")
LEGACY.skip("SetDungeonGravity") LEGACY.skip("SetDungeonGravity")
LEGACY.skip("SetDungeonBreathable") LEGACY.skip("SetDungeonBreathable")

View File

@ -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")
}
}

View File

@ -9,6 +9,7 @@ import ru.dbotthepony.kommons.util.KOptional
import ru.dbotthepony.kstarbound.defs.WarpAction import ru.dbotthepony.kstarbound.defs.WarpAction
import ru.dbotthepony.kstarbound.defs.WarpAlias import ru.dbotthepony.kstarbound.defs.WarpAlias
import ru.dbotthepony.kstarbound.defs.WorldID import ru.dbotthepony.kstarbound.defs.WorldID
import ru.dbotthepony.kstarbound.defs.world.SkyType
import ru.dbotthepony.kstarbound.network.Connection import ru.dbotthepony.kstarbound.network.Connection
import ru.dbotthepony.kstarbound.network.ConnectionSide import ru.dbotthepony.kstarbound.network.ConnectionSide
import ru.dbotthepony.kstarbound.network.ConnectionType import ru.dbotthepony.kstarbound.network.ConnectionType
@ -23,7 +24,7 @@ import ru.dbotthepony.kstarbound.server.world.ServerWorld
import java.util.HashMap import java.util.HashMap
import java.util.UUID import java.util.UUID
import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletableFuture
import java.util.concurrent.ConcurrentLinkedQueue import java.util.concurrent.TimeUnit
import kotlin.properties.Delegates import kotlin.properties.Delegates
// serverside part of connection // serverside part of connection

View File

@ -83,7 +83,7 @@ class ServerWorld private constructor(
if (action != null) if (action != null)
client.send(PlayerWarpResultPacket(true, action, false)) client.send(PlayerWarpResultPacket(true, action, false))
client.tracker?.remove() client.tracker?.remove("Transiting to new world")
clients.add(ServerWorldTracker(this, client, start)) clients.add(ServerWorldTracker(this, client, start))
} }

View File

@ -20,6 +20,7 @@ import ru.dbotthepony.kstarbound.network.packets.EntityCreatePacket
import ru.dbotthepony.kstarbound.network.packets.EntityDestroyPacket import ru.dbotthepony.kstarbound.network.packets.EntityDestroyPacket
import ru.dbotthepony.kstarbound.network.packets.EntityUpdateSetPacket import ru.dbotthepony.kstarbound.network.packets.EntityUpdateSetPacket
import ru.dbotthepony.kstarbound.network.packets.clientbound.CentralStructureUpdatePacket 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.LegacyTileArrayUpdatePacket
import ru.dbotthepony.kstarbound.network.packets.clientbound.LegacyTileUpdatePacket import ru.dbotthepony.kstarbound.network.packets.clientbound.LegacyTileUpdatePacket
import ru.dbotthepony.kstarbound.network.packets.clientbound.TileDamageUpdatePacket import ru.dbotthepony.kstarbound.network.packets.clientbound.TileDamageUpdatePacket
@ -141,6 +142,12 @@ class ServerWorldTracker(val world: ServerWorld, val client: ServerConnection, p
return return
} }
run {
val (data, version) = world.sky.networkedGroup.write(skyVersion, isLegacy = client.isLegacy)
skyVersion = version
send(EnvironmentUpdatePacket(data, ByteArrayList()))
}
run { run {
var next = tasks.poll() 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)) { if (isRemoved.compareAndSet(false, true)) {
// erase all tasks just to be sure // erase all tasks just to be sure
tasks.clear() tasks.clear()
@ -283,7 +290,7 @@ class ServerWorldTracker(val world: ServerWorld, val client: ServerConnection, p
client.tracker = null client.tracker = null
client.playerEntity = null client.playerEntity = null
client.worldID = WorldID.Limbo client.worldID = WorldID.Limbo
client.send(WorldStopPacket("Removed")) client.send(WorldStopPacket(reason))
} }
} }

View File

@ -15,6 +15,9 @@ fun String.sbIntern2(): String {
return Starbound.STRINGS.intern(this.intern()) return Starbound.STRINGS.intern(this.intern())
} }
val JsonElement.asStringOrNull: String?
get() = if (isJsonNull) null else asString
fun traverseJsonPath(path: String?, element: JsonElement?): JsonElement? { fun traverseJsonPath(path: String?, element: JsonElement?): JsonElement? {
element ?: return null element ?: return null
path ?: return element path ?: return element

View File

@ -1,65 +1,89 @@
package ru.dbotthepony.kstarbound.world 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.getValue
import ru.dbotthepony.kommons.util.setValue import ru.dbotthepony.kommons.util.setValue
import ru.dbotthepony.kommons.util.value import ru.dbotthepony.kommons.util.value
import ru.dbotthepony.kommons.vector.Vector2d
import ru.dbotthepony.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.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.network.syncher.NetworkedGroup import ru.dbotthepony.kstarbound.network.syncher.NetworkedGroup
import ru.dbotthepony.kstarbound.network.syncher.MasterElement import ru.dbotthepony.kstarbound.network.syncher.MasterElement
import ru.dbotthepony.kstarbound.network.syncher.networkedBoolean import ru.dbotthepony.kstarbound.network.syncher.networkedBoolean
import ru.dbotthepony.kstarbound.network.syncher.networkedData
import ru.dbotthepony.kstarbound.network.syncher.networkedDouble 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.networkedEnumStupid
import ru.dbotthepony.kstarbound.network.syncher.networkedFloat import ru.dbotthepony.kstarbound.network.syncher.networkedFloat
import ru.dbotthepony.kstarbound.network.syncher.networkedJson import ru.dbotthepony.kstarbound.network.syncher.networkedJson
import ru.dbotthepony.kstarbound.network.syncher.networkedUnsignedInt
import ru.dbotthepony.kstarbound.network.syncher.networkedVec2f import ru.dbotthepony.kstarbound.network.syncher.networkedVec2f
import kotlin.math.cos
import kotlin.math.pow
import kotlin.math.sin
class Sky() { class Sky() {
private val skyParametersNetState = networkedJson(SkyParameters()) val networkedGroup = MasterElement(NetworkedGroup())
private val skyTypeNetState = networkedEnumStupid(SkyType.ORBITAL) private val skyParametersNetState = networkedGroup.upstream.add(networkedJson(SkyParameters()))
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()
var skyType by skyTypeNetState var skyType by networkedGroup.upstream.add(networkedEnumStupid(SkyType.ORBITAL))
var time by networkedGroup.upstream.add(networkedDouble())
private set private set
var time by timeNetState var flyingType by networkedGroup.upstream.add(networkedEnum(FlyingType.NONE))
private set private set
var flyingType by flyingTypeNetState var enterHyperspace by networkedGroup.upstream.add(networkedBoolean())
private set private set
var enterHyperspace by enterHyperspaceNetState var startInWarp by networkedGroup.upstream.add(networkedBoolean())
private set 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 private set
var worldMove by worldMoveNetState var worldMoveOffset by networkedGroup.upstream.add(networkedVec2f())
private set private set
var starMove by starMoveNetState var starMoveOffset by networkedGroup.upstream.add(networkedVec2f())
private set private set
var warpPhase by warpPhaseNetState var flyingTimer by networkedGroup.upstream.add(networkedFloat())
private set
var flyingTimer by flyingTimerNetState
private set private set
val networkedGroup = MasterElement(NetworkedGroup( var flashTimer = 0.0
skyParametersNetState, private set
skyTypeNetState,
timeNetState, var starOffset = Vector2d.ZERO
flyingTypeNetState, private set
enterHyperspaceNetState, var worldOffset = Vector2d.ZERO
startInWarpNetState, private set
worldMoveNetState, var pathOffset = Vector2d.ZERO
starMoveNetState, private set
warpPhaseNetState,
flyingTimerNetState, 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() { constructor(parameters: SkyParameters, inOrbit: Boolean) : this() {
skyParametersNetState.value = parameters.copy() skyParametersNetState.value = parameters.copy()
@ -70,4 +94,158 @@ class Sky() {
skyType = parameters.skyType 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<SkyGlobalConfig.PathPiece>, 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
}
} }

View File

@ -266,11 +266,11 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
entities.values.forEach { it.tick() } entities.values.forEach { it.tick() }
mailbox.executeQueuedTasks() mailbox.executeQueuedTasks()
for (chunk in chunkMap) { for (chunk in chunkMap)
chunk.tick() chunk.tick()
}
mailbox.executeQueuedTasks() mailbox.executeQueuedTasks()
sky.tick()
} }
protected abstract fun chunkFactory(pos: ChunkPos): ChunkType protected abstract fun chunkFactory(pos: ChunkPos): ChunkType

View File

@ -78,7 +78,7 @@ abstract class AbstractEntity(path: String) : JsonDriven(path), Comparable<Abstr
get() = true get() = true
protected open fun onJoinWorld(world: World<*, *>) { } protected open fun onJoinWorld(world: World<*, *>) { }
protected open fun onRemove(world: World<*, *>) { } protected open fun onRemove(world: World<*, *>, isDeath: Boolean) { }
val networkGroup = MasterElement(NetworkedGroup()) val networkGroup = MasterElement(NetworkedGroup())
abstract fun writeNetwork(stream: DataOutputStream, isLegacy: Boolean) abstract fun writeNetwork(stream: DataOutputStream, isLegacy: Boolean)
@ -116,7 +116,7 @@ abstract class AbstractEntity(path: String) : JsonDriven(path), Comparable<Abstr
mailbox.shutdownNow() mailbox.shutdownNow()
check(world.entities.remove(entityID) == this) { "Tried to remove $this from $world, but removed something else!" } check(world.entities.remove(entityID) == this) { "Tried to remove $this from $world, but removed something else!" }
onRemove(world) onRemove(world, isDeath)
spatialEntry?.remove() spatialEntry?.remove()
spatialEntry = null spatialEntry = null
innerWorld = null innerWorld = null

View File

@ -41,7 +41,7 @@ abstract class DynamicEntity(path: String) : AbstractEntity(path) {
forceChunkRepos = true forceChunkRepos = true
} }
override fun onRemove(world: World<*, *>) { override fun onRemove(world: World<*, *>, isDeath: Boolean) {
world.dynamicEntities.remove(this) world.dynamicEntities.remove(this)
movement.remove() movement.remove()
} }

View File

@ -28,6 +28,6 @@ abstract class TileEntity(path: String) : AbstractEntity(path) {
tilePosition = tilePosition tilePosition = tilePosition
} }
override fun onRemove(world: World<*, *>) { override fun onRemove(world: World<*, *>, isDeath: Boolean) {
} }
} }

View File

@ -20,6 +20,7 @@ import ru.dbotthepony.kstarbound.server.world.ServerWorld
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.kstarbound.defs.EntityType import ru.dbotthepony.kstarbound.defs.EntityType
import ru.dbotthepony.kstarbound.util.asStringOrNull
import ru.dbotthepony.kstarbound.world.Side import ru.dbotthepony.kstarbound.world.Side
import ru.dbotthepony.kstarbound.world.LightCalculator import ru.dbotthepony.kstarbound.world.LightCalculator
import ru.dbotthepony.kstarbound.world.PIXELS_IN_STARBOUND_UNITf import ru.dbotthepony.kstarbound.world.PIXELS_IN_STARBOUND_UNITf
@ -35,10 +36,7 @@ open class WorldObject(
orientationIndex = data.get("orientationIndex", -1) orientationIndex = data.get("orientationIndex", -1)
interactive = data.get("interactive", false) interactive = data.get("interactive", false)
data["uniqueId"]?.let { uniqueId = data["uniqueId"]?.asStringOrNull
if (!it.isJsonNull)
uniqueId = it.asString
}
for ((k, v) in data.get("parameters") { JsonObject() }.entrySet()) { for ((k, v) in data.get("parameters") { JsonObject() }.entrySet()) {
properties[k] = v.deepCopy() properties[k] = v.deepCopy()

View File

@ -107,8 +107,8 @@ class PlayerEntity() : HumanoidActorEntity("/") {
metaFixture = spatialEntry!!.Fixture() metaFixture = spatialEntry!!.Fixture()
} }
override fun onRemove(world: World<*, *>) { override fun onRemove(world: World<*, *>, isDeath: Boolean) {
super.onRemove(world) super.onRemove(world, isDeath)
metaFixture?.remove() metaFixture?.remove()
metaFixture = null metaFixture = null
} }