holy shit i can spawn invisible particles

This commit is contained in:
2024-11-14 21:13:17 +01:00
parent cbcff4e157
commit 9c0bd44f14
8 changed files with 170 additions and 25 deletions
@@ -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<ItemStack> {
fun onRightClick(player: PlayerEntity, world: ServerWorld, hand: Hand) : TypedActionResult<ItemStack> {
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)
}
@@ -42,7 +42,11 @@ fun getToolDetails(item: ItemStack) : Pair<Boolean, String> {
val isParticleEmitterTool = customData?.nbt?.getByte("BPS_particleTool") == 1.toByte()
val particleId = customData?.nbt?.getString("BPS_particleId")
if (particleId == null) { return Pair(isParticleEmitterTool, "") }
else { return Pair(isParticleEmitterTool, particleId) }
return if (particleId == null) {
Pair(isParticleEmitterTool, "")
}
else {
Pair(isParticleEmitterTool, particleId)
}
}
@@ -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? {
@@ -29,3 +36,57 @@ fun raycastFromPlayer(player: ServerPlayerEntity, maxDistance: Double): HitResul
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)
}
@@ -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() {
}
}
@@ -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<Particle> = emptyArray()
val timeAlive = 0
fun tick() {
repeat(this.params.spawnsPerTick) {
val particle = Particle(ParticleParams())
particle.init(this.pos)
particle.spawn(world)
}
}
}
@@ -1,12 +1,11 @@
package com.bytedice.bde_particles.particle
class ParticleEmitterParams {
data class init (
val maxCount: Int = 20,
val spawnDur: Int = 20,
data class ParticleEmitterParams (
val maxCount: Int = 100,
val spawnsPerTick: Int = 1,
val particleTypes: Array<Particle> = emptyArray(),
val loop: Boolean = false,
val loopDur: Int = 1,
val loopDelay: Int = 10,
val loopCount: Int = 2,
)
}
@@ -6,7 +6,8 @@ import org.joml.Vector3f
data class ParticleParams (
//val shape: Shape, // add later, start with single point
val blockCurve: Array<String> = arrayOf("minecraft:black_concrete", "minecraft:green_concrete"),
val rotVelRandom: Pair<Vector3f, Vector3f> = Pair(Vector3f(0.0f, 0.0f, 0.0f), Vector3f(360.0f, 360.0f, 360.0f)),
val rotRandom: Pair<Vector3f, Vector3f> = Pair(Vector3f(0.0f, 0.0f, 0.0f), Vector3f(360.0f, 360.0f, 360.0f)),
val rotVelRandom: Pair<Vector3f, Vector3f> = Pair(Vector3f(1.0f, 1.0f, 1.0f), Vector3f(5.0f, 5.0f, 5.0f)),
val rotVelCurve: Array<Vector3f> = arrayOf(Vector3f(1.0f, 1.0f, 1.0f), Vector3f(0.0f, 0.0f, 0.0f)),
val sizeRandom: Pair<Vector3f, Vector3f> = Pair(Vector3f(0.5f, 0.5f, 0.5f), Vector3f(1.0f, 1.0f, 1.0f)),
val sizeCurve: Array<Vector3f> = arrayOf(Vector3f(1.0f, 1.0f, 1.0f), Vector3f(0.0f, 0.0f, 0.0f)),
@@ -14,3 +14,8 @@ fun returnParticleFunction(id: String) : ParticleEmitterParams? {
fun addToParticleRegister(id: String, params: ParticleEmitterParams) {
particleIdRegister[id] = params
}
fun getParticleEmitterParams(id: String) : ParticleEmitterParams? {
return particleIdRegister[id]
}