From 9c0bd44f1462a074975d7d23f0a16564337bc688 Mon Sep 17 00:00:00 2001 From: Byte Dice Date: Thu, 14 Nov 2024 21:13:17 +0100 Subject: [PATCH] holy shit i can spawn invisible particles --- .../bytedice/bde_particles/Bde_particles.kt | 34 ++++++++--- .../items/ParticleEmitterTool.kt | 8 ++- .../com/bytedice/bde_particles/math/main.kt | 61 +++++++++++++++++++ .../bde_particles/particle/Particle.kt | 44 +++++++++++-- .../bde_particles/particle/ParticleEmitter.kt | 21 +++++++ .../particle/ParticleEmitterParams.kt | 19 +++--- .../bde_particles/particle/ParticleParams.kt | 3 +- .../particle/particleIdRegister.kt | 5 ++ 8 files changed, 170 insertions(+), 25 deletions(-) create mode 100644 src/main/kotlin/com/bytedice/bde_particles/particle/ParticleEmitter.kt diff --git a/src/main/kotlin/com/bytedice/bde_particles/Bde_particles.kt b/src/main/kotlin/com/bytedice/bde_particles/Bde_particles.kt index 1fe50ec..774fc2a 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/Bde_particles.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/Bde_particles.kt @@ -2,8 +2,8 @@ package com.bytedice.bde_particles import com.bytedice.bde_particles.commands.GiveParticleEmitter import com.bytedice.bde_particles.items.getToolDetails -import com.bytedice.bde_particles.particle.Particle -import com.bytedice.bde_particles.particle.returnParticleFunction +import com.bytedice.bde_particles.math.raycastFromPlayer +import com.bytedice.bde_particles.particle.* import net.fabricmc.api.ModInitializer import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents @@ -12,10 +12,13 @@ import net.fabricmc.fabric.api.event.player.UseItemCallback import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack import net.minecraft.server.MinecraftServer +import net.minecraft.server.network.ServerPlayerEntity +import net.minecraft.server.world.ServerWorld import net.minecraft.text.Text import net.minecraft.util.ActionResult import net.minecraft.util.Hand import net.minecraft.util.TypedActionResult +import net.minecraft.world.World // const val ALL_PARTICLE_EMITTERS: Array<> // ParticleEmitter @@ -31,6 +34,8 @@ val cfg = Config() class Bde_particles : ModInitializer { override fun onInitialize() { + init() + ServerTickEvents.START_SERVER_TICK.register { _ -> tick() } @@ -39,8 +44,8 @@ class Bde_particles : ModInitializer { GiveParticleEmitter.register(dispatcher, registryAccess) } - UseItemCallback.EVENT.register(UseItemCallback { player: PlayerEntity, _, hand: Hand -> - onRightClick(player, hand) + UseItemCallback.EVENT.register(UseItemCallback { player: PlayerEntity, world: World, hand: Hand -> + onRightClick(player, world as ServerWorld, hand) }) ServerLifecycleEvents.SERVER_STARTED.register(ServerLifecycleEvents.ServerStarted { server: MinecraftServer -> @@ -52,19 +57,32 @@ class Bde_particles : ModInitializer { } +fun init() { + addToParticleRegister("DEBUG", ParticleEmitterParams()) +} + + fun tick() { } -fun onRightClick(player: PlayerEntity, hand: Hand) : TypedActionResult { +fun onRightClick(player: PlayerEntity, world: ServerWorld, hand: Hand) : TypedActionResult { val handItem = player.getStackInHand(hand) val (isEmitterTool, particleId) = getToolDetails(handItem) + val hitResult = raycastFromPlayer(player as ServerPlayerEntity, 50.0) + val emitterParams = getParticleEmitterParams(particleId) - if (isEmitterTool) { - val particleFunction = returnParticleFunction(particleId) - if (particleFunction != null) { /* spawn particle with params */ } + if ( + !isEmitterTool + || emitterParams == null + || hitResult == null + ) { + return TypedActionResult(ActionResult.PASS, handItem) } + val emitter = ParticleEmitter(hitResult.pos, world, emitterParams) + emitter.tick() + return TypedActionResult(ActionResult.PASS, handItem) } \ No newline at end of file diff --git a/src/main/kotlin/com/bytedice/bde_particles/items/ParticleEmitterTool.kt b/src/main/kotlin/com/bytedice/bde_particles/items/ParticleEmitterTool.kt index 7cc4ef0..9011bf5 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/items/ParticleEmitterTool.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/items/ParticleEmitterTool.kt @@ -42,7 +42,11 @@ fun getToolDetails(item: ItemStack) : Pair { val isParticleEmitterTool = customData?.nbt?.getByte("BPS_particleTool") == 1.toByte() val particleId = customData?.nbt?.getString("BPS_particleId") - if (particleId == null) { return Pair(isParticleEmitterTool, "") } + return if (particleId == null) { + Pair(isParticleEmitterTool, "") + } - else { return Pair(isParticleEmitterTool, particleId) } + else { + Pair(isParticleEmitterTool, particleId) + } } \ No newline at end of file diff --git a/src/main/kotlin/com/bytedice/bde_particles/math/main.kt b/src/main/kotlin/com/bytedice/bde_particles/math/main.kt index bb70cf6..0140e48 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/math/main.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/math/main.kt @@ -5,6 +5,13 @@ import net.minecraft.util.hit.HitResult import net.minecraft.util.math.Vec3d import net.minecraft.world.RaycastContext import net.minecraft.world.World +import org.joml.Vector3f +import org.joml.Vector4f +import kotlin.math.asin +import kotlin.math.atan2 +import kotlin.math.cos +import kotlin.math.sin +import kotlin.random.Random fun raycastFromPlayer(player: ServerPlayerEntity, maxDistance: Double): HitResult? { @@ -28,4 +35,58 @@ fun raycastFromPlayer(player: ServerPlayerEntity, maxDistance: Double): HitResul } else { null } +} + + +fun randomFloatBetween(min: Float, max: Float) : Float { + return Random.nextFloat() * (max - min) + min +} + + +fun eulerToQuat(euler: Vector3f): Vector4f { + val roll = euler.x + val pitch = euler.y + val yaw = euler.z + + val cy = cos(yaw * 0.5) + val sy = sin(yaw * 0.5) + val cp = cos(pitch * 0.5) + val sp = sin(pitch * 0.5) + val cr = cos(roll * 0.5) + val sr = sin(roll * 0.5) + + val w = cr * cp * cy + sr * sp * sy + val x = sr * cp * cy - cr * sp * sy + val y = cr * sp * cy + sr * cp * sy + val z = cr * cp * sy - sr * sp * cy + + return Vector4f(x.toFloat(), y.toFloat(), z.toFloat(), w.toFloat()) +} + +fun quatToEuler(quat: Vector4f): Vector3f { + val x = quat.x + val y = quat.y + val z = quat.z + val w = quat.w + + // Roll (X-axis rotation) + val sinr_cosp = 2 * (w * x + y * z) + val cosr_cosp = 1 - 2 * (x * x + y * y) + val roll = atan2(sinr_cosp, cosr_cosp) + + // Pitch (Y-axis rotation) + val sinp = 2 * (w * y - z * x) + val pitch = if (kotlin.math.abs(sinp) >= 1) { + // Use 90 degrees if out of range + kotlin.math.sign(sinp) * (Math.PI.toFloat() / 2) + } else { + asin(sinp) + } + + // Yaw (Z-axis rotation) + val siny_cosp = 2 * (w * z + x * y) + val cosy_cosp = 1 - 2 * (y * y + z * z) + val yaw = atan2(siny_cosp, cosy_cosp) + + return Vector3f(roll, pitch, yaw) } \ No newline at end of file diff --git a/src/main/kotlin/com/bytedice/bde_particles/particle/Particle.kt b/src/main/kotlin/com/bytedice/bde_particles/particle/Particle.kt index da2da7f..964bcfb 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/particle/Particle.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/particle/Particle.kt @@ -1,15 +1,51 @@ package com.bytedice.bde_particles.particle +import com.bytedice.bde_particles.DisplayEntity +import com.bytedice.bde_particles.DisplayEntityProperties +import com.bytedice.bde_particles.math.eulerToQuat +import com.bytedice.bde_particles.math.randomFloatBetween +import net.minecraft.server.world.ServerWorld import net.minecraft.util.math.Vec3d import org.joml.Vector3f -import org.joml.Vector4f + class Particle(particleParams: ParticleParams) { - fun init() { + val rot = Vector3f( + randomFloatBetween(particleParams.rotRandom.first.x, particleParams.rotRandom.second.x), + randomFloatBetween(particleParams.rotRandom.first.y, particleParams.rotRandom.second.x), + randomFloatBetween(particleParams.rotRandom.first.z, particleParams.rotRandom.second.z) + ) + val rotVel = Vector3f( + randomFloatBetween(particleParams.rotVelRandom.first.x, particleParams.rotVelRandom.second.x), + randomFloatBetween(particleParams.rotVelRandom.first.y, particleParams.rotVelRandom.second.x), + randomFloatBetween(particleParams.rotVelRandom.first.z, particleParams.rotVelRandom.second.z) + ) + val size = Vector3f( + randomFloatBetween(particleParams.sizeRandom.first.x, particleParams.sizeRandom.second.x), + randomFloatBetween(particleParams.sizeRandom.first.y, particleParams.sizeRandom.second.x), + randomFloatBetween(particleParams.sizeRandom.first.z, particleParams.sizeRandom.second.z) + ) + var blockDisplay: DisplayEntity? = null + val params = particleParams + fun init(pos: Vec3d) { + val properties = DisplayEntityProperties( + pos = pos, + blockType = this.params.blockCurve[0], + leftRotation = eulerToQuat(rot), + scale = size + ) + + blockDisplay = DisplayEntity(properties) } - fun registerEmitter(id: String, params: ParticleEmitterParams) { - addToParticleRegister(id, params) + + fun spawn(world: ServerWorld) { + blockDisplay?.spawn(world) + } + + + fun tick() { + } } \ No newline at end of file diff --git a/src/main/kotlin/com/bytedice/bde_particles/particle/ParticleEmitter.kt b/src/main/kotlin/com/bytedice/bde_particles/particle/ParticleEmitter.kt new file mode 100644 index 0000000..fc79465 --- /dev/null +++ b/src/main/kotlin/com/bytedice/bde_particles/particle/ParticleEmitter.kt @@ -0,0 +1,21 @@ +package com.bytedice.bde_particles.particle + +import net.minecraft.server.world.ServerWorld +import net.minecraft.util.math.Vec3d + +class ParticleEmitter(emitterPos: Vec3d, emitterWorld: ServerWorld, emitterParams: ParticleEmitterParams) { + val world = emitterWorld + val pos = emitterPos + val params = emitterParams + val allParticles: Array = emptyArray() + val timeAlive = 0 + + + fun tick() { + repeat(this.params.spawnsPerTick) { + val particle = Particle(ParticleParams()) + particle.init(this.pos) + particle.spawn(world) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/bytedice/bde_particles/particle/ParticleEmitterParams.kt b/src/main/kotlin/com/bytedice/bde_particles/particle/ParticleEmitterParams.kt index be31dca..fb4ce4c 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/particle/ParticleEmitterParams.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/particle/ParticleEmitterParams.kt @@ -1,12 +1,11 @@ package com.bytedice.bde_particles.particle -class ParticleEmitterParams { - data class init ( - val maxCount: Int = 20, - val spawnDur: Int = 20, - val particleTypes: Array = emptyArray(), - val loop: Boolean = false, - val loopDelay: Int = 10, - val loopCount: Int = 2, - ) -} \ No newline at end of file +data class ParticleEmitterParams ( + val maxCount: Int = 100, + val spawnsPerTick: Int = 1, + val particleTypes: Array = emptyArray(), + val loop: Boolean = false, + val loopDur: Int = 1, + val loopDelay: Int = 10, + val loopCount: Int = 2, +) \ No newline at end of file diff --git a/src/main/kotlin/com/bytedice/bde_particles/particle/ParticleParams.kt b/src/main/kotlin/com/bytedice/bde_particles/particle/ParticleParams.kt index fbfe38d..e78450c 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/particle/ParticleParams.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/particle/ParticleParams.kt @@ -6,7 +6,8 @@ import org.joml.Vector3f data class ParticleParams ( //val shape: Shape, // add later, start with single point val blockCurve: Array = arrayOf("minecraft:black_concrete", "minecraft:green_concrete"), - val rotVelRandom: Pair = Pair(Vector3f(0.0f, 0.0f, 0.0f), Vector3f(360.0f, 360.0f, 360.0f)), + val rotRandom: Pair = Pair(Vector3f(0.0f, 0.0f, 0.0f), Vector3f(360.0f, 360.0f, 360.0f)), + val rotVelRandom: Pair = Pair(Vector3f(1.0f, 1.0f, 1.0f), Vector3f(5.0f, 5.0f, 5.0f)), val rotVelCurve: Array = arrayOf(Vector3f(1.0f, 1.0f, 1.0f), Vector3f(0.0f, 0.0f, 0.0f)), val sizeRandom: Pair = Pair(Vector3f(0.5f, 0.5f, 0.5f), Vector3f(1.0f, 1.0f, 1.0f)), val sizeCurve: Array = arrayOf(Vector3f(1.0f, 1.0f, 1.0f), Vector3f(0.0f, 0.0f, 0.0f)), diff --git a/src/main/kotlin/com/bytedice/bde_particles/particle/particleIdRegister.kt b/src/main/kotlin/com/bytedice/bde_particles/particle/particleIdRegister.kt index 3ed2d2b..694d8c2 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/particle/particleIdRegister.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/particle/particleIdRegister.kt @@ -13,4 +13,9 @@ fun returnParticleFunction(id: String) : ParticleEmitterParams? { fun addToParticleRegister(id: String, params: ParticleEmitterParams) { particleIdRegister[id] = params +} + + +fun getParticleEmitterParams(id: String) : ParticleEmitterParams? { + return particleIdRegister[id] } \ No newline at end of file