148 lines
4.8 KiB
Kotlin
148 lines
4.8 KiB
Kotlin
package ru.dbotthepony.kstarbound.defs
|
|
|
|
import com.google.gson.reflect.TypeToken
|
|
import ru.dbotthepony.kstarbound.io.readDouble
|
|
import ru.dbotthepony.kstarbound.io.readNullableDouble
|
|
import ru.dbotthepony.kstarbound.io.readVector2d
|
|
import ru.dbotthepony.kstarbound.io.writeDouble
|
|
import ru.dbotthepony.kstarbound.io.writeNullableDouble
|
|
import ru.dbotthepony.kstarbound.io.writeStruct2d
|
|
import ru.dbotthepony.kstarbound.json.builder.DispatchingAdapter
|
|
import ru.dbotthepony.kstarbound.json.builder.IStringSerializable
|
|
import ru.dbotthepony.kstarbound.json.builder.JsonFactory
|
|
import ru.dbotthepony.kstarbound.json.builder.JsonFlat
|
|
import ru.dbotthepony.kstarbound.math.Line2d
|
|
import ru.dbotthepony.kstarbound.math.vector.Vector2d
|
|
import ru.dbotthepony.kstarbound.network.syncher.legacyCodec
|
|
import ru.dbotthepony.kstarbound.network.syncher.nativeCodec
|
|
import ru.dbotthepony.kstarbound.world.physics.Poly
|
|
import java.io.DataInputStream
|
|
import java.io.DataOutputStream
|
|
|
|
sealed class PhysicsForceRegion {
|
|
// ephemeral property from json
|
|
abstract val enabled: Boolean
|
|
abstract val filter: PhysicsCategoryFilter
|
|
abstract fun write(stream: DataOutputStream, isLegacy: Boolean)
|
|
|
|
abstract val type: Type
|
|
|
|
enum class Type(override val jsonName: String, val token: TypeToken<out PhysicsForceRegion>) : IStringSerializable {
|
|
DIRECTIONAL("DirectionalForceRegion", TypeToken.get(Directional::class.java)),
|
|
RADIAL("RadialForceRegion", TypeToken.get(Radial::class.java)),
|
|
GRADIENT("GradientForceRegion", TypeToken.get(Gradient::class.java))
|
|
}
|
|
|
|
@JsonFactory
|
|
data class Directional(
|
|
val region: Poly,
|
|
val xTargetVelocity: Double?,
|
|
val yTargetVelocity: Double?,
|
|
val controlForce: Double,
|
|
@JsonFlat
|
|
override val filter: PhysicsCategoryFilter,
|
|
override val enabled: Boolean = true
|
|
) : PhysicsForceRegion() {
|
|
constructor(stream: DataInputStream, isLegacy: Boolean) : this(
|
|
Poly.read(stream, isLegacy),
|
|
stream.readNullableDouble(isLegacy),
|
|
stream.readNullableDouble(isLegacy),
|
|
stream.readDouble(isLegacy),
|
|
PhysicsCategoryFilter(stream, isLegacy)
|
|
)
|
|
|
|
override val type: Type
|
|
get() = Type.DIRECTIONAL
|
|
|
|
override fun write(stream: DataOutputStream, isLegacy: Boolean) {
|
|
stream.writeByte(0)
|
|
region.write(stream, isLegacy)
|
|
stream.writeNullableDouble(xTargetVelocity, isLegacy)
|
|
stream.writeNullableDouble(yTargetVelocity, isLegacy)
|
|
stream.writeDouble(controlForce, isLegacy)
|
|
filter.write(stream, isLegacy)
|
|
}
|
|
}
|
|
|
|
@JsonFactory
|
|
data class Radial(
|
|
val center: Vector2d = Vector2d.ZERO,
|
|
val outerRadius: Double,
|
|
val innerRadius: Double,
|
|
val targetRadialVelocity: Double,
|
|
val controlForce: Double,
|
|
@JsonFlat
|
|
override val filter: PhysicsCategoryFilter,
|
|
override val enabled: Boolean = true
|
|
) : PhysicsForceRegion() {
|
|
constructor(stream: DataInputStream, isLegacy: Boolean) : this(
|
|
stream.readVector2d(isLegacy),
|
|
stream.readDouble(isLegacy),
|
|
stream.readDouble(isLegacy),
|
|
stream.readDouble(isLegacy),
|
|
stream.readDouble(isLegacy),
|
|
PhysicsCategoryFilter(stream, isLegacy)
|
|
)
|
|
|
|
override val type: Type
|
|
get() = Type.RADIAL
|
|
|
|
override fun write(stream: DataOutputStream, isLegacy: Boolean) {
|
|
stream.writeByte(1)
|
|
stream.writeStruct2d(center, isLegacy)
|
|
stream.writeDouble(outerRadius, isLegacy)
|
|
stream.writeDouble(innerRadius, isLegacy)
|
|
stream.writeDouble(targetRadialVelocity, isLegacy)
|
|
stream.writeDouble(controlForce, isLegacy)
|
|
filter.write(stream, isLegacy)
|
|
}
|
|
}
|
|
|
|
@JsonFactory
|
|
data class Gradient(
|
|
val region: Poly,
|
|
val gradient: Line2d,
|
|
val baseTargetVelocity: Double,
|
|
val baseControlForce: Double,
|
|
@JsonFlat
|
|
override val filter: PhysicsCategoryFilter,
|
|
override val enabled: Boolean = true
|
|
) : PhysicsForceRegion() {
|
|
constructor(stream: DataInputStream, isLegacy: Boolean) : this(
|
|
Poly.read(stream, isLegacy),
|
|
Line2d(stream, isLegacy),
|
|
stream.readDouble(isLegacy),
|
|
stream.readDouble(isLegacy),
|
|
PhysicsCategoryFilter(stream, isLegacy)
|
|
)
|
|
|
|
override val type: Type
|
|
get() = Type.GRADIENT
|
|
|
|
override fun write(stream: DataOutputStream, isLegacy: Boolean) {
|
|
stream.writeByte(2)
|
|
region.write(stream, isLegacy)
|
|
gradient.write(stream, isLegacy)
|
|
stream.writeDouble(baseTargetVelocity, isLegacy)
|
|
stream.writeDouble(baseControlForce, isLegacy)
|
|
filter.write(stream, isLegacy)
|
|
}
|
|
}
|
|
|
|
companion object {
|
|
val CODEC = nativeCodec(::read, PhysicsForceRegion::write)
|
|
val LEGACY_CODEC = legacyCodec(::read, PhysicsForceRegion::write)
|
|
|
|
val ADAPTER = DispatchingAdapter("type", { type }, { token }, Type.entries)
|
|
|
|
fun read(stream: DataInputStream, isLegacy: Boolean): PhysicsForceRegion {
|
|
return when (val type = stream.readUnsignedByte()) {
|
|
0 -> Directional(stream, isLegacy)
|
|
1 -> Radial(stream, isLegacy)
|
|
2 -> Gradient(stream, isLegacy)
|
|
else -> throw IllegalArgumentException("Unknown force region type $type!")
|
|
}
|
|
}
|
|
}
|
|
}
|