bugfixes
This commit is contained in:
@@ -163,7 +163,8 @@ fun onRightClick(player: PlayerEntity, world: ServerWorld, hand: Hand) : TypedAc
|
||||
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
|
||||
|
||||
return TypedActionResult(ActionResult.PASS, handItem)
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
package com.bytedice.bde_particles
|
||||
|
||||
import net.minecraft.component.Component
|
||||
import net.minecraft.component.ComponentType
|
||||
import net.minecraft.entity.EntityType
|
||||
import net.minecraft.entity.decoration.DisplayEntity.ItemDisplayEntity
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.nbt.NbtCompound
|
||||
import net.minecraft.nbt.NbtFloat
|
||||
import net.minecraft.nbt.NbtList
|
||||
import net.minecraft.nbt.NbtString
|
||||
import net.minecraft.registry.Registries
|
||||
import net.minecraft.registry.Registry
|
||||
import net.minecraft.server.world.ServerWorld
|
||||
|
||||
class DisplayEntity(private var properties: DisplayEntityProperties?) {
|
||||
@@ -38,7 +33,7 @@ class DisplayEntity(private var properties: DisplayEntityProperties?) {
|
||||
|
||||
if (matchResult != null) {
|
||||
modelName = matchResult.groupValues[1]
|
||||
customModelNum = matchResult.groupValues[2].toInt()
|
||||
customModelNum = matchResult.groupValues[2].toIntOrNull() ?: 0
|
||||
}
|
||||
else {
|
||||
modelName = properties.model
|
||||
@@ -92,6 +87,10 @@ class DisplayEntity(private var properties: DisplayEntityProperties?) {
|
||||
|
||||
put("view_range", NbtCompound().apply { properties.viewRange })
|
||||
|
||||
if (properties.name != null) {
|
||||
putString("CustomName", properties.name)
|
||||
putByte("CustomNameVisible", 1)
|
||||
}
|
||||
}
|
||||
|
||||
entity?.readNbt(nbt)
|
||||
|
||||
@@ -17,5 +17,6 @@ data class DisplayEntityProperties (
|
||||
val scale: Vector3f = Vector3f(1.0f, 1.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) {
|
||||
companion object {
|
||||
val Constant = LerpCurves { _ -> 1.0f }
|
||||
val Linear = LerpCurves { y -> y }
|
||||
val Sqrt = LerpCurves { y -> sqrt(y) }
|
||||
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 {
|
||||
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 {
|
||||
val DEFAULT = EmitterParams(
|
||||
maxCount = 400,
|
||||
spawnRate = 100,
|
||||
maxCount = 200,
|
||||
spawnRate = 50,
|
||||
spawnChance = 1.0f,
|
||||
spawnDuration = ParamClasses.Duration.SingleBurst(4),
|
||||
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),
|
||||
initVel = ParamClasses.PairVec3f.Null,
|
||||
initCenterVel = ParamClasses.PairFloat(0.4f, 0.5f),
|
||||
initScale = ParamClasses.PairVec3f.Uniform(1.5f, 1.0f),
|
||||
transformWithVel = ParamClasses.TransformWithVel.none,
|
||||
initScale = ParamClasses.PairVec3f.Uniform(0.5f, 1.5f),
|
||||
transformWithVel = ParamClasses.TransformWithVel.None,
|
||||
forceFields = emptyArray(),
|
||||
constVel = Vector3f(0.0f, 0.0f, 0.0f),
|
||||
drag = 0.075f,
|
||||
minVel = 0.0f,
|
||||
offsetCurve = ParamClasses.LerpVal.NoLerpVec3f,
|
||||
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(
|
||||
arrayOf("shroomlight", "orange_concrete", "orange_stained_glass", "gray_wool", "gray_stained_glass", "light_gray_stained_glass", "light_gray_stained_glass_pane"),
|
||||
LerpCurves.Sqrt
|
||||
|
||||
@@ -119,8 +119,8 @@ class ParamClasses {
|
||||
) : Duration()
|
||||
}
|
||||
enum class TransformWithVel {
|
||||
rotOnly,
|
||||
scaleAndRot,
|
||||
none
|
||||
RotOnly,
|
||||
ScaleAndRot,
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.bytedice.bde_particles.particles
|
||||
|
||||
import com.bytedice.bde_particles.*
|
||||
import net.minecraft.particle.DustParticleEffect
|
||||
import net.minecraft.server.world.ServerWorld
|
||||
import net.minecraft.util.math.Vec3d
|
||||
import org.joml.Vector2f
|
||||
@@ -61,8 +62,6 @@ class Particle(
|
||||
private var lifeTime = emitterParams.lifeTime.randomize()
|
||||
|
||||
private lateinit var particleEntity: DisplayEntity
|
||||
private lateinit var debugOriginEntity: DisplayEntity
|
||||
private lateinit var debugVelEntity: DisplayEntity
|
||||
|
||||
fun init() {
|
||||
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,
|
||||
translation = newPos.add(pos),
|
||||
leftRotation = quatRot,
|
||||
scale = scale,
|
||||
scale = Vector3f(scale).mul(emitterParams.scaleCurve.lerpToVector3f(0.0f)),
|
||||
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.") }
|
||||
|
||||
val newProperties = calcNewProperties()
|
||||
@@ -114,6 +113,10 @@ class Particle(
|
||||
|
||||
if (timeAlive > lifeTime) { kill() }
|
||||
|
||||
if (debug) {
|
||||
tickDebug(world)
|
||||
}
|
||||
|
||||
timeAlive += 1
|
||||
}
|
||||
|
||||
@@ -195,7 +198,7 @@ class Particle(
|
||||
private fun calcRot(t: Float) : Vector3f {
|
||||
val newRot = Vector3f(rot)
|
||||
|
||||
if (emitterParams.transformWithVel == ParamClasses.TransformWithVel.none) {
|
||||
if (emitterParams.transformWithVel == ParamClasses.TransformWithVel.None) {
|
||||
val newVel = Vector3f(rotVel)
|
||||
|
||||
newVel.mul(emitterParams.rotVelCurve.lerpToVector3f(t))
|
||||
@@ -225,27 +228,46 @@ class Particle(
|
||||
|
||||
private fun calcScale(t: Float) : Vector3f {
|
||||
val newScale = Vector3f(scale)
|
||||
newScale.mul(emitterParams.scaleCurve.lerpToVector3f(t))
|
||||
return scale
|
||||
return newScale.mul(emitterParams.scaleCurve.lerpToVector3f(t))
|
||||
}
|
||||
|
||||
|
||||
private fun spawnDebug() {
|
||||
// spawn cube at particle origin
|
||||
// show arrow pointing toward particle direction
|
||||
// name-tag its data
|
||||
private fun tickDebug(world: ServerWorld) {
|
||||
// spawn particle at particle origin
|
||||
// show trail pointing toward particle direction
|
||||
|
||||
// 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
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
||||
private fun updateDebug() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
private fun calcDebug() {
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -7,8 +7,13 @@ import net.minecraft.server.world.ServerWorld
|
||||
import net.minecraft.util.math.Vec3d
|
||||
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 timeAlive = 0
|
||||
@@ -28,7 +33,7 @@ class ParticleEmitter(private val pos: Vec3d, private val rot: Vector2f, private
|
||||
|
||||
for (particle in allParticles) {
|
||||
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))
|
||||
if (randomSpawnChance > params.spawnChance) { return }
|
||||
|
||||
val debug = world.gameRules.getBoolean(Bde_particles.SHOW_PARTICLE_DEBUG)
|
||||
val particle = Particle(params, pos, rot, debug)
|
||||
particle.init()
|
||||
particle.spawn(world)
|
||||
@@ -91,6 +95,8 @@ class ParticleEmitter(private val pos: Vec3d, private val rot: Vector2f, private
|
||||
isTicking = false
|
||||
isDead = true
|
||||
}
|
||||
|
||||
|
||||
fun stopTicking() {
|
||||
isTicking = false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user