tint optimisations, refactor and abstract color maps

This commit is contained in:
Moritz Zwerger 2023-12-08 18:18:18 +01:00
parent 272df21f9e
commit 1686a6695d
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
22 changed files with 224 additions and 113 deletions

View File

@ -11,17 +11,9 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.biomes
package de.bixilon.minosoft.data.registries.versions.registries.pixlyzer
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.testng.annotations.Test
class BiomeTest {
@Test
fun `color map index`() {
val biome = Biome(minecraft("plains"), temperature = 0.8f, downfall = 0.4f)
assertEquals(biome.colorMapPixelIndex, 44338)
}
}
@Test(groups = ["pixlyzer"], dependsOnGroups = ["version"], priority = Int.MAX_VALUE, timeOut = 15000L)
class `1_20_4` : PixLyzerLoadingTest("1.20.4")

View File

@ -67,6 +67,13 @@ class RGB8BufferTest {
assertEquals(source.getA(3, 3), 0xFF)
}
fun `get rgb at 3,3`() {
val source = RGB8Buffer(Vec2i(12, 13))
source.data.put(117 + 0, 0x11).put(117 + 1, 0x22).put(117 + 2, 0x33)
val rgba = source.getRGB(3, 3)
assertEquals(rgba, 0x112233)
}
fun `put complete texture`() {
val source = RGB8Buffer(Vec2i(12, 13))

View File

@ -69,6 +69,12 @@ class RGBA8BufferTest {
assertEquals(source.getB(3, 3), 0x33)
assertEquals(source.getA(3, 3), 0x44)
}
fun `get rgb at 3,3`() {
val source = RGBA8Buffer(Vec2i(12, 13))
source.data.put(156 + 0, 0x11).put(156 + 1, 0x22).put(156 + 2, 0x33).put(156 + 3, 0x44)
val rgba = source.getRGB(3, 3)
assertEquals(rgba, 0x112233)
}
fun `put complete texture`() {

View File

@ -0,0 +1,37 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.tint.tints
import de.bixilon.minosoft.data.registries.biomes.Biome
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import org.testng.Assert.assertEquals
import org.testng.annotations.Test
@Test(groups = ["biome"])
class ColorMapTintTest {
@Test
fun `plains color map index`() {
val biome = Biome(minecraft("plains"), temperature = 0.8f, downfall = 0.4f)
assertEquals(biome.temperatureIndex, 50)
assertEquals(biome.downfallIndex, 173)
}
@Test
fun `dessert color map index`() {
val biome = Biome(minecraft("dessert"), temperature = 2.0f, downfall = 0.0f)
assertEquals(biome.temperatureIndex, 0)
assertEquals(biome.downfallIndex, 255)
}
}

View File

@ -0,0 +1,35 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.tint.tints.grass
import de.bixilon.minosoft.assets.MemoryAssetsManager
import org.testng.Assert.assertEquals
import org.testng.annotations.Test
@Test(groups = ["tint"])
class GrassTintCalculatorTest {
private val map by lazy {
val map = GrassTintCalculator()
val assets = MemoryAssetsManager()
assets.push(GrassTintCalculator.FILE, GrassTintCalculatorTest::class.java.getResourceAsStream("/tint/grass.png")!!.readAllBytes())
map.init(assets)
return@lazy map
}
fun `color of dessert`() {
assertEquals(map.getColor(255, 0), 0xBFB755)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@ -25,7 +25,7 @@ import de.bixilon.minosoft.assets.properties.manager.pack.PackProperties
import de.bixilon.minosoft.assets.util.FileAssetsTypes
import de.bixilon.minosoft.assets.util.FileAssetsUtil
import de.bixilon.minosoft.assets.util.HashTypes
import de.bixilon.minosoft.assets.util.InputStreamUtil.readArchive
import de.bixilon.minosoft.assets.util.InputStreamUtil.readTarArchive
import de.bixilon.minosoft.assets.util.InputStreamUtil.readZipArchive
import de.bixilon.minosoft.assets.util.PathUtil
import de.bixilon.minosoft.config.profile.profiles.resources.ResourcesProfile
@ -66,7 +66,7 @@ class JarAssetsManager(
private fun tryLoadAssets(): Boolean {
val assets = FileAssetsUtil.readOrNull(jarAssetsHash, FileAssetsTypes.GAME, verify = profile.verify)?.let { ByteArrayInputStream(it).readArchive() } ?: return false
val assets = FileAssetsUtil.readOrNull(jarAssetsHash, FileAssetsTypes.GAME, verify = profile.verify)?.let { ByteArrayInputStream(it).readTarArchive() } ?: return false
for ((path, data) in assets) {
this.assets[path.removePrefix("assets/" + Namespaces.MINECRAFT + "/")] = data

View File

@ -21,9 +21,7 @@ import de.bixilon.kutil.cast.CastUtil.unsafeCast
import de.bixilon.kutil.json.JsonObject
import de.bixilon.mbf.MBFBinaryReader
import de.bixilon.minosoft.util.json.Jackson
import de.matthiasmann.twl.utils.PNGDecoder
import org.kamranzafar.jtar.TarInputStream
import org.lwjgl.BufferUtils
import java.io.InputStream
import java.util.zip.ZipInputStream
@ -50,13 +48,7 @@ object InputStreamUtil {
}
fun InputStream.readJsonObject(close: Boolean = true): JsonObject {
try {
return Jackson.MAPPER.readValue(this, Jackson.JSON_MAP_TYPE)
} finally {
if (close) {
this.close()
}
}
return readJson(close = close, reader = Jackson.MAP_READER)
}
inline fun <reified T> InputStream.readJson(close: Boolean = true): T {
@ -89,7 +81,7 @@ object InputStreamUtil {
}
}
fun InputStream.readArchive(): Map<String, ByteArray> {
fun InputStream.readTarArchive(): Map<String, ByteArray> {
val content: MutableMap<String, ByteArray> = mutableMapOf()
val stream = TarInputStream(this)
while (true) {
@ -111,21 +103,6 @@ object InputStreamUtil {
return content
}
fun InputStream.readRGBArray(): IntArray {
val decoder = PNGDecoder(this)
val buffer = BufferUtils.createByteBuffer(decoder.width * decoder.height * PNGDecoder.Format.RGB.numComponents)
decoder.decode(buffer, decoder.width * PNGDecoder.Format.RGB.numComponents, PNGDecoder.Format.RGB)
buffer.flip()
val colors = IntArray(decoder.width * decoder.height)
for (i in colors.indices) {
colors[i] = ((buffer.get().toInt() and 0xFF) shl 16) or ((buffer.get().toInt() and 0xFF) shl 8) or (buffer.get().toInt() and 0xFF)
}
return colors
}
fun InputStream.readMBFMap(): Map<Any, Any> {
return MBFBinaryReader(this).readMBF().data.unsafeCast()
}

View File

@ -12,7 +12,6 @@
*/
package de.bixilon.minosoft.data.registries.biomes
import de.bixilon.kotlinglm.func.common.clamp
import de.bixilon.kutil.json.JsonUtil.toJsonObject
import de.bixilon.kutil.primitive.FloatUtil.toFloat
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
@ -20,9 +19,8 @@ import de.bixilon.minosoft.data.registries.registries.Registries
import de.bixilon.minosoft.data.registries.registries.registry.RegistryItem
import de.bixilon.minosoft.data.registries.registries.registry.codec.IdentifierCodec
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.tint.TintManager.Companion.jsonTint
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.gui.rendering.tint.tints.ColorMapTint
data class Biome(
override val identifier: ResourceLocation,
@ -34,26 +32,15 @@ data class Biome(
val waterFogColor: RGBColor? = null,
val precipitation: BiomePrecipitation? = null,
) : RegistryItem() {
val grassColorModifier = GrassColorModifiers.BIOME_MAP[identifier]
val temperatureColorMapCoordinate = getColorMapCoordinate(temperature)
val downfallColorMapCoordinate = getColorMapCoordinate(downfall * temperature)
val colorMapPixelIndex = downfallColorMapCoordinate shl 8 or temperatureColorMapCoordinate
val grassModifier = GrassColorModifiers.BIOME_MAP[identifier]
fun getClampedTemperature(height: Int): Int {
return getColorMapCoordinate((temperature + ((height - ProtocolDefinition.SEA_LEVEL_HEIGHT).clamp(1, Int.MAX_VALUE) * ProtocolDefinition.HEIGHT_SEA_LEVEL_MODIFIER)).clamp(0.0f, 1.0f))
}
val temperatureIndex = ColorMapTint.getIndex(temperature)
val downfallIndex = ColorMapTint.getIndex(downfall * temperature)
override fun toString(): String {
return identifier.toString()
}
companion object : IdentifierCodec<Biome> {
private fun getColorMapCoordinate(value: Float): Int {
return ((1.0 - value.clamp(0.0f, 1.0f)) * RenderConstants.COLORMAP_SIZE).toInt()
}
override fun deserialize(registries: Registries?, identifier: ResourceLocation, data: Map<String, Any>): Biome {
val effects = data["effects"].toJsonObject() // nbt data
val skyColor = (data["sky_color"] ?: effects?.get("sky_color"))?.jsonTint()

View File

@ -18,9 +18,6 @@ import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture
object RenderConstants {
const val COLORMAP_SIZE = 255
val TEXT_BACKGROUND_COLOR = RGBColor(0, 0, 0, 80)

View File

@ -34,7 +34,7 @@ class ChunkMeshingQueue(
@Volatile
private var working = false
private val queue: MutableList<WorldQueueItem> = mutableListOf()
private val queue: MutableList<WorldQueueItem> = ArrayList()
private val set: MutableSet<WorldQueueItem> = HashSet()
private val lock = SimpleLock()

View File

@ -21,7 +21,7 @@ import de.bixilon.kutil.concurrent.pool.runnable.ForcePooledRunnable
import de.bixilon.kutil.concurrent.pool.runnable.SimplePoolRunnable
import de.bixilon.kutil.latch.AbstractLatch
import de.bixilon.kutil.latch.AbstractLatch.Companion.child
import de.bixilon.minosoft.assets.util.InputStreamUtil.readAsString
import de.bixilon.minosoft.assets.util.InputStreamUtil.readJson
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureStates
@ -31,7 +31,6 @@ import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.file.PNGTexture
import de.bixilon.minosoft.gui.rendering.textures.properties.ImageProperties
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import de.bixilon.minosoft.util.json.Jackson
import java.util.concurrent.atomic.AtomicInteger
abstract class StaticTextureArray(
@ -88,8 +87,8 @@ abstract class StaticTextureArray(
private fun readImageProperties(texture: ResourceLocation): ImageProperties? {
try {
val data = context.connection.assetsManager.getOrNull("$texture.mcmeta".toResourceLocation())?.readAsString() ?: return null
return Jackson.MAPPER.readValue(data, ImageProperties::class.java)
val stream = context.connection.assetsManager.getOrNull("$texture.mcmeta".toResourceLocation()) ?: return null
return stream.readJson(reader = ImageProperties.READER)
} catch (error: Throwable) {
error.printStackTrace()
}

View File

@ -62,6 +62,11 @@ class RGB8Buffer(
return (this[stride + 0] shl 24) or (this[stride + 1] shl 16) or (this[stride + 2] shl 8) or 0xFF
}
override fun getRGB(x: Int, y: Int): Int {
val stride = stride(x, y)
return (this[stride + 0] shl 16) or (this[stride + 1] shl 8) or this[stride + 2]
}
override fun getR(x: Int, y: Int) = this[stride(x, y) + 0]
override fun getG(x: Int, y: Int) = this[stride(x, y) + 1]
@ -70,6 +75,7 @@ class RGB8Buffer(
private fun stride(x: Int, y: Int): Int {
if (x >= size.x || y >= size.y) throw IllegalArgumentException("Can not access pixel at ($x,$y), exceeds size: $size")
return ((size.x * y) + x) * bytes
}
}

View File

@ -58,18 +58,21 @@ class RGBA8Buffer(
override fun getRGBA(x: Int, y: Int): Int {
val stride = stride(x, y)
if (stride > data.capacity()) {
throw IllegalArgumentException("Can not access pixel at ($x,$y), exceeds size: $size")
}
return (this[stride + 0] shl 24) or (this[stride + 1] shl 16) or (this[stride + 2] shl 8) or (this[stride + 3] shl 0)
}
override fun getRGB(x: Int, y: Int): Int {
val stride = stride(x, y)
return (this[stride + 0] shl 16) or (this[stride + 1] shl 8) or this[stride + 2]
}
override fun getR(x: Int, y: Int) = this[stride(x, y) + 0]
override fun getG(x: Int, y: Int) = this[stride(x, y) + 1]
override fun getB(x: Int, y: Int) = this[stride(x, y) + 2]
override fun getA(x: Int, y: Int) = this[stride(x, y) + 3]
private fun stride(x: Int, y: Int): Int {
if (x >= size.x || y >= size.y) throw IllegalArgumentException("Can not access pixel at ($x,$y), exceeds size: $size")
return ((size.x * y) + x) * bytes
}
}

View File

@ -55,6 +55,8 @@ interface TextureBuffer {
fun getB(x: Int, y: Int): Int
fun getA(x: Int, y: Int): Int
fun getRGB(x: Int, y: Int): Int
fun getRGBA(x: Int, y: Int): Int
fun setRGBA(x: Int, y: Int, value: Int)
fun setRGBA(x: Int, y: Int, red: Int, green: Int, blue: Int, alpha: Int)

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2021 Moritz Zwerger
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
@ -14,6 +14,7 @@
package de.bixilon.minosoft.gui.rendering.textures.properties
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
import de.bixilon.minosoft.util.json.Jackson
data class ImageProperties(
val texture: TextureProperties = TextureProperties(),
@ -27,5 +28,6 @@ data class ImageProperties(
companion object {
val DEFAULT = ImageProperties()
val READER = Jackson.MAPPER.readerFor(ImageProperties::class.java)
}
}

View File

@ -0,0 +1,62 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.tint.tints
import de.bixilon.kutil.exception.ExceptionUtil.ignoreAll
import de.bixilon.minosoft.assets.AssetsManager
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.gui.rendering.system.base.texture.data.buffer.TextureBuffer
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.readTexture
import de.bixilon.minosoft.gui.rendering.tint.TintProvider
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.LogMessageType
abstract class ColorMapTint(
private val file: ResourceLocation,
) : TintProvider {
protected var map: IntArray? = null
fun init(assets: AssetsManager) {
val map = ignoreAll { assets[file].readTexture() } ?: return
if (map.size.x != SIZE || map.size.y != SIZE) {
Log.log(LogMessageType.LOADING, LogLevels.WARN) { "Color map ($file) has invalid size: ${map.size}" }
return
}
this.map = map.toColorMap()
}
private fun TextureBuffer.toColorMap(): IntArray {
val array = IntArray(size.x * size.y)
var index = 0
for (y in 0 until size.y) {
for (x in 0 until size.x) {
array[index++] = getRGB(x, y)
}
}
return array
}
companion object {
const val SIZE = 256
fun getIndex(value: Float): Int {
if (value <= 0.0f) return SIZE - 1
if (value >= 1.0f) return 0
val delta = 1.0f - value
return (delta * (SIZE - 1)).toInt()
}
}
}

View File

@ -13,48 +13,33 @@
package de.bixilon.minosoft.gui.rendering.tint.tints.grass
import de.bixilon.kutil.exception.ExceptionUtil.ignoreAll
import de.bixilon.minosoft.assets.AssetsManager
import de.bixilon.minosoft.assets.util.InputStreamUtil.readRGBArray
import de.bixilon.minosoft.data.container.stack.ItemStack
import de.bixilon.minosoft.data.registries.biomes.Biome
import de.bixilon.minosoft.data.registries.biomes.GrassColorModifiers
import de.bixilon.minosoft.data.registries.blocks.state.BlockState
import de.bixilon.minosoft.data.registries.blocks.types.building.dirt.GrassBlock
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.data.text.formatting.color.Colors
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture
import de.bixilon.minosoft.gui.rendering.tint.TintProvider
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import de.bixilon.minosoft.gui.rendering.tint.tints.ColorMapTint
class GrassTintCalculator : TintProvider {
private lateinit var colorMap: IntArray
class GrassTintCalculator : ColorMapTint(FILE) {
fun init(assetsManager: AssetsManager) {
colorMap = ignoreAll { assetsManager["minecraft:colormap/grass".toResourceLocation().texture()].readRGBArray() } ?: IntArray(256)
}
fun getColor(downfallIndex: Int, temperatureIndex: Int): Int {
val map = map ?: return FALLBACK
inline fun getColor(downfall: Int, temperature: Int): Int {
return getColor(downfall shl 8 or temperature)
}
fun getColor(colorMapPixelIndex: Int): Int {
if (colorMapPixelIndex > colorMap.size) {
return 0xFF00FF // ToDo: Is this correct? Was used in my old implementation
}
val color = colorMap[colorMapPixelIndex]
if (color == 0xFFFFFF) {
return 0x48B518
}
val color = map[downfallIndex shl 8 or temperatureIndex]
if (color == 0xFFFFFF) return 0x48B518
return color
}
fun getBlockColor(biome: Biome?): Int {
if (biome == null) {
return getColor(127, 255)
}
val color = getColor(biome.colorMapPixelIndex)
if (biome == null) return getColor(127, 255)
return when (biome.grassColorModifier) {
val color = getColor(biome.downfallIndex, biome.temperatureIndex)
return when (biome.grassModifier) {
null -> color
GrassColorModifiers.SWAMP -> 0x6A7039 // ToDo: Biome noise is applied here
GrassColorModifiers.DARK_FOREST -> (color and 0xFEFEFE) + 0x28340A shr 1
@ -71,4 +56,13 @@ class GrassTintCalculator : TintProvider {
}
return getBlockColor(biome)
}
override fun getItemColor(stack: ItemStack, tintIndex: Int): Int {
return getColor(127, 255) // TODO: verify
}
companion object {
val FILE = minecraft("colormap/grass").texture()
private const val FALLBACK = 0xFF00FF // ToDo: Is this correct? Was used in my old implementation
}
}

View File

@ -13,29 +13,23 @@
package de.bixilon.minosoft.gui.rendering.tint.tints.plants
import de.bixilon.kutil.exception.ExceptionUtil.ignoreAll
import de.bixilon.minosoft.assets.AssetsManager
import de.bixilon.minosoft.assets.util.InputStreamUtil.readRGBArray
import de.bixilon.kotlinglm.func.common.clamp
import de.bixilon.minosoft.data.container.stack.ItemStack
import de.bixilon.minosoft.data.registries.biomes.Biome
import de.bixilon.minosoft.data.registries.blocks.state.BlockState
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture
import de.bixilon.minosoft.gui.rendering.tint.TintProvider
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import de.bixilon.minosoft.gui.rendering.tint.tints.ColorMapTint
class FoliageTintCalculator : TintProvider {
private lateinit var colorMap: IntArray
fun init(assetsManager: AssetsManager) {
colorMap = ignoreAll { assetsManager["minecraft:colormap/foliage".toResourceLocation().texture()].readRGBArray() } ?: IntArray(256)
}
class FoliageTintCalculator : ColorMapTint(FILE) {
fun getBlockColor(biome: Biome?, y: Int): Int {
if (biome == null) {
return FALLBACK_COLOR
}
if (biome == null) return FALLBACK_COLOR
val map = this.map ?: return FALLBACK_COLOR
// ToDo: Override
return colorMap[biome.downfallColorMapCoordinate shl 8 or biome.getClampedTemperature(y)]
val temperature = modifyTemperature(biome.temperature, y)
return map[biome.downfallIndex shl 8 or temperature]
}
override fun getBlockColor(blockState: BlockState, biome: Biome?, x: Int, y: Int, z: Int, tintIndex: Int): Int {
@ -51,6 +45,19 @@ class FoliageTintCalculator : TintProvider {
}
companion object {
private val FILE = minecraft("colormap/foliage").texture()
private const val FALLBACK_COLOR = 0x48B518
// not sure if that is accurate or relevant
private const val SEA_LEVEL = 62
private const val SEA_LEVEL_MODIFIER = 0.00166667f
fun modifyTemperature(temperature: Float, height: Int): Int {
val modifier = maxOf(1, height - SEA_LEVEL) * SEA_LEVEL_MODIFIER
val modified = (temperature + modifier).clamp(0.0f, 1.0f)
return getIndex(modified)
}
}
}

View File

@ -68,9 +68,6 @@ public final class ProtocolDefinition {
public static final float VELOCITY_NETWORK_DIVIDER = 8000.0f;
public static final int SEA_LEVEL_HEIGHT = 62;
public static final float HEIGHT_SEA_LEVEL_MODIFIER = 0.00166667f;
public static final RGBColor DEFAULT_COLOR = ChatColors.WHITE;

View File

@ -64,6 +64,7 @@ object Jackson {
val JSON_MAP_TYPE: MapType = MAPPER.typeFactory.constructMapType(HashMap::class.java, Any::class.java, Any::class.java)
val MAP_READER = MAPPER.readerFor(JSON_MAP_TYPE)
fun init() = Unit
}