mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 11:24:56 -04:00
proper light map, proper sky light
This commit is contained in:
parent
2c2ec5bd9f
commit
80ca0bf788
@ -30,4 +30,5 @@ data class GameConfig(
|
||||
var sound: SoundConfig = SoundConfig(),
|
||||
var entities: EntitiesConfig = EntitiesConfig(),
|
||||
var world: WorldConfig = WorldConfig(),
|
||||
var light: LightConfig = LightConfig(),
|
||||
)
|
||||
|
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 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.config.config.game
|
||||
|
||||
data class LightConfig(
|
||||
var gamma: Float = 1.0f,
|
||||
)
|
@ -16,6 +16,7 @@ import com.google.gson.JsonObject
|
||||
import de.bixilon.minosoft.data.registries.registry.RegistryItem
|
||||
import de.bixilon.minosoft.data.registries.registry.ResourceLocationDeserializer
|
||||
import de.bixilon.minosoft.data.registries.versions.Registries
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.lerp
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import de.bixilon.minosoft.util.KUtil.nullCast
|
||||
|
||||
@ -48,6 +49,18 @@ data class Dimension(
|
||||
} else {
|
||||
height / ProtocolDefinition.SECTION_HEIGHT_Y
|
||||
}
|
||||
val lightLevels = FloatArray(16)
|
||||
|
||||
init {
|
||||
val ambientLight = 0.0f // ToDo: 0.1 in nether
|
||||
|
||||
for (i in lightLevels.indices) {
|
||||
val asFloat = i / 15.0f
|
||||
|
||||
lightLevels[i] = lerp(ambientLight, asFloat / (4.0f - 3.0f * asFloat), 1.0f)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun toString(): String {
|
||||
return resourceLocation.full
|
||||
|
@ -23,4 +23,6 @@ object DefaultStatusEffects {
|
||||
val HASTE = "minecraft:haste".asResourceLocation()
|
||||
val MINING_FATIGUE = "minecraft:mining_fatigue".asResourceLocation()
|
||||
val DOLPHINS_GRACE = "minecraft:dolphins_grace".asResourceLocation()
|
||||
val NIGHT_VISION = "minecraft:night_vision".asResourceLocation()
|
||||
val CONDUIT_POWER = "minecraft:conduit_power".asResourceLocation()
|
||||
}
|
||||
|
@ -16,7 +16,15 @@ package de.bixilon.minosoft.data.registries.other.game.event
|
||||
import de.bixilon.minosoft.data.registries.DefaultFactory
|
||||
import de.bixilon.minosoft.data.registries.other.game.event.handlers.GameEventHandler
|
||||
import de.bixilon.minosoft.data.registries.other.game.event.handlers.GameMoveChangeGameEventHandler
|
||||
import de.bixilon.minosoft.data.registries.other.game.event.handlers.gradients.RainGradientSetGameEventHandler
|
||||
import de.bixilon.minosoft.data.registries.other.game.event.handlers.gradients.ThunderGradientSetGameEventHandler
|
||||
import de.bixilon.minosoft.data.registries.other.game.event.handlers.rain.RainStartGameEventHandler
|
||||
import de.bixilon.minosoft.data.registries.other.game.event.handlers.rain.RainStopGameEventHandler
|
||||
|
||||
object DefaultGameEventHandlers : DefaultFactory<GameEventHandler>(
|
||||
GameMoveChangeGameEventHandler
|
||||
GameMoveChangeGameEventHandler,
|
||||
RainStartGameEventHandler,
|
||||
RainStopGameEventHandler,
|
||||
RainGradientSetGameEventHandler,
|
||||
ThunderGradientSetGameEventHandler,
|
||||
)
|
||||
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 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.data.registries.other.game.event.handlers.gradients
|
||||
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.data.registries.other.game.event.handlers.GameEventHandler
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.util.KUtil.asResourceLocation
|
||||
|
||||
object RainGradientSetGameEventHandler : GameEventHandler {
|
||||
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:rain_gradient_set".asResourceLocation()
|
||||
|
||||
override fun handle(data: Float, connection: PlayConnection) {
|
||||
connection.world.rainGradient = data
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 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.data.registries.other.game.event.handlers.gradients
|
||||
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.data.registries.other.game.event.handlers.GameEventHandler
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.util.KUtil.asResourceLocation
|
||||
|
||||
object ThunderGradientSetGameEventHandler : GameEventHandler {
|
||||
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:thunder_gradient_set".asResourceLocation()
|
||||
|
||||
override fun handle(data: Float, connection: PlayConnection) {
|
||||
connection.world.thunderGradient = data
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 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.data.registries.other.game.event.handlers.rain
|
||||
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.data.registries.other.game.event.handlers.GameEventHandler
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.util.KUtil.asResourceLocation
|
||||
|
||||
object RainStartGameEventHandler : GameEventHandler {
|
||||
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:rain_start".asResourceLocation()
|
||||
|
||||
override fun handle(data: Float, connection: PlayConnection) {
|
||||
connection.world.raining = true
|
||||
connection.world.rainGradient = 1.0f
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 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.data.registries.other.game.event.handlers.rain
|
||||
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.data.registries.other.game.event.handlers.GameEventHandler
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.util.KUtil.asResourceLocation
|
||||
|
||||
object RainStopGameEventHandler : GameEventHandler {
|
||||
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:rain_stop".asResourceLocation()
|
||||
|
||||
override fun handle(data: Float, connection: PlayConnection) {
|
||||
connection.world.raining = false
|
||||
connection.world.rainGradient = 0.0f
|
||||
}
|
||||
}
|
@ -39,11 +39,17 @@ import de.bixilon.minosoft.modding.event.EventInitiators
|
||||
import de.bixilon.minosoft.modding.event.events.BlockSetEvent
|
||||
import de.bixilon.minosoft.modding.event.events.ChunkUnloadEvent
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
|
||||
import de.bixilon.minosoft.util.KUtil.toSynchronizedMap
|
||||
import de.bixilon.minosoft.util.MMath
|
||||
import glm_.func.common.clamp
|
||||
import glm_.vec2.Vec2i
|
||||
import glm_.vec3.Vec3
|
||||
import glm_.vec3.Vec3i
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.cos
|
||||
import kotlin.random.Random
|
||||
|
||||
/**
|
||||
@ -63,6 +69,9 @@ class World(
|
||||
var biomeAccessor: BiomeAccessor = NullBiomeAccessor
|
||||
var time = 0L
|
||||
var age = 0L
|
||||
var raining = false
|
||||
var rainGradient = 0.0f
|
||||
var thunderGradient = 0.0f
|
||||
private val random = Random
|
||||
|
||||
var audioPlayer: AudioPlayer? = null
|
||||
@ -252,6 +261,24 @@ class World(
|
||||
return true
|
||||
}
|
||||
|
||||
val skyAngle: Double
|
||||
get() {
|
||||
val fractionalPath = MMath.fractionalPart(abs(time) / ProtocolDefinition.TICKS_PER_DAYf - 0.25)
|
||||
val angle = 0.5 - cos(fractionalPath * Math.PI) / 2.0
|
||||
return (fractionalPath * 2.0 + angle) / 3.0
|
||||
}
|
||||
|
||||
val lightBase: Double
|
||||
get() {
|
||||
var base = 1.0f - (cos(skyAngle * 2.0 * PI) * 2.0 + 0.2)
|
||||
base = base.clamp(0.0, 1.0)
|
||||
base = 1.0 - base
|
||||
|
||||
base *= 1.0 - ((rainGradient * 5.0) / 16.0)
|
||||
base *= 1.0 - (((thunderGradient * rainGradient) * 5.0) / 16.0)
|
||||
return base * 0.8 + 0.2
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MAX_SIZE = 29999999
|
||||
const val MAX_SIZEf = MAX_SIZE.toFloat()
|
||||
|
@ -13,16 +13,27 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.block
|
||||
|
||||
import de.bixilon.minosoft.data.text.RGBColor.Companion.asGray
|
||||
import de.bixilon.minosoft.Minosoft
|
||||
import de.bixilon.minosoft.data.registries.effects.DefaultStatusEffects
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.shader.Shader
|
||||
import de.bixilon.minosoft.gui.rendering.system.opengl.FloatUniformBuffer
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.ONE
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.clamp
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.lerp
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.modify
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import glm_.glm
|
||||
import glm_.vec3.Vec3
|
||||
import kotlin.math.max
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.sin
|
||||
|
||||
|
||||
class LightMap(private val connection: PlayConnection) {
|
||||
private val nightVisionStatusEffect = connection.registries.statusEffectRegistry[DefaultStatusEffects.NIGHT_VISION]
|
||||
private val conduitPowerStatusEffect = connection.registries.statusEffectRegistry[DefaultStatusEffects.CONDUIT_POWER]
|
||||
private val uniformBuffer = FloatUniformBuffer(1, FloatArray(16 * 16 * 4) { 1.0f })
|
||||
private var lastUpdate = -1L
|
||||
|
||||
|
||||
fun init() {
|
||||
@ -35,22 +46,69 @@ class LightMap(private val connection: PlayConnection) {
|
||||
}
|
||||
|
||||
fun update() {
|
||||
val currentTime = System.currentTimeMillis()
|
||||
if (currentTime - lastUpdate < ProtocolDefinition.TICK_TIME * 10) {
|
||||
return
|
||||
}
|
||||
lastUpdate = currentTime
|
||||
val skyGradient = connection.world.lightBase.toFloat()
|
||||
|
||||
// ToDo: Lightning
|
||||
|
||||
val underwaterVisibility = 0.0f // ToDo
|
||||
|
||||
val nightVisionEffect = connection.player.activeStatusEffects[nightVisionStatusEffect]
|
||||
|
||||
val nightVisionVisibility = if (nightVisionEffect != null) {
|
||||
if (nightVisionEffect.duration > 200) {
|
||||
1.0f
|
||||
} else {
|
||||
0.7f + sin((nightVisionEffect.duration.toFloat()) * glm.PIf * 0.2f) * 0.3f
|
||||
}
|
||||
} else if (underwaterVisibility > 0.0f && connection.player.activeStatusEffects[conduitPowerStatusEffect] != null) {
|
||||
underwaterVisibility
|
||||
} else {
|
||||
0.0f
|
||||
}
|
||||
|
||||
|
||||
var skyGradientColor = Vec3(skyGradient, skyGradient, 1.0f)
|
||||
skyGradientColor = lerp(0.35f, skyGradientColor, Vec3.ONE)
|
||||
|
||||
// ToDo
|
||||
for (skyLight in 0 until 16) {
|
||||
for (blockLight in 0 until 16) {
|
||||
val index = ((skyLight shl 4) or blockLight) * 4
|
||||
|
||||
val color = ((blockLight + skyLight) / 30.0f).asGray()
|
||||
|
||||
uniformBuffer.data[index + 0] = color.floatRed
|
||||
uniformBuffer.data[index + 1] = color.floatRed
|
||||
uniformBuffer.data[index + 2] = color.floatGreen
|
||||
val skyLightBrightness = (connection.world.dimension?.lightLevels?.get(skyLight) ?: 1.0f) * (skyGradient * 0.95f + 0.05f)
|
||||
val blockLightBrightness = (connection.world.dimension?.lightLevels?.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))
|
||||
|
||||
// ToDo: Lightning
|
||||
|
||||
let {
|
||||
color = color + (skyGradientColor * skyLightBrightness)
|
||||
|
||||
color = lerp(0.04f, color, Vec3(0.75f))
|
||||
|
||||
// ToDo: Sky darkness
|
||||
}
|
||||
|
||||
color = color.clamp(0.0f, 1.0f)
|
||||
|
||||
if (nightVisionVisibility > 0.0f) {
|
||||
val gamma = max(color.x, max(color.y, color.z))
|
||||
if (gamma < 1.0f) {
|
||||
val copy = color.toVec3 * (1.0f / gamma)
|
||||
color = lerp(nightVisionVisibility, color, copy)
|
||||
}
|
||||
}
|
||||
|
||||
color = lerp(Minosoft.config.config.game.light.gamma, color, color.toVec3 modify { 1.0f - (1.0f - it).pow(4) })
|
||||
color = lerp(0.04f, color, Vec3(0.75f))
|
||||
color = color.clamp(0.0f, 1.0f)
|
||||
|
||||
|
||||
uniformBuffer.data[index + 0] = color.x
|
||||
uniformBuffer.data[index + 1] = color.y
|
||||
uniformBuffer.data[index + 2] = color.z
|
||||
}
|
||||
}
|
||||
uniformBuffer.upload()
|
||||
|
@ -54,7 +54,10 @@ class FluidRenderer(
|
||||
if (!RenderConstants.RENDER_FLUIDS) {
|
||||
return
|
||||
}
|
||||
val lightLevel = context.lightAccessor.getLightLevel(context.blockPosition)
|
||||
val blockLight = context.lightAccessor.getBlockLight(context.blockPosition)
|
||||
val skyLight = context.lightAccessor.getSkyLight(context.blockPosition)
|
||||
|
||||
val light = (skyLight shl 4) or blockLight
|
||||
val heights = calculateHeights(context.neighbourBlocks, context.blockState, context.world, context.blockPosition)
|
||||
val isFlowing = isLiquidFlowing(heights)
|
||||
|
||||
@ -88,7 +91,7 @@ class FluidRenderer(
|
||||
tintColor = context.renderWindow.tintColorCalculator.getAverageTint(biome, context.blockState, context.blockPosition)
|
||||
}
|
||||
|
||||
createQuad(drawPositions, face.getTexturePositionArray(direction), texture, context.blockPosition, context.meshCollection, tintColor, lightLevel)
|
||||
createQuad(drawPositions, face.getTexturePositionArray(direction), texture, context.blockPosition, context.meshCollection, tintColor, light)
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,7 +138,7 @@ class FluidRenderer(
|
||||
return heights.toSet().size != 1 // liquid is flowing, if not all of the heights are the same
|
||||
}
|
||||
|
||||
private fun createQuad(drawPositions: Array<Vec3>, texturePositions: Array<Vec2?>, texture: Texture, blockPosition: Vec3i, meshCollection: ChunkSectionMeshCollection, tintColor: RGBColor?, lightLevel: Int) {
|
||||
private fun createQuad(drawPositions: Array<Vec3>, texturePositions: Array<Vec2?>, texture: Texture, blockPosition: Vec3i, meshCollection: ChunkSectionMeshCollection, tintColor: RGBColor?, light: Int) {
|
||||
val mesh = ElementRenderer.getMesh(meshCollection, texture.transparency)
|
||||
for (vertex in ElementRenderer.DRAW_ODER) {
|
||||
mesh.addVertex(
|
||||
@ -143,7 +146,7 @@ class FluidRenderer(
|
||||
textureCoordinates = texturePositions[vertex.second]!!,
|
||||
texture = texture,
|
||||
tintColor = tintColor,
|
||||
light = lightLevel,
|
||||
light = light,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -27,14 +27,12 @@ import de.bixilon.minosoft.modding.event.CallbackEventInvoker
|
||||
import de.bixilon.minosoft.modding.event.events.TimeChangeEvent
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import de.bixilon.minosoft.util.MMath
|
||||
import glm_.func.rad
|
||||
import glm_.mat4x4.Mat4
|
||||
import glm_.mat4x4.Mat4d
|
||||
import glm_.vec2.Vec2
|
||||
import glm_.vec3.Vec3
|
||||
import glm_.vec3.Vec3d
|
||||
import kotlin.math.cos
|
||||
|
||||
class SkyRenderer(
|
||||
private val connection: PlayConnection,
|
||||
@ -73,7 +71,7 @@ class SkyRenderer(
|
||||
}
|
||||
|
||||
private fun setSunMatrix(projectionViewMatrix: Mat4d) {
|
||||
val timeAngle = ((getSkyAngle(connection.world.time) * 360.0) + 180.0).rad
|
||||
val timeAngle = (connection.world.skyAngle * 360.0).rad
|
||||
val rotatedMatrix = if (timeAngle == 0.0) {
|
||||
projectionViewMatrix
|
||||
} else {
|
||||
@ -151,11 +149,5 @@ class SkyRenderer(
|
||||
override fun build(connection: PlayConnection, renderWindow: RenderWindow): SkyRenderer {
|
||||
return SkyRenderer(connection, renderWindow)
|
||||
}
|
||||
|
||||
fun getSkyAngle(time: Long): Double {
|
||||
val fractionalPath = MMath.fractionalPart(time / ProtocolDefinition.TICKS_PER_DAYf - 0.25)
|
||||
val angle = 0.5 - cos(fractionalPath * Math.PI) / 2.0
|
||||
return (fractionalPath * 2.0 + angle) / 3.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,6 +87,22 @@ object VecUtil {
|
||||
)
|
||||
}
|
||||
|
||||
infix operator fun Vec3.times(lambda: () -> Float): Vec3 {
|
||||
return Vec3(
|
||||
x = x * lambda(),
|
||||
y = y * lambda(),
|
||||
z = z * lambda(),
|
||||
)
|
||||
}
|
||||
|
||||
infix fun Vec3.modify(lambda: (Float) -> Float): Vec3 {
|
||||
return Vec3(
|
||||
x = lambda(x),
|
||||
y = lambda(y),
|
||||
z = lambda(z),
|
||||
)
|
||||
}
|
||||
|
||||
infix operator fun Vec3d.plus(lambda: () -> Double): Vec3d {
|
||||
return Vec3d(
|
||||
x = x + lambda(),
|
||||
|
@ -536,10 +536,10 @@
|
||||
"minecraft:arrow_player_hit": {
|
||||
"id": 6
|
||||
},
|
||||
"minecraft:rain_level_set": {
|
||||
"minecraft:rain_gradient_set": {
|
||||
"id": 7
|
||||
},
|
||||
"minecraft:thunder_level_Set": {
|
||||
"minecraft:thunder_gradient_set": {
|
||||
"id": 8
|
||||
},
|
||||
"minecraft:pufferfish_sting": {
|
||||
@ -571,10 +571,10 @@
|
||||
"minecraft:arrow_player_hit": {
|
||||
"id": 6
|
||||
},
|
||||
"minecraft:rain_level_set": {
|
||||
"minecraft:rain_gradient_set": {
|
||||
"id": 7
|
||||
},
|
||||
"minecraft:thunder_level_Set": {
|
||||
"minecraft:thunder_gradient_set": {
|
||||
"id": 8
|
||||
},
|
||||
"minecraft:pufferfish_sting": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user