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 4a7def6..91be9ee 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/Bde_particles.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/Bde_particles.kt @@ -50,12 +50,7 @@ import java.util.concurrent.CompletableFuture // Cylinder and cone force field shape. // Copying particle params in-game // Custom curve equation command args (parse from strings) - - -// TODO: (project) -// fix ManageEmitter command -// Better command auto-completion. (and change names of args) - // force field "config" option +// force field "config" option var ALL_PARTICLE_EMITTERS: Array = emptyArray() 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 bb4aa6c..62a5367 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/commands/ConfigArgs.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/commands/ConfigArgs.kt @@ -22,7 +22,6 @@ import org.joml.Vector2f import org.joml.Vector3f import kotlin.reflect.* import kotlin.reflect.full.memberProperties -import net.minecraft.server.command.GiveCommand typealias CommandArgumentBuilder = KFunction> @@ -72,7 +71,6 @@ fun parseArgNameToAccess(name: String) : KProperty1? { return access } -// TODO: add forceField & implement rest of args fun parseArgTypeToFunc(type: KType) : CommandArgumentBuilder? { return when (type.classifier) { Int::class -> ::intArg @@ -86,7 +84,8 @@ fun parseArgTypeToFunc(type: KType) : CommandArgumentBuilder? { ParamClasses.PairFloat::class -> ::pairFloatArg ParamClasses.TransformWithVel::class -> ::transformWithVelArg ParamClasses.StringCurve::class -> ::stringCurveArg - ParamClasses.LerpVal::class -> null + ParamClasses.LerpVal::class -> ::lerpValArg + ParamClasses.ForceFieldArray::class -> ::forceFieldArg else -> null } } @@ -509,5 +508,214 @@ fun stringCurveRemoveArg(context: CommandContext, updateParam(id, access, modelCurve) } + successText(access, "--item at $index", id, context) +} + +fun lerpValArg(access: KProperty1, + configArg: LiteralArgumentBuilder + ) : LiteralArgumentBuilder +{ + return configArg + .then(CommandManager.literal("LerpVec3f") + .then(CommandManager.argument("Min X", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Min Y", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Min Z", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Max X", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Max Y", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Max Z", FloatArgumentType.floatArg()) + .then(curveListArg("Curve") + .executes { context -> + val id = StringArgumentType.getString(context, "Emitter ID") + val minX = FloatArgumentType.getFloat(context, "Min X") + val minY = FloatArgumentType.getFloat(context, "Min Y") + val minZ = FloatArgumentType.getFloat(context, "Min Z") + val maxX = FloatArgumentType.getFloat(context, "Max X") + val maxY = FloatArgumentType.getFloat(context, "Max Y") + val maxZ = FloatArgumentType.getFloat(context, "Max Z") + val curveName = StringArgumentType.getString(context, "Curve") + + val curve = stringToCurve(curveName) + + updateParam(id, access, ParamClasses.LerpVal.LerpVec3f(minX, minY, minZ, maxX, maxY, maxZ, curve!!)) + + successText(access, "LerpVec3f", id, context) + Command.SINGLE_SUCCESS + } + ) + ) + ) + ) + ) + ) + ) + ) + .then(CommandManager.literal("MultiLerpVec3f") + .then(CommandManager.argument("Min X", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Min Y", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Min Z", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Max X", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Max Y", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Max Z", FloatArgumentType.floatArg()) + .then(curveListArg("CurveX") + .then(curveListArg("CurveY") + .then(curveListArg("CurveZ") + .executes { context -> + val id = StringArgumentType.getString(context, "Emitter ID") + val minX = FloatArgumentType.getFloat(context, "Min X") + val minY = FloatArgumentType.getFloat(context, "Min Y") + val minZ = FloatArgumentType.getFloat(context, "Min Z") + val maxX = FloatArgumentType.getFloat(context, "Max X") + val maxY = FloatArgumentType.getFloat(context, "Max Y") + val maxZ = FloatArgumentType.getFloat(context, "Max Z") + val curveNameX = StringArgumentType.getString(context, "CurveX") + val curveNameY = StringArgumentType.getString(context, "CurveY") + val curveNameZ = StringArgumentType.getString(context, "CurveZ") + + val curveX = stringToCurve(curveNameX) + val curveY = stringToCurve(curveNameY) + val curveZ = stringToCurve(curveNameZ) + + updateParam(id, access, ParamClasses.LerpVal.MultiLerpVec3f(minX, minY, minZ, maxX, maxY, maxZ, curveX!!, curveY!!, curveZ!!)) + + successText(access, "MultiLerpVec3f", id, context) + Command.SINGLE_SUCCESS + } + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + .then(CommandManager.literal("Null") + .executes { context -> + val id = StringArgumentType.getString(context, "Emitter ID") + + updateParam(id, access, ParamClasses.LerpVal.Null) + + successText(access, "Null", id, context) + Command.SINGLE_SUCCESS + } + ) +} + + +fun forceFieldArg(access: KProperty1, + configArg: LiteralArgumentBuilder + ) : LiteralArgumentBuilder +{ + return configArg + .then(CommandManager.literal("Add") + .then(CommandManager.argument("X", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Y", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Z", FloatArgumentType.floatArg()) + .then(CommandManager.literal("Sphere") + .then(CommandManager.argument("Radius", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Min Force", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Max Force", FloatArgumentType.floatArg()) + .executes { context -> + forceFieldAddArg(context, access, "Sphere") + Command.SINGLE_SUCCESS + } + ) + ) + ) + ) + .then(CommandManager.literal("Cube") + .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()) + .executes { context -> + forceFieldAddArg(context, access, "Cube") + Command.SINGLE_SUCCESS + } + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + + + + .then(CommandManager.literal("Remove") + .then(CommandManager.argument("Index", IntegerArgumentType.integer()) + .executes { context -> + val index = IntegerArgumentType.getInteger(context, "Index") + forceFieldRemoveArg(context, access, index) + Command.SINGLE_SUCCESS + } + ) + .executes { context -> + forceFieldRemoveArg(context, access, -1) + Command.SINGLE_SUCCESS + } + ) +} + +fun forceFieldAddArg(context: CommandContext, + access: KProperty1, + shape: String +) { + 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") + + + val forceFields = getEmitterDataById(id)?.forceFields + var forceField: ForceField? = null + + if (shape == "Sphere") { + val radius = FloatArgumentType.getFloat(context, "Radius") + val minForce = FloatArgumentType.getFloat(context, "Min Force") + val maxForce = FloatArgumentType.getFloat(context, "Max Force") + + forceField = ForceField( + Vector3f(x, y, z), + ForceFieldShape.Sphere(radius, Pair(minForce, maxForce)) + ) + } + + if (forceFields != null && forceField != null) { + forceFields.array.toMutableList().apply { add(forceField) }.toTypedArray() + updateParam(id, access, forceFields) + successText(access, "++ForceField", id, context) + } + else { + negativeFeedback("Failed to update param \"forceFields\"! The Emitter ID is most likely invalid!", context) + } +} + +fun forceFieldRemoveArg(context: CommandContext, + access: KProperty1, + index: Int +) { + val id = StringArgumentType.getString(context, "Emitter ID") + + val forceFields = getEmitterDataById(id)?.forceFields + + if (index == -1 && forceFields != null) { + forceFields.array.toMutableList().apply { removeLast() }.toTypedArray() + updateParam(id, access, forceFields) + } + else if (forceFields != null) { + forceFields.array.toMutableList().apply { removeAt(index.coerceIn(0, forceFields.array.lastIndex)) }.toTypedArray() + updateParam(id, access, forceFields) + } + successText(access, "--item at $index", id, context) } \ No newline at end of file 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 1afbeca..da62180 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/particles/EmitterParams.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/particles/EmitterParams.kt @@ -22,7 +22,7 @@ data class EmitterParams ( var initScale: ParamClasses.PairVec3f, var transformWithVel: ParamClasses.TransformWithVel, // velocity - var forceFields: Array, + var forceFields: ParamClasses.ForceFieldArray, var constVel: Vector3f, var drag: Float, var minVel: Float, @@ -49,11 +49,11 @@ data class EmitterParams ( initCenterVel = ParamClasses.PairFloat(0.4f, 0.5f), initScale = ParamClasses.PairVec3f.Uniform(0.5f, 1.5f), transformWithVel = ParamClasses.TransformWithVel.None, - forceFields = emptyArray(), + forceFields = ParamClasses.ForceFieldArray(emptyArray()), constVel = Vector3f(0.0f, 0.0f, 0.0f), drag = 0.075f, minVel = 0.0f, - offsetCurve = ParamClasses.LerpVal.NoLerpVec3f, + offsetCurve = ParamClasses.LerpVal.Null, rotVelCurve = ParamClasses.LerpVal.LerpUniform(1.0f, 0.0f, LerpCurves.Sqrt), scaleCurve = ParamClasses.LerpVal.LerpUniform(1.0f, 2.5f, LerpCurves.Linear), modelCurve = ParamClasses.StringCurve( @@ -83,11 +83,11 @@ data class EmitterParams ( initCenterVel = ParamClasses.PairFloat(1.5f, 1.5f), initScale = ParamClasses.PairVec3f.Uniform(2.0f, 2.0f), transformWithVel = ParamClasses.TransformWithVel.ScaleAndRot(0.75f), - forceFields = emptyArray(), + forceFields = ParamClasses.ForceFieldArray(emptyArray()), constVel = Vector3f(0.0f, -0.05f, 0.0f), drag = 0.075f, minVel = 0.0f, - offsetCurve = ParamClasses.LerpVal.NoLerpVec3f, + offsetCurve = ParamClasses.LerpVal.Null, rotVelCurve = ParamClasses.LerpVal.LerpUniform(1.0f, 0.0f, LerpCurves.Linear), scaleCurve = ParamClasses.LerpVal.LerpUniform(1.0f, 1.0f, LerpCurves.Linear), modelCurve = ParamClasses.StringCurve( @@ -117,15 +117,16 @@ data class EmitterParams ( initCenterVel = ParamClasses.PairFloat(-1.5f, -1.5f), initScale = ParamClasses.PairVec3f.Uniform(10.0f, 15.0f), transformWithVel = ParamClasses.TransformWithVel.None, - forceFields = arrayOf(ForceField( - "MUSHROOM_HEAD", - Vector3f(0.0f, 75.0f, 0.0f), - ForceFieldShape.Sphere(15.0f, Pair(0.1f, 0.2f)) - )), + forceFields = ParamClasses.ForceFieldArray( + arrayOf(ForceField( + Vector3f(0.0f, 75.0f, 0.0f), + ForceFieldShape.Sphere(15.0f, Pair(0.1f, 0.2f)) + )) + ), constVel = Vector3f(0.0f, 0.001f, 0.0f), drag = 0.075f, minVel = 0.0f, - offsetCurve = ParamClasses.LerpVal.NoLerpVec3f, + offsetCurve = ParamClasses.LerpVal.Null, rotVelCurve = ParamClasses.LerpVal.LerpUniform(1.0f, 0.0f, LerpCurves.Linear), scaleCurve = ParamClasses.LerpVal.LerpUniform(1.0f, 1.5f, LerpCurves.Linear), modelCurve = ParamClasses.StringCurve( 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 e399407..ba4012a 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/particles/ForceFields.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/particles/ForceFields.kt @@ -3,7 +3,6 @@ package com.bytedice.bde_particles.particles import org.joml.Vector3f data class ForceField ( - val name: String = "DEFAULT", - val pos: Vector3f = Vector3f(0.0f, 5.0f, 0.0f), - val shape: ForceFieldShape = ForceFieldShape.Sphere() + val pos: Vector3f, + val shape: ForceFieldShape ) \ 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 ec18625..2ee309d 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/particles/ParamClasses.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/particles/ParamClasses.kt @@ -94,7 +94,7 @@ class ParamClasses { return com.bytedice.bde_particles.lerp(from, to, curve.function(t)) } } - data object NoLerpVec3f : LerpVal() + data object Null : LerpVal() fun lerpToVector3f(t: Float) : Vector3f { when (this) { @@ -104,7 +104,7 @@ class ParamClasses { val x = this.lerp(t) return Vector3f(x, x, x) } - is NoLerpVec3f -> return Vector3f(1.0f, 1.0f, 1.0f) + is Null -> return Vector3f(1.0f, 1.0f, 1.0f) } } } @@ -162,4 +162,7 @@ class ParamClasses { ) { fun lerp(t: Float) : String { return lerpArray(array as Array, t, curve) as String } } + data class ForceFieldArray ( + val array: Array + ) } \ 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 e9eeba3..e32be3e 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/particles/Particle.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/particles/Particle.kt @@ -157,7 +157,7 @@ class Particle( pos = newPos - for (forceField in emitterParams.forceFields) { + 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)) } } 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 d11d78b..b80e68c 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/particles/ParticleIdRegister.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/particles/ParticleIdRegister.kt @@ -27,7 +27,7 @@ fun addToRegister(id: String, params: EmitterParams) : Pair { val newModels: MutableList = mutableListOf() - for (model in params.modelCurve.first) { + for (model in params.modelCurve.array) { val modelModIdRegex = ".*:".toRegex() if (modelModIdRegex.containsMatchIn(model)) { break } else { @@ -35,7 +35,7 @@ fun addToRegister(id: String, params: EmitterParams) : Pair { } } - params.modelCurve = Pair(newModels.toTypedArray(), params.modelCurve.second) + params.modelCurve = ParamClasses.StringCurve(newModels.toTypedArray(), params.modelCurve.curve) idRegister[id] = params println("BPS - Registered Emitter ID \"$newId\".") 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 ed600c6..c9c0710 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/particles/Shapes.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/particles/Shapes.kt @@ -118,12 +118,12 @@ sealed class SpawningShape() { sealed class ForceFieldShape { data class Sphere( - val radius: Float = 3.0f, - val force: Pair = Pair(0.0f, 0.02f), + val radius: Float, + val force: Pair, ) : ForceFieldShape() data class Cube( - val size: Vector3f = Vector3f(1.0f, 1.0f, 1.0f), - val dir: Vector3f = Vector3f(0.0f, 1.0f, 0.0f), - val force: Float = 0.02f + val size: Vector3f, + val dir: Vector3f, + val force: Float ) : ForceFieldShape() } \ No newline at end of file