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 3eb899a..546c103 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/Bde_particles.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/Bde_particles.kt @@ -22,7 +22,7 @@ import net.minecraft.world.World // TODO: finish the particle ticking // TODO: save particle emitters in world file, or kill them on server restart (so they don't linger forever) // TODO: make custom commands to create particles easier (only temporarily saved) -// TODO: add interpolation curves (easing) +// TODO: add interpolation curves (easing). Also remake the Array's to Triple // TODO: kill all particles command diff --git a/src/main/kotlin/com/bytedice/bde_particles/DisplayEntity.kt b/src/main/kotlin/com/bytedice/bde_particles/DisplayEntity.kt index b55ad2f..c3c8b36 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/DisplayEntity.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/DisplayEntity.kt @@ -73,7 +73,7 @@ class DisplayEntity(private var properties: DisplayEntityProperties?) { } fun kill() { - if (entity == null) { println("BPS - Particle entity is null!"); return } + if (entity == null) { println("BPS - Particle Emitter entity is null!"); return } entity?.kill() } } \ No newline at end of file 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 d691a9c..ac26c16 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/commands/GiveEmitterTool.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/commands/GiveEmitterTool.kt @@ -28,11 +28,10 @@ object GiveEmitterTool { val emitterIdSuggestion = CommandManager.argument("Emitter ID", StringArgumentType.string()) .suggests { _, builder -> - val suggestionsBuilder = SuggestionsBuilder(builder.remaining, 0) allEmitterIds.forEach { key -> - suggestionsBuilder.suggest(key) + builder.suggest(key) } - CompletableFuture.completedFuture(suggestionsBuilder.build()) + CompletableFuture.completedFuture(builder.build()) } dispatcher.register( diff --git a/src/main/kotlin/com/bytedice/bde_particles/commands/ManageConfigArgs.kt b/src/main/kotlin/com/bytedice/bde_particles/commands/ManageConfigArgs.kt index f7a7953..0bfe0f2 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/commands/ManageConfigArgs.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/commands/ManageConfigArgs.kt @@ -1,6 +1,9 @@ package com.bytedice.bde_particles.commands + +import com.bytedice.bde_particles.particleIdRegister.SpawningShape import com.bytedice.bde_particles.particleIdRegister.updateSingleParam import com.mojang.brigadier.Command +import com.mojang.brigadier.arguments.FloatArgumentType import com.mojang.brigadier.arguments.IntegerArgumentType import com.mojang.brigadier.arguments.StringArgumentType import com.mojang.brigadier.builder.LiteralArgumentBuilder @@ -10,20 +13,41 @@ import net.minecraft.server.command.ServerCommandSource import net.minecraft.text.MutableText import net.minecraft.text.Style import net.minecraft.text.Text +import org.joml.Vector2f +import org.joml.Vector3f +import org.lwjgl.system.linux.X11 import java.awt.Color fun argUpdateEmitterParam(context: CommandContext, paramName: String, typeValue: Any) : MutableText { val emitterIdVal = StringArgumentType.getString(context, "Registered Emitter ID") - - val success = updateSingleParam(emitterIdVal, -1, "maxCount", typeValue) + val success = updateSingleParam(emitterIdVal, -1, paramName, typeValue) val feedback = if (success) { - Text.literal("BPS - Successfully updated Emitter ID \"$emitterIdVal\" parameter \"$paramName\" to value \"$typeValue\"") + Text.literal("BPS - Successfully updated Emitter ID \"$emitterIdVal\": Parameter \"$paramName\", value \"$typeValue\"") .setStyle(Style.EMPTY.withColor(Color(0, 200, 0).rgb)) } else { - Text.literal("BPS - Failed to update Emitter ID \"$emitterIdVal\" parameter \"$paramName\" to value \"$typeValue\": Unknown Error") + Text.literal("BPS - Failed to update Emitter ID \"$emitterIdVal\": Parameter \"$paramName\", value \"$typeValue\": Unknown Error\n" + + "Try checking if the emitter and parameter exist, and the value is the correct type.") + .setStyle(Style.EMPTY.withColor(Color(200, 0, 0).rgb)) + } + + return feedback +} + + +fun argUpdateParticleParam(context: CommandContext, particleIndex: Int, paramName: String, typeValue: Any) : MutableText { + val emitterIdVal = StringArgumentType.getString(context, "Registered Emitter ID") + val success = updateSingleParam(emitterIdVal, particleIndex, paramName, typeValue) + + val feedback = if (success) { + Text.literal("BPS - Successfully updated Emitter ID \"$emitterIdVal\": Index \"$particleIndex\", parameter \"$paramName\", value \"$typeValue\"") + .setStyle(Style.EMPTY.withColor(Color(0, 200, 0).rgb)) + } + else { + Text.literal("BPS - Failed to update Emitter ID \"$emitterIdVal\": Index \"$particleIndex\", parameter \"$paramName\", value \"$typeValue\": Unknown Error\n" + + "Try checking if the emitter, particle index, and parameter exist, and the value is the correct type.") .setStyle(Style.EMPTY.withColor(Color(200, 0, 0).rgb)) } @@ -92,4 +116,144 @@ class ArgConfigEmitterKeys { } ) } +} + + +class ArgConfigParticleKeys { + fun shape() : LiteralArgumentBuilder { + return CommandManager.literal("shape") + .then( + CommandManager.literal("circle") + .then( + CommandManager.argument("Radius", FloatArgumentType.floatArg()) + .executes { context -> + val particleIndex = IntegerArgumentType.getInteger(context, "Particle Index") + val radius = FloatArgumentType.getFloat(context, "Radius") + val feedback = argUpdateParticleParam(context, particleIndex, "shape", SpawningShape.Circle(radius)) + context.source.sendFeedback( { feedback }, false) + Command.SINGLE_SUCCESS + } + ) + ) + .then( + CommandManager.literal("rect") + .then( + CommandManager.argument("Width", FloatArgumentType.floatArg()) + .then( + CommandManager.argument("Height", FloatArgumentType.floatArg()) + .executes { context -> + val particleIndex = IntegerArgumentType.getInteger(context, "Particle Index") + val w = FloatArgumentType.getFloat(context, "Width") + val h = FloatArgumentType.getFloat(context, "Height") + val feedback = argUpdateParticleParam(context, particleIndex, "shape", SpawningShape.Rect(Vector2f(w, h))) + context.source.sendFeedback( { feedback }, false) + Command.SINGLE_SUCCESS + } + ) + ) + ) + .then( + CommandManager.literal("cube") + .then( + CommandManager.argument("X", FloatArgumentType.floatArg()) + .then( + CommandManager.argument("Y", FloatArgumentType.floatArg()) + .then( + CommandManager.argument("Z", FloatArgumentType.floatArg()) + .executes { context -> + val particleIndex = IntegerArgumentType.getInteger(context, "Particle Index") + val x = FloatArgumentType.getFloat(context, "X") + val y = FloatArgumentType.getFloat(context, "Y") + val z = FloatArgumentType.getFloat(context, "Z") + val feedback = argUpdateParticleParam(context, particleIndex, "shape", SpawningShape.Cube(Vector3f(x, y, z))) + context.source.sendFeedback( { feedback }, false) + Command.SINGLE_SUCCESS + } + ) + ) + ) + ) + .then( + CommandManager.literal("sphere") + .then( + CommandManager.argument("Radius", FloatArgumentType.floatArg()) + .executes { context -> + val particleIndex = IntegerArgumentType.getInteger(context, "Particle Index") + val radius = FloatArgumentType.getFloat(context, "Radius") + val feedback = argUpdateParticleParam(context, particleIndex, "shape", SpawningShape.Sphere(radius)) + context.source.sendFeedback( { feedback }, false) + Command.SINGLE_SUCCESS + } + ) + ) + } + fun blockCurve() : LiteralArgumentBuilder { + return CommandManager.literal("blockCurve") + .then( + CommandManager.argument("Array (separate by comma)", StringArgumentType.string()) + .executes { context -> + val typeValue = StringArgumentType.getString(context, "Array (separate by comma)") + val typeArray = typeValue.split(",").toTypedArray() + val feedback = argUpdateEmitterParam(context, "blockCurve", typeArray) + context.source.sendFeedback({ feedback }, false) + Command.SINGLE_SUCCESS + } + ) + } + fun rotRandom() : LiteralArgumentBuilder { + // I'd like to introduce you to, drumroll please... *drumroll*... The pyramid of "X1,Y1,Z1,X2,Y2,Z2" + return CommandManager.literal("rotRandom") + .then(CommandManager.argument("X1", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Y1", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Z1", FloatArgumentType.floatArg()) + .then(CommandManager.argument("X2", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Y2", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Z2", FloatArgumentType.floatArg()) + .executes { context -> + val x1 = FloatArgumentType.getFloat(context, "X1") + val y1 = FloatArgumentType.getFloat(context, "Y1") + val z1 = FloatArgumentType.getFloat(context, "Z1") + val x2 = FloatArgumentType.getFloat(context, "X2") + val y2 = FloatArgumentType.getFloat(context, "Y2") + val z2 = FloatArgumentType.getFloat(context, "Z2") + + val feedback = argUpdateEmitterParam(context, "rotRandom", Pair(Vector3f(x1, y1, z1), Vector3f(x2, y2, z2))) + context.source.sendFeedback({ feedback }, false) + Command.SINGLE_SUCCESS + } + ) + ) + ) + ) + ) + ) + } + fun rotVelRandom() : LiteralArgumentBuilder { + // I'd like to introduce you to, drumroll please... *drumroll*... The pyramid of "X1,Y1,Z1,X2,Y2,Z2" + return CommandManager.literal("rotVelRandom") + .then(CommandManager.argument("X1", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Y1", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Z1", FloatArgumentType.floatArg()) + .then(CommandManager.argument("X2", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Y2", FloatArgumentType.floatArg()) + .then(CommandManager.argument("Z2", FloatArgumentType.floatArg()) + .executes { context -> + val x1 = FloatArgumentType.getFloat(context, "X1") + val y1 = FloatArgumentType.getFloat(context, "Y1") + val z1 = FloatArgumentType.getFloat(context, "Z1") + val x2 = FloatArgumentType.getFloat(context, "X2") + val y2 = FloatArgumentType.getFloat(context, "Y2") + val z2 = FloatArgumentType.getFloat(context, "Z2") + + val feedback = argUpdateEmitterParam(context, "rotVelRandom", Pair(Vector3f(x1, y1, z1), Vector3f(x2, y2, z2))) + context.source.sendFeedback({ feedback }, false) + Command.SINGLE_SUCCESS + } + ) + ) + ) + ) + ) + ) + } } \ No newline at end of file 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 b9490cd..8ef0d0e 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/commands/ManageEmitters.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/commands/ManageEmitters.kt @@ -4,6 +4,7 @@ import com.bytedice.bde_particles.emitterParamsToJson import com.bytedice.bde_particles.particleIdRegister.* import com.mojang.brigadier.Command import com.mojang.brigadier.CommandDispatcher +import com.mojang.brigadier.arguments.IntegerArgumentType import com.mojang.brigadier.arguments.StringArgumentType import com.mojang.brigadier.builder.LiteralArgumentBuilder import com.mojang.brigadier.builder.RequiredArgumentBuilder @@ -69,17 +70,17 @@ object ManageEmitters { val allEmitterIds = emitterIdRegister.keys -// TODO: maybe make this a Command.literal() +// TODO: maybe make this a Command.literal() if possible val emitterIdSuggestion: RequiredArgumentBuilder = CommandManager.argument("Registered Emitter ID", StringArgumentType.string()) .suggests { _, builder -> - val suggestionsBuilder = SuggestionsBuilder(builder.remaining, 0) allEmitterIds.forEach { key -> - suggestionsBuilder.suggest(key) + builder.suggest(key) } - CompletableFuture.completedFuture(suggestionsBuilder.build()) + CompletableFuture.completedFuture(builder.build()) } -val configKeys = ArgConfigEmitterKeys() +val emitterConfigKeys = ArgConfigEmitterKeys() +val particleConfigKeys = ArgConfigParticleKeys() // TODO: fix "new emitter id" error @@ -222,11 +223,26 @@ fun argConfig() : LiteralArgumentBuilder { emitterIdSuggestion .then( CommandManager.literal("EMITTER") - .then(configKeys.maxCount()) - .then(configKeys.spawnsPerTick()) - .then(configKeys.loopDur()) - .then(configKeys.loopDelay()) - .then(configKeys.loopCount()) + .then(emitterConfigKeys.maxCount()) + .then(emitterConfigKeys.spawnsPerTick()) + .then(emitterConfigKeys.loopDur()) + .then(emitterConfigKeys.loopDelay()) + .then(emitterConfigKeys.loopCount()) + ) + .then( + CommandManager.argument("Particle Index", IntegerArgumentType.integer()) + .suggests { context, builder -> + val emitterId = StringArgumentType.getString(context, "Registered Emitter ID") + + getEmitterParams(emitterId)?.particleTypes?.indices?.forEach { + builder.suggest(it) + } + + CompletableFuture.completedFuture(builder.build()) + } + .then(particleConfigKeys.shape()) + .then(particleConfigKeys.blockCurve()) + .then(particleConfigKeys.rotRandom()) ) ) }