package com.tiedup.remake.commands; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.tiedup.remake.items.ModItems; import com.tiedup.remake.items.base.KnifeVariant; import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem; import java.util.Optional; import net.minecraft.resources.ResourceLocation; import net.minecraft.ChatFormatting; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.item.ItemStack; /** * Utility commands. * * Commands: * /kidnapset - Get a starter kit of mod items * /kidnapreload [type] - Reload data files (jobs, sales, gagtalk) */ public class KidnapSetCommand { public static void register( CommandDispatcher dispatcher ) { dispatcher.register(createKidnapSetCommand()); dispatcher.register(createKidnapReloadCommand()); } /** * Create the kidnapset command builder (for use as subcommand of /tiedup). * @return The command builder */ public static com.mojang.brigadier.builder.LiteralArgumentBuilder< CommandSourceStack > createKidnapSetCommand() { return Commands.literal("kidnapset") .requires(CommandHelper.REQUIRES_OP) .executes(KidnapSetCommand::giveSet); } /** * Create the kidnapreload command builder (for use as subcommand of /tiedup). * @return The command builder */ public static com.mojang.brigadier.builder.LiteralArgumentBuilder< CommandSourceStack > createKidnapReloadCommand() { return Commands.literal("kidnapreload") .requires(CommandHelper.REQUIRES_OP) .executes(ctx -> reload(ctx, "all")) .then(Commands.literal("jobs").executes(ctx -> reload(ctx, "jobs"))) .then( Commands.literal("sales").executes(ctx -> reload(ctx, "sales")) ) .then( Commands.literal("gagtalk").executes(ctx -> reload(ctx, "gagtalk") ) ) .then(Commands.literal("all").executes(ctx -> reload(ctx, "all"))); } /** * Give a starter kit of mod items to the player. */ private static int giveSet(CommandContext context) throws CommandSyntaxException { CommandSourceStack source = context.getSource(); Optional playerOpt = CommandHelper.getPlayerOrFail( source ); if (playerOpt.isEmpty()) return 0; ServerPlayer player = playerOpt.get(); int given = 0; // Binds given += giveDataDrivenItems(player, "ropes", 8); given += giveDataDrivenItems(player, "chain", 4); given += giveDataDrivenItems(player, "leather_straps", 4); // Gags given += giveDataDrivenItems(player, "cloth_gag", 4); given += giveDataDrivenItems(player, "ball_gag", 4); given += giveDataDrivenItems(player, "tape_gag", 4); // Blindfolds given += giveDataDrivenItems(player, "classic_blindfold", 4); given += giveDataDrivenItems(player, "blindfold_mask", 2); // Collars (data-driven) ItemStack classicCollars = com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem.createStack( new net.minecraft.resources.ResourceLocation("tiedup", "classic_collar")); classicCollars.setCount(4); given += giveItem(player, classicCollars); ItemStack shockCollars = com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem.createStack( new net.minecraft.resources.ResourceLocation("tiedup", "shock_collar")); shockCollars.setCount(2); given += giveItem(player, shockCollars); ItemStack gpsCollars = com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem.createStack( new net.minecraft.resources.ResourceLocation("tiedup", "gps_collar")); gpsCollars.setCount(2); given += giveItem(player, gpsCollars); // Tools given += giveItem( player, new ItemStack(ModItems.getKnife(KnifeVariant.IRON), 2) ); given += giveItem( player, new ItemStack(ModItems.getKnife(KnifeVariant.GOLDEN), 1) ); given += giveItem(player, new ItemStack(ModItems.WHIP.get(), 1)); given += giveItem(player, new ItemStack(ModItems.PADDLE.get(), 1)); // Controllers given += giveItem( player, new ItemStack(ModItems.SHOCKER_CONTROLLER.get(), 1) ); given += giveItem(player, new ItemStack(ModItems.GPS_LOCATOR.get(), 1)); // Keys and locks given += giveItem(player, new ItemStack(ModItems.PADLOCK.get(), 4)); given += giveItem(player, new ItemStack(ModItems.COLLAR_KEY.get(), 2)); given += giveItem(player, new ItemStack(ModItems.MASTER_KEY.get(), 1)); // Earplugs given += giveDataDrivenItems(player, "classic_earplugs", 4); // Rope arrows given += giveItem(player, new ItemStack(ModItems.ROPE_ARROW.get(), 16)); // Chloroform given += giveItem( player, new ItemStack(ModItems.CHLOROFORM_BOTTLE.get(), 2) ); given += giveItem(player, new ItemStack(ModItems.RAG.get(), 4)); int finalGiven = given; source.sendSuccess( () -> Component.translatable( "command.tiedup.kidnapset.gave", finalGiven ).withStyle(ChatFormatting.GREEN), true ); return finalGiven; } private static int giveDataDrivenItems(ServerPlayer player, String itemName, int count) { int given = 0; for (int i = 0; i < count; i++) { ItemStack stack = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", itemName)); if (!stack.isEmpty()) { giveItem(player, stack); given++; } } return given; } private static int giveItem(ServerPlayer player, ItemStack stack) { if (!player.getInventory().add(stack)) { // Drop on ground if inventory full player.drop(stack, false); } return 1; } /** * Reload data files. */ private static int reload( CommandContext context, String type ) { CommandSourceStack source = context.getSource(); int reloaded = 0; if (type.equals("all") || type.equals("jobs")) { com.tiedup.remake.util.tasks.JobLoader.init(); reloaded++; } if (type.equals("all") || type.equals("sales")) { com.tiedup.remake.util.tasks.SaleLoader.init(); reloaded++; } if (type.equals("all") || type.equals("gagtalk")) { // GagTalkManager is code-based (no external data files) // No reload needed - materials/logic defined in GagMaterial enum reloaded++; } int finalReloaded = reloaded; source.sendSuccess( () -> Component.translatable( "command.tiedup.kidnapreload.reloaded", type.equals("all") ? "all data files" : type, finalReloaded ).withStyle(ChatFormatting.GREEN), true ); return reloaded; } }