diff --git a/src/main/java/de/bixilon/minosoft/data/world/World.kt b/src/main/java/de/bixilon/minosoft/data/world/World.kt index 88179d46f..f4ca85c43 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/World.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/World.kt @@ -57,7 +57,7 @@ class World( val connection: PlayConnection, ) : WorldAudioPlayer, WorldParticleRenderer { val lock = SimpleLock() - val random = Random() + override val random = Random() val biomes = WorldBiomes(this) val chunks = ChunkManager(this, 1000, 100) val entities = WorldEntities() diff --git a/src/main/java/de/bixilon/minosoft/data/world/particle/AbstractParticleRenderer.kt b/src/main/java/de/bixilon/minosoft/data/world/particle/AbstractParticleRenderer.kt index 8c90e9017..2d5654e20 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/particle/AbstractParticleRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/particle/AbstractParticleRenderer.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -14,8 +14,10 @@ package de.bixilon.minosoft.data.world.particle import de.bixilon.minosoft.gui.rendering.particle.types.Particle +import java.util.* interface AbstractParticleRenderer { + val random: Random fun addParticle(particle: Particle) 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 71276f369..d0ecc9e60 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,57 +14,27 @@ package de.bixilon.minosoft.gui.rendering.particle import de.bixilon.kotlinglm.vec3.Vec3d -import de.bixilon.kutil.concurrent.pool.DefaultThreadPool import de.bixilon.minosoft.config.profile.profiles.particle.ParticleProfile import de.bixilon.minosoft.gui.rendering.particle.types.norender.ExplosionEmitterParticle import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.explosion.ExplosionParticle -import de.bixilon.minosoft.gui.rendering.util.VecUtil.times import de.bixilon.minosoft.modding.event.events.ExplosionEvent -import de.bixilon.minosoft.modding.event.events.ParticleSpawnEvent -import de.bixilon.minosoft.modding.event.listener.CallbackEventListener +import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection -import java.util.* object DefaultParticleBehavior { fun register(connection: PlayConnection, renderer: ParticleRenderer) { - val random = Random() val profile = connection.profiles.particle - val invokers = listOf( - connection.explosion(renderer, random, profile), - - CallbackEventListener.of { - DefaultThreadPool += add@{ - fun spawn(position: Vec3d, velocity: Vec3d) { - val factory = it.data.type.factory ?: return - renderer += factory.build(connection, position, velocity, it.data) ?: return - } - // ToDo: long distance = always spawn? - if (it.count == 0) { - val velocity = it.offset * it.speed - - spawn(it.position, Vec3d(velocity)) - } else { - for (i in 0 until it.count) { - val offset = Vec3d(it.offset) * { random.nextGaussian() } - val velocity = Vec3d(it.speed) * { random.nextGaussian() } - - spawn(it.position + offset, velocity) - } - } - } - }, - ) - connection.events.register(*invokers.filterNotNull().toTypedArray()) + connection.explosion(renderer, profile) } - private fun PlayConnection.explosion(renderer: ParticleRenderer, random: Random, profile: ParticleProfile): CallbackEventListener<*>? { - val explosion = registries.particleType[ExplosionParticle] ?: return null - val emitter = registries.particleType[ExplosionEmitterParticle] ?: return null + private fun PlayConnection.explosion(renderer: ParticleRenderer, profile: ParticleProfile) { + val explosion = registries.particleType[ExplosionParticle] ?: return + val emitter = registries.particleType[ExplosionEmitterParticle] ?: return - return CallbackEventListener.of { + this.listen { if (!profile.types.explosions) { - return@of + return@listen } if (it.power >= 2.0f) { renderer += ExplosionEmitterParticle(this, Vec3d(it.position), emitter.default()) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt index 8a34a438d..c4446d43b 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt @@ -33,12 +33,14 @@ import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companio import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.packets.s2c.play.block.chunk.ChunkUtil.isInViewDistance import de.bixilon.minosoft.util.collections.floats.BufferedArrayFloatList +import java.util.* class ParticleRenderer( private val connection: PlayConnection, override val context: RenderContext, ) : WorldRenderer, AsyncRenderer, SkipAll, AbstractParticleRenderer { + override val random = Random() override val layers = LayerSettings() override val renderSystem: RenderSystem = context.system private val profile = connection.profiles.particle diff --git a/src/main/java/de/bixilon/minosoft/modding/event/events/ParticleSpawnEvent.kt b/src/main/java/de/bixilon/minosoft/modding/event/events/ParticleSpawnEvent.kt deleted file mode 100644 index 3f72876e0..000000000 --- a/src/main/java/de/bixilon/minosoft/modding/event/events/ParticleSpawnEvent.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Minosoft - * Copyright (C) 2020-2023 Moritz Zwerger - * - * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with this program. If not, see . - * - * This software is not affiliated with Mojang AB, the original developer of Minecraft. - */ -package de.bixilon.minosoft.modding.event.events - -import de.bixilon.kotlinglm.vec3.Vec3 -import de.bixilon.kotlinglm.vec3.Vec3d -import de.bixilon.minosoft.data.registries.particle.data.ParticleData -import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent -import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection -import de.bixilon.minosoft.protocol.packets.s2c.play.world.ParticleS2CP - -class ParticleSpawnEvent( - connection: PlayConnection, - position: Vec3d, - offset: Vec3, - val speed: Float, - val count: Int, - val data: ParticleData, -) : PlayConnectionEvent(connection), CancelableEvent { - val position: Vec3d = position - get() = Vec3d(field) - val offset: Vec3 = offset - get() = Vec3(field) - - constructor(connection: PlayConnection, packet: ParticleS2CP) : this(connection, packet.position, packet.offset, packet.speed, packet.count, packet.data) -} diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/world/ParticleS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/world/ParticleS2CP.kt index ca326cdf3..42a1067de 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/world/ParticleS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/world/ParticleS2CP.kt @@ -15,7 +15,7 @@ package de.bixilon.minosoft.protocol.packets.s2c.play.world import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.kotlinglm.vec3.Vec3d import de.bixilon.minosoft.data.registries.particle.data.ParticleData -import de.bixilon.minosoft.modding.event.events.ParticleSpawnEvent +import de.bixilon.minosoft.gui.rendering.util.VecUtil.times import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket import de.bixilon.minosoft.protocol.protocol.ProtocolVersions @@ -48,8 +48,21 @@ class ParticleS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { if (!connection.profiles.particle.types.packet) { return } - if (connection.events.fire(ParticleSpawnEvent(connection, this))) { - return + val renderer = connection.world.particle ?: return + + fun spawn(position: Vec3d, velocity: Vec3d) { + val factory = data.type.factory ?: return + renderer += factory.build(connection, position, velocity, data) ?: return + } + + if (count <= 1) { + return spawn(position, Vec3d(offset * speed)) + } + for (i in 0 until count) { + val offset = Vec3d(offset) * { renderer.random.nextGaussian() } + val velocity = Vec3d(speed) * { renderer.random.nextGaussian() } + + spawn(position + offset, velocity) } }