bugfixes
This commit is contained in:
@@ -163,7 +163,8 @@ fun onRightClick(player: PlayerEntity, world: ServerWorld, hand: Hand) : TypedAc
|
|||||||
return TypedActionResult(ActionResult.PASS, handItem)
|
return TypedActionResult(ActionResult.PASS, handItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
val emitter = ParticleEmitter(hitResult.pos, Vector2f(0.0f, 0.0f), world, emitterParams)
|
val debug = world.gameRules.getBoolean(Bde_particles.SHOW_PARTICLE_DEBUG)
|
||||||
|
val emitter = ParticleEmitter(hitResult.pos, Vector2f(0.0f, 0.0f), world, emitterParams, debug)
|
||||||
ALL_PARTICLE_EMITTERS += emitter
|
ALL_PARTICLE_EMITTERS += emitter
|
||||||
|
|
||||||
return TypedActionResult(ActionResult.PASS, handItem)
|
return TypedActionResult(ActionResult.PASS, handItem)
|
||||||
|
|||||||
@@ -1,16 +1,11 @@
|
|||||||
package com.bytedice.bde_particles
|
package com.bytedice.bde_particles
|
||||||
|
|
||||||
import net.minecraft.component.Component
|
|
||||||
import net.minecraft.component.ComponentType
|
|
||||||
import net.minecraft.entity.EntityType
|
import net.minecraft.entity.EntityType
|
||||||
import net.minecraft.entity.decoration.DisplayEntity.ItemDisplayEntity
|
import net.minecraft.entity.decoration.DisplayEntity.ItemDisplayEntity
|
||||||
import net.minecraft.item.Item
|
|
||||||
import net.minecraft.nbt.NbtCompound
|
import net.minecraft.nbt.NbtCompound
|
||||||
import net.minecraft.nbt.NbtFloat
|
import net.minecraft.nbt.NbtFloat
|
||||||
import net.minecraft.nbt.NbtList
|
import net.minecraft.nbt.NbtList
|
||||||
import net.minecraft.nbt.NbtString
|
import net.minecraft.nbt.NbtString
|
||||||
import net.minecraft.registry.Registries
|
|
||||||
import net.minecraft.registry.Registry
|
|
||||||
import net.minecraft.server.world.ServerWorld
|
import net.minecraft.server.world.ServerWorld
|
||||||
|
|
||||||
class DisplayEntity(private var properties: DisplayEntityProperties?) {
|
class DisplayEntity(private var properties: DisplayEntityProperties?) {
|
||||||
@@ -38,7 +33,7 @@ class DisplayEntity(private var properties: DisplayEntityProperties?) {
|
|||||||
|
|
||||||
if (matchResult != null) {
|
if (matchResult != null) {
|
||||||
modelName = matchResult.groupValues[1]
|
modelName = matchResult.groupValues[1]
|
||||||
customModelNum = matchResult.groupValues[2].toInt()
|
customModelNum = matchResult.groupValues[2].toIntOrNull() ?: 0
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
modelName = properties.model
|
modelName = properties.model
|
||||||
@@ -92,6 +87,10 @@ class DisplayEntity(private var properties: DisplayEntityProperties?) {
|
|||||||
|
|
||||||
put("view_range", NbtCompound().apply { properties.viewRange })
|
put("view_range", NbtCompound().apply { properties.viewRange })
|
||||||
|
|
||||||
|
if (properties.name != null) {
|
||||||
|
putString("CustomName", properties.name)
|
||||||
|
putByte("CustomNameVisible", 1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
entity?.readNbt(nbt)
|
entity?.readNbt(nbt)
|
||||||
|
|||||||
@@ -17,5 +17,6 @@ data class DisplayEntityProperties (
|
|||||||
val scale: Vector3f = Vector3f(1.0f, 1.0f, 1.0f),
|
val scale: Vector3f = Vector3f(1.0f, 1.0f, 1.0f),
|
||||||
val rightRotation: Vector4f = Vector4f(0.0f, 0.0f, 0.0f, 1.0f),
|
val rightRotation: Vector4f = Vector4f(0.0f, 0.0f, 0.0f, 1.0f),
|
||||||
|
|
||||||
val viewRange: Float = 2.0f
|
val viewRange: Float = 2.0f,
|
||||||
|
var name: String? = null
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import kotlin.random.Random
|
|||||||
|
|
||||||
class LerpCurves(val function: (Float) -> Float) {
|
class LerpCurves(val function: (Float) -> Float) {
|
||||||
companion object {
|
companion object {
|
||||||
|
val Constant = LerpCurves { _ -> 1.0f }
|
||||||
val Linear = LerpCurves { y -> y }
|
val Linear = LerpCurves { y -> y }
|
||||||
val Sqrt = LerpCurves { y -> sqrt(y) }
|
val Sqrt = LerpCurves { y -> sqrt(y) }
|
||||||
val Exponent = LerpCurves { y -> y.pow(2.0f) }
|
val Exponent = LerpCurves { y -> y.pow(2.0f) }
|
||||||
@@ -166,7 +167,8 @@ fun transformOffsetByScale(offset: Vector3f, scale: Vector3f): Vector3f {
|
|||||||
|
|
||||||
|
|
||||||
fun lerp(x: Float, y: Float, t: Float) : Float {
|
fun lerp(x: Float, y: Float, t: Float) : Float {
|
||||||
return x + (y - x) * t
|
val clampedT = t.coerceIn(0f, 1f)
|
||||||
|
return x + (y - x) * clampedT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ data class EmitterParams (
|
|||||||
{
|
{
|
||||||
companion object Presets {
|
companion object Presets {
|
||||||
val DEFAULT = EmitterParams(
|
val DEFAULT = EmitterParams(
|
||||||
maxCount = 400,
|
maxCount = 200,
|
||||||
spawnRate = 100,
|
spawnRate = 50,
|
||||||
spawnChance = 1.0f,
|
spawnChance = 1.0f,
|
||||||
spawnDuration = ParamClasses.Duration.SingleBurst(4),
|
spawnDuration = ParamClasses.Duration.SingleBurst(4),
|
||||||
spawnPosOffset = Vector3f(0.0f, 0.0f, 0.0f),
|
spawnPosOffset = Vector3f(0.0f, 0.0f, 0.0f),
|
||||||
@@ -47,15 +47,15 @@ data class EmitterParams (
|
|||||||
rotVel = ParamClasses.PairVec3f.NonUniform(-0.2f, -0.2f, -0.2f, 0.2f, 0.2f, 0.2f),
|
rotVel = ParamClasses.PairVec3f.NonUniform(-0.2f, -0.2f, -0.2f, 0.2f, 0.2f, 0.2f),
|
||||||
initVel = ParamClasses.PairVec3f.Null,
|
initVel = ParamClasses.PairVec3f.Null,
|
||||||
initCenterVel = ParamClasses.PairFloat(0.4f, 0.5f),
|
initCenterVel = ParamClasses.PairFloat(0.4f, 0.5f),
|
||||||
initScale = ParamClasses.PairVec3f.Uniform(1.5f, 1.0f),
|
initScale = ParamClasses.PairVec3f.Uniform(0.5f, 1.5f),
|
||||||
transformWithVel = ParamClasses.TransformWithVel.none,
|
transformWithVel = ParamClasses.TransformWithVel.None,
|
||||||
forceFields = emptyArray(),
|
forceFields = emptyArray(),
|
||||||
constVel = Vector3f(0.0f, 0.0f, 0.0f),
|
constVel = Vector3f(0.0f, 0.0f, 0.0f),
|
||||||
drag = 0.075f,
|
drag = 0.075f,
|
||||||
minVel = 0.0f,
|
minVel = 0.0f,
|
||||||
offsetCurve = ParamClasses.LerpVal.NoLerpVec3f,
|
offsetCurve = ParamClasses.LerpVal.NoLerpVec3f,
|
||||||
rotVelCurve = ParamClasses.LerpVal.LerpUniform(1.0f, 0.0f, LerpCurves.Sqrt),
|
rotVelCurve = ParamClasses.LerpVal.LerpUniform(1.0f, 0.0f, LerpCurves.Sqrt),
|
||||||
scaleCurve = ParamClasses.LerpVal.LerpUniform(0.0f, 2.0f, LerpCurves.Linear),
|
scaleCurve = ParamClasses.LerpVal.LerpUniform(1.0f, 2.5f, LerpCurves.Constant),
|
||||||
modelCurve = Pair(
|
modelCurve = Pair(
|
||||||
arrayOf("shroomlight", "orange_concrete", "orange_stained_glass", "gray_wool", "gray_stained_glass", "light_gray_stained_glass", "light_gray_stained_glass_pane"),
|
arrayOf("shroomlight", "orange_concrete", "orange_stained_glass", "gray_wool", "gray_stained_glass", "light_gray_stained_glass", "light_gray_stained_glass_pane"),
|
||||||
LerpCurves.Sqrt
|
LerpCurves.Sqrt
|
||||||
|
|||||||
@@ -119,8 +119,8 @@ class ParamClasses {
|
|||||||
) : Duration()
|
) : Duration()
|
||||||
}
|
}
|
||||||
enum class TransformWithVel {
|
enum class TransformWithVel {
|
||||||
rotOnly,
|
RotOnly,
|
||||||
scaleAndRot,
|
ScaleAndRot,
|
||||||
none
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.bytedice.bde_particles.particles
|
package com.bytedice.bde_particles.particles
|
||||||
|
|
||||||
import com.bytedice.bde_particles.*
|
import com.bytedice.bde_particles.*
|
||||||
|
import net.minecraft.particle.DustParticleEffect
|
||||||
import net.minecraft.server.world.ServerWorld
|
import net.minecraft.server.world.ServerWorld
|
||||||
import net.minecraft.util.math.Vec3d
|
import net.minecraft.util.math.Vec3d
|
||||||
import org.joml.Vector2f
|
import org.joml.Vector2f
|
||||||
@@ -61,8 +62,6 @@ class Particle(
|
|||||||
private var lifeTime = emitterParams.lifeTime.randomize()
|
private var lifeTime = emitterParams.lifeTime.randomize()
|
||||||
|
|
||||||
private lateinit var particleEntity: DisplayEntity
|
private lateinit var particleEntity: DisplayEntity
|
||||||
private lateinit var debugOriginEntity: DisplayEntity
|
|
||||||
private lateinit var debugVelEntity: DisplayEntity
|
|
||||||
|
|
||||||
fun init() {
|
fun init() {
|
||||||
val so = emitterParams.spawnPosOffset
|
val so = emitterParams.spawnPosOffset
|
||||||
@@ -86,7 +85,7 @@ class Particle(
|
|||||||
model = lerpArray(emitterParams.modelCurve.first as Array<Any>, 0.0f, emitterParams.modelCurve.second) as String,
|
model = lerpArray(emitterParams.modelCurve.first as Array<Any>, 0.0f, emitterParams.modelCurve.second) as String,
|
||||||
translation = newPos.add(pos),
|
translation = newPos.add(pos),
|
||||||
leftRotation = quatRot,
|
leftRotation = quatRot,
|
||||||
scale = scale,
|
scale = Vector3f(scale).mul(emitterParams.scaleCurve.lerpToVector3f(0.0f)),
|
||||||
tags = arrayOf("BPS_Particle", "BPS_UUID", SESSION_UUID.toString())
|
tags = arrayOf("BPS_Particle", "BPS_UUID", SESSION_UUID.toString())
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -105,7 +104,7 @@ class Particle(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun tick() {
|
fun tick(world: ServerWorld) {
|
||||||
if (!isInit) { error("Particle is not initialized before being ticked. Please use Particle.init() to initialize it.") }
|
if (!isInit) { error("Particle is not initialized before being ticked. Please use Particle.init() to initialize it.") }
|
||||||
|
|
||||||
val newProperties = calcNewProperties()
|
val newProperties = calcNewProperties()
|
||||||
@@ -114,6 +113,10 @@ class Particle(
|
|||||||
|
|
||||||
if (timeAlive > lifeTime) { kill() }
|
if (timeAlive > lifeTime) { kill() }
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
tickDebug(world)
|
||||||
|
}
|
||||||
|
|
||||||
timeAlive += 1
|
timeAlive += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +198,7 @@ class Particle(
|
|||||||
private fun calcRot(t: Float) : Vector3f {
|
private fun calcRot(t: Float) : Vector3f {
|
||||||
val newRot = Vector3f(rot)
|
val newRot = Vector3f(rot)
|
||||||
|
|
||||||
if (emitterParams.transformWithVel == ParamClasses.TransformWithVel.none) {
|
if (emitterParams.transformWithVel == ParamClasses.TransformWithVel.None) {
|
||||||
val newVel = Vector3f(rotVel)
|
val newVel = Vector3f(rotVel)
|
||||||
|
|
||||||
newVel.mul(emitterParams.rotVelCurve.lerpToVector3f(t))
|
newVel.mul(emitterParams.rotVelCurve.lerpToVector3f(t))
|
||||||
@@ -225,27 +228,46 @@ class Particle(
|
|||||||
|
|
||||||
private fun calcScale(t: Float) : Vector3f {
|
private fun calcScale(t: Float) : Vector3f {
|
||||||
val newScale = Vector3f(scale)
|
val newScale = Vector3f(scale)
|
||||||
newScale.mul(emitterParams.scaleCurve.lerpToVector3f(t))
|
return newScale.mul(emitterParams.scaleCurve.lerpToVector3f(t))
|
||||||
return scale
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun spawnDebug() {
|
private fun tickDebug(world: ServerWorld) {
|
||||||
// spawn cube at particle origin
|
// spawn particle at particle origin
|
||||||
// show arrow pointing toward particle direction
|
// show trail pointing toward particle direction
|
||||||
// name-tag its data
|
|
||||||
|
|
||||||
|
// origin debug
|
||||||
|
val greenDustEffect = DustParticleEffect(Vector3f(0.0f, 1.0f, 0.0f), 2.0f)
|
||||||
|
world.spawnParticles(
|
||||||
|
greenDustEffect,
|
||||||
|
entityPos.x + pos.x,
|
||||||
|
entityPos.y + pos.y,
|
||||||
|
entityPos.z + pos.z,
|
||||||
|
1,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
0.0
|
||||||
|
)
|
||||||
|
|
||||||
|
// vel debug
|
||||||
|
var timesLooped = 0
|
||||||
|
repeat(3) {
|
||||||
|
val redDustEffect = DustParticleEffect(Vector3f(1.0f, 0.0f, 0.0f), 1.0f)
|
||||||
|
world.spawnParticles(
|
||||||
|
redDustEffect,
|
||||||
|
entityPos.x + pos.x + originOffset.x + vel.x * timesLooped,
|
||||||
|
entityPos.y + pos.y + originOffset.y + vel.y * timesLooped,
|
||||||
|
entityPos.z + pos.z + originOffset.z + vel.z * timesLooped,
|
||||||
|
1,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
0.0
|
||||||
|
)
|
||||||
|
|
||||||
|
timesLooped += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun updateDebug() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun calcDebug() {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,13 @@ import net.minecraft.server.world.ServerWorld
|
|||||||
import net.minecraft.util.math.Vec3d
|
import net.minecraft.util.math.Vec3d
|
||||||
import org.joml.Vector2f
|
import org.joml.Vector2f
|
||||||
|
|
||||||
class ParticleEmitter(private val pos: Vec3d, private val rot: Vector2f, private val world: ServerWorld, private val params: EmitterParams) {
|
class ParticleEmitter(
|
||||||
|
private val pos: Vec3d,
|
||||||
|
private val rot: Vector2f,
|
||||||
|
private val world: ServerWorld,
|
||||||
|
private val params: EmitterParams,
|
||||||
|
private val debug: Boolean
|
||||||
|
) {
|
||||||
private var allParticles: Array<Particle> = emptyArray()
|
private var allParticles: Array<Particle> = emptyArray()
|
||||||
|
|
||||||
private var timeAlive = 0
|
private var timeAlive = 0
|
||||||
@@ -28,7 +33,7 @@ class ParticleEmitter(private val pos: Vec3d, private val rot: Vector2f, private
|
|||||||
|
|
||||||
for (particle in allParticles) {
|
for (particle in allParticles) {
|
||||||
if (particle.isDead) { allParticles = allParticles.toMutableList().apply { remove(particle) }.toTypedArray() }
|
if (particle.isDead) { allParticles = allParticles.toMutableList().apply { remove(particle) }.toTypedArray() }
|
||||||
else { particle.tick() }
|
else { particle.tick(world) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +50,6 @@ class ParticleEmitter(private val pos: Vec3d, private val rot: Vector2f, private
|
|||||||
val randomSpawnChance = randomFloatBetween(0.0f, params.spawnChance.coerceIn(0.0f, 1.0f))
|
val randomSpawnChance = randomFloatBetween(0.0f, params.spawnChance.coerceIn(0.0f, 1.0f))
|
||||||
if (randomSpawnChance > params.spawnChance) { return }
|
if (randomSpawnChance > params.spawnChance) { return }
|
||||||
|
|
||||||
val debug = world.gameRules.getBoolean(Bde_particles.SHOW_PARTICLE_DEBUG)
|
|
||||||
val particle = Particle(params, pos, rot, debug)
|
val particle = Particle(params, pos, rot, debug)
|
||||||
particle.init()
|
particle.init()
|
||||||
particle.spawn(world)
|
particle.spawn(world)
|
||||||
@@ -91,6 +95,8 @@ class ParticleEmitter(private val pos: Vec3d, private val rot: Vector2f, private
|
|||||||
isTicking = false
|
isTicking = false
|
||||||
isDead = true
|
isDead = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun stopTicking() {
|
fun stopTicking() {
|
||||||
isTicking = false
|
isTicking = false
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user