167 lines
5.3 KiB
Kotlin
167 lines
5.3 KiB
Kotlin
package ru.dbotthepony.kstarbound.world
|
|
|
|
import ru.dbotthepony.kstarbound.io.readVector2d
|
|
import ru.dbotthepony.kstarbound.io.readVector2f
|
|
import ru.dbotthepony.kommons.io.writeStruct2d
|
|
import ru.dbotthepony.kommons.io.writeStruct2f
|
|
import ru.dbotthepony.kommons.util.getValue
|
|
import ru.dbotthepony.kommons.util.setValue
|
|
import ru.dbotthepony.kstarbound.math.vector.Vector2d
|
|
import ru.dbotthepony.kstarbound.defs.tile.TileDamage
|
|
import ru.dbotthepony.kstarbound.defs.tile.TileDamageParameters
|
|
import ru.dbotthepony.kstarbound.defs.tile.TileDamageType
|
|
import ru.dbotthepony.kstarbound.math.Interpolator
|
|
import ru.dbotthepony.kstarbound.network.syncher.NetworkedGroup
|
|
import ru.dbotthepony.kstarbound.network.syncher.networkedBoolean
|
|
import ru.dbotthepony.kstarbound.network.syncher.networkedEnum
|
|
import ru.dbotthepony.kstarbound.network.syncher.networkedFixedPoint
|
|
import java.io.DataInputStream
|
|
import java.io.DataOutputStream
|
|
|
|
sealed class TileHealth() {
|
|
var damageSource: Vector2d = Vector2d.ZERO
|
|
protected set
|
|
abstract var damagePercent: Double
|
|
protected set
|
|
abstract var damageEffectTimeFactor: Double
|
|
protected set
|
|
abstract var isHarvested: Boolean
|
|
protected set
|
|
abstract var damageType: TileDamageType
|
|
protected set
|
|
var damageEffectPercentage: Double = 0.0
|
|
protected set
|
|
|
|
abstract fun copy(): TileHealth
|
|
|
|
val isHealthy: Boolean
|
|
get() = damagePercent <= 0.0
|
|
|
|
val isDead: Boolean
|
|
get() = damagePercent >= 1.0 && damageType != TileDamageType.PROTECTED
|
|
|
|
fun write(stream: DataOutputStream, isLegacy: Boolean) {
|
|
if (isLegacy) {
|
|
stream.writeFloat(damagePercent.toFloat())
|
|
stream.writeFloat(damageEffectTimeFactor.toFloat())
|
|
stream.writeBoolean(isHarvested)
|
|
stream.writeStruct2f(damageSource.toFloatVector())
|
|
} else {
|
|
stream.writeDouble(damagePercent)
|
|
stream.writeDouble(damageEffectTimeFactor)
|
|
stream.writeBoolean(isHarvested)
|
|
stream.writeStruct2d(damageSource)
|
|
}
|
|
|
|
stream.writeByte(damageType.ordinal)
|
|
}
|
|
|
|
fun read(stream: DataInputStream, isLegacy: Boolean) {
|
|
if (isLegacy) {
|
|
damagePercent = stream.readFloat().toDouble()
|
|
damageEffectTimeFactor = stream.readFloat().toDouble()
|
|
isHarvested = stream.readBoolean()
|
|
damageSource = stream.readVector2f().toDoubleVector()
|
|
} else {
|
|
damagePercent = stream.readDouble()
|
|
damageEffectTimeFactor = stream.readDouble()
|
|
isHarvested = stream.readBoolean()
|
|
damageSource = stream.readVector2d()
|
|
}
|
|
|
|
damageType = TileDamageType.entries[stream.readUnsignedByte()]
|
|
damageEffectPercentage = damageEffectTimeFactor.coerceIn(0.0, 1.0) * damagePercent
|
|
}
|
|
|
|
fun reset() {
|
|
isHarvested = false
|
|
damageSource = Vector2d.ZERO
|
|
damageType = TileDamageType.PROTECTED
|
|
damagePercent = 0.0
|
|
damageEffectTimeFactor = 0.0
|
|
}
|
|
|
|
fun damage(config: TileDamageParameters, source: Vector2d, damage: TileDamage) {
|
|
val actualDamage = config.damageDone(damage) / config.totalHealth
|
|
damagePercent = (damagePercent + actualDamage).coerceAtMost(1.0)
|
|
isHarvested = damage.harvestLevel >= config.harvestLevel
|
|
damageSource = source
|
|
damageType = damage.type
|
|
|
|
if (actualDamage > 0.0)
|
|
damageEffectTimeFactor = config.maximumEffectTime
|
|
|
|
damageEffectPercentage = damageEffectTimeFactor.coerceIn(0.0, 1.0) * damagePercent
|
|
}
|
|
|
|
val isTicking: Boolean
|
|
get() = !isHealthy && !isDead
|
|
|
|
fun tick(config: TileDamageParameters, delta: Double): Boolean {
|
|
if (isDead || isHealthy)
|
|
return false
|
|
|
|
damagePercent -= config.damageRecovery * delta / config.totalHealth
|
|
damageEffectTimeFactor -= delta
|
|
|
|
if (damagePercent <= 0.0) {
|
|
damagePercent = 0.0
|
|
damageEffectTimeFactor = 0.0
|
|
damageType = TileDamageType.PROTECTED
|
|
}
|
|
|
|
damageEffectPercentage = damageEffectTimeFactor.coerceIn(0.0, 1.0) * damagePercent
|
|
return damagePercent > 0.0
|
|
}
|
|
|
|
class Tile() : TileHealth() {
|
|
constructor(stream: DataInputStream, isLegacy: Boolean) : this() {
|
|
read(stream, isLegacy)
|
|
}
|
|
|
|
override var damagePercent: Double = 0.0
|
|
override var damageEffectTimeFactor: Double = 0.0
|
|
override var isHarvested: Boolean = false
|
|
override var damageType: TileDamageType = TileDamageType.PROTECTED
|
|
|
|
override fun copy(): Tile {
|
|
val copy = Tile()
|
|
|
|
copy.isHarvested = isHarvested
|
|
copy.damageSource = damageSource
|
|
copy.damageType = damageType
|
|
copy.damagePercent = damagePercent
|
|
copy.damageEffectTimeFactor = damageEffectTimeFactor
|
|
copy.damageEffectPercentage = damageEffectPercentage
|
|
|
|
return copy
|
|
}
|
|
}
|
|
|
|
class TileEntity() : TileHealth() {
|
|
constructor(stream: DataInputStream, isLegacy: Boolean) : this() {
|
|
read(stream, isLegacy)
|
|
}
|
|
|
|
val networkGroup = NetworkedGroup()
|
|
|
|
override var damagePercent: Double by networkedFixedPoint(0.001).also { networkGroup.add(it); it.interpolator = Interpolator.Linear }
|
|
override var damageEffectTimeFactor: Double by networkedFixedPoint(0.001).also { networkGroup.add(it); it.interpolator = Interpolator.Linear }
|
|
override var isHarvested: Boolean by networkedBoolean().also { networkGroup.add(it) }
|
|
override var damageType: TileDamageType by networkedEnum(TileDamageType.PROTECTED).also { networkGroup.add(it) }
|
|
|
|
override fun copy(): TileEntity {
|
|
val copy = TileEntity()
|
|
|
|
copy.isHarvested = isHarvested
|
|
copy.damageSource = damageSource
|
|
copy.damageType = damageType
|
|
copy.damagePercent = damagePercent
|
|
copy.damageEffectTimeFactor = damageEffectTimeFactor
|
|
copy.damageEffectPercentage = damageEffectPercentage
|
|
|
|
return copy
|
|
}
|
|
}
|
|
}
|