diff --git a/src/main/java/dev/xpple/seedmapper/command/arguments/BlockArgument.java b/src/main/java/dev/xpple/seedmapper/command/arguments/BlockArgument.java index 962e3fdb..ce52c1ce 100644 --- a/src/main/java/dev/xpple/seedmapper/command/arguments/BlockArgument.java +++ b/src/main/java/dev/xpple/seedmapper/command/arguments/BlockArgument.java @@ -10,6 +10,7 @@ import com.mojang.brigadier.suggestion.SuggestionsBuilder; import com.mojang.datafixers.util.Pair; import dev.xpple.seedmapper.command.CommandExceptions; +import dev.xpple.seedmapper.util.BlockColorConfig; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.minecraft.commands.SharedSuggestionProvider; import net.minecraft.world.level.material.MapColor; @@ -23,34 +24,66 @@ public class BlockArgument implements ArgumentType> { private static final Collection EXAMPLES = Arrays.asList("diamond_ore", "gold_ore", "nether_quartz_ore"); - public static final Map> BLOCKS = ImmutableMap.>builder() - .put("ancient_debris", Pair.of(Cubiomes.ANCIENT_DEBRIS(), MapColor.TERRACOTTA_BROWN.col)) - .put("andesite", Pair.of(Cubiomes.ANDESITE(), MapColor.STONE.col)) - .put("basalt", Pair.of(Cubiomes.BASALT(), MapColor.COLOR_BLACK.col)) - .put("blackstone", Pair.of(Cubiomes.BLACKSTONE(), MapColor.COLOR_BLACK.col)) - .put("clay", Pair.of(Cubiomes.CLAY(), MapColor.CLAY.col)) - .put("coal_ore", Pair.of(Cubiomes.COAL_ORE(), MapColor.COLOR_BLACK.col)) - .put("copper_ore", Pair.of(Cubiomes.COPPER_ORE(), MapColor.COLOR_ORANGE.col)) - .put("deepslate", Pair.of(Cubiomes.DEEPSLATE(), MapColor.DEEPSLATE.col)) - .put("diamond_ore", Pair.of(Cubiomes.DIAMOND_ORE(), MapColor.DIAMOND.col)) - .put("diorite", Pair.of(Cubiomes.DIORITE(), MapColor.QUARTZ.col)) - .put("dirt", Pair.of(Cubiomes.DIRT(), MapColor.DIRT.col)) - .put("emerald_ore", Pair.of(Cubiomes.EMERALD_ORE(), MapColor.EMERALD.col)) - .put("gold_ore", Pair.of(Cubiomes.GOLD_ORE(), MapColor.GOLD.col)) - .put("granite", Pair.of(Cubiomes.GRANITE(), MapColor.DIRT.col)) - .put("gravel", Pair.of(Cubiomes.GRAVEL(), MapColor.STONE.col)) - .put("iron_ore", Pair.of(Cubiomes.IRON_ORE(), MapColor.RAW_IRON.col)) - .put("lapis_ore", Pair.of(Cubiomes.LAPIS_ORE(), MapColor.LAPIS.col)) - .put("magma_block", Pair.of(Cubiomes.MAGMA_BLOCK(), MapColor.NETHER.col)) - .put("netherrack", Pair.of(Cubiomes.NETHERRACK(), MapColor.NETHER.col)) - .put("nether_gold_ore", Pair.of(Cubiomes.NETHER_GOLD_ORE(), MapColor.GOLD.col)) - .put("nether_quartz_ore", Pair.of(Cubiomes.NETHER_QUARTZ_ORE(), MapColor.QUARTZ.col)) - .put("raw_copper_block", Pair.of(Cubiomes.RAW_COPPER_BLOCK(), MapColor.COLOR_YELLOW.col)) - .put("raw_iron_block", Pair.of(Cubiomes.RAW_IRON_BLOCK(), MapColor.COLOR_YELLOW.col)) - .put("redstone_ore", Pair.of(Cubiomes.REDSTONE_ORE(), MapColor.FIRE.col)) - .put("soul_sand", Pair.of(Cubiomes.SOUL_SAND(), MapColor.COLOR_BROWN.col)) - .put("stone", Pair.of(Cubiomes.STONE(), MapColor.STONE.col)) - .put("tuff", Pair.of(Cubiomes.TUFF(), MapColor.COLOR_GRAY.col)) + // 只存储方块名称和对应的Cubiomes ID,颜色从配置中获取 + public static final Map BLOCK_IDS = ImmutableMap.builder() + .put("ancient_debris", Cubiomes.ANCIENT_DEBRIS()) + .put("andesite", Cubiomes.ANDESITE()) + .put("basalt", Cubiomes.BASALT()) + .put("blackstone", Cubiomes.BLACKSTONE()) + .put("clay", Cubiomes.CLAY()) + .put("coal_ore", Cubiomes.COAL_ORE()) + .put("copper_ore", Cubiomes.COPPER_ORE()) + .put("deepslate", Cubiomes.DEEPSLATE()) + .put("diamond_ore", Cubiomes.DIAMOND_ORE()) + .put("diorite", Cubiomes.DIORITE()) + .put("dirt", Cubiomes.DIRT()) + .put("emerald_ore", Cubiomes.EMERALD_ORE()) + .put("gold_ore", Cubiomes.GOLD_ORE()) + .put("granite", Cubiomes.GRANITE()) + .put("gravel", Cubiomes.GRAVEL()) + .put("iron_ore", Cubiomes.IRON_ORE()) + .put("lapis_ore", Cubiomes.LAPIS_ORE()) + .put("magma_block", Cubiomes.MAGMA_BLOCK()) + .put("netherrack", Cubiomes.NETHERRACK()) + .put("nether_gold_ore", Cubiomes.NETHER_GOLD_ORE()) + .put("nether_quartz_ore", Cubiomes.NETHER_QUARTZ_ORE()) + .put("raw_copper_block", Cubiomes.RAW_COPPER_BLOCK()) + .put("raw_iron_block", Cubiomes.RAW_IRON_BLOCK()) + .put("redstone_ore", Cubiomes.REDSTONE_ORE()) + .put("soul_sand", Cubiomes.SOUL_SAND()) + .put("stone", Cubiomes.STONE()) + .put("tuff", Cubiomes.TUFF()) + .build(); + + // 默认颜色映射,用于重置 + public static final Map DEFAULT_COLORS = ImmutableMap.builder() + .put("ancient_debris", MapColor.TERRACOTTA_BROWN.col) + .put("andesite", MapColor.STONE.col) + .put("basalt", MapColor.COLOR_BLACK.col) + .put("blackstone", MapColor.COLOR_BLACK.col) + .put("clay", MapColor.CLAY.col) + .put("coal_ore", MapColor.COLOR_BLACK.col) + .put("copper_ore", MapColor.COLOR_ORANGE.col) + .put("deepslate", MapColor.DEEPSLATE.col) + .put("diamond_ore", MapColor.DIAMOND.col) + .put("diorite", MapColor.QUARTZ.col) + .put("dirt", MapColor.DIRT.col) + .put("emerald_ore", MapColor.EMERALD.col) + .put("gold_ore", MapColor.GOLD.col) + .put("granite", MapColor.DIRT.col) + .put("gravel", MapColor.STONE.col) + .put("iron_ore", MapColor.RAW_IRON.col) + .put("lapis_ore", MapColor.LAPIS.col) + .put("magma_block", MapColor.NETHER.col) + .put("netherrack", MapColor.NETHER.col) + .put("nether_gold_ore", MapColor.GOLD.col) + .put("nether_quartz_ore", MapColor.QUARTZ.col) + .put("raw_copper_block", MapColor.COLOR_YELLOW.col) + .put("raw_iron_block", MapColor.COLOR_YELLOW.col) + .put("redstone_ore", MapColor.FIRE.col) + .put("soul_sand", MapColor.COLOR_BROWN.col) + .put("stone", MapColor.STONE.col) + .put("tuff", MapColor.COLOR_GRAY.col) .build(); public static BlockArgument block() { @@ -66,17 +99,23 @@ public static Pair getBlock(CommandContext parse(StringReader reader) throws CommandSyntaxException { int cursor = reader.getCursor(); String blockString = reader.readUnquotedString(); - Pair blockPair = BLOCKS.get(blockString); - if (blockPair == null) { + + // 检查方块是否存在 + if (!BLOCK_IDS.containsKey(blockString)) { reader.setCursor(cursor); throw CommandExceptions.UNKNOWN_BLOCK_EXCEPTION.create(blockString); } - return blockPair; + + // 从配置获取颜色,如果没有则使用默认颜色 + int blockId = BLOCK_IDS.get(blockString); + int color = BlockColorConfig.getColor(blockString, DEFAULT_COLORS.getOrDefault(blockString, MapColor.STONE.col)); + + return Pair.of(blockId, color); } @Override public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { - return SharedSuggestionProvider.suggest(BLOCKS.keySet(), builder); + return SharedSuggestionProvider.suggest(BLOCK_IDS.keySet(), builder); } @Override diff --git a/src/main/java/dev/xpple/seedmapper/command/arguments/BlockColorConfig.java b/src/main/java/dev/xpple/seedmapper/command/arguments/BlockColorConfig.java new file mode 100644 index 00000000..1d77e148 --- /dev/null +++ b/src/main/java/dev/xpple/seedmapper/command/arguments/BlockColorConfig.java @@ -0,0 +1,66 @@ +package dev.xpple.seedmapper.util; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +import net.fabricmc.loader.api.FabricLoader; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; + +public class BlockColorConfig { + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + private static final Path CONFIG_PATH = FabricLoader.getInstance().getConfigDir().resolve("seedmapper_block_colors.json"); + private static Map customColors = new HashMap<>(); + + static { + loadConfig(); + } + + public static int getColor(String blockName, int defaultColor) { + return customColors.getOrDefault(blockName, defaultColor); + } + + public static void setColor(String blockName, int color) { + customColors.put(blockName, color); + saveConfig(); + } + + public static void resetColor(String blockName) { + customColors.remove(blockName); + saveConfig(); + } + + public static void resetAllColors() { + customColors.clear(); + saveConfig(); + } + + private static void loadConfig() { + if (Files.exists(CONFIG_PATH)) { + try { + String json = Files.readString(CONFIG_PATH); + customColors = GSON.fromJson(json, new TypeToken>(){}.getType()); + if (customColors == null) { + customColors = new HashMap<>(); + } + } catch (IOException e) { + e.printStackTrace(); + customColors = new HashMap<>(); + } + } + } + + private static void saveConfig() { + try { + Files.createDirectories(CONFIG_PATH.getParent()); + String json = GSON.toJson(customColors); + Files.writeString(CONFIG_PATH, json); + } catch (IOException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/main/java/dev/xpple/seedmapper/command/commands/BlockColorCommands.java b/src/main/java/dev/xpple/seedmapper/command/commands/BlockColorCommands.java new file mode 100644 index 00000000..2540ee87 --- /dev/null +++ b/src/main/java/dev/xpple/seedmapper/command/commands/BlockColorCommands.java @@ -0,0 +1,57 @@ +package dev.xpple.seedmapper.command; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import dev.xpple.seedmapper.command.arguments.BlockArgument; +import dev.xpple.seedmapper.util.BlockColorConfig; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.minecraft.text.Text; + +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; + +public class BlockColorCommands { + public static void register(CommandDispatcher dispatcher) { + dispatcher.register(literal("blockcolor") + .then(literal("set") + .then(argument("block", StringArgumentType.word()) + .then(argument("color", IntegerArgumentType.integer(0, 0xFFFFFF)) + .executes(context -> { + String block = StringArgumentType.getString(context, "block"); + int color = IntegerArgumentType.getInteger(context, "color"); + + if (!BlockArgument.BLOCK_IDS.containsKey(block)) { + throw CommandExceptions.UNKNOWN_BLOCK_EXCEPTION.create(block); + } + + BlockColorConfig.setColor(block, color); + context.getSource().sendFeedback(Text.literal("Set color for " + block + " to #" + + String.format("%06X", color))); + return 1; + }))) + ) + .then(literal("reset") + .then(argument("block", StringArgumentType.word()) + .executes(context -> { + String block = StringArgumentType.getString(context, "block"); + + if (!BlockArgument.BLOCK_IDS.containsKey(block)) { + throw CommandExceptions.UNKNOWN_BLOCK_EXCEPTION.create(block); + } + + BlockColorConfig.resetColor(block); + context.getSource().sendFeedback(Text.literal("Reset color for " + block)); + return 1; + })) + ) + .then(literal("resetall") + .executes(context -> { + BlockColorConfig.resetAllColors(); + context.getSource().sendFeedback(Text.literal("Reset all block colors")); + return 1; + }) + ) + ); + } +}