ready for 1.0! Idc that it may be buggy, I want 1.0 now!

This commit is contained in:
2024-12-29 15:21:06 +01:00
parent 46498d25f4
commit 2423efbd92
14 changed files with 221 additions and 116 deletions
@@ -52,6 +52,10 @@ import kotlin.reflect.full.declaredMemberProperties
// Copying particle params in-game.
// Custom curve equation command args (parse from strings).
// Force field "config" option.
// add rotation offset to transformWithVel
// TODO: (now)
// nothing lmao
var ALL_PARTICLE_EMITTERS: Array<ParticleEmitter> = emptyArray()
@@ -77,7 +77,7 @@ class DisplayEntity(var properties: DisplayEntityProperties?) {
putString("billboard", properties.billboard)
if (properties.customName != null) {
putString("CustomName", properties.customName)
putString("CustomName", "{\"text\":\"${properties.customName}\"}")
putByte("CustomNameVisible", 1)
}
@@ -44,6 +44,10 @@ class LerpCurves(val function: (Float) -> Float) {
fun custom(equation: (Float) -> Float) = LerpCurves(equation)
}
fun deepCopy() : LerpCurves {
return LerpCurves(this.function)
}
}
@@ -72,12 +76,16 @@ fun raycastFromPlayer(player: ServerPlayerEntity, maxDistance: Double): HitResul
fun randomFloatBetween(min: Float, max: Float) : Float {
return Random.nextFloat() * (max - min) + min
return if (min == max) { max }
else if (min > max) { Random.nextFloat() * (min - max) + max }
else { Random.nextFloat() * (max - min) + min }
}
fun randomIntBetween(min: Int, max: Int) : Int {
return Random.nextInt(max - min) + min
return if (min == max) { max }
else if (min > max) { Random.nextInt(min - max) + max }
else { Random.nextInt(max - min) + min }
}
@@ -377,6 +377,25 @@ fun pairVec3fArg(access: KProperty1<EmitterParams,ParamClasses.PairVec3f>,
)
)
)
.then(CommandManager.literal("Constant")
.then(CommandManager.argument("X", FloatArgumentType.floatArg())
.then(CommandManager.argument("Y", FloatArgumentType.floatArg())
.then(CommandManager.argument("Z", FloatArgumentType.floatArg())
.executes { context ->
val id = StringArgumentType.getString(context, "Emitter ID")
val x = FloatArgumentType.getFloat(context, "X")
val y = FloatArgumentType.getFloat(context, "Y")
val z = FloatArgumentType.getFloat(context, "Z")
updateParam(id, access, ParamClasses.PairVec3f.Constant(Vector3f(x, y, z)))
successText(access, "Constant", id, context)
Command.SINGLE_SUCCESS
}
)
)
)
)
.then(CommandManager.literal("Null")
.executes { context ->
val id = StringArgumentType.getString(context, "Emitter ID")
@@ -430,12 +449,12 @@ fun transformWithVelArg(access: KProperty1<EmitterParams, ParamClasses.Transform
}
)
)
.then(CommandManager.literal("None")
.then(CommandManager.literal("Null")
.executes { context ->
val id = StringArgumentType.getString(context, "Emitter ID")
updateParam(id, access, ParamClasses.TransformWithVel.None)
successText(access, "None", id, context)
updateParam(id, access, ParamClasses.TransformWithVel.Null)
successText(access, "Null", id, context)
Command.SINGLE_SUCCESS
}
)
@@ -458,7 +477,7 @@ fun stringCurveArg(access: KProperty1<EmitterParams, ParamClasses.StringCurve>,
}
)
.executes { context ->
stringCurveAddArg(context, access, -1)
stringCurveAddArg(context, access, null)
Command.SINGLE_SUCCESS
}
)
@@ -472,7 +491,7 @@ fun stringCurveArg(access: KProperty1<EmitterParams, ParamClasses.StringCurve>,
}
)
.executes { context ->
stringCurveRemoveArg(context, access, -1)
stringCurveRemoveArg(context, access, null)
Command.SINGLE_SUCCESS
}
)
@@ -492,7 +511,6 @@ fun stringCurveArg(access: KProperty1<EmitterParams, ParamClasses.StringCurve>,
Command.SINGLE_SUCCESS
}
else {
println("$modelCurve, $curve, $curveName")
negativeFeedback("Failed to update param \"modelCurve.curve\"! The curve is invalid!", context)
Command.SINGLE_SUCCESS
}
@@ -505,7 +523,7 @@ fun stringCurveArg(access: KProperty1<EmitterParams, ParamClasses.StringCurve>,
fun stringCurveAddArg(context: CommandContext<ServerCommandSource>,
access: KProperty1<EmitterParams, ParamClasses.StringCurve>,
index: Int
index: Int?
) {
val id = StringArgumentType.getString(context, "Emitter ID")
val item = ItemStackArgumentType.getItemStackArgument(context, "Item").item
@@ -513,12 +531,12 @@ fun stringCurveAddArg(context: CommandContext<ServerCommandSource>,
val modelCurve = getEmitterDataById(id)?.modelCurve
if (index == -1 && modelCurve != null) {
if (index == null && modelCurve != null) {
modelCurve.array = modelCurve.array.toMutableList().apply { add(itemId) }.toTypedArray()
updateParam(id, access, modelCurve)
}
else if (modelCurve != null) {
modelCurve.array = modelCurve.array.toMutableList().apply { add(index.coerceIn(0, modelCurve.array.lastIndex), itemId) }.toTypedArray()
modelCurve.array = modelCurve.array.toMutableList().apply { add(index!!.coerceIn(0, modelCurve.array.lastIndex), itemId) }.toTypedArray()
updateParam(id, access, modelCurve)
}
@@ -527,7 +545,7 @@ fun stringCurveAddArg(context: CommandContext<ServerCommandSource>,
fun stringCurveRemoveArg(context: CommandContext<ServerCommandSource>,
access: KProperty1<EmitterParams, ParamClasses.StringCurve>,
index: Int
index: Int?
) {
val id = StringArgumentType.getString(context, "Emitter ID")
@@ -535,13 +553,13 @@ fun stringCurveRemoveArg(context: CommandContext<ServerCommandSource>,
val item: String
if (index == -1 && modelCurve != null && modelCurve.array.isNotEmpty()) {
if (index == null && modelCurve != null && modelCurve.array.isNotEmpty()) {
item = modelCurve.array.last()
modelCurve.array = modelCurve.array.toMutableList().apply { removeLast() }.toTypedArray()
updateParam(id, access, modelCurve)
}
else if (modelCurve != null && modelCurve.array.isNotEmpty()) {
item = modelCurve.array[index.coerceIn(0, modelCurve.array.lastIndex)]
item = modelCurve.array[index!!.coerceIn(0, modelCurve.array.lastIndex)]
modelCurve.array = modelCurve.array.toMutableList().apply { removeAt(index.coerceIn(0, modelCurve.array.lastIndex)) }.toTypedArray()
updateParam(id, access, modelCurve)
}
@@ -698,8 +716,15 @@ fun forceFieldArg(access: KProperty1<EmitterParams,ParamClasses.ForceFieldArray>
.then(CommandManager.argument("Radius", FloatArgumentType.floatArg())
.then(CommandManager.argument("Min Force", FloatArgumentType.floatArg())
.then(CommandManager.argument("Max Force", FloatArgumentType.floatArg())
.then(CommandManager.argument("Index", IntegerArgumentType.integer())
.executes { context ->
val index = IntegerArgumentType.getInteger(context, "Index")
forceFieldAddArg(context, access, "Sphere", index)
Command.SINGLE_SUCCESS
}
)
.executes { context ->
forceFieldAddArg(context, access, "Sphere")
forceFieldAddArg(context, access, "Sphere", null)
Command.SINGLE_SUCCESS
}
)
@@ -710,15 +735,20 @@ fun forceFieldArg(access: KProperty1<EmitterParams,ParamClasses.ForceFieldArray>
.then(CommandManager.argument("Size X", FloatArgumentType.floatArg())
.then(CommandManager.argument("Size Y", FloatArgumentType.floatArg())
.then(CommandManager.argument("Size Z", FloatArgumentType.floatArg())
.then(CommandManager.argument("Dir X", FloatArgumentType.floatArg())
.then(CommandManager.argument("Dir Y", FloatArgumentType.floatArg())
.then(CommandManager.argument("Dir Z", FloatArgumentType.floatArg())
.then(CommandManager.argument("Force", FloatArgumentType.floatArg())
.then(CommandManager.argument("Force X", FloatArgumentType.floatArg())
.then(CommandManager.argument("Force Y", FloatArgumentType.floatArg())
.then(CommandManager.argument("Force Z", FloatArgumentType.floatArg())
.then(CommandManager.argument("Index", IntegerArgumentType.integer())
.executes { context ->
forceFieldAddArg(context, access, "Cube")
val index = IntegerArgumentType.getInteger(context, "Index")
forceFieldAddArg(context, access, "Cube", index)
Command.SINGLE_SUCCESS
}
)
.executes { context ->
forceFieldAddArg(context, access, "Cube", null)
Command.SINGLE_SUCCESS
}
)
)
)
@@ -742,7 +772,7 @@ fun forceFieldArg(access: KProperty1<EmitterParams,ParamClasses.ForceFieldArray>
}
)
.executes { context ->
forceFieldRemoveArg(context, access, -1)
forceFieldRemoveArg(context, access, null)
Command.SINGLE_SUCCESS
}
)
@@ -750,7 +780,8 @@ fun forceFieldArg(access: KProperty1<EmitterParams,ParamClasses.ForceFieldArray>
fun forceFieldAddArg(context: CommandContext<ServerCommandSource>,
access: KProperty1<EmitterParams, ParamClasses.ForceFieldArray>,
shape: String
shape: String,
index: Int?
) {
val id = StringArgumentType.getString(context, "Emitter ID")
val x = FloatArgumentType.getFloat(context, "X")
@@ -775,21 +806,29 @@ fun forceFieldAddArg(context: CommandContext<ServerCommandSource>,
val sizeX = FloatArgumentType.getFloat(context, "Size X")
val sizeY = FloatArgumentType.getFloat(context, "Size Y")
val sizeZ = FloatArgumentType.getFloat(context, "Size Z")
val dirX = FloatArgumentType.getFloat(context, "Dir X")
val dirY = FloatArgumentType.getFloat(context, "Dir Y")
val dirZ = FloatArgumentType.getFloat(context, "Dir Z")
val force = FloatArgumentType.getFloat(context, "Force")
val forceX = FloatArgumentType.getFloat(context, "Force X")
val forceY = FloatArgumentType.getFloat(context, "Force Y")
val forceZ = FloatArgumentType.getFloat(context, "Force Z")
forceField = ForceField(
Vector3f(x, y, z),
ForceFieldShape.Cube(Vector3f(sizeX, sizeY, sizeZ), Vector3f(dirX, dirY, dirZ), force)
ForceFieldShape.Cube(Vector3f(sizeX, sizeY, sizeZ), Vector3f(forceX, forceY, forceZ))
)
}
if (forceFields != null && forceField != null) {
forceFields.array = forceFields.array.toMutableList().apply { add(forceField) }.toTypedArray()
if (forceFields != null && forceField != null) {
if (index == null) {
forceFields.array = forceFields.array.toMutableList().apply { add(forceField) }.toTypedArray()
}
else {
val newIndex = index.coerceIn(0, forceFields.array.size)
forceFields.array = forceFields.array.toMutableList().apply { add(newIndex, forceField) }.toTypedArray()
}
val calcIndex = index?.coerceIn(0, forceFields.array.size)
updateParam(id, access, forceFields)
successText(access, "++ForceField", id, context)
successText(access, "++ForceField at $calcIndex", id, context)
}
else {
negativeFeedback("Failed to update param \"forceFields\"! The Emitter ID is most likely invalid!", context)
@@ -798,18 +837,19 @@ fun forceFieldAddArg(context: CommandContext<ServerCommandSource>,
fun forceFieldRemoveArg(context: CommandContext<ServerCommandSource>,
access: KProperty1<EmitterParams, ParamClasses.ForceFieldArray>,
index: Int
index: Int?
) {
val id = StringArgumentType.getString(context, "Emitter ID")
val forceFields = getEmitterDataById(id)?.forceFields
if (index == -1 && forceFields != null && forceFields.array.isNotEmpty()) {
if (index == null && forceFields != null && forceFields.array.isNotEmpty()) {
forceFields.array = forceFields.array.toMutableList().apply { removeLast() }.toTypedArray()
updateParam(id, access, forceFields)
}
else if (forceFields != null && forceFields.array.isNotEmpty()) {
forceFields.array = forceFields.array.toMutableList().apply { removeAt(index.coerceIn(0, forceFields.array.lastIndex)) }.toTypedArray()
val newIndex = index?.coerceIn(0, forceFields.array.lastIndex) ?: forceFields.array.lastIndex
forceFields.array = forceFields.array.toMutableList().apply { removeAt(newIndex) }.toTypedArray()
updateParam(id, access, forceFields)
}
else {
@@ -817,7 +857,7 @@ fun forceFieldRemoveArg(context: CommandContext<ServerCommandSource>,
return
}
val calcIndex = if (index == -1) { forceFields.array.size } else { index.coerceIn(0, forceFields.array.size) }
val calcIndex = index?.coerceIn(0, forceFields.array.size) ?: forceFields.array.size
successText(access, "--ForceField at $calcIndex", id, context)
}
@@ -828,18 +868,18 @@ fun lerpValIntArg(access: KProperty1<EmitterParams, ParamClasses.LerpValInt>,
{
return configArg
.then(CommandManager.literal("LerpInt")
.then(CommandManager.argument("Min", IntegerArgumentType.integer())
.then(CommandManager.argument("Max", IntegerArgumentType.integer())
.then(CommandManager.argument("From", IntegerArgumentType.integer())
.then(CommandManager.argument("To", IntegerArgumentType.integer())
.then(curveListArg("Curve")
.executes { context ->
val id = StringArgumentType.getString(context, "Emitter ID")
val min = IntegerArgumentType.getInteger(context, "Min")
val max = IntegerArgumentType.getInteger(context, "Max")
val from = IntegerArgumentType.getInteger(context, "From")
val to = IntegerArgumentType.getInteger(context, "To")
val curveName = StringArgumentType.getString(context, "Curve")
val curve = stringToCurve(curveName)
updateParam(id, access, ParamClasses.LerpValInt.LerpInt(min, max, curve!!))
updateParam(id, access, ParamClasses.LerpValInt.LerpInt(from, to, curve!!))
successText(access, "LerpInt", id, context)
Command.SINGLE_SUCCESS
@@ -5,8 +5,12 @@ import com.bytedice.bde_particles.particles.idRegister
import com.mojang.brigadier.Command
import com.mojang.brigadier.CommandDispatcher
import com.mojang.brigadier.arguments.StringArgumentType
import com.mojang.brigadier.context.CommandContext
import net.minecraft.command.CommandRegistryAccess
import net.minecraft.command.argument.ItemStackArgumentType
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import net.minecraft.item.Items
import net.minecraft.server.command.CommandManager
import net.minecraft.server.command.ServerCommandSource
import net.minecraft.text.Style
@@ -33,26 +37,42 @@ object GiveEmitterTool {
CompletableFuture.completedFuture(builder.build())
}
dispatcher.register(
command
.then(itemNameArg
.then(itemTypeArg
.then(emitterIdSuggestion
.executes { context ->
val name = StringArgumentType.getString(context, "Item Name")
val item = ItemStackArgumentType.getItemStackArgument(context, "Item Type")
val emitterId = StringArgumentType.getString(context, "Emitter ID")
dispatcher.register(command
.then(emitterIdSuggestion
.then(itemTypeArg
.then(itemNameArg
.executes { context ->
val name = StringArgumentType.getString(context, "Item Name")
val item = ItemStackArgumentType.getItemStackArgument(context, "Item Type")
val emitterId = StringArgumentType.getString(context, "Emitter ID")
val feedback = Text.literal("BPS - You like fancy particles. Don't you?\nBPS - gave particle emitter, bound to ID: \"${emitterId}\".")
.setStyle(Style.EMPTY.withColor(TextColor.fromRgb(Color(0, 200, 0).rgb)))
context.source.player?.inventory?.insertStack(ParticleEmitterTool.makeData(item.item, name, emitterId))
context.source.sendFeedback({ feedback }, false)
Command.SINGLE_SUCCESS
}
)
exec(context, emitterId, item.item, name)
Command.SINGLE_SUCCESS
}
)
.executes { context ->
val item = ItemStackArgumentType.getItemStackArgument(context, "Item Type")
val emitterId = StringArgumentType.getString(context, "Emitter ID")
exec(context, emitterId, item.item, emitterId)
Command.SINGLE_SUCCESS
}
)
.executes { context ->
val emitterId = StringArgumentType.getString(context, "Emitter ID")
exec(context, emitterId, Items.AMETHYST_SHARD, emitterId)
Command.SINGLE_SUCCESS
}
)
)
}
private fun exec(context: CommandContext<ServerCommandSource>, emitterId: String, itemType: Item, itemName: String) {
val feedback = Text.literal("BPS - You like fancy particles. Don't you?\nBPS - gave particle emitter, bound to ID: \"${emitterId}\".")
.setStyle(Style.EMPTY.withColor(TextColor.fromRgb(Color(0, 200, 0).rgb)))
context.source.player?.inventory?.insertStack(ParticleEmitterTool.makeData(itemType, itemName, emitterId))
context.source.sendFeedback({ feedback }, false)
}
}
@@ -122,19 +122,18 @@ object ManageEmitters {
}
private fun createExec(context: CommandContext<ServerCommandSource>, newEmitterId: String, presetEmitterId: String) {
val params = getEmitterDataById(presetEmitterId)?.copy()
val params = getEmitterDataById(presetEmitterId)
val usedDefault = params == null
println(params?.modelCurve?.array?.size)
val result = addToRegister(
newEmitterId,
params ?: EmitterParams.DEFAULT,
(params ?: EmitterParams.DEFAULT).deepCopy(),
)
if (usedDefault && result.second) {
positiveFeedback(
"Successfully added new Emitter with ID \"${result.first}\" to register.\n(DEFAULT params were used as a preset because the specified Preset Emitter ID wasn't valid.)",
"Successfully added new Emitter with ID \"${result.first}\" to register.\n" +
"(DEFAULT preset was used because the specified Preset Emitter ID wasn't valid.)",
context
)
}
@@ -146,7 +145,8 @@ object ManageEmitters {
}
else {
negativeFeedback(
"Failed to add new Emitter with ID \"${result.first}\" to register.\nThe provided Emitter ID is either reserved for system use or already in use.",
"Failed to add new Emitter with ID \"${result.first}\" to register.\n" +
"The provided Emitter ID is either reserved for system use or already in use.",
context
)
}
@@ -74,8 +74,8 @@ class EOrigin(rot: Vector2f, eOrigin: Vec3d) {
class ShapeDebug(eOrigin: Vec3d, spawnPosOffset: Vector3f, shape: SpawningShape) {
val shapeScale: Vector3f? = when (shape) {
is SpawningShape.Circle -> Vector3f(shape.radius * 1.75f * 2, shape.radius * 1.75f * 2, 0.0001f)
is SpawningShape.Sphere -> Vector3f(shape.radius * 1.75f * 2, shape.radius * 1.75f * 2, 0.0001f)
is SpawningShape.Circle -> Vector3f(shape.radius * 2 * 2, shape.radius * 2 * 2, 0.0001f)
is SpawningShape.Sphere -> Vector3f(shape.radius * 2 * 2, shape.radius * 2 * 2, 0.0001f)
is SpawningShape.Rect -> Vector3f(shape.size.x, 0.0001f, shape.size.y)
is SpawningShape.Cube -> Vector3f(shape.size.x, shape.size.y, shape.size.z)
else -> null
@@ -135,7 +135,7 @@ class ForceFieldDebug {
var FFDEArray: Array<DisplayEntity> = emptyArray()
fun makeArray(eOrigin: Vec3d, forceFieldArray: ParamClasses.ForceFieldArray, spawnPosOffset: Vector3f) {
forceFieldArray.array.forEach {
forceFieldArray.array.forEachIndexed { index, it ->
val shapeScale = when (it.shape) {
is ForceFieldShape.Sphere -> Vector3f(1.333f * it.shape.radius * 2, 1.333f * it.shape.radius * 2, 0.0001f)
is ForceFieldShape.Cube -> it.shape.size
@@ -143,14 +143,14 @@ class ForceFieldDebug {
val newOffset = Vector3f(spawnPosOffset).add(it.pos)
val displayEntity = DisplayEntity(
DisplayEntityProperties(
pos = eOrigin.add(newOffset.x.toDouble(), newOffset.y.toDouble(), newOffset.z.toDouble()),
model = if (it.shape is ForceFieldShape.Sphere) { "minecraft:snowball" } else { "minecraft:white_stained_glass" },
tags = arrayOf("DEBUG", "E_DEBUG", "eOrigin_DEBUG", "BPS_UUID", SESSION_UUID.toString()),
brightnessOverride = 15,
billboard = if (it.shape is ForceFieldShape.Sphere) { Billboard.CENTER } else { Billboard.FIXED },
scale = shapeScale
val displayEntity = DisplayEntity(DisplayEntityProperties(
pos = eOrigin.add(newOffset.x.toDouble(), newOffset.y.toDouble(), newOffset.z.toDouble()),
model = if (it.shape is ForceFieldShape.Sphere) { "minecraft:snowball" } else { "minecraft:white_stained_glass" },
tags = arrayOf("DEBUG", "E_DEBUG", "eOrigin_DEBUG", "BPS_UUID", SESSION_UUID.toString()),
customName = "forceField index: $index",
brightnessOverride = 15,
billboard = if (it.shape is ForceFieldShape.Sphere) { Billboard.CENTER } else { Billboard.FIXED },
scale = shapeScale
))
FFDEArray += displayEntity
@@ -34,6 +34,16 @@ data class EmitterParams (
var brightnessCurve: ParamClasses.LerpValInt,
)
{
fun deepCopy() : EmitterParams {
val cModelCurveArray = this.modelCurve.deepCopy()
val cForceFieldArray = this.forceFields.deepCopy()
val cParams = this.copy()
cParams.modelCurve = cModelCurveArray
cParams.forceFields = cForceFieldArray
return cParams
}
companion object Presets {
val DEFAULT = EmitterParams(
maxCount = 200,
@@ -49,7 +59,7 @@ data class EmitterParams (
initVel = ParamClasses.PairVec3f.Null,
initCenterVel = ParamClasses.PairFloat(0.4f, 0.5f),
initScale = ParamClasses.PairVec3f.Uniform(0.5f, 1.5f),
transformWithVel = ParamClasses.TransformWithVel.None,
transformWithVel = ParamClasses.TransformWithVel.Null,
forceFields = ParamClasses.ForceFieldArray(emptyArray()),
constVel = Vector3f(0.0f, 0.0f, 0.0f),
drag = 0.075f,
@@ -68,7 +78,7 @@ data class EmitterParams (
),
LerpCurves.Sqrt
),
brightnessCurve = ParamClasses.LerpValInt.LerpInt(15, 0, LerpCurves.Sqrt)
brightnessCurve = ParamClasses.LerpValInt.LerpInt(15, 5, LerpCurves.Sqrt)
)
val DEBUG = EmitterParams(
maxCount = 50,
@@ -103,7 +113,7 @@ data class EmitterParams (
),
LerpCurves.Linear
),
brightnessCurve = ParamClasses.LerpValInt.Null
brightnessCurve = ParamClasses.LerpValInt.LerpInt(15, 5, LerpCurves.Sqrt)
)
val STRESS_TEST = EmitterParams(
maxCount = 10000,
@@ -119,7 +129,7 @@ data class EmitterParams (
initVel = ParamClasses.PairVec3f.NonUniform(0.0f, 4.0f, 0.0f, 0.0f, 8.0f, 0.0f),
initCenterVel = ParamClasses.PairFloat(-1.5f, -1.5f),
initScale = ParamClasses.PairVec3f.Uniform(10.0f, 15.0f),
transformWithVel = ParamClasses.TransformWithVel.None,
transformWithVel = ParamClasses.TransformWithVel.Null,
forceFields = ParamClasses.ForceFieldArray(
arrayOf(ForceField(
Vector3f(0.0f, 75.0f, 0.0f),
@@ -5,4 +5,11 @@ import org.joml.Vector3f
data class ForceField (
val pos: Vector3f,
val shape: ForceFieldShape
)
) {
fun deepCopy(): ForceField {
return ForceField(
Vector3f(pos),
shape.deepCopy()
)
}
}
@@ -36,29 +36,22 @@ class ParamClasses {
)
}
}
data class Constant(val value: Vector3f) : PairVec3f()
data object Null : PairVec3f()
}
class PairInt (
private val min: Int,
private val max: Int,
val min: Int,
val max: Int,
) {
fun randomize() : Int {
return if (min == max) { max }
else if (min > max) { max }
else { randomIntBetween(min, max) }
}
fun randomize() : Int { return randomIntBetween(min, max) }
}
class PairFloat(
private val min: Float,
private val max: Float,
val min: Float,
val max: Float,
) {
fun randomize() : Float {
return if (min == max) { max }
else if (min > max) { max }
else { randomFloatBetween(min, max) }
}
fun randomize() : Float { return randomFloatBetween(min, max) }
}
sealed class LerpValVec3f {
@@ -191,7 +184,7 @@ class ParamClasses {
return Vector3f(contractFactor, contractFactor, stretchFactor)
}
}
data object None : TransformWithVel()
data object Null : TransformWithVel()
}
class StringCurve (
@@ -199,9 +192,17 @@ class ParamClasses {
var curve: LerpCurves
) {
fun lerp(t: Float) : String { return lerpArray(array as Array<Any>, t, curve) as String }
fun deepCopy(): StringCurve {
return StringCurve(array.copyOf(), curve.deepCopy())
}
}
data class ForceFieldArray (
var array: Array<ForceField>
)
) {
fun deepCopy(): ForceFieldArray {
return ForceFieldArray(array.map { it.deepCopy() }.toTypedArray())
}
}
}
@@ -25,31 +25,36 @@ class Particle(
private val originOffset = when (val offset = emitterParams.offset) {
is ParamClasses.PairVec3f.Uniform -> offset.randomize()
is ParamClasses.PairVec3f.NonUniform -> offset.randomize()
ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
is ParamClasses.PairVec3f.Constant -> offset.value
is ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
}
private var rot = when (val initRot = emitterParams.initRot) {
is ParamClasses.PairVec3f.Uniform -> initRot.randomize()
is ParamClasses.PairVec3f.NonUniform -> initRot.randomize()
ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
is ParamClasses.PairVec3f.Constant -> initRot.value
is ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
}
private var rotVel = when (val initRotVel = emitterParams.rotVel) {
is ParamClasses.PairVec3f.Uniform -> initRotVel.randomize()
is ParamClasses.PairVec3f.NonUniform -> initRotVel.randomize()
ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
is ParamClasses.PairVec3f.Constant -> initRotVel.value
is ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
}
private var vel = when (val initVel = emitterParams.initVel) {
is ParamClasses.PairVec3f.Uniform -> initVel.randomize()
is ParamClasses.PairVec3f.NonUniform -> initVel.randomize()
ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
is ParamClasses.PairVec3f.Constant -> initVel.value
is ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
}
private var scale = when (val initScale = emitterParams.initScale) {
is ParamClasses.PairVec3f.Uniform -> initScale.randomize()
is ParamClasses.PairVec3f.NonUniform -> initScale.randomize()
ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
is ParamClasses.PairVec3f.Constant -> initScale.value
is ParamClasses.PairVec3f.Null -> Vector3f(0.0f, 0.0f, 0.0f)
}
private var lifeTime = emitterParams.lifeTime.randomize()
@@ -138,29 +143,32 @@ class Particle(
val newOriginOffset = Vector3f(originOffset.mul(emitterParams.offsetCurve.lerpToVector3f(timeAliveClamped)))
val newBrightness = emitterParams.brightnessCurve.lerpToInt(timeAliveClamped)
val newScale: Vector3f
val TWVScale: Vector3f
//val TWVRot: Vector3f
val newRot: Vector3f
when (emitterParams.transformWithVel) {
is ParamClasses.TransformWithVel.RotOnly -> {
newScale = calcScale(timeAliveClamped)
TWVScale = Vector3f(1.0f, 1.0f, 1.0f)
newRot = (emitterParams.transformWithVel as ParamClasses.TransformWithVel.RotOnly).velToRot(vel)
}
is ParamClasses.TransformWithVel.ScaleAndRot -> {
newScale = Vector3f(scale).mul((emitterParams.transformWithVel as ParamClasses.TransformWithVel.ScaleAndRot).velToScale(vel))
TWVScale = (emitterParams.transformWithVel as ParamClasses.TransformWithVel.ScaleAndRot).velToScale(vel)
newRot = (emitterParams.transformWithVel as ParamClasses.TransformWithVel.ScaleAndRot).velToRot(vel)
}
else -> {
newScale = calcScale(timeAliveClamped)
TWVScale = Vector3f(1.0f, 1.0f, 1.0f)
newRot = calcRot(timeAliveClamped)
rot = newRot
}
}
val newScale = TWVScale.mul(calcScale(timeAliveClamped))
//val newRot = TWVRot.add(calcRot(timeAliveClamped))
rot = newRot
vel = newVel
pos = newPos
for (forceField in emitterParams.forceFields.array) {
if (forceField.shape is ForceFieldShape.Sphere) { vel.add(sphereSdfVel(forceField)) }
else if (forceField.shape is ForceFieldShape.Cube) { vel.add(cubeSdfVel(forceField)) }
@@ -206,8 +214,8 @@ class Particle(
val shape = forceField.shape
val sdfVal = sdfCube(forceField.pos, shape.size, pos)
val velDir = if (sdfVal < 0) { shape.dir.mul(shape.force) }
else { Vector3f(0.0f, 0.0f, 0.0f) }
val velDir = if (sdfVal < 0) { shape.force }
else { Vector3f(0.0f, 0.0f, 0.0f) }
return velDir
}
@@ -11,10 +11,10 @@ import net.minecraft.util.math.Vec3d
import org.joml.Vector2f
class ParticleEmitter(
private var pos: Vec3d,
private var rot: Vector2f,
private val world: ServerWorld,
private val params: EmitterParams,
var pos: Vec3d,
var rot: Vector2f,
val world: ServerWorld,
val params: EmitterParams,
private val debug: Boolean = false
) {
private var allParticles: Array<Particle> = emptyArray()
@@ -33,7 +33,7 @@ fun addToRegister(id: String, params: EmitterParams) : Pair<String, Boolean> {
params.modelCurve.array = newModels.toTypedArray()
idRegister[id] = params
idRegister[newId] = params
println("BPS - Registered Emitter ID \"$newId\".")
return Pair(newId, true)
}
@@ -7,7 +7,7 @@ import org.joml.Vector3f
import kotlin.math.*
import kotlin.random.Random
sealed class SpawningShape() {
sealed class SpawningShape {
class Circle(val radius: Float, val spawnOnEdge: Boolean) : SpawningShape() {
fun randomWithin(): Vector3f {
val randRadius = radius * sqrt(randomFloatBetween(0.0f, 1.0f))
@@ -121,9 +121,16 @@ sealed class ForceFieldShape {
val radius: Float,
val force: Pair<Float, Float>,
) : ForceFieldShape()
data class Cube(
val size: Vector3f,
val dir: Vector3f,
val force: Float
val force: Vector3f
) : ForceFieldShape()
fun deepCopy() : ForceFieldShape {
return when (this) {
is Sphere -> Sphere(this.radius, this.force)
is Cube -> Cube(Vector3f(this.size), Vector3f(this.force))
}
}
}