diff --git a/doc/Sky.md b/doc/Sky.md index 93c8ae72e..c77ab7e51 100644 --- a/doc/Sky.md +++ b/doc/Sky.md @@ -44,11 +44,11 @@ Resources: - [x] Clouds - [ ] interpolate world time - [ ] Lightmap - - potion effects (nigh vision, underwater visibility, conduit, darkness) + - [ ] potion effects (nigh vision, underwater visibility, conduit, darkness) - submerged fluid - - gamma setting - - weather, thunder flashing + - [x] gamma setting + - [x] weather, thunder flashing - wither - - dimension (e.g. fulbright) - - fullbright setting/key - - stars/moon + - [x] dimension (e.g. brighten in end) + - [x] fullbright setting/key + - [x] stars/moon influence diff --git a/src/main/java/de/bixilon/minosoft/data/entities/StatusEffectInstance.kt b/src/main/java/de/bixilon/minosoft/data/entities/StatusEffectInstance.kt index e3a3f6070..b6b25a74a 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/StatusEffectInstance.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/StatusEffectInstance.kt @@ -22,8 +22,8 @@ data class StatusEffectInstance( val amplifier: Int, val duration: Int, ) : Tickable { - private val start = millis() - private val end = start + duration * ProtocolDefinition.TICK_TIME + val start = millis() + val end = start + duration * ProtocolDefinition.TICK_TIME var remaining: Int = duration private set diff --git a/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt b/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt index be8a575a2..706abb753 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt @@ -310,6 +310,7 @@ abstract class Entity( open val pushableByFluids: Boolean = false open fun tick() { + effects.tick() previousPosition = position if (spawnSprintingParticles) { spawnSprintingParticles() diff --git a/src/main/java/de/bixilon/minosoft/data/entities/entities/properties/StatusEffectProperty.kt b/src/main/java/de/bixilon/minosoft/data/entities/entities/properties/StatusEffectProperty.kt index 80a0a3d5b..9c95b6ede 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/entities/properties/StatusEffectProperty.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/entities/properties/StatusEffectProperty.kt @@ -28,13 +28,13 @@ class StatusEffectProperty : Tickable { override fun tick() { effects.lock.lock() val remove: MutableSet = mutableSetOf() - for ((effect, instance) in effects) { + for ((effect, instance) in effects.unsafe) { instance.tick() if (instance.expired) { remove += effect } } - this.effects -= remove + this.effects.unsafe -= remove effects.lock.unlock() } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/light/updater/LegacyLightmapUpdater.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/light/updater/LegacyLightmapUpdater.kt index f808083fa..3ce5888d5 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/light/updater/LegacyLightmapUpdater.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/light/updater/LegacyLightmapUpdater.kt @@ -35,6 +35,7 @@ class LegacyLightmapUpdater(private val connection: PlayConnection) : LightmapUp private val conduitPowerStatusEffect = connection.registries.statusEffectRegistry[DefaultStatusEffects.CONDUIT_POWER] override fun update(force: Boolean, buffer: LightmapBuffer) { + val brightness = connection.world.dimension?.brightness ?: return val skyGradient = connection.world.time.lightBase.toFloat() // ToDo: Lightning @@ -61,24 +62,19 @@ class LegacyLightmapUpdater(private val connection: PlayConnection) : LightmapUp for (skyLight in 0 until ProtocolDefinition.LIGHT_LEVELS) { for (blockLight in 0 until ProtocolDefinition.LIGHT_LEVELS) { - val index = ((skyLight shl 4) or blockLight) * 4 + val skyBrightness = brightness[skyLight] * (skyGradient * 0.95f + 0.05f) + val blockBrightness = brightness[blockLight]// ToDo: multiply with time somewhat thing? - val skyLightBrightness = (connection.world.dimension?.brightness?.get(skyLight) ?: 1.0f) * (skyGradient * 0.95f + 0.05f) - val blockLightBrightness = (connection.world.dimension?.brightness?.get(blockLight) ?: 1.0f) * 1.5// ToDo: multiply with time somewhat thing? - - - var color = Vec3(blockLightBrightness, blockLightBrightness * ((blockLightBrightness * 0.6f + 0.4f) * 0.6f + 0.4f), blockLightBrightness * (blockLightBrightness * blockLightBrightness * 0.6f + 0.4f)) + var color = Vec3(blockBrightness, blockBrightness * ((blockBrightness * 0.6f + 0.4f) * 0.6f + 0.4f), blockBrightness * (blockBrightness * blockBrightness * 0.6f + 0.4f)) // ToDo: Lightning - let { - color = color + (skyGradientColor * skyLightBrightness) + color = color + (skyGradientColor * skyBrightness) - color = Vec3Util.interpolateLinear(0.04f, color, Vec3(0.75f)) + color = Vec3Util.interpolateLinear(0.04f, color, Vec3(0.75f)) - // ToDo: Sky darkness - } + // ToDo: Sky darkness color = color.clamp(0.0f, 1.0f) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/light/updater/normal/NormalLightmapUpdater.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/light/updater/normal/NormalLightmapUpdater.kt index 8b52916c4..efe27940a 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/light/updater/normal/NormalLightmapUpdater.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/light/updater/normal/NormalLightmapUpdater.kt @@ -14,8 +14,11 @@ package de.bixilon.minosoft.gui.rendering.world.light.updater.normal import de.bixilon.kotlinglm.vec3.Vec3 +import de.bixilon.kutil.math.MathConstants.PIf +import de.bixilon.kutil.time.TimeUtil.millis import de.bixilon.kutil.watcher.DataWatcher.Companion.observe import de.bixilon.minosoft.data.registries.dimension.DimensionProperties +import de.bixilon.minosoft.data.registries.effects.DefaultStatusEffects import de.bixilon.minosoft.data.world.time.DayPhases import de.bixilon.minosoft.data.world.time.WorldTime import de.bixilon.minosoft.data.world.weather.WorldWeather @@ -29,6 +32,7 @@ import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import kotlin.math.abs import kotlin.math.pow +import kotlin.math.sin class NormalLightmapUpdater( private val connection: PlayConnection, @@ -36,6 +40,8 @@ class NormalLightmapUpdater( ) : LightmapUpdater { private val profile = connection.profiles.rendering.light private var force = true + private val nightVision = connection.registries.statusEffectRegistry[DefaultStatusEffects.NIGHT_VISION] + init { connection.world::dimension.observe(this) { force = true } @@ -62,10 +68,11 @@ class NormalLightmapUpdater( private fun updateBlock(dimension: DimensionProperties, buffer: LightmapBuffer) { val gamma = profile.gamma + val nightVision = getNightVisionStrength() for (block in 0 until ProtocolDefinition.LIGHT_LEVELS) { var color = calculateBlock(dimension.brightness[block]) - color = tweak(color, gamma, dimension.effects.brighten) + color = tweak(color, gamma, dimension.effects.brighten, nightVision) buffer[0, block] = color } } @@ -78,11 +85,12 @@ class NormalLightmapUpdater( val blockColors = Array(ProtocolDefinition.LIGHT_LEVELS.toInt()) { calculateBlock(dimension.brightness[it]) } val gamma = profile.gamma + val nightVision = getNightVisionStrength() for (sky in 0 until ProtocolDefinition.LIGHT_LEVELS) { for (block in 0 until ProtocolDefinition.LIGHT_LEVELS) { var color = combine(skyColors[sky], blockColors[block]) - color = tweak(color, gamma, dimension.effects.brighten) + color = tweak(color, gamma, dimension.effects.brighten, nightVision) buffer[sky, block] = color } } @@ -154,33 +162,67 @@ class NormalLightmapUpdater( private fun combine(sky: Vec3, block: Vec3): Vec3 { - var color = sky + block + val color = sky + block - color = color.clamp(0.0f, 1.0f) - - return color + return color.clamp() } - private fun tweak(color: Vec3, gamma: Float, brighten: Vec3?): Vec3 { + private fun tweak( + color: Vec3, + gamma: Float, + brighten: Vec3?, + nightVision: Float, + ): Vec3 { var output = color output = applyGamma(output, gamma) brighten?.let { output = applyBrighten(color, brighten) } + output = applyNightVision(output, nightVision) + - output = output.clamp(0.0f, 1.0f) return output } + private fun applyNightVision(color: Vec3, strength: Float): Vec3 { + if (strength <= 0.0f) { + return color + } + val max = maxOf(color.r, color.g, color.b) + if (max >= 1.0f) { + return color + } + return interpolateLinear(strength, color, color * (1.0f / max)) + } + private fun applyBrighten(color: Vec3, brighten: Vec3): Vec3 { - return interpolateLinear(0.25f, color, brighten) + return interpolateLinear(0.25f, color, brighten).clamp() } private fun applyGamma(color: Vec3, gamma: Float): Vec3 { return interpolateLinear(gamma, color, color modify { 1.0f - (1.0f - it).pow(4) }) } + private fun getNightVisionStrength(): Float { + val nightVision = connection.player.effects[this.nightVision] ?: return 0.0f + val time = millis() + val end = nightVision.end + if (time > end) { + return 0.0f + } + val remaining = end - time + if (remaining > 8000) { + return 1.0f + } + + return 0.3f + sin(remaining / 8000.0f * PIf * 0.2f) * 0.7f + } + private fun Vec3.brighten(value: Float): Vec3 { return this * (1.0f - value) + value } + + private fun Vec3.clamp(): Vec3 { + return clamp(0.0f, 1.0f) + } }