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 { 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 init { val builder = ImmutableMap.Builder() 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 } } } }