From d1861a067923a656d1e966f237686d02f44ba190 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Fri, 28 May 2021 23:17:46 +0200 Subject: [PATCH] smoke and lava particles --- .../mappings/blocks/types/CampfireBlock.kt | 51 ++++++++++----- .../particle/DefaultParticleBehavior.kt | 6 +- .../particle/DefaultParticleFactory.kt | 12 ++-- .../gui/rendering/particle/types/Particle.kt | 27 ++++---- .../norender/ExplosionEmitterParticle.kt | 15 ++--- .../particle/types/render/RenderParticle.kt | 49 +-------------- .../texture/simple/AscendingParticle.kt | 55 ++++++++++++++++ .../texture/simple/CampfireSmokeParticle.kt | 13 ++-- ...nLargeParticle.kt => ExplosionParticle.kt} | 11 ++-- .../texture/simple/fire/SmokeParticle.kt | 35 +++++++++++ .../texture/simple/lava/LavaParticle.kt | 62 +++++++++++++++++++ .../minosoft/gui/rendering/util/VecUtil.kt | 12 ++++ 12 files changed, 239 insertions(+), 109 deletions(-) create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/AscendingParticle.kt rename src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/{ExplosionLargeParticle.kt => ExplosionParticle.kt} (77%) create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/fire/SmokeParticle.kt create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/lava/LavaParticle.kt diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/blocks/types/CampfireBlock.kt b/src/main/java/de/bixilon/minosoft/data/mappings/blocks/types/CampfireBlock.kt index 69590a8b7..02e1f7b54 100644 --- a/src/main/java/de/bixilon/minosoft/data/mappings/blocks/types/CampfireBlock.kt +++ b/src/main/java/de/bixilon/minosoft/data/mappings/blocks/types/CampfireBlock.kt @@ -25,6 +25,10 @@ import de.bixilon.minosoft.data.player.Hands import de.bixilon.minosoft.gui.rendering.input.camera.RaycastHit import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.CampfireSmokeParticle +import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.fire.SmokeParticle +import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.lava.LavaParticle +import de.bixilon.minosoft.gui.rendering.util.VecUtil.noise +import de.bixilon.minosoft.gui.rendering.util.VecUtil.verticalPlus import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.util.KUtil.asResourceLocation import de.bixilon.minosoft.util.KUtil.chance @@ -34,8 +38,10 @@ import kotlin.random.Random open class CampfireBlock(resourceLocation: ResourceLocation, registries: Registries, data: JsonObject) : Block(resourceLocation, registries, data) { private val campfireCrackleSoundEvent = registries.soundEventRegistry[CAMPFIRE_CRACKLE_SOUND_RESOURCE_LOCATION]!! - private val cosySmokeParticle = registries.particleTypeRegistry[CampfireSmokeParticle.CosySmokeParticleFactory]!! - private val signalSmokeParticle = registries.particleTypeRegistry[CampfireSmokeParticle.SignalSmokeParticleFactory]!! + private val cosySmokeParticle = registries.particleTypeRegistry[CampfireSmokeParticle.CosyFactory]!! + private val signalSmokeParticle = registries.particleTypeRegistry[CampfireSmokeParticle.SignalFactory]!! + private val lavaParticle = registries.particleTypeRegistry[LavaParticle]!! + private val smokeParticle = registries.particleTypeRegistry[SmokeParticle]!! private fun extinguish(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i) { val particleRenderer = connection.rendering?.renderWindow?.get(ParticleRenderer) ?: return @@ -45,24 +51,29 @@ open class CampfireBlock(resourceLocation: ResourceLocation, registries: Registr } fun spawnSmokeParticles(connection: PlayConnection, particleRenderer: ParticleRenderer, blockState: BlockState, blockPosition: Vec3i, extinguished: Boolean) { - val horizontal = { 0.5f + Random.nextFloat() / 3.0f * if (Random.nextBoolean()) 1.0f else -1.0f } - val position = Vec3( - blockPosition.x + horizontal(), - blockPosition.y + Random.nextFloat() + Random.nextFloat(), - blockPosition.z + horizontal() - ) - val isSignal = blockState.properties[BlockProperties.CAMPFIRE_SIGNAL_FIRE] == true + let { + val position = Vec3(blockPosition).verticalPlus( + { 0.5f + 3.0f.noise }, + Random.nextFloat() + Random.nextFloat() + 0.5f // ToDo: This +0.5f is a temporary fix for not making the particle stuck in ourself + ) - val particleType = if (isSignal) { - signalSmokeParticle - } else { - cosySmokeParticle + val isSignal = blockState.properties[BlockProperties.CAMPFIRE_SIGNAL_FIRE] == true + + val particleType = if (isSignal) { + signalSmokeParticle + } else { + cosySmokeParticle + } + + particleRenderer.add(CampfireSmokeParticle(connection, particleRenderer, position, Vec3(0.0f, 0.07f, 0.0f), particleType.simple(), isSignal)) } - particleRenderer.add(CampfireSmokeParticle(connection, particleRenderer, position, Vec3(0.0f, 0.07f, 0.0f), particleType.simple(), isSignal)) - if (extinguished) { - // ToDo: Spawn smoke particles + val position = Vec3(blockPosition).verticalPlus( + { 0.5f + 4.0f.noise }, + 0.5f + ) + particleRenderer.add(SmokeParticle(connection, particleRenderer, position, Vec3(0.0f, 0.005f, 0.0f), smokeParticle.simple())) } } @@ -74,7 +85,13 @@ open class CampfireBlock(resourceLocation: ResourceLocation, registries: Registr if (random.chance(10)) { connection.rendering?.audioPlayer?.playSoundEvent(campfireCrackleSoundEvent, blockPosition + Vec3(0.5f), 0.5f + random.nextFloat(), 0.6f + random.nextFloat() * 0.7f) } - // ToDo: Spawn Lava particles + + if (random.chance(20)) { + val position = Vec3(blockPosition) + Vec3(0.5f) + for (i in 0 until random.nextInt(1) + 1) { + particleRenderer.add(LavaParticle(connection, particleRenderer, position, lavaParticle.simple())) + } + } } override fun onUse(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack?): BlockUsages { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/DefaultParticleBehavior.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/DefaultParticleBehavior.kt index 7f5e80f41..b5c489ff0 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/DefaultParticleBehavior.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/DefaultParticleBehavior.kt @@ -14,7 +14,7 @@ package de.bixilon.minosoft.gui.rendering.particle import de.bixilon.minosoft.gui.rendering.particle.types.norender.ExplosionEmitterParticle -import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.ExplosionLargeParticle +import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.ExplosionParticle import de.bixilon.minosoft.gui.rendering.util.VecUtil.times import de.bixilon.minosoft.modding.event.CallbackEventInvoker import de.bixilon.minosoft.modding.event.events.ExplosionEvent @@ -29,14 +29,14 @@ object DefaultParticleBehavior { fun register(connection: PlayConnection, particleRenderer: ParticleRenderer) { val random = java.util.Random() - val explosionParticleType = connection.registries.particleTypeRegistry[ExplosionLargeParticle]!! + val explosionParticleType = connection.registries.particleTypeRegistry[ExplosionParticle]!! val explosionEmitterParticleType = connection.registries.particleTypeRegistry[ExplosionEmitterParticle]!! val invokers = listOf( CallbackEventInvoker.of { if (it.power >= 2.0f) { particleRenderer.add(ExplosionEmitterParticle(connection, particleRenderer, it.position, explosionEmitterParticleType.simple())) } else { - particleRenderer.add(ExplosionLargeParticle(connection, particleRenderer, it.position, explosionParticleType.simple())) + particleRenderer.add(ExplosionParticle(connection, particleRenderer, it.position, explosionParticleType.simple())) } }, CallbackEventInvoker.of { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/DefaultParticleFactory.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/DefaultParticleFactory.kt index 05a0a4b9d..5c1fdd18d 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/DefaultParticleFactory.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/DefaultParticleFactory.kt @@ -17,11 +17,15 @@ import de.bixilon.minosoft.data.mappings.DefaultFactory import de.bixilon.minosoft.gui.rendering.particle.types.Particle import de.bixilon.minosoft.gui.rendering.particle.types.norender.ExplosionEmitterParticle import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.CampfireSmokeParticle -import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.ExplosionLargeParticle +import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.ExplosionParticle +import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.fire.SmokeParticle +import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.lava.LavaParticle object DefaultParticleFactory : DefaultFactory>( ExplosionEmitterParticle, - ExplosionLargeParticle, - CampfireSmokeParticle.CosySmokeParticleFactory, - CampfireSmokeParticle.SignalSmokeParticleFactory, + ExplosionParticle, + CampfireSmokeParticle.CosyFactory, + CampfireSmokeParticle.SignalFactory, + LavaParticle, + SmokeParticle, ) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt index fa91a076e..0e84e02b2 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt @@ -25,7 +25,6 @@ import de.bixilon.minosoft.gui.rendering.util.VecUtil.plusAssign import de.bixilon.minosoft.gui.rendering.util.VecUtil.sqr import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition -import de.bixilon.minosoft.util.KUtil.millis import glm_.vec3.Vec3 import kotlin.math.abs import kotlin.math.sqrt @@ -45,7 +44,9 @@ abstract class Particle( var dead = false var age: Int = 0 protected set - var maxAge: Int = (4.0f / (random.nextFloat() * 0.9f + 0.1f)).millis + val floatAge: Float + get() = age.toFloat() + var maxAge: Int = (4.0f / (random.nextFloat() * 0.9f + 0.1f)).toInt() // moving var previousPosition = position @@ -62,6 +63,7 @@ abstract class Particle( var spacing: Vec3 = Vec3.EMPTY set(value) { if (field == value) { + return } field = value @@ -113,8 +115,6 @@ abstract class Particle( } previousPosition = Vec3(position) - velocity.y -= (0.04f * gravityStrength).millis - move(velocity.millis * (deltaTime / 1000.0f)) } @@ -144,10 +144,8 @@ abstract class Particle( lastTickTime = currentTime } - protected fun age(deltaTime: Int) { - age += deltaTime - - if (age >= maxAge) { + protected fun age() { + if (age++ >= maxAge) { dead = true } } @@ -155,11 +153,6 @@ abstract class Particle( open fun tick(deltaTime: Int) { check(!dead) { "Cannot tick dead particle!" } check(deltaTime >= 0) - - age(deltaTime) - if (dead) { - return - } } open fun postTick(deltaTime: Int) { @@ -170,6 +163,12 @@ abstract class Particle( if (!movement) { return } + age() + if (dead) { + return + } + + velocity.y -= 0.04f * gravityStrength if (accelerateIfYBlocked && position.y == previousPosition.y) { velocity.x *= 1.1f @@ -180,7 +179,7 @@ abstract class Particle( if (onGround) { velocity.x *= 0.699999988079071f - velocity.y *= 0.699999988079071f + velocity.z *= 0.699999988079071f } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/norender/ExplosionEmitterParticle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/norender/ExplosionEmitterParticle.kt index 98fe31532..b9269986d 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/norender/ExplosionEmitterParticle.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/norender/ExplosionEmitterParticle.kt @@ -17,7 +17,7 @@ import de.bixilon.minosoft.data.mappings.ResourceLocation import de.bixilon.minosoft.data.mappings.particle.data.ParticleData import de.bixilon.minosoft.gui.rendering.particle.ParticleFactory import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer -import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.ExplosionLargeParticle +import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.ExplosionParticle import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus import de.bixilon.minosoft.protocol.network.connection.PlayConnection @@ -25,30 +25,25 @@ import de.bixilon.minosoft.util.KUtil.asResourceLocation import glm_.vec3.Vec3 class ExplosionEmitterParticle(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, data: ParticleData) : NoRenderParticle(connection, particleRenderer, position, Vec3.EMPTY, data) { - private val explosionParticleType = connection.registries.particleTypeRegistry[ExplosionLargeParticle]!! + private val explosionParticleType = connection.registries.particleTypeRegistry[ExplosionParticle]!! init { - maxAge = Int.MAX_VALUE + maxAge = MAX_AGE movement = false } - private var ticks = 0 override fun realTick() { super.realTick() for (i in 0 until 6) { val position = position + { (random.nextFloat() - random.nextFloat()) * 4.0f } - particleRenderer.add(ExplosionLargeParticle(connection, particleRenderer, position, explosionParticleType.simple(), (ticks.toFloat() / MAX_AGE))) - } - - if (ticks == MAX_AGE) { - dead = true + particleRenderer.add(ExplosionParticle(connection, particleRenderer, position, explosionParticleType.simple(), floatAge / MAX_AGE)) } } companion object : ParticleFactory { override val RESOURCE_LOCATION: ResourceLocation = "minecraft:explosion_emitter".asResourceLocation() - private const val MAX_AGE = 8 + private const val MAX_AGE = 9 override fun build(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, velocity: Vec3, data: ParticleData): ExplosionEmitterParticle { return ExplosionEmitterParticle(connection, particleRenderer, position, data) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/RenderParticle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/RenderParticle.kt index 28516dda8..ea154e8e2 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/RenderParticle.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/RenderParticle.kt @@ -20,55 +20,8 @@ import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer import de.bixilon.minosoft.gui.rendering.particle.types.Particle import de.bixilon.minosoft.protocol.network.connection.PlayConnection import glm_.vec3.Vec3 -import kotlin.math.abs abstract class RenderParticle(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, velocity: Vec3, data: ParticleData) : Particle(connection, particleRenderer, position, velocity, data) { - protected var scale: Float = 0.1f * (random.nextFloat() * 0.5f + 0.5f) * 2.0f + protected open var scale: Float = 0.1f * (random.nextFloat() * 0.5f + 0.5f) * 2.0f protected var color: RGBColor = ChatColors.WHITE - - // growing - protected var nextScale: Float = scale - protected var scalePerMillisecond = Float.NEGATIVE_INFINITY - - - override fun tick(deltaTime: Int) { - super.tick(deltaTime) - if (dead) { - return - } - grow(deltaTime) - } - - fun grow(scale: Float, time: Long) { - nextScale = scale - scalePerMillisecond = (scale - this.scale) / time - } - - private fun grow(deltaTime: Int) { - if (scalePerMillisecond == Float.NEGATIVE_INFINITY) { - return - } - val deltaScale = nextScale - scale - if (abs(deltaScale) > GROW_LOWER_LIMIT) { - // we need to grow - val scaleAdd = scalePerMillisecond * deltaTime - - // checke if the delta gets bigger (aka. we'd grew to much) - val nextScale = scale + scaleAdd - if (abs(this.nextScale - nextScale) > deltaScale) { - // abort scaling and avoid getting called another time - scale = nextScale - scalePerMillisecond = Float.NEGATIVE_INFINITY - return - } - // we can grow - scale = nextScale - } - } - - companion object { - const val GROW_LOWER_LIMIT = 0.001f - } - - } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/AscendingParticle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/AscendingParticle.kt new file mode 100644 index 000000000..c3b1397de --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/AscendingParticle.kt @@ -0,0 +1,55 @@ +/* + * 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 . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple + +import de.bixilon.minosoft.data.mappings.particle.data.ParticleData +import de.bixilon.minosoft.data.text.RGBColor.Companion.asGray +import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer +import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY +import de.bixilon.minosoft.protocol.network.connection.PlayConnection +import de.bixilon.minosoft.util.MMath +import glm_.vec3.Vec3 + +abstract class AscendingParticle( + connection: PlayConnection, + particleRenderer: ParticleRenderer, + position: Vec3, + velocity: Vec3, + velocityMultiplier: Vec3, + scaleMultiplier: Float, + colorMultiplier: Float, + baseAge: Int, + gravityStrength: Float, + physics: Boolean, + data: ParticleData, +) : SimpleTextureParticle(connection, particleRenderer, position, Vec3.EMPTY, data) { + + override var scale: Float + get() = super.scale * MMath.clamp(floatAge / maxAge * 32.0f, 0.0f, 1.0f) + set(value) { + super.scale = value + } + + init { + friction = 0.96f + this.gravityStrength = gravityStrength + accelerateIfYBlocked = true + this.velocity *= velocityMultiplier + this.velocity += velocity + color = (random.nextFloat() * colorMultiplier).asGray() + super.scale *= 0.75f * scaleMultiplier + super.maxAge = ((baseAge.toFloat() / (random.nextFloat() * 0.8f + 0.2f)).toInt() * scaleMultiplier).toInt().coerceAtLeast(1) + this.physics = physics + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/CampfireSmokeParticle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/CampfireSmokeParticle.kt index c5b1b2c5c..f9ae82fed 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/CampfireSmokeParticle.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/CampfireSmokeParticle.kt @@ -22,7 +22,6 @@ import de.bixilon.minosoft.gui.rendering.util.VecUtil.assign import de.bixilon.minosoft.gui.rendering.util.VecUtil.millis import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.util.KUtil.asResourceLocation -import de.bixilon.minosoft.util.KUtil.millis import glm_.vec3.Vec3 class CampfireSmokeParticle(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, velocity: Vec3, data: ParticleData, signal: Boolean) : SimpleTextureParticle(connection, particleRenderer, position, Vec3.EMPTY, data) { @@ -30,12 +29,12 @@ class CampfireSmokeParticle(connection: PlayConnection, particleRenderer: Partic init { scale *= 3.0f spacing = Vec3(0.25f) - maxAge = random.nextInt(50).millis + maxAge = random.nextInt(50) if (signal) { - maxAge += 280.millis + maxAge += 280 color = color.with(alpha = 0.95f) } else { - maxAge += 80.millis + maxAge += 80 color = color.with(alpha = 0.90f) } @@ -54,7 +53,7 @@ class CampfireSmokeParticle(connection: PlayConnection, particleRenderer: Partic velocity.y -= gravityStrength velocity.z += horizontal() - if (age >= maxAge - 60.millis) { + if (age >= maxAge - 60) { color = color.with(alpha = color.floatAlpha - 0.015f) } if (color.alpha == 0) { @@ -68,7 +67,7 @@ class CampfireSmokeParticle(connection: PlayConnection, particleRenderer: Partic } - object CosySmokeParticleFactory : ParticleFactory { + object CosyFactory : ParticleFactory { override val RESOURCE_LOCATION: ResourceLocation = "minecraft:campfire_cosy_smoke".asResourceLocation() override fun build(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, velocity: Vec3, data: ParticleData): CampfireSmokeParticle { @@ -77,7 +76,7 @@ class CampfireSmokeParticle(connection: PlayConnection, particleRenderer: Partic } - object SignalSmokeParticleFactory : ParticleFactory { + object SignalFactory : ParticleFactory { override val RESOURCE_LOCATION: ResourceLocation = "minecraft:campfire_signal_smoke".asResourceLocation() override fun build(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, velocity: Vec3, data: ParticleData): CampfireSmokeParticle { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/ExplosionLargeParticle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/ExplosionParticle.kt similarity index 77% rename from src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/ExplosionLargeParticle.kt rename to src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/ExplosionParticle.kt index 8276c394c..9a7ef0483 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/ExplosionLargeParticle.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/ExplosionParticle.kt @@ -21,24 +21,23 @@ import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.util.KUtil.asResourceLocation -import de.bixilon.minosoft.util.KUtil.millis import glm_.vec3.Vec3 -class ExplosionLargeParticle(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, data: ParticleData, power: Float = 1.0f) : SimpleTextureParticle(connection, particleRenderer, position, Vec3.EMPTY, data) { +class ExplosionParticle(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, data: ParticleData, power: Float = 1.0f) : SimpleTextureParticle(connection, particleRenderer, position, Vec3.EMPTY, data) { init { movement = false - maxAge = (6 + random.nextInt(4)).millis + maxAge = 6 + random.nextInt(4) val gray = random.nextFloat() * 0.6f + 0.4f color = gray.asGray() scale = 2.0f * (power - gray * 0.5f) } - companion object : ParticleFactory { + companion object : ParticleFactory { override val RESOURCE_LOCATION: ResourceLocation = "minecraft:explosion".asResourceLocation() - override fun build(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, velocity: Vec3, data: ParticleData): ExplosionLargeParticle { - return ExplosionLargeParticle(connection, particleRenderer, position, data, velocity.x) + override fun build(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, velocity: Vec3, data: ParticleData): ExplosionParticle { + return ExplosionParticle(connection, particleRenderer, position, data, velocity.x) } } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/fire/SmokeParticle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/fire/SmokeParticle.kt new file mode 100644 index 000000000..942efcb7c --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/fire/SmokeParticle.kt @@ -0,0 +1,35 @@ +/* + * 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 . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.fire + +import de.bixilon.minosoft.data.mappings.ResourceLocation +import de.bixilon.minosoft.data.mappings.particle.data.ParticleData +import de.bixilon.minosoft.gui.rendering.particle.ParticleFactory +import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer +import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.AscendingParticle +import de.bixilon.minosoft.protocol.network.connection.PlayConnection +import de.bixilon.minosoft.util.KUtil.asResourceLocation +import glm_.vec3.Vec3 + +class SmokeParticle(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, velocity: Vec3, data: ParticleData, scaleMultiplier: Float = 1.0f) : AscendingParticle(connection, particleRenderer, position, velocity, Vec3(0.1f), scaleMultiplier, 0.3f, 8, -0.1f, true, data) { + + + companion object : ParticleFactory { + override val RESOURCE_LOCATION: ResourceLocation = "minecraft:smoke".asResourceLocation() + + override fun build(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, velocity: Vec3, data: ParticleData): SmokeParticle { + return SmokeParticle(connection, particleRenderer, position, velocity, data) + } + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/lava/LavaParticle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/lava/LavaParticle.kt new file mode 100644 index 000000000..88572f28f --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/lava/LavaParticle.kt @@ -0,0 +1,62 @@ +/* + * 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 . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.lava + +import de.bixilon.minosoft.data.mappings.ResourceLocation +import de.bixilon.minosoft.data.mappings.particle.data.ParticleData +import de.bixilon.minosoft.gui.rendering.particle.ParticleFactory +import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer +import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.SimpleTextureParticle +import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.fire.SmokeParticle +import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY +import de.bixilon.minosoft.gui.rendering.util.VecUtil.sqr +import de.bixilon.minosoft.protocol.network.connection.PlayConnection +import de.bixilon.minosoft.util.KUtil.asResourceLocation +import glm_.vec3.Vec3 + +class LavaParticle(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, data: ParticleData) : SimpleTextureParticle(connection, particleRenderer, position, Vec3.EMPTY, data) { + private val smokeParticleType = connection.registries.particleTypeRegistry[SmokeParticle]!! + + override var scale: Float + get() = super.scale * (1.0f - (floatAge / maxAge).sqr) + set(value) { + super.scale = value + } + + init { + gravityStrength = 0.75f + friction = 0.999f + velocity.x *= 0.800000011920929f + velocity.y = random.nextFloat() * 0.4f + 0.05f + velocity.z *= 0.800000011920929f + scale *= random.nextFloat() * 2.0f + 0.2f + maxAge = (16.0f / (random.nextFloat() * 0.8f + 0.2f)).toInt() + } + + override fun realTick() { + super.realTick() + + if (random.nextFloat() > (floatAge / maxAge)) { + particleRenderer.add(SmokeParticle(connection, particleRenderer, Vec3(position), Vec3(velocity), smokeParticleType.simple())) + } + } + + companion object : ParticleFactory { + override val RESOURCE_LOCATION: ResourceLocation = "minecraft:lava".asResourceLocation() + + override fun build(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, velocity: Vec3, data: ParticleData): LavaParticle { + return LavaParticle(connection, particleRenderer, position, data) + } + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/util/VecUtil.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/util/VecUtil.kt index 1b45a2a31..e239cb40a 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/util/VecUtil.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/util/VecUtil.kt @@ -35,6 +35,7 @@ import glm_.vec2.Vec2 import glm_.vec2.Vec2i import glm_.vec3.Vec3 import glm_.vec3.Vec3i +import kotlin.random.Random object VecUtil { val Vec3.Companion.EMPTY: Vec3 @@ -351,4 +352,15 @@ object VecUtil { Axes.Z -> this.z } } + + fun Vec3.Companion.vertical(xz: () -> Float, y: Float): Vec3 { + return Vec3(xz(), y, xz()) + } + + fun Vec3.verticalPlus(xz: () -> Float, y: Float): Vec3 { + return Vec3(this.x + xz(), this.y + y, this.z + xz()) + } + + val Float.noise: Float + get() = Random.nextFloat() / this * if (Random.nextBoolean()) 1.0f else -1.0f }