KStarbound/src/main/kotlin/ru/dbotthepony/kstarbound/client/render/RenderLayer.kt

133 lines
3.7 KiB
Kotlin

package ru.dbotthepony.kstarbound.client.render
import com.google.common.collect.ImmutableMap
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.kstarbound.world.api.AbstractTileState
import ru.dbotthepony.kstarbound.world.api.TileColor
enum class RenderLayer {
BackgroundOverlay,
BackgroundTile,
BackgroundTileMod,
Platform,
Plant,
PlantDrop,
Object,
PreviewObject,
BackParticle,
Vehicle,
Effect,
Projectile,
Monster,
Npc,
Player,
ItemDrop,
Liquid,
MiddleParticle,
ForegroundTile,
ForegroundTileMod,
ForegroundEntity,
ForegroundOverlay,
FrontParticle,
Overlay;
private val base = Point(this)
fun point(offset: Long = 0L, index: Long = 0L, hueShift: Float = 0f, colorVariant: TileColor = TileColor.DEFAULT): Point {
return if (offset == 0L && index == 0L && hueShift == 0f && colorVariant === TileColor.DEFAULT)
base
else
Point(this, offset, index, hueShift, colorVariant)
}
fun point(): Point {
return base
}
data class Point(val base: RenderLayer, val offset: Long = 0L, val index: Long = 0L, val hueShift: Float = 0f, val colorVariant: TileColor = TileColor.DEFAULT) : Comparable<Point> {
override fun compareTo(other: Point): Int {
if (this === other) return 0
var cmp = base.compareTo(other.base)
if (cmp == 0) cmp = offset.compareTo(other.offset)
if (cmp == 0) cmp = index.compareTo(other.index)
if (cmp == 0) cmp = hueShift.compareTo(other.hueShift)
if (cmp == 0) cmp = colorVariant.compareTo(other.colorVariant)
return cmp
}
}
companion object {
fun tileLayer(isBackground: Boolean, isModifier: Boolean, offset: Long = 0L, index: Long = 0L, hueShift: Float = 0f, colorVariant: TileColor = TileColor.DEFAULT): Point {
if (isBackground && isModifier) {
return BackgroundTileMod.point(offset, index, hueShift, colorVariant)
} else if (isBackground) {
return BackgroundTile.point(offset, index, hueShift, colorVariant)
} else if (isModifier) {
return ForegroundTileMod.point(offset, index, hueShift, colorVariant)
} else {
return ForegroundTile.point(offset, index, hueShift, colorVariant)
}
}
fun tileLayer(isBackground: Boolean, isModifier: Boolean, tile: AbstractTileState): Point {
if (isModifier) {
return tileLayer(isBackground, true, tile.modifier.value.renderParameters.zLevel, tile.modifier.value.modId?.toLong() ?: 0L, tile.modifierHueShift)
} else {
return tileLayer(isBackground, false, tile.material.value.renderParameters.zLevel, tile.material.value.materialId?.toLong() ?: 0L, tile.hueShift)
}
}
private val logger = LogManager.getLogger()
private val lowercase: ImmutableMap<String, RenderLayer>
init {
val builder = ImmutableMap.Builder<String, RenderLayer>()
for (value in entries) {
builder.put(value.name.lowercase(), value)
}
lowercase = builder.build()
}
private fun perform(value: String, symbol: Char): Point {
val before = value.substringBefore(symbol).lowercase()
val after = value.substring(before.length)
val enum = lowercase[before]
if (enum == null) {
logger.error("Unknown render layer: $before in $value; assuming BackgroundOverlay")
return BackgroundOverlay.base
}
val num = after.toLongOrNull()
if (num == null) {
logger.error("Invalid render layer string: $value; assuming BackgroundOverlay")
return BackgroundOverlay.base
}
return enum.point(num)
}
fun parse(value: String): Point {
if ('+' in value) {
return perform(value, '+')
} else if ('-' in value) {
return perform(value, '-')
} else {
val enum = lowercase[value.lowercase()]
if (enum == null) {
logger.error("Unknown render layer: $value; assuming BackgroundOverlay")
return BackgroundOverlay.base
}
return enum.base
}
}
}
}