From 1f55aa676b7548f24595d26427debbc0496b4231 Mon Sep 17 00:00:00 2001 From: ByteDice Date: Thu, 21 Nov 2024 19:08:02 +0100 Subject: [PATCH] created "copy" argument for ManageEmitters command --- .../bytedice/bde_particles/Bde_particles.kt | 41 +++++- .../bde_particles/commands/GiveEmitterTool.kt | 6 +- .../bde_particles/commands/ManageEmitters.kt | 137 ++++++++++++++---- .../items/ParticleEmitterTool.kt | 54 +++---- .../particle/particleIdRegister.kt | 33 ++--- 5 files changed, 190 insertions(+), 81 deletions(-) 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 36b7da3..10f0a4f 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/Bde_particles.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/Bde_particles.kt @@ -2,7 +2,7 @@ package com.bytedice.bde_particles import com.bytedice.bde_particles.commands.GiveEmitterTool import com.bytedice.bde_particles.commands.ManageEmitters -import com.bytedice.bde_particles.items.getToolDetails +import com.bytedice.bde_particles.items.ParticleEmitterTool import com.bytedice.bde_particles.math.raycastFromPlayer import com.bytedice.bde_particles.particle.* import net.fabricmc.api.ModInitializer @@ -75,7 +75,7 @@ fun tick() { fun onRightClick(player: PlayerEntity, world: ServerWorld, hand: Hand) : TypedActionResult { val handItem = player.getStackInHand(hand) - val (isEmitterTool, emitterId) = getToolDetails(handItem) + val (isEmitterTool, emitterId) = ParticleEmitterTool.getToolDetails(handItem) val hitResult = raycastFromPlayer(player as ServerPlayerEntity, 50.0) val emitterParams = getParticleEmitterParams(emitterId) @@ -91,4 +91,41 @@ fun onRightClick(player: PlayerEntity, world: ServerWorld, hand: Hand) : TypedAc ALL_PARTICLE_EMITTERS += emitter return TypedActionResult(ActionResult.PASS, handItem) +} + + +fun emitterParamsToJSON(params: ParticleEmitterParams) : Map { + val allParticleParamsJSON: MutableList> = mutableListOf() + + for (particle in params.particleTypes) { + val particleParamsJSON = mapOf( + "shape" to particle.shape, + "blockCurve" to particle.blockCurve, + "rotRandom" to particle.rotRandom, + "rotVelRandom" to particle.rotVelRandom, + "rotVelCurve" to particle.rotVelCurve, + "sizeRandom" to particle.sizeRandom, + "uniformSize" to particle.uniformSize, + "sizeCurve" to particle.sizeCurve, + "velRandom" to particle.velRandom, + "forceFields" to particle.forceFields, + "gravity" to particle.gravity, + "drag" to particle.drag, + "minVel" to particle.minVel, + "lifeTime" to particle.lifeTime + ) + + allParticleParamsJSON.add(particleParamsJSON) + } + + val emitterParamsJSON = mapOf( + "maxCount" to params.maxCount, + "spawnsPerTick" to params.spawnsPerTick, + "loopDur" to params.loopDur, + "loopDelay" to params.loopDelay, + "loopCount" to params.loopCount, + "particleTypes" to allParticleParamsJSON + ) + + return emitterParamsJSON } \ 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 b7b1e4b..b718446 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/commands/GiveEmitterTool.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/commands/GiveEmitterTool.kt @@ -1,6 +1,6 @@ package com.bytedice.bde_particles.commands -import com.bytedice.bde_particles.items.makeData +import com.bytedice.bde_particles.items.ParticleEmitterTool import com.bytedice.bde_particles.particle.emitterIdRegister import com.mojang.brigadier.Command import com.mojang.brigadier.CommandDispatcher @@ -44,10 +44,10 @@ object GiveEmitterTool { 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}\"") + 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)).withItalic(true)) - context.source.player?.inventory?.insertStack(makeData(item.item, name, emitterId)) + context.source.player?.inventory?.insertStack(ParticleEmitterTool.makeData(item.item, name, emitterId)) context.source.sendFeedback({ feedback }, false) Command.SINGLE_SUCCESS } 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 a514286..cae4851 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/commands/ManageEmitters.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/commands/ManageEmitters.kt @@ -1,13 +1,18 @@ package com.bytedice.bde_particles.commands -import com.bytedice.bde_particles.particle.addToEmitterRegister -import com.bytedice.bde_particles.particle.emitterIdRegister -import com.bytedice.bde_particles.particle.getParticleEmitterParams +import com.bytedice.bde_particles.emitterParamsToJSON +import com.bytedice.bde_particles.particle.* import com.mojang.brigadier.Command import com.mojang.brigadier.CommandDispatcher import com.mojang.brigadier.arguments.StringArgumentType import com.mojang.brigadier.builder.LiteralArgumentBuilder import com.mojang.brigadier.suggestion.SuggestionsBuilder +import net.minecraft.component.DataComponentTypes +import net.minecraft.component.type.LoreComponent +import net.minecraft.component.type.NbtComponent +import net.minecraft.item.ItemStack +import net.minecraft.item.Items +import net.minecraft.nbt.NbtCompound import net.minecraft.server.command.CommandManager import net.minecraft.server.command.ServerCommandSource import net.minecraft.text.MutableText @@ -15,6 +20,8 @@ import net.minecraft.text.Style import net.minecraft.text.Text import net.minecraft.text.TextColor import java.awt.Color +import java.awt.TextComponent +import java.io.Serializable import java.util.concurrent.CompletableFuture @@ -29,7 +36,7 @@ import java.util.concurrent.CompletableFuture // [emitter id] // output -> removes the particle with that id - // config + // config // TODO // [emitter id] // <[particle index] / EMITTER> @@ -47,6 +54,7 @@ import java.util.concurrent.CompletableFuture // output -> all registered emitters // copy + // [emitter id] // output -> give player a command block with the particle params (should be paste-able in kotlin) @@ -93,21 +101,25 @@ fun argCreate() : LiteralArgumentBuilder { val emitterPresetVal = StringArgumentType.getString(context, "Registered Emitter ID") ?: "DEFAULT" val emitterPresetParams = getParticleEmitterParams(emitterPresetVal) - var newEmitterId = "NULL_EMITTER_ID" - if (emitterPresetParams != null) { - newEmitterId = addToEmitterRegister(emitterIdVal, emitterPresetParams).second - } + var newEmitterId = "NULL" + val emitterRegisterData: Pair - val feedback = if (newEmitterId in allEmitterIds) { - Text.literal("BPS - Emitter ID \"$newEmitterId\" already exists!\n" + - "BPS - Use \"/ManageEmitters list\" to view all Emitter ID's.") - .setStyle(Style.EMPTY.withColor(TextColor.fromRgb(Color(255, 0, 0).rgb))) + if (emitterPresetParams != null) { + emitterRegisterData = addToEmitterRegister(emitterIdVal, emitterPresetParams) + newEmitterId = emitterRegisterData.first } - else { - Text.literal("BPS - created particle emitter with ID \"$newEmitterId\".\n" + + else { emitterRegisterData = Pair("NULL", false) } + + val feedback = if (emitterRegisterData.second) { + Text.literal("BPS - Created particle emitter with ID \"$newEmitterId\".\n" + "BPS - This emitter will be removed on server restart! Use \"/ManageEmitters copy\" to save the data to your clipboard!") .setStyle(Style.EMPTY.withColor(TextColor.fromRgb(Color(0, 200, 0).rgb))) } + else { + Text.literal("BPS - Emitter ID \"$newEmitterId\" already exists!\n" + + "BPS - Use \"/ManageEmitters list\" to view all Emitter ID's.") + .setStyle(Style.EMPTY.withColor(TextColor.fromRgb(Color(200, 0, 0).rgb))) + } context.source.sendFeedback( { feedback }, false ) Command.SINGLE_SUCCESS @@ -119,11 +131,26 @@ fun argCreate() : LiteralArgumentBuilder { fun argRemove() : LiteralArgumentBuilder { return CommandManager.literal("remove") - .executes { context -> - val feedback = Text.literal("remove") - context.source.sendFeedback({ feedback }, false) - Command.SINGLE_SUCCESS - } + .then( + emitterIdSuggestion + .executes { context -> + val emitterIdVal = StringArgumentType.getString(context, "Registered Emitter ID") ?: "NULL" + val isRemoved = removeFromEmitterRegister(emitterIdVal) + + val feedback = if (isRemoved) { + Text.literal("BPS - Removed particle emitter with ID \"$emitterIdVal\".") + .setStyle(Style.EMPTY.withColor(TextColor.fromRgb(Color(0, 200, 0).rgb))) + } + else { + Text.literal("BPS - Emitter ID \"$emitterIdVal\" doesn't exist or is reserved!\n" + + "BPS - Use \"/ManageEmitters list\" to view all Emitter ID's.") + .setStyle(Style.EMPTY.withColor(TextColor.fromRgb(Color(200, 0, 0).rgb))) + } + + context.source.sendFeedback( { feedback }, false ) + Command.SINGLE_SUCCESS + } + ) } @@ -140,7 +167,16 @@ fun argConfig() : LiteralArgumentBuilder { fun argList() : LiteralArgumentBuilder { return CommandManager.literal("list") .executes { context -> - val feedback = Text.literal("remove") + val allEmittersString = allEmitterIds.joinToString(", ") + + val feedbackStatic = Text.literal("BPS - List of all available Emitter IDs:\n") + .setStyle(Style.EMPTY.withColor(TextColor.fromRgb(Color(0, 200, 0).rgb))) + + val feedbackVar = Text.literal(allEmittersString) + .setStyle(Style.EMPTY.withColor(TextColor.fromRgb(Color(255, 255, 255).rgb))) + + val feedback = feedbackStatic.append(feedbackVar) + context.source.sendFeedback({ feedback }, false) Command.SINGLE_SUCCESS } @@ -149,16 +185,57 @@ fun argList() : LiteralArgumentBuilder { fun argCopy() : LiteralArgumentBuilder { return CommandManager.literal("copy") - .executes { context -> - val feedback = Text.literal("remove") - context.source.sendFeedback({ feedback }, false) - Command.SINGLE_SUCCESS - } + .then( + emitterIdSuggestion + .executes { context -> + val emitterIdVal = StringArgumentType.getString(context, "Registered Emitter ID") + val commandBlock = makeCommandBlock( + emitterParamsToJSON( + getParticleEmitterParams( + emitterIdVal + )!! + ) + ) + + val feedback: MutableText + + if (context.source.server.areCommandBlocksEnabled()) { + feedback = Text.literal("BPS - Copied Emitter data as a JSON. Place down the command block and copy it to your clipboard to use the value.") + .setStyle(Style.EMPTY.withColor(Color(0, 200, 0).rgb)) + } + else { + feedback = Text.literal("BPS - Could not copy Emitter data: Command blocks aren't enabled. Go to server.properties and enable command blocks before retrying.") + .setStyle(Style.EMPTY.withColor(Color(200, 0, 0).rgb)) + + Command.SINGLE_SUCCESS + } + + + context.source.player?.inventory?.insertStack(commandBlock) + context.source.sendFeedback({ feedback }, false) + Command.SINGLE_SUCCESS + } + ) } -/* -fun argCopyPasta() : LiteralArgumentBuilder { - return -} -*/ +fun makeCommandBlock(emitterData: Map): ItemStack { + val i = ItemStack(Items.COMMAND_BLOCK) + + val nbt = NbtCompound() + nbt.putString("Command", emitterData.toString()) + nbt.putString("id", "minecraft:command_block") + nbt.putByte("powered", 0) + nbt.putByte("auto", 0) + nbt.putByte("UpdateLastExecution", 1) + nbt.putByte("conditionMet", 0) + nbt.putByte("TrackOutput", 1) + nbt.putInt("SuccessCount", 0) + + + val component: NbtComponent = NbtComponent.of(nbt) + + i.set(DataComponentTypes.BLOCK_ENTITY_DATA, component) + + return i +} \ No newline at end of file diff --git a/src/main/kotlin/com/bytedice/bde_particles/items/ParticleEmitterTool.kt b/src/main/kotlin/com/bytedice/bde_particles/items/ParticleEmitterTool.kt index 193c8ca..707c8bb 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/items/ParticleEmitterTool.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/items/ParticleEmitterTool.kt @@ -12,41 +12,41 @@ import net.minecraft.text.TextColor import java.awt.Color -fun makeData(itemId: Item, name: String, emitterId: String): ItemStack { - val i = ItemStack(itemId) +object ParticleEmitterTool { + fun makeData(itemId: Item, name: String, emitterId: String): ItemStack { + val i = ItemStack(itemId) - val nbt = NbtCompound() - nbt.putByte("BPS_particleTool", 1) - nbt.putString("BPS_emitterID", emitterId) + val nbt = NbtCompound() + nbt.putByte("BPS_particleTool", 1) + nbt.putString("BPS_emitterID", emitterId) - val component: NbtComponent = NbtComponent.of(nbt) + val component: NbtComponent = NbtComponent.of(nbt) - val displayName = Text.literal(name) - .setStyle(Style.EMPTY.withColor(TextColor.fromRgb(Color(0, 200, 0).rgb)).withItalic(true)) + val displayName = Text.literal(name) + .setStyle(Style.EMPTY.withColor(TextColor.fromRgb(Color(0, 200, 0).rgb)).withItalic(true)) - val loreLines = Text.literal("BPS - Bound to ID \"$emitterId\"") - .setStyle(Style.EMPTY.withColor(TextColor.fromRgb(Color(0, 200, 0).rgb)).withItalic(true)) + val loreLines = Text.literal("BPS - Bound to ID \"$emitterId\".") + .setStyle(Style.EMPTY.withColor(TextColor.fromRgb(Color(0, 200, 0).rgb)).withItalic(true)) - val lore = LoreComponent(listOf(loreLines)) + val lore = LoreComponent(listOf(loreLines)) - i.set(DataComponentTypes.ITEM_NAME, displayName) - i.set(DataComponentTypes.CUSTOM_DATA, component) - i.set(DataComponentTypes.LORE, lore) + i.set(DataComponentTypes.ITEM_NAME, displayName) + i.set(DataComponentTypes.CUSTOM_DATA, component) + i.set(DataComponentTypes.LORE, lore) - return i -} - - -fun getToolDetails(item: ItemStack) : Pair { - val customData = item.get(DataComponentTypes.CUSTOM_DATA) - val isParticleEmitterTool = customData?.nbt?.getByte("BPS_particleTool") == 1.toByte() - val emitterId = customData?.nbt?.getString("BPS_emitterID") - - return if (emitterId == null) { - Pair(isParticleEmitterTool, "") + return i } - else { - Pair(isParticleEmitterTool, emitterId) + + fun getToolDetails(item: ItemStack): Pair { + val customData = item.get(DataComponentTypes.CUSTOM_DATA) + val isParticleEmitterTool = customData?.nbt?.getByte("BPS_particleTool") == 1.toByte() + val emitterId = customData?.nbt?.getString("BPS_emitterID") + + return if (emitterId == null) { + Pair(isParticleEmitterTool, "") + } else { + Pair(isParticleEmitterTool, emitterId) + } } } \ No newline at end of file diff --git a/src/main/kotlin/com/bytedice/bde_particles/particle/particleIdRegister.kt b/src/main/kotlin/com/bytedice/bde_particles/particle/particleIdRegister.kt index 0c4dbaa..160f188 100644 --- a/src/main/kotlin/com/bytedice/bde_particles/particle/particleIdRegister.kt +++ b/src/main/kotlin/com/bytedice/bde_particles/particle/particleIdRegister.kt @@ -1,31 +1,26 @@ package com.bytedice.bde_particles.particle val emitterIdRegister: MutableMap = mutableMapOf() +val forbiddenIds = arrayOf("", "DEFAULT", "NULL") -fun returnParticleFunction(id: String) : ParticleEmitterParams? { - if (emitterIdRegister.containsKey(id)) { - return emitterIdRegister[id] - } - return null +fun addToEmitterRegister(id: String, params: ParticleEmitterParams) : Pair { + val newId = id.replace(" ", "_") + + if (newId in forbiddenIds && newId != "DEFAULT") {return Pair(newId, false) } + if (emitterIdRegister.containsKey(newId)) {return Pair(newId, false) } + + emitterIdRegister[id] = params + return Pair(newId, true) } -fun addToEmitterRegister(id: String, params: ParticleEmitterParams) : Pair { - val newId = id.replace(" ", "_") +fun removeFromEmitterRegister(id: String) : Boolean { + if (id in forbiddenIds) { return false } + if (!emitterIdRegister.containsKey(id)) { return false } - if (!emitterIdRegister.containsKey(id)) { - emitterIdRegister[id] = params - - val msg = "BPS - Successfully added Emitter ID \"$newId\" to register" - println(msg) - return Pair(msg, newId) - } - else { - val msg = "BPS - Emitter ID \"$newId\" is already registered, please choose another ID!" - println(msg) - return Pair(msg, newId) - } + emitterIdRegister.remove(id) + return true }