diff --git a/src/main/kotlin/com/bytedice/bde_particles/Bde_particles.kt b/src/main/kotlin/com/bytedice/bde_particles/Bde_particles.kt index fe5b069..31bb460 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/Bde_particles.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/Bde_particles.kt @@ -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 = emptyArray() diff --git a/src/main/kotlin/com/bytedice/bde_particles/DisplayEntity.kt b/src/main/kotlin/com/bytedice/bde_particles/DisplayEntity.kt index 0afd2b5..0bad411 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/DisplayEntity.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/DisplayEntity.kt @@ -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) } diff --git a/src/main/kotlin/com/bytedice/bde_particles/Math.kt b/src/main/kotlin/com/bytedice/bde_particles/Math.kt index 751d073..881097e 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/Math.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/Math.kt @@ -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 } } diff --git a/src/main/kotlin/com/bytedice/bde_particles/commands/ConfigArgs.kt b/src/main/kotlin/com/bytedice/bde_particles/commands/ConfigArgs.kt index ad207df..5794230 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/commands/ConfigArgs.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/commands/ConfigArgs.kt @@ -377,6 +377,25 @@ fun pairVec3fArg(access: KProperty1, ) ) ) + .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 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, } ) .executes { context -> - stringCurveAddArg(context, access, -1) + stringCurveAddArg(context, access, null) Command.SINGLE_SUCCESS } ) @@ -472,7 +491,7 @@ fun stringCurveArg(access: KProperty1, } ) .executes { context -> - stringCurveRemoveArg(context, access, -1) + stringCurveRemoveArg(context, access, null) Command.SINGLE_SUCCESS } ) @@ -492,7 +511,6 @@ fun stringCurveArg(access: KProperty1, 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, fun stringCurveAddArg(context: CommandContext, access: KProperty1, - 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, 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, fun stringCurveRemoveArg(context: CommandContext, access: KProperty1, - index: Int + index: Int? ) { val id = StringArgumentType.getString(context, "Emitter ID") @@ -535,13 +553,13 @@ fun stringCurveRemoveArg(context: CommandContext, 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 .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 .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 } ) .executes { context -> - forceFieldRemoveArg(context, access, -1) + forceFieldRemoveArg(context, access, null) Command.SINGLE_SUCCESS } ) @@ -750,7 +780,8 @@ fun forceFieldArg(access: KProperty1 fun forceFieldAddArg(context: CommandContext, access: KProperty1, - 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, 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, fun forceFieldRemoveArg(context: CommandContext, access: KProperty1, - 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, 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, { 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 diff --git a/src/main/kotlin/com/bytedice/bde_particles/commands/GiveEmitterTool.kt b/src/main/kotlin/com/bytedice/bde_particles/commands/GiveEmitterTool.kt index 1305db2..dda4da1 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/commands/GiveEmitterTool.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/commands/GiveEmitterTool.kt @@ -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, 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) + } } diff --git a/src/main/kotlin/com/bytedice/bde_particles/commands/ManageEmitters.kt b/src/main/kotlin/com/bytedice/bde_particles/commands/ManageEmitters.kt index 3b52455..e33e469 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/commands/ManageEmitters.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/commands/ManageEmitters.kt @@ -122,19 +122,18 @@ object ManageEmitters { } private fun createExec(context: CommandContext, 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 ) } diff --git a/src/main/kotlin/com/bytedice/bde_particles/particles/EmitterDebug.kt b/src/main/kotlin/com/bytedice/bde_particles/particles/EmitterDebug.kt index 88d03a3..94e3359 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/particles/EmitterDebug.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/particles/EmitterDebug.kt @@ -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 = 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 diff --git a/src/main/kotlin/com/bytedice/bde_particles/particles/EmitterParams.kt b/src/main/kotlin/com/bytedice/bde_particles/particles/EmitterParams.kt index 1cd7e21..14dee92 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/particles/EmitterParams.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/particles/EmitterParams.kt @@ -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), diff --git a/src/main/kotlin/com/bytedice/bde_particles/particles/ForceFields.kt b/src/main/kotlin/com/bytedice/bde_particles/particles/ForceFields.kt index ba4012a..7811967 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/particles/ForceFields.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/particles/ForceFields.kt @@ -5,4 +5,11 @@ import org.joml.Vector3f data class ForceField ( val pos: Vector3f, val shape: ForceFieldShape -) \ No newline at end of file +) { + fun deepCopy(): ForceField { + return ForceField( + Vector3f(pos), + shape.deepCopy() + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/bytedice/bde_particles/particles/ParamClasses.kt b/src/main/kotlin/com/bytedice/bde_particles/particles/ParamClasses.kt index 2e1e243..78ab3e5 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/particles/ParamClasses.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/particles/ParamClasses.kt @@ -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, t, curve) as String } + + fun deepCopy(): StringCurve { + return StringCurve(array.copyOf(), curve.deepCopy()) + } } data class ForceFieldArray ( var array: Array - ) + ) { + fun deepCopy(): ForceFieldArray { + return ForceFieldArray(array.map { it.deepCopy() }.toTypedArray()) + } + } } \ No newline at end of file diff --git a/src/main/kotlin/com/bytedice/bde_particles/particles/Particle.kt b/src/main/kotlin/com/bytedice/bde_particles/particles/Particle.kt index 58d0bb8..b93335c 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/particles/Particle.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/particles/Particle.kt @@ -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 } diff --git a/src/main/kotlin/com/bytedice/bde_particles/particles/ParticleEmitter.kt b/src/main/kotlin/com/bytedice/bde_particles/particles/ParticleEmitter.kt index eed4a8b..cf5adf3 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/particles/ParticleEmitter.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/particles/ParticleEmitter.kt @@ -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 = emptyArray() diff --git a/src/main/kotlin/com/bytedice/bde_particles/particles/ParticleIdRegister.kt b/src/main/kotlin/com/bytedice/bde_particles/particles/ParticleIdRegister.kt index e568efb..4c09f5b 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/particles/ParticleIdRegister.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/particles/ParticleIdRegister.kt @@ -33,7 +33,7 @@ fun addToRegister(id: String, params: EmitterParams) : Pair { params.modelCurve.array = newModels.toTypedArray() - idRegister[id] = params + idRegister[newId] = params println("BPS - Registered Emitter ID \"$newId\".") return Pair(newId, true) } diff --git a/src/main/kotlin/com/bytedice/bde_particles/particles/Shapes.kt b/src/main/kotlin/com/bytedice/bde_particles/particles/Shapes.kt index 6ee669b..5fb760c 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/particles/Shapes.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/particles/Shapes.kt @@ -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, ) : 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)) + } + } } \ No newline at end of file