Some sky implementation work
This commit is contained in:
parent
ff746f43ae
commit
cb63b47b12
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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")
|
||||||
|
@ -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")
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user