From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: violetc <58360096+s-yh-china@users.noreply.github.com> Date: Mon, 4 Sep 2023 00:16:09 +0800 Subject: [PATCH] Wool Hopper Counter This patch is Powered by fabric-carpet(https://github.com/gnembon/fabric-carpet) diff --git a/src/main/java/net/minecraft/world/item/crafting/Ingredient.java b/src/main/java/net/minecraft/world/item/crafting/Ingredient.java index e314f36951e9ac15c57137e24fce8c410373130a..dd232d9e86c5bf03cfb4597d3291a172d8c17741 100644 --- a/src/main/java/net/minecraft/world/item/crafting/Ingredient.java +++ b/src/main/java/net/minecraft/world/item/crafting/Ingredient.java @@ -35,7 +35,7 @@ public final class Ingredient implements Predicate { }, (recipeitemstack) -> { return Arrays.asList(recipeitemstack.getItems()); }); - private final Ingredient.Value[] values; + public final Ingredient.Value[] values; // Leaves - private -> public @Nullable public ItemStack[] itemStacks; @Nullable diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java index cee74a6c47cd56a17a8faf68405fee09d6fd4655..9cc932fb547686db7c06f7ef29e3b07b2e755982 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java @@ -447,7 +447,14 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen private static final java.util.function.BiPredicate IS_EMPTY_TEST = (itemstack, i) -> itemstack.isEmpty(); // Paper end - Perf: Optimize Hoppers + // Leaves start - hopper counter private static boolean ejectItems(Level world, BlockPos pos, HopperBlockEntity blockEntity) { + if (org.leavesmc.leaves.util.HopperCounter.isEnabled()) { + if (woolHopperCounter(world, pos, world.getBlockState(pos), (Container) blockEntity, blockEntity)) { + return true; + } + } + // Leaves end - hopper counter Container iinventory = HopperBlockEntity.getAttachedContainer(world, pos, blockEntity); if (iinventory == null) { @@ -511,6 +518,23 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen } } + // Leaves start - hopper counter + private static boolean woolHopperCounter(Level level, BlockPos blockPos, BlockState state, Container container, HopperBlockEntity hopper) { + net.minecraft.world.item.DyeColor woolColor = org.leavesmc.leaves.util.WoolUtils.getWoolColorAtPosition(level, blockPos.relative(state.getValue(HopperBlock.FACING))); + if (woolColor != null) { + for (int i = 0; i < container.getContainerSize(); ++i) { + if (!container.getItem(i).isEmpty()) { + ItemStack itemstack = container.getItem(i); + org.leavesmc.leaves.util.HopperCounter.getCounter(woolColor).add(level.getServer(), itemstack); + container.setItem(i, ItemStack.EMPTY); + } + } + return true; + } + return false; + } + // Leaves end - hopper counter + private static int[] getSlots(Container inventory, Direction side) { if (inventory instanceof WorldlyContainer iworldinventory) { return iworldinventory.getSlotsForFace(side); diff --git a/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java b/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java index 92a8c3e4fc400988b3d984e7632a8149a2ce152e..99823283690fcc1e6c0f76d8dcbcca9dfb50470d 100644 --- a/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java +++ b/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java @@ -34,6 +34,7 @@ public final class LeavesCommand extends Command { commands.put(Set.of("config"), new ConfigCommand()); commands.put(Set.of("update"), new UpdateCommand()); commands.put(Set.of("peaceful"), new PeacefulModeSwitchCommand()); + commands.put(Set.of("counter"), new CounterCommand()); return commands.entrySet().stream() .flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue()))) diff --git a/src/main/java/org/leavesmc/leaves/command/subcommands/CounterCommand.java b/src/main/java/org/leavesmc/leaves/command/subcommands/CounterCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..06b4d287bf545a51b9eeb7cd24fdc6a0c05271d9 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/command/subcommands/CounterCommand.java @@ -0,0 +1,121 @@ +package org.leavesmc.leaves.command.subcommands; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.JoinConfiguration; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextColor; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.item.DyeColor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.LeavesConfig; +import org.leavesmc.leaves.command.LeavesCommandUtil; +import org.leavesmc.leaves.command.LeavesSubcommand; +import org.leavesmc.leaves.util.HopperCounter; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class CounterCommand implements LeavesSubcommand { + + @Override + public boolean execute(CommandSender sender, String subCommand, String[] args) { + if (!LeavesConfig.hopperCounter) { + return false; + } + + if (args.length < 1) { + sender.sendMessage(Component.join(JoinConfiguration.noSeparators(), + Component.text("Hopper Counter: ", NamedTextColor.GRAY), + Component.text(HopperCounter.isEnabled(), HopperCounter.isEnabled() ? NamedTextColor.AQUA : NamedTextColor.GRAY) + )); + return true; + } + + if (!HopperCounter.isEnabled()) { + if (args[0].equals("enable")) { + HopperCounter.setEnabled(true); + sender.sendMessage(Component.text("Hopper Counter now is enabled", NamedTextColor.AQUA)); + } else { + sender.sendMessage(Component.text("Hopper Counter is not enabled", NamedTextColor.RED)); + } + return true; + } + + DyeColor color = DyeColor.byName(args[0], null); + if (color != null) { + HopperCounter counter = HopperCounter.getCounter(color); + if (args.length < 2) { + displayCounter(sender, counter, false); + } else { + switch (args[1]) { + case "reset" -> { + counter.reset(MinecraftServer.getServer()); + sender.sendMessage(Component.join(JoinConfiguration.noSeparators(), + Component.text("Restarted "), + Component.text(color.getName(), TextColor.color(color.getTextColor())), + Component.text(" counter") + )); + } + case "realtime" -> displayCounter(sender, counter, true); + } + } + return true; + } + + switch (args[0]) { + case "reset" -> { + HopperCounter.resetAll(MinecraftServer.getServer(), false); + sender.sendMessage(Component.text("Restarted all counters")); + } + case "disable" -> { + HopperCounter.setEnabled(false); + HopperCounter.resetAll(MinecraftServer.getServer(), true); + sender.sendMessage(Component.text("Hopper Counter now is disabled", NamedTextColor.GRAY)); + } + } + + return true; + } + + private void displayCounter(CommandSender sender, @NotNull HopperCounter counter, boolean realTime) { + for (Component component : counter.format(MinecraftServer.getServer(), realTime)) { + sender.sendMessage(component); + } + } + + @Override + public List tabComplete(CommandSender sender, String subCommand, String[] args) { + if (!LeavesConfig.hopperCounter) { + return Collections.emptyList(); + } + + switch (args.length) { + case 1 -> { + if (!HopperCounter.isEnabled()) { + return Collections.singletonList("enable"); + } + + List list = new ArrayList<>(Arrays.stream(DyeColor.values()).map(DyeColor::getName).toList()); + list.add("reset"); + list.add("disable"); + return LeavesCommandUtil.getListMatchingLast(sender, args, list); + } + + case 2 -> { + if (DyeColor.byName(args[0], null) != null) { + return LeavesCommandUtil.getListMatchingLast(sender, args, "reset", "realtime"); + } + } + } + + return Collections.emptyList(); + } + + @Override + public boolean tabCompletes() { + return LeavesConfig.hopperCounter; + } +} diff --git a/src/main/java/org/leavesmc/leaves/util/HopperCounter.java b/src/main/java/org/leavesmc/leaves/util/HopperCounter.java new file mode 100644 index 0000000000000000000000000000000000000000..1a83b3918bc040ab32e648b54b498e9a556c17a3 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/util/HopperCounter.java @@ -0,0 +1,338 @@ +package org.leavesmc.leaves.util; + +import it.unimi.dsi.fastutil.objects.Object2LongLinkedOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2LongMap; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.format.TextDecoration; +import net.minecraft.core.Registry; +import net.minecraft.core.RegistryAccess; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.item.DyeItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.RecipeHolder; +import net.minecraft.world.item.crafting.RecipeManager; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.level.block.AbstractBannerBlock; +import net.minecraft.world.level.block.BeaconBeamBlock; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.material.MapColor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.leavesmc.leaves.LeavesConfig; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +import static java.util.Map.entry; + +public class HopperCounter { + + private static boolean enabled = false; + private static final Map COUNTERS; + + static { + EnumMap counterMap = new EnumMap<>(DyeColor.class); + for (DyeColor color : DyeColor.values()) { + counterMap.put(color, new HopperCounter(color)); + } + COUNTERS = Collections.unmodifiableMap(counterMap); + } + + public final DyeColor color; + private final TextComponent coloredName; + private final Object2LongMap counter = new Object2LongLinkedOpenHashMap<>(); + private long startTick; + private long startMillis; + + private HopperCounter(DyeColor color) { + this.startTick = -1; + this.color = color; + this.coloredName = Component.text(color.getName(), TextColor.color(color.getTextColor())); + } + + public void add(MinecraftServer server, ItemStack stack) { + if (startTick < 0) { + startTick = server.overworld().getGameTime(); + startMillis = System.currentTimeMillis(); + } + Item item = stack.getItem(); + counter.put(item, counter.getLong(item) + stack.getCount()); + } + + public void reset(MinecraftServer server) { + counter.clear(); + startTick = server.overworld().getGameTime(); + startMillis = System.currentTimeMillis(); + } + + public List format(MinecraftServer server, boolean realTime) { + long ticks = Math.max(realTime ? (System.currentTimeMillis() - startMillis) / 50 : server.overworld().getGameTime() - startTick, -1); + + if (startTick < 0 || ticks == -1) { + return Collections.singletonList(Component.text().append(coloredName, Component.text(" hasn't started counting yet")).build()); + } + + long total = getTotalItems(); + if (total <= 0) { + return Collections.singletonList(Component.text() + .append(Component.text("No items for "), coloredName) + .append(Component.text(" yet ("), Component.text(String.format("%.2f ", ticks / (20.0 * 60.0)), Style.style(TextDecoration.BOLD))) + .append(Component.text("min"), Component.text(realTime ? " - real time" : ""), Component.text(")")) + .build()); + } + + List items = new ArrayList<>(); + items.add(Component.text() + .append(Component.text("Items for "), coloredName, Component.text(" ")) + .append(Component.text("("), Component.text(String.format("%.2f ", ticks * 1.0 / (20 * 60)), Style.style(TextDecoration.BOLD))) + .append(Component.text("min"), Component.text(realTime ? " - real time" : ""), Component.text("), ")) + .append(Component.text("total: "), Component.text(total, Style.style(TextDecoration.BOLD)), Component.text(", ")) + .append(Component.text("("), Component.text(String.format("%.1f", total * 1.0 * (20 * 60 * 60) / ticks), Style.style(TextDecoration.BOLD))) + .append(Component.text("/h):")) + .build()); + + counter.object2LongEntrySet().forEach(entry -> { + Item item = entry.getKey(); + Component name = Component.translatable(item.getDescriptionId()); + TextColor textColor = guessColor(server, item); + + if (textColor != null) { + name = name.style(name.style().merge(Style.style(textColor))); + } else { + name = name.style(name.style().merge(Style.style(TextDecoration.ITALIC))); + } + + long count = entry.getLongValue(); + items.add(Component.text() + .append(Component.text("- ", NamedTextColor.GRAY)) + .append(name) + .append(Component.text(": ", NamedTextColor.GRAY)) + .append(Component.text(count, Style.style(TextDecoration.BOLD)), Component.text(", ", NamedTextColor.GRAY)) + .append(Component.text(String.format("%.1f", count * (20.0 * 60.0 * 60.0) / ticks), Style.style(TextDecoration.BOLD))) + .append(Component.text("/h")) + .build()); + }); + return items; + } + + private static final Map DEFAULTS = Map.ofEntries( + entry(Items.DANDELION, Blocks.YELLOW_WOOL), + entry(Items.POPPY, Blocks.RED_WOOL), + entry(Items.BLUE_ORCHID, Blocks.LIGHT_BLUE_WOOL), + entry(Items.ALLIUM, Blocks.MAGENTA_WOOL), + entry(Items.AZURE_BLUET, Blocks.SNOW_BLOCK), + entry(Items.RED_TULIP, Blocks.RED_WOOL), + entry(Items.ORANGE_TULIP, Blocks.ORANGE_WOOL), + entry(Items.WHITE_TULIP, Blocks.SNOW_BLOCK), + entry(Items.PINK_TULIP, Blocks.PINK_WOOL), + entry(Items.OXEYE_DAISY, Blocks.SNOW_BLOCK), + entry(Items.CORNFLOWER, Blocks.BLUE_WOOL), + entry(Items.WITHER_ROSE, Blocks.BLACK_WOOL), + entry(Items.LILY_OF_THE_VALLEY, Blocks.WHITE_WOOL), + entry(Items.BROWN_MUSHROOM, Blocks.BROWN_MUSHROOM_BLOCK), + entry(Items.RED_MUSHROOM, Blocks.RED_MUSHROOM_BLOCK), + entry(Items.STICK, Blocks.OAK_PLANKS), + entry(Items.GOLD_INGOT, Blocks.GOLD_BLOCK), + entry(Items.IRON_INGOT, Blocks.IRON_BLOCK), + entry(Items.DIAMOND, Blocks.DIAMOND_BLOCK), + entry(Items.NETHERITE_INGOT, Blocks.NETHERITE_BLOCK), + entry(Items.SUNFLOWER, Blocks.YELLOW_WOOL), + entry(Items.LILAC, Blocks.MAGENTA_WOOL), + entry(Items.ROSE_BUSH, Blocks.RED_WOOL), + entry(Items.PEONY, Blocks.PINK_WOOL), + entry(Items.CARROT, Blocks.ORANGE_WOOL), + entry(Items.APPLE, Blocks.RED_WOOL), + entry(Items.WHEAT, Blocks.HAY_BLOCK), + entry(Items.PORKCHOP, Blocks.PINK_WOOL), + entry(Items.RABBIT, Blocks.PINK_WOOL), + entry(Items.CHICKEN, Blocks.WHITE_TERRACOTTA), + entry(Items.BEEF, Blocks.NETHERRACK), + entry(Items.ENCHANTED_GOLDEN_APPLE, Blocks.GOLD_BLOCK), + entry(Items.COD, Blocks.WHITE_TERRACOTTA), + entry(Items.SALMON, Blocks.ACACIA_PLANKS), + entry(Items.ROTTEN_FLESH, Blocks.BROWN_WOOL), + entry(Items.PUFFERFISH, Blocks.YELLOW_TERRACOTTA), + entry(Items.TROPICAL_FISH, Blocks.ORANGE_WOOL), + entry(Items.POTATO, Blocks.WHITE_TERRACOTTA), + entry(Items.MUTTON, Blocks.RED_WOOL), + entry(Items.BEETROOT, Blocks.NETHERRACK), + entry(Items.MELON_SLICE, Blocks.MELON), + entry(Items.POISONOUS_POTATO, Blocks.SLIME_BLOCK), + entry(Items.SPIDER_EYE, Blocks.NETHERRACK), + entry(Items.GUNPOWDER, Blocks.GRAY_WOOL), + entry(Items.TURTLE_SCUTE, Blocks.LIME_WOOL), + entry(Items.ARMADILLO_SCUTE, Blocks.ANCIENT_DEBRIS), + entry(Items.FEATHER, Blocks.WHITE_WOOL), + entry(Items.FLINT, Blocks.BLACK_WOOL), + entry(Items.LEATHER, Blocks.SPRUCE_PLANKS), + entry(Items.GLOWSTONE_DUST, Blocks.GLOWSTONE), + entry(Items.PAPER, Blocks.WHITE_WOOL), + entry(Items.BRICK, Blocks.BRICKS), + entry(Items.INK_SAC, Blocks.BLACK_WOOL), + entry(Items.SNOWBALL, Blocks.SNOW_BLOCK), + entry(Items.WATER_BUCKET, Blocks.WATER), + entry(Items.LAVA_BUCKET, Blocks.LAVA), + entry(Items.MILK_BUCKET, Blocks.WHITE_WOOL), + entry(Items.CLAY_BALL, Blocks.CLAY), + entry(Items.COCOA_BEANS, Blocks.COCOA), + entry(Items.BONE, Blocks.BONE_BLOCK), + entry(Items.COD_BUCKET, Blocks.BROWN_TERRACOTTA), + entry(Items.PUFFERFISH_BUCKET, Blocks.YELLOW_TERRACOTTA), + entry(Items.SALMON_BUCKET, Blocks.PINK_TERRACOTTA), + entry(Items.TROPICAL_FISH_BUCKET, Blocks.ORANGE_TERRACOTTA), + entry(Items.SUGAR, Blocks.WHITE_WOOL), + entry(Items.BLAZE_POWDER, Blocks.GOLD_BLOCK), + entry(Items.ENDER_PEARL, Blocks.WARPED_PLANKS), + entry(Items.NETHER_STAR, Blocks.DIAMOND_BLOCK), + entry(Items.PRISMARINE_CRYSTALS, Blocks.SEA_LANTERN), + entry(Items.PRISMARINE_SHARD, Blocks.PRISMARINE), + entry(Items.RABBIT_HIDE, Blocks.OAK_PLANKS), + entry(Items.CHORUS_FRUIT, Blocks.PURPUR_BLOCK), + entry(Items.SHULKER_SHELL, Blocks.SHULKER_BOX), + entry(Items.NAUTILUS_SHELL, Blocks.BONE_BLOCK), + entry(Items.HEART_OF_THE_SEA, Blocks.CONDUIT), + entry(Items.HONEYCOMB, Blocks.HONEYCOMB_BLOCK), + entry(Items.NAME_TAG, Blocks.BONE_BLOCK), + entry(Items.TOTEM_OF_UNDYING, Blocks.YELLOW_TERRACOTTA), + entry(Items.TRIDENT, Blocks.PRISMARINE), + entry(Items.GHAST_TEAR, Blocks.WHITE_WOOL), + entry(Items.PHANTOM_MEMBRANE, Blocks.BONE_BLOCK), + entry(Items.EGG, Blocks.BONE_BLOCK), + entry(Items.COPPER_INGOT, Blocks.COPPER_BLOCK), + entry(Items.AMETHYST_SHARD, Blocks.AMETHYST_BLOCK) + ); + + @Nullable + public static TextColor guessColor(@NotNull MinecraftServer server, Item item) { + RegistryAccess registryAccess = server.registryAccess(); + TextColor direct = fromItem(item, registryAccess); + if (direct != null) { + return direct; + } + + ResourceLocation id = registryAccess.registryOrThrow(Registries.ITEM).getKey(item); + for (RecipeType type : registryAccess.registryOrThrow(Registries.RECIPE_TYPE)) { + for (Recipe r : getAllMatching(server.getRecipeManager(), type, id, registryAccess)) { + for (Ingredient ingredient : r.getIngredients()) { + for (Collection stacks : getRecipeStacks(ingredient)) { + for (ItemStack itemStack : stacks) { + TextColor textColor = fromItem(itemStack.getItem(), registryAccess); + if (textColor != null) { + return textColor; + } + } + } + } + } + } + return null; + } + + @Nullable + public static TextColor fromItem(Item item, RegistryAccess registryAccess) { + if (DEFAULTS.containsKey(item)) { + return TextColor.color(appropriateColor(DEFAULTS.get(item).defaultMapColor().col)); + } + if (item instanceof DyeItem dye) { + return TextColor.color(appropriateColor(dye.getDyeColor().getMapColor().col)); + } + + Block block = null; + final Registry itemRegistry = registryAccess.registryOrThrow(Registries.ITEM); + final Registry blockRegistry = registryAccess.registryOrThrow(Registries.BLOCK); + ResourceLocation id = itemRegistry.getKey(item); + if (item instanceof BlockItem blockItem) { + block = blockItem.getBlock(); + } else if (blockRegistry.getOptional(id).isPresent()) { + block = blockRegistry.get(id); + } + + if (block != null) { + if (block instanceof AbstractBannerBlock) { + return TextColor.color(appropriateColor(((AbstractBannerBlock) block).getColor().getMapColor().col)); + } else if (block instanceof BeaconBeamBlock) { + return TextColor.color(appropriateColor(((BeaconBeamBlock) block).getColor().getMapColor().col)); + } + return TextColor.color(appropriateColor(block.defaultMapColor().col)); + } + return null; + } + + public static List> getAllMatching(@NotNull RecipeManager manager, RecipeType type, ResourceLocation output, final RegistryAccess registryAccess) { + RecipeHolder recipe = manager.byName.get(output); + if (recipe != null && recipe.value().getType().equals(type)) { + return List.of(recipe.value()); + } + if (!manager.byType.containsKey(type)) { + return List.of(); + } + + Collection> typeRecipes = manager.byType.get(type); + Registry regs = registryAccess.registryOrThrow(Registries.ITEM); + Item item = regs.get(output); + return typeRecipes.stream() + .>map(RecipeHolder::value) + .filter(r -> r.getResultItem(registryAccess).getItem() == item) + .toList(); + } + + public static List> getRecipeStacks(@NotNull Ingredient ingredient) { + return Arrays.stream(ingredient.values).map(Ingredient.Value::getItems).toList(); + } + + public static int appropriateColor(int color) { + if (color == 0) { + return MapColor.SNOW.col; + } + int r = (color >> 16 & 255); + int g = (color >> 8 & 255); + int b = (color & 255); + if (r < 70) r = 70; + if (g < 70) g = 70; + if (b < 70) b = 70; + return (r << 16) + (g << 8) + b; + } + + public long getTotalItems() { + return counter.isEmpty() ? 0 : counter.values().longStream().sum(); + } + + public static void resetAll(MinecraftServer server, boolean fresh) { + for (HopperCounter counter : COUNTERS.values()) { + counter.reset(server); + if (fresh) { + counter.startTick = -1; + } + } + } + + public static HopperCounter getCounter(DyeColor color) { + return COUNTERS.get(color); + } + + public static void setEnabled(boolean is) { + enabled = is; + } + + public static boolean isEnabled() { + return LeavesConfig.hopperCounter && enabled; + } +} diff --git a/src/main/java/org/leavesmc/leaves/util/WoolUtils.java b/src/main/java/org/leavesmc/leaves/util/WoolUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..a4cd63179a15e5f172c43a2da963e23d7d71fc28 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/util/WoolUtils.java @@ -0,0 +1,38 @@ +package org.leavesmc.leaves.util; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.Map; + +import static java.util.Map.entry; + +public class WoolUtils { + private static final Map WOOL_BLOCK_TO_DYE = Map.ofEntries( + entry(Blocks.WHITE_WOOL, DyeColor.WHITE), + entry(Blocks.ORANGE_WOOL, DyeColor.ORANGE), + entry(Blocks.MAGENTA_WOOL, DyeColor.MAGENTA), + entry(Blocks.LIGHT_BLUE_WOOL, DyeColor.LIGHT_BLUE), + entry(Blocks.YELLOW_WOOL, DyeColor.YELLOW), + entry(Blocks.LIME_WOOL, DyeColor.LIME), + entry(Blocks.PINK_WOOL, DyeColor.PINK), + entry(Blocks.GRAY_WOOL, DyeColor.GRAY), + entry(Blocks.LIGHT_GRAY_WOOL, DyeColor.LIGHT_GRAY), + entry(Blocks.CYAN_WOOL, DyeColor.CYAN), + entry(Blocks.PURPLE_WOOL, DyeColor.PURPLE), + entry(Blocks.BLUE_WOOL, DyeColor.BLUE), + entry(Blocks.BROWN_WOOL, DyeColor.BROWN), + entry(Blocks.GREEN_WOOL, DyeColor.GREEN), + entry(Blocks.RED_WOOL, DyeColor.RED), + entry(Blocks.BLACK_WOOL, DyeColor.BLACK) + ); + + public static DyeColor getWoolColorAtPosition(Level worldIn, BlockPos pos) { + BlockState state = worldIn.getBlockState(pos); + return WOOL_BLOCK_TO_DYE.get(state.getBlock()); + } +}