made some newly added params function correctly
This commit is contained in:
@@ -3,8 +3,13 @@
|
||||
|
||||
BDE_ParticleSys is a highly customizable **server-side** particle system that uses `Block Display Entities` (BDEs) as particles. It is meant to be used as a library for other mods, but can be used as a standalone mod too.
|
||||
|
||||
<!-- change GiveParticleEmitter to GiveEmitterTool -->
|
||||
If BDE_ParticleSys is used as a standalone mod, you will only be able to use it with the custom in-game commands `/GiveEmitterTool`, `/KillAllEmitters` and `/ManageEmitters`. Any particles made with those commands are **temporary** and get removed once the server shuts down, as they are meant for quick testing.
|
||||
If BDE_ParticleSys is used as a standalone mod, you will only be able to use it with the custom in-game commands `/GiveEmitterTool`, `/KillAllEmitters`, and `/ManageEmitters`. Any particles made, removed, or changed with those commands are **temporary** and get reverted once the server shuts down, as they are meant for quick testing.
|
||||
|
||||
### Contents (in-game)
|
||||
* `/GiveEmitterTool`
|
||||
* `/KillAllEmitters`
|
||||
* `/ManageEmitters`
|
||||
* `GlobalMaxParticles` (GameRule)
|
||||
|
||||
# Open-source - Copyright
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.bytedice.bde_particles.client
|
||||
|
||||
import com.bytedice.bde_particles.commands.GiveEmitterTool
|
||||
import com.bytedice.bde_particles.commands.KillAllEmitters
|
||||
import com.bytedice.bde_particles.commands.ManageEmitters
|
||||
//import com.bytedice.bde_particles.commands.ManageEmitters
|
||||
import com.bytedice.bde_particles.init
|
||||
import com.bytedice.bde_particles.onRightClick
|
||||
import com.bytedice.bde_particles.tick
|
||||
@@ -38,7 +38,7 @@ class Bde_particlesClient : ClientModInitializer {
|
||||
|
||||
CommandRegistrationCallback.EVENT.register { dispatcher, registryAccess, _ ->
|
||||
GiveEmitterTool.register(dispatcher, registryAccess)
|
||||
ManageEmitters .register(dispatcher)
|
||||
//ManageEmitters .register(dispatcher)
|
||||
KillAllEmitters.register(dispatcher)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.bytedice.bde_particles
|
||||
|
||||
import com.bytedice.bde_particles.commands.GiveEmitterTool
|
||||
import com.bytedice.bde_particles.commands.KillAllEmitters
|
||||
import com.bytedice.bde_particles.commands.ManageEmitters
|
||||
//import com.bytedice.bde_particles.commands.ManageEmitters
|
||||
import com.bytedice.bde_particles.items.ParticleEmitterTool
|
||||
import com.bytedice.bde_particles.particles.*
|
||||
import kotlinx.coroutines.async
|
||||
@@ -47,23 +47,31 @@ import java.util.*
|
||||
// Custom curve equation command args (parse from strings)
|
||||
// Cylinder and cone force field shape.
|
||||
// Better particle performance.
|
||||
// Global max particles variable.
|
||||
// gamerule max particles
|
||||
|
||||
// Emitter groups (multiple emitters for EmitterTool)
|
||||
// Private functions/classes
|
||||
// Debug tools
|
||||
// RenderParticleDebug gamerule
|
||||
// render emitter origin
|
||||
// render particle origin
|
||||
// name-tag particle with its data
|
||||
// render particle velocity direction
|
||||
|
||||
|
||||
var ALL_PARTICLE_EMITTERS: Array<ParticleEmitter> = emptyArray()
|
||||
var LIVING_PARTICLE_COUNT: Int = 0
|
||||
val SESSION_UUID: UUID = UUID.randomUUID()
|
||||
val GLOBAL_MAX_PARTICLES = GameRuleRegistry.register(
|
||||
|
||||
|
||||
class Bde_particles : ModInitializer {
|
||||
companion object {
|
||||
val GLOBAL_MAX_PARTICLES: GameRules.Key<GameRules.IntRule> = GameRuleRegistry.register(
|
||||
"GlobalMaxParticles",
|
||||
GameRules.Category.UPDATES,
|
||||
GameRuleFactory.createIntRule(3000, 0)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
class Bde_particles : ModInitializer {
|
||||
override fun onInitialize() {
|
||||
if (FabricLoader.getInstance().environmentType != EnvType.SERVER) {
|
||||
return
|
||||
@@ -71,17 +79,13 @@ class Bde_particles : ModInitializer {
|
||||
|
||||
println("BPS - Initializing on ${FabricLoader.getInstance().environmentType}")
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTED.register { _ ->
|
||||
init()
|
||||
}
|
||||
|
||||
ServerTickEvents.START_SERVER_TICK.register { server ->
|
||||
tick(server)
|
||||
}
|
||||
|
||||
CommandRegistrationCallback.EVENT.register { dispatcher, registryAccess, _ ->
|
||||
GiveEmitterTool.register(dispatcher, registryAccess)
|
||||
ManageEmitters .register(dispatcher)
|
||||
//ManageEmitters .register(dispatcher)
|
||||
KillAllEmitters.register(dispatcher)
|
||||
}
|
||||
|
||||
@@ -93,6 +97,8 @@ class Bde_particles : ModInitializer {
|
||||
})
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTED.register(ServerLifecycleEvents.ServerStarted { _ ->
|
||||
init()
|
||||
|
||||
println("BPS - Progress bar filled :3")
|
||||
println(
|
||||
"\n____________ _____ _____ \n" +
|
||||
|
||||
@@ -75,7 +75,7 @@ class DisplayEntity(private var properties: DisplayEntityProperties?) {
|
||||
|
||||
|
||||
fun kill() {
|
||||
if (entity == null) { println("BPS - Particle Emitter entity is null!"); return }
|
||||
if (entity == null) { println("BPS - Failed to kill BDE. Entity is null!"); return }
|
||||
entity?.kill()
|
||||
}
|
||||
}
|
||||
@@ -186,7 +186,6 @@ fun sdfSphere(pos: Vector3f, radius: Float, objectPos: Vector3f): Float {
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun sdfCube(pos: Vector3f, size: Vector3f, objectPos: Vector3f): Float {
|
||||
val px = objectPos.x - pos.x
|
||||
val py = objectPos.y - pos.y
|
||||
@@ -216,3 +215,21 @@ fun sdfCube(pos: Vector3f, size: Vector3f, objectPos: Vector3f): Float {
|
||||
fun normalizeSdf(sdf: Float, radius: Float): Float {
|
||||
return if (sdf < 0) (sdf + radius) / radius else 0f
|
||||
}
|
||||
|
||||
|
||||
fun velToRot(velocity: Vector3f): Vector3f {
|
||||
val normalizedVelocity = Vector3f(velocity).normalize()
|
||||
|
||||
val yaw = Math.toDegrees(atan2(normalizedVelocity.z.toDouble(), normalizedVelocity.x.toDouble())).toFloat()
|
||||
|
||||
val pitch = Math.toDegrees(
|
||||
atan2(
|
||||
-normalizedVelocity.y.toDouble(),
|
||||
sqrt(
|
||||
normalizedVelocity.x.toDouble().pow(2) + normalizedVelocity.z.toDouble().pow(2)
|
||||
)
|
||||
)
|
||||
).toFloat()
|
||||
|
||||
return Vector3f(pitch, yaw, 0f)
|
||||
}
|
||||
@@ -16,11 +16,13 @@ object KillAllEmitters {
|
||||
|
||||
dispatcher.register(
|
||||
command.executes { context ->
|
||||
var amountEmitters = 0
|
||||
for (emitter in ALL_PARTICLE_EMITTERS) {
|
||||
emitter.kill()
|
||||
amountEmitters += 1
|
||||
}
|
||||
|
||||
val feedback = Text.literal("BPS - Killed all living Emitters.")
|
||||
val feedback = Text.literal("BPS - Killed all living Emitters. [$amountEmitters]")
|
||||
.setStyle(Style.EMPTY.withColor(Color(0, 200, 0).rgb))
|
||||
|
||||
context.source.sendFeedback({ feedback }, false)
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.util.concurrent.CompletableFuture
|
||||
|
||||
// TODO: completely redesign
|
||||
|
||||
|
||||
/*
|
||||
// CLOSE THIS FILE IMMEDIATELY, YOU ARE ENTERING EGYPTIAN (pyramid) AND ITALIAN (spaghetti) TERRITORY
|
||||
|
||||
val curves = arrayOf("LINEAR", "SQRT", "EXPONENT", "CUBIC", "SINE", "COSINE", "INVERSE", "LOG", "EXP", "BOUNCE")
|
||||
@@ -603,3 +603,4 @@ fun forceFieldGenericParams(context: CommandContext<ServerCommandSource>, shape:
|
||||
shape
|
||||
)
|
||||
}
|
||||
*/
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.bytedice.bde_particles.commands
|
||||
|
||||
import com.bytedice.bde_particles.emitterParamsToJson
|
||||
import com.bytedice.bde_particles.particles.*
|
||||
import com.mojang.brigadier.Command
|
||||
import com.mojang.brigadier.CommandDispatcher
|
||||
@@ -81,7 +80,7 @@ blockCurve: Pair<Array<String>, LerpCurves>,
|
||||
// <emitter id>
|
||||
// output -> give player a command block with the particle params (should be paste-able in kotlin)
|
||||
|
||||
|
||||
/*
|
||||
object ManageEmitters {
|
||||
fun register(dispatcher: CommandDispatcher<ServerCommandSource>) {
|
||||
val command = CommandManager.literal("ManageEmitters")
|
||||
@@ -299,3 +298,4 @@ fun makeCommandBlock(emitterData: Map<String, Any>): ItemStack {
|
||||
|
||||
return i
|
||||
}
|
||||
*/
|
||||
@@ -17,11 +17,10 @@ data class EmitterParams (
|
||||
var offset: ParamClasses.PairVec3f,
|
||||
var initRot: ParamClasses.PairVec3f,
|
||||
var rotVel: ParamClasses.PairVec3f,
|
||||
var rotWithVel: Boolean,
|
||||
var initVel: ParamClasses.PairVec3f,
|
||||
var initCenterVel: ParamClasses.PairFloat,
|
||||
var initScale: ParamClasses.PairVec3f,
|
||||
var scaleWithVel: Boolean,
|
||||
var transformWithVel: ParamClasses.TransformWithVel,
|
||||
// velocity
|
||||
var forceFields: Array<ForceField>,
|
||||
var constVel: Vector3f,
|
||||
@@ -36,30 +35,29 @@ data class EmitterParams (
|
||||
{
|
||||
companion object Presets {
|
||||
val DEFAULT = EmitterParams(
|
||||
maxCount = 200,
|
||||
spawnRate = 1,
|
||||
maxCount = 400,
|
||||
spawnRate = 100,
|
||||
spawnChance = 1.0f,
|
||||
spawnDuration = ParamClasses.Duration.SingleBurst(25),
|
||||
spawnDuration = ParamClasses.Duration.SingleBurst(4),
|
||||
spawnPosOffset = Vector3f(0.0f, 0.0f, 0.0f),
|
||||
lifeTime = ParamClasses.PairInt(25, 40),
|
||||
shape = SpawningShape.Circle(3.0f, false),
|
||||
shape = SpawningShape.Sphere(1.0f, true),
|
||||
offset = ParamClasses.PairVec3f.Uniform(-0.5f, -0.5f),
|
||||
initRot = ParamClasses.PairVec3f.Null,
|
||||
initRot = ParamClasses.PairVec3f.NonUniform(0.0f, 0.0f, 0.0f, 360.0f, 360.0f, 360.0f),
|
||||
rotVel = ParamClasses.PairVec3f.NonUniform(-0.2f, -0.2f, -0.2f, 0.2f, 0.2f, 0.2f),
|
||||
rotWithVel = true,
|
||||
initVel = ParamClasses.PairVec3f.Null,
|
||||
initCenterVel = ParamClasses.PairFloat(0.1f, 0.3f),
|
||||
initScale = ParamClasses.PairVec3f.Uniform(1.0f, 0.2f),
|
||||
scaleWithVel = true,
|
||||
initCenterVel = ParamClasses.PairFloat(0.4f, 0.5f),
|
||||
initScale = ParamClasses.PairVec3f.Uniform(1.5f, 1.0f),
|
||||
transformWithVel = ParamClasses.TransformWithVel.none,
|
||||
forceFields = emptyArray(),
|
||||
constVel = Vector3f(0.0f, -0.01f, 0.0f),
|
||||
constVel = Vector3f(0.0f, 0.0f, 0.0f),
|
||||
drag = 0.075f,
|
||||
minVel = 0.0f,
|
||||
offsetCurve = ParamClasses.LerpVal.NoLerpVec3f(Vector3f(-0.5f, -0.5f, -0.5f)),
|
||||
offsetCurve = ParamClasses.LerpVal.NoLerpVec3f,
|
||||
rotVelCurve = ParamClasses.LerpVal.LerpUniform(1.0f, 0.0f, LerpCurves.Sqrt),
|
||||
scaleCurve = ParamClasses.LerpVal.LerpUniform(1.0f, 0.5f, LerpCurves.Linear),
|
||||
scaleCurve = ParamClasses.LerpVal.LerpUniform(0.0f, 2.0f, LerpCurves.Linear),
|
||||
blockCurve = Pair(
|
||||
arrayOf("minecraft:purple_concrete", "minecraft:purple_stained_glass"),
|
||||
arrayOf("shroomlight", "orange_concrete", "orange_stained_glass", "gray_wool", "gray_stained_glass", "light_gray_stained_glass"),
|
||||
LerpCurves.Sqrt
|
||||
),
|
||||
)
|
||||
|
||||
@@ -90,7 +90,7 @@ class ParamClasses {
|
||||
return com.bytedice.bde_particles.lerp(from, to, t) * curve.function(t)
|
||||
}
|
||||
}
|
||||
data class NoLerpVec3f(val value: Vector3f) : LerpVal()
|
||||
data object NoLerpVec3f : LerpVal()
|
||||
|
||||
fun lerpToVector3f(t: Float) : Vector3f {
|
||||
when (this) {
|
||||
@@ -100,7 +100,7 @@ class ParamClasses {
|
||||
val x = this.lerp(t)
|
||||
return Vector3f(x, x, x)
|
||||
}
|
||||
is NoLerpVec3f -> return this.value
|
||||
is NoLerpVec3f -> return Vector3f(1.0f, 1.0f, 1.0f)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,4 +118,9 @@ class ParamClasses {
|
||||
val loopDelay: Int
|
||||
) : Duration()
|
||||
}
|
||||
enum class TransformWithVel {
|
||||
rotOnly,
|
||||
scaleAndRot,
|
||||
none
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,8 @@ class Particle(private val emitterParams: EmitterParams, private var entityPos:
|
||||
|
||||
pos = newSpawnPos
|
||||
|
||||
val dirFromCenter = entityPos.subtract(pos.x.toDouble(), pos.y.toDouble(), pos.z.toDouble()).normalize()
|
||||
val posDouble = Vec3d(pos.x.toDouble(), pos.y.toDouble(), pos.z.toDouble())
|
||||
val dirFromCenter = posDouble.normalize()
|
||||
val forceFromCenter = dirFromCenter.multiply(emitterParams.initCenterVel.randomize().toDouble())
|
||||
vel.add(forceFromCenter.x.toFloat(), forceFromCenter.y.toFloat(), forceFromCenter.z.toFloat())
|
||||
|
||||
@@ -89,7 +90,10 @@ class Particle(private val emitterParams: EmitterParams, private var entityPos:
|
||||
|
||||
|
||||
fun spawn(world: ServerWorld) {
|
||||
if (isInit) { blockDisplay.spawn(world) }
|
||||
if (isInit) {
|
||||
blockDisplay.spawn(world)
|
||||
LIVING_PARTICLE_COUNT += 1
|
||||
}
|
||||
else { error("Particle is not initialized before being spawned. Please use Particle.init() to initialize it.") }
|
||||
}
|
||||
|
||||
@@ -101,7 +105,7 @@ class Particle(private val emitterParams: EmitterParams, private var entityPos:
|
||||
|
||||
blockDisplay.updateProperties(newProperties)
|
||||
|
||||
if (timeAlive > lifeTime) { isDead = true; blockDisplay.kill() }
|
||||
if (timeAlive > lifeTime) { kill() }
|
||||
|
||||
timeAlive += 1
|
||||
}
|
||||
@@ -144,7 +148,7 @@ class Particle(private val emitterParams: EmitterParams, private var entityPos:
|
||||
val newProperties = DisplayEntityProperties(
|
||||
pos = entityPos,
|
||||
blockType = newBlock,
|
||||
translation = combinedOffset,
|
||||
translation = combinedOffset.add(newOriginOffset),
|
||||
leftRotation = quatRot,
|
||||
scale = newScale,
|
||||
tags = arrayOf("BPS_Particle", "BPS_UUID", SESSION_UUID.toString())
|
||||
@@ -183,11 +187,17 @@ class Particle(private val emitterParams: EmitterParams, private var entityPos:
|
||||
|
||||
private fun calcRot(t: Float) : Vector3f {
|
||||
val newRot = Vector3f(rot)
|
||||
|
||||
if (emitterParams.transformWithVel == ParamClasses.TransformWithVel.none) {
|
||||
val newVel = Vector3f(rotVel)
|
||||
|
||||
newVel.mul(emitterParams.rotVelCurve.lerpToVector3f(t))
|
||||
newRot.add(newVel)
|
||||
return newRot
|
||||
return newRot.add(newVel)
|
||||
}
|
||||
else {
|
||||
val rotWithVel = velToRot(vel)
|
||||
return newRot.add(rotWithVel)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -214,6 +224,10 @@ class Particle(private val emitterParams: EmitterParams, private var entityPos:
|
||||
|
||||
|
||||
fun kill() {
|
||||
if (!isDead) { blockDisplay.kill() }
|
||||
if (!isDead) {
|
||||
blockDisplay.kill()
|
||||
LIVING_PARTICLE_COUNT -= 1
|
||||
isDead = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.bytedice.bde_particles.particles
|
||||
|
||||
import com.bytedice.bde_particles.Bde_particles
|
||||
import com.bytedice.bde_particles.LIVING_PARTICLE_COUNT
|
||||
import com.bytedice.bde_particles.randomFloatBetween
|
||||
import net.minecraft.server.world.ServerWorld
|
||||
import net.minecraft.util.math.Vec3d
|
||||
@@ -37,6 +39,9 @@ class ParticleEmitter(private val pos: Vec3d, private val rot: Vector2f, private
|
||||
repeat(params.spawnRate) {
|
||||
if (allParticles.size >= params.maxCount) { return }
|
||||
|
||||
val maxParticles = world.gameRules.getInt(Bde_particles.GLOBAL_MAX_PARTICLES)
|
||||
if (LIVING_PARTICLE_COUNT >= maxParticles) { return }
|
||||
|
||||
val randomSpawnChance = randomFloatBetween(0.0f, params.spawnChance.coerceIn(0.0f, 1.0f))
|
||||
if (randomSpawnChance > params.spawnChance) { return }
|
||||
|
||||
|
||||
@@ -13,6 +13,18 @@ fun addToRegister(id: String, params: EmitterParams) : Pair<String, Boolean> {
|
||||
return Pair(newId, false)
|
||||
}
|
||||
|
||||
val newBlocks: MutableList<String> = mutableListOf()
|
||||
|
||||
for (block in params.blockCurve.first) {
|
||||
val blockModIdRegex = ".*:".toRegex()
|
||||
if (blockModIdRegex.containsMatchIn(block)) { break }
|
||||
else {
|
||||
newBlocks.add("minecraft:$block")
|
||||
}
|
||||
}
|
||||
|
||||
params.blockCurve = Pair(newBlocks.toTypedArray(), params.blockCurve.second)
|
||||
|
||||
idRegister[id] = params
|
||||
println("BPS - Registered Emitter ID \"$newId\".")
|
||||
return Pair(newId, true)
|
||||
|
||||
Reference in New Issue
Block a user