130 lines
4.6 KiB
Kotlin
130 lines
4.6 KiB
Kotlin
package ru.dbotthepony.kstarbound.defs
|
|
|
|
import com.google.common.collect.ImmutableSet
|
|
import ru.dbotthepony.kommons.io.readCollection
|
|
import ru.dbotthepony.kommons.io.writeBinaryString
|
|
import ru.dbotthepony.kommons.io.writeCollection
|
|
import ru.dbotthepony.kstarbound.math.vector.Vector2d
|
|
import ru.dbotthepony.kstarbound.io.readDouble
|
|
import ru.dbotthepony.kstarbound.io.readInternedString
|
|
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.math.Line2d
|
|
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
|
|
import java.util.function.Predicate
|
|
|
|
sealed class PhysicsForceRegion {
|
|
abstract fun write(stream: DataOutputStream, isLegacy: Boolean)
|
|
|
|
// enum class Type int32_t
|
|
// type -> isBlacklist
|
|
class Filter(val isBlacklist: Boolean, val categories: Set<String>) : Predicate<String> {
|
|
constructor(stream: DataInputStream, isLegacy: Boolean) : this(if (isLegacy) stream.readInt() > 0 else stream.readBoolean(), ImmutableSet.copyOf(stream.readCollection { readInternedString() }))
|
|
|
|
fun write(stream: DataOutputStream, isLegacy: Boolean) {
|
|
if (isLegacy)
|
|
stream.writeInt(if (isBlacklist) 1 else 0)
|
|
else
|
|
stream.writeBoolean(isBlacklist)
|
|
|
|
stream.writeCollection(categories) { writeBinaryString(it) }
|
|
}
|
|
|
|
fun test(categories: Collection<String>): Boolean {
|
|
if (isBlacklist) {
|
|
return categories.any { it in this.categories }
|
|
} else {
|
|
return categories.any { it in this.categories }
|
|
}
|
|
}
|
|
|
|
override fun test(t: String): Boolean {
|
|
if (isBlacklist) {
|
|
return t !in this.categories
|
|
} else {
|
|
return t in this.categories
|
|
}
|
|
}
|
|
}
|
|
|
|
data class Directional(val region: Poly, val xTargetVelocity: Double?, val yTargetVelocity: Double?, val controlForce: Double, val filter: Filter) : PhysicsForceRegion() {
|
|
constructor(stream: DataInputStream, isLegacy: Boolean) : this(
|
|
Poly.read(stream, isLegacy),
|
|
stream.readNullableDouble(isLegacy),
|
|
stream.readNullableDouble(isLegacy),
|
|
stream.readDouble(isLegacy),
|
|
Filter(stream, isLegacy)
|
|
)
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
data class Radial(val center: Vector2d, val outerRadius: Double, val innerRadius: Double, val targetRadialVelocity: Double, val controlForce: Double, val filter: Filter) : PhysicsForceRegion() {
|
|
constructor(stream: DataInputStream, isLegacy: Boolean) : this(
|
|
stream.readVector2d(isLegacy),
|
|
stream.readDouble(isLegacy),
|
|
stream.readDouble(isLegacy),
|
|
stream.readDouble(isLegacy),
|
|
stream.readDouble(isLegacy),
|
|
Filter(stream, isLegacy)
|
|
)
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
data class Gradient(val region: Poly, val gradient: Line2d, val baseTargetVelocity: Double, val baseControlForce: Double, val filter: Filter) : PhysicsForceRegion() {
|
|
constructor(stream: DataInputStream, isLegacy: Boolean) : this(
|
|
Poly.read(stream, isLegacy),
|
|
Line2d(stream, isLegacy),
|
|
stream.readDouble(isLegacy),
|
|
stream.readDouble(isLegacy),
|
|
Filter(stream, isLegacy)
|
|
)
|
|
|
|
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)
|
|
|
|
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!")
|
|
}
|
|
}
|
|
}
|
|
}
|