mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-12 00:47:26 -04:00
smoke and lava particles
This commit is contained in:
parent
9af4f479a9
commit
d1861a0679
@ -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.input.camera.RaycastHit
|
||||||
import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer
|
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.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.protocol.network.connection.PlayConnection
|
||||||
import de.bixilon.minosoft.util.KUtil.asResourceLocation
|
import de.bixilon.minosoft.util.KUtil.asResourceLocation
|
||||||
import de.bixilon.minosoft.util.KUtil.chance
|
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) {
|
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 campfireCrackleSoundEvent = registries.soundEventRegistry[CAMPFIRE_CRACKLE_SOUND_RESOURCE_LOCATION]!!
|
||||||
private val cosySmokeParticle = registries.particleTypeRegistry[CampfireSmokeParticle.CosySmokeParticleFactory]!!
|
private val cosySmokeParticle = registries.particleTypeRegistry[CampfireSmokeParticle.CosyFactory]!!
|
||||||
private val signalSmokeParticle = registries.particleTypeRegistry[CampfireSmokeParticle.SignalSmokeParticleFactory]!!
|
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) {
|
private fun extinguish(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i) {
|
||||||
val particleRenderer = connection.rendering?.renderWindow?.get(ParticleRenderer) ?: return
|
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) {
|
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 }
|
let {
|
||||||
val position = Vec3(
|
val position = Vec3(blockPosition).verticalPlus(
|
||||||
blockPosition.x + horizontal(),
|
{ 0.5f + 3.0f.noise },
|
||||||
blockPosition.y + Random.nextFloat() + Random.nextFloat(),
|
Random.nextFloat() + Random.nextFloat() + 0.5f // ToDo: This +0.5f is a temporary fix for not making the particle stuck in ourself
|
||||||
blockPosition.z + horizontal()
|
)
|
||||||
)
|
|
||||||
val isSignal = blockState.properties[BlockProperties.CAMPFIRE_SIGNAL_FIRE] == true
|
|
||||||
|
|
||||||
val particleType = if (isSignal) {
|
val isSignal = blockState.properties[BlockProperties.CAMPFIRE_SIGNAL_FIRE] == true
|
||||||
signalSmokeParticle
|
|
||||||
} else {
|
val particleType = if (isSignal) {
|
||||||
cosySmokeParticle
|
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) {
|
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)) {
|
if (random.chance(10)) {
|
||||||
connection.rendering?.audioPlayer?.playSoundEvent(campfireCrackleSoundEvent, blockPosition + Vec3(0.5f), 0.5f + random.nextFloat(), 0.6f + random.nextFloat() * 0.7f)
|
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 {
|
override fun onUse(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack?): BlockUsages {
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
package de.bixilon.minosoft.gui.rendering.particle
|
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.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.gui.rendering.util.VecUtil.times
|
||||||
import de.bixilon.minosoft.modding.event.CallbackEventInvoker
|
import de.bixilon.minosoft.modding.event.CallbackEventInvoker
|
||||||
import de.bixilon.minosoft.modding.event.events.ExplosionEvent
|
import de.bixilon.minosoft.modding.event.events.ExplosionEvent
|
||||||
@ -29,14 +29,14 @@ object DefaultParticleBehavior {
|
|||||||
|
|
||||||
fun register(connection: PlayConnection, particleRenderer: ParticleRenderer) {
|
fun register(connection: PlayConnection, particleRenderer: ParticleRenderer) {
|
||||||
val random = java.util.Random()
|
val random = java.util.Random()
|
||||||
val explosionParticleType = connection.registries.particleTypeRegistry[ExplosionLargeParticle]!!
|
val explosionParticleType = connection.registries.particleTypeRegistry[ExplosionParticle]!!
|
||||||
val explosionEmitterParticleType = connection.registries.particleTypeRegistry[ExplosionEmitterParticle]!!
|
val explosionEmitterParticleType = connection.registries.particleTypeRegistry[ExplosionEmitterParticle]!!
|
||||||
val invokers = listOf(
|
val invokers = listOf(
|
||||||
CallbackEventInvoker.of<ExplosionEvent> {
|
CallbackEventInvoker.of<ExplosionEvent> {
|
||||||
if (it.power >= 2.0f) {
|
if (it.power >= 2.0f) {
|
||||||
particleRenderer.add(ExplosionEmitterParticle(connection, particleRenderer, it.position, explosionEmitterParticleType.simple()))
|
particleRenderer.add(ExplosionEmitterParticle(connection, particleRenderer, it.position, explosionEmitterParticleType.simple()))
|
||||||
} else {
|
} else {
|
||||||
particleRenderer.add(ExplosionLargeParticle(connection, particleRenderer, it.position, explosionParticleType.simple()))
|
particleRenderer.add(ExplosionParticle(connection, particleRenderer, it.position, explosionParticleType.simple()))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CallbackEventInvoker.of<ParticleSpawnEvent> {
|
CallbackEventInvoker.of<ParticleSpawnEvent> {
|
||||||
|
@ -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.Particle
|
||||||
import de.bixilon.minosoft.gui.rendering.particle.types.norender.ExplosionEmitterParticle
|
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.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<ParticleFactory<out Particle>>(
|
object DefaultParticleFactory : DefaultFactory<ParticleFactory<out Particle>>(
|
||||||
ExplosionEmitterParticle,
|
ExplosionEmitterParticle,
|
||||||
ExplosionLargeParticle,
|
ExplosionParticle,
|
||||||
CampfireSmokeParticle.CosySmokeParticleFactory,
|
CampfireSmokeParticle.CosyFactory,
|
||||||
CampfireSmokeParticle.SignalSmokeParticleFactory,
|
CampfireSmokeParticle.SignalFactory,
|
||||||
|
LavaParticle,
|
||||||
|
SmokeParticle,
|
||||||
)
|
)
|
||||||
|
@ -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.gui.rendering.util.VecUtil.sqr
|
||||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
import de.bixilon.minosoft.util.KUtil.millis
|
|
||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
@ -45,7 +44,9 @@ abstract class Particle(
|
|||||||
var dead = false
|
var dead = false
|
||||||
var age: Int = 0
|
var age: Int = 0
|
||||||
protected set
|
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
|
// moving
|
||||||
var previousPosition = position
|
var previousPosition = position
|
||||||
@ -62,6 +63,7 @@ abstract class Particle(
|
|||||||
var spacing: Vec3 = Vec3.EMPTY
|
var spacing: Vec3 = Vec3.EMPTY
|
||||||
set(value) {
|
set(value) {
|
||||||
if (field == value) {
|
if (field == value) {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
field = value
|
field = value
|
||||||
|
|
||||||
@ -113,8 +115,6 @@ abstract class Particle(
|
|||||||
}
|
}
|
||||||
previousPosition = Vec3(position)
|
previousPosition = Vec3(position)
|
||||||
|
|
||||||
velocity.y -= (0.04f * gravityStrength).millis
|
|
||||||
|
|
||||||
move(velocity.millis * (deltaTime / 1000.0f))
|
move(velocity.millis * (deltaTime / 1000.0f))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,10 +144,8 @@ abstract class Particle(
|
|||||||
lastTickTime = currentTime
|
lastTickTime = currentTime
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun age(deltaTime: Int) {
|
protected fun age() {
|
||||||
age += deltaTime
|
if (age++ >= maxAge) {
|
||||||
|
|
||||||
if (age >= maxAge) {
|
|
||||||
dead = true
|
dead = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,11 +153,6 @@ abstract class Particle(
|
|||||||
open fun tick(deltaTime: Int) {
|
open fun tick(deltaTime: Int) {
|
||||||
check(!dead) { "Cannot tick dead particle!" }
|
check(!dead) { "Cannot tick dead particle!" }
|
||||||
check(deltaTime >= 0)
|
check(deltaTime >= 0)
|
||||||
|
|
||||||
age(deltaTime)
|
|
||||||
if (dead) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun postTick(deltaTime: Int) {
|
open fun postTick(deltaTime: Int) {
|
||||||
@ -170,6 +163,12 @@ abstract class Particle(
|
|||||||
if (!movement) {
|
if (!movement) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
age()
|
||||||
|
if (dead) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
velocity.y -= 0.04f * gravityStrength
|
||||||
|
|
||||||
if (accelerateIfYBlocked && position.y == previousPosition.y) {
|
if (accelerateIfYBlocked && position.y == previousPosition.y) {
|
||||||
velocity.x *= 1.1f
|
velocity.x *= 1.1f
|
||||||
@ -180,7 +179,7 @@ abstract class Particle(
|
|||||||
|
|
||||||
if (onGround) {
|
if (onGround) {
|
||||||
velocity.x *= 0.699999988079071f
|
velocity.x *= 0.699999988079071f
|
||||||
velocity.y *= 0.699999988079071f
|
velocity.z *= 0.699999988079071f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ import de.bixilon.minosoft.data.mappings.ResourceLocation
|
|||||||
import de.bixilon.minosoft.data.mappings.particle.data.ParticleData
|
import de.bixilon.minosoft.data.mappings.particle.data.ParticleData
|
||||||
import de.bixilon.minosoft.gui.rendering.particle.ParticleFactory
|
import de.bixilon.minosoft.gui.rendering.particle.ParticleFactory
|
||||||
import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer
|
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.EMPTY
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
|
||||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||||
@ -25,30 +25,25 @@ import de.bixilon.minosoft.util.KUtil.asResourceLocation
|
|||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
|
|
||||||
class ExplosionEmitterParticle(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, data: ParticleData) : NoRenderParticle(connection, particleRenderer, position, Vec3.EMPTY, data) {
|
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 {
|
init {
|
||||||
maxAge = Int.MAX_VALUE
|
maxAge = MAX_AGE
|
||||||
movement = false
|
movement = false
|
||||||
}
|
}
|
||||||
|
|
||||||
private var ticks = 0
|
|
||||||
override fun realTick() {
|
override fun realTick() {
|
||||||
super.realTick()
|
super.realTick()
|
||||||
for (i in 0 until 6) {
|
for (i in 0 until 6) {
|
||||||
val position = position + { (random.nextFloat() - random.nextFloat()) * 4.0f }
|
val position = position + { (random.nextFloat() - random.nextFloat()) * 4.0f }
|
||||||
|
|
||||||
particleRenderer.add(ExplosionLargeParticle(connection, particleRenderer, position, explosionParticleType.simple(), (ticks.toFloat() / MAX_AGE)))
|
particleRenderer.add(ExplosionParticle(connection, particleRenderer, position, explosionParticleType.simple(), floatAge / MAX_AGE))
|
||||||
}
|
|
||||||
|
|
||||||
if (ticks == MAX_AGE) {
|
|
||||||
dead = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object : ParticleFactory<ExplosionEmitterParticle> {
|
companion object : ParticleFactory<ExplosionEmitterParticle> {
|
||||||
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:explosion_emitter".asResourceLocation()
|
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 {
|
override fun build(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, velocity: Vec3, data: ParticleData): ExplosionEmitterParticle {
|
||||||
return ExplosionEmitterParticle(connection, particleRenderer, position, data)
|
return ExplosionEmitterParticle(connection, particleRenderer, position, data)
|
||||||
|
@ -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.gui.rendering.particle.types.Particle
|
||||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||||
import glm_.vec3.Vec3
|
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) {
|
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
|
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
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
}
|
||||||
|
}
|
@ -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.gui.rendering.util.VecUtil.millis
|
||||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||||
import de.bixilon.minosoft.util.KUtil.asResourceLocation
|
import de.bixilon.minosoft.util.KUtil.asResourceLocation
|
||||||
import de.bixilon.minosoft.util.KUtil.millis
|
|
||||||
import glm_.vec3.Vec3
|
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) {
|
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 {
|
init {
|
||||||
scale *= 3.0f
|
scale *= 3.0f
|
||||||
spacing = Vec3(0.25f)
|
spacing = Vec3(0.25f)
|
||||||
maxAge = random.nextInt(50).millis
|
maxAge = random.nextInt(50)
|
||||||
if (signal) {
|
if (signal) {
|
||||||
maxAge += 280.millis
|
maxAge += 280
|
||||||
color = color.with(alpha = 0.95f)
|
color = color.with(alpha = 0.95f)
|
||||||
} else {
|
} else {
|
||||||
maxAge += 80.millis
|
maxAge += 80
|
||||||
color = color.with(alpha = 0.90f)
|
color = color.with(alpha = 0.90f)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +53,7 @@ class CampfireSmokeParticle(connection: PlayConnection, particleRenderer: Partic
|
|||||||
velocity.y -= gravityStrength
|
velocity.y -= gravityStrength
|
||||||
velocity.z += horizontal()
|
velocity.z += horizontal()
|
||||||
|
|
||||||
if (age >= maxAge - 60.millis) {
|
if (age >= maxAge - 60) {
|
||||||
color = color.with(alpha = color.floatAlpha - 0.015f)
|
color = color.with(alpha = color.floatAlpha - 0.015f)
|
||||||
}
|
}
|
||||||
if (color.alpha == 0) {
|
if (color.alpha == 0) {
|
||||||
@ -68,7 +67,7 @@ class CampfireSmokeParticle(connection: PlayConnection, particleRenderer: Partic
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
object CosySmokeParticleFactory : ParticleFactory<CampfireSmokeParticle> {
|
object CosyFactory : ParticleFactory<CampfireSmokeParticle> {
|
||||||
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:campfire_cosy_smoke".asResourceLocation()
|
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:campfire_cosy_smoke".asResourceLocation()
|
||||||
|
|
||||||
override fun build(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, velocity: Vec3, data: ParticleData): CampfireSmokeParticle {
|
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<CampfireSmokeParticle> {
|
object SignalFactory : ParticleFactory<CampfireSmokeParticle> {
|
||||||
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:campfire_signal_smoke".asResourceLocation()
|
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:campfire_signal_smoke".asResourceLocation()
|
||||||
|
|
||||||
override fun build(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, velocity: Vec3, data: ParticleData): CampfireSmokeParticle {
|
override fun build(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, velocity: Vec3, data: ParticleData): CampfireSmokeParticle {
|
||||||
|
@ -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.gui.rendering.util.VecUtil.EMPTY
|
||||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||||
import de.bixilon.minosoft.util.KUtil.asResourceLocation
|
import de.bixilon.minosoft.util.KUtil.asResourceLocation
|
||||||
import de.bixilon.minosoft.util.KUtil.millis
|
|
||||||
import glm_.vec3.Vec3
|
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 {
|
init {
|
||||||
movement = false
|
movement = false
|
||||||
maxAge = (6 + random.nextInt(4)).millis
|
maxAge = 6 + random.nextInt(4)
|
||||||
val gray = random.nextFloat() * 0.6f + 0.4f
|
val gray = random.nextFloat() * 0.6f + 0.4f
|
||||||
color = gray.asGray()
|
color = gray.asGray()
|
||||||
scale = 2.0f * (power - gray * 0.5f)
|
scale = 2.0f * (power - gray * 0.5f)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object : ParticleFactory<ExplosionLargeParticle> {
|
companion object : ParticleFactory<ExplosionParticle> {
|
||||||
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:explosion".asResourceLocation()
|
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:explosion".asResourceLocation()
|
||||||
|
|
||||||
override fun build(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, velocity: Vec3, data: ParticleData): ExplosionLargeParticle {
|
override fun build(connection: PlayConnection, particleRenderer: ParticleRenderer, position: Vec3, velocity: Vec3, data: ParticleData): ExplosionParticle {
|
||||||
return ExplosionLargeParticle(connection, particleRenderer, position, data, velocity.x)
|
return ExplosionParticle(connection, particleRenderer, position, data, velocity.x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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<SmokeParticle> {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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<LavaParticle> {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -35,6 +35,7 @@ import glm_.vec2.Vec2
|
|||||||
import glm_.vec2.Vec2i
|
import glm_.vec2.Vec2i
|
||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
import glm_.vec3.Vec3i
|
import glm_.vec3.Vec3i
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
object VecUtil {
|
object VecUtil {
|
||||||
val Vec3.Companion.EMPTY: Vec3
|
val Vec3.Companion.EMPTY: Vec3
|
||||||
@ -351,4 +352,15 @@ object VecUtil {
|
|||||||
Axes.Z -> this.z
|
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
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user