From 3bab1b9e72b91a36fb1eefccef1847fbf0826a64 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sun, 25 Dec 2022 00:15:18 +0800 Subject: [PATCH] Fix #333 and implement some of #509 (Dye Armor, Clone Banner, Clone Book, Firework Rocket, Clone Map, Extend Map, Decorate Shield, Dye Shulker Box, Suspicious Stew) --- .../plugin/client/DefaultClientPlugin.java | 23 +++- .../crafting/filler/ArmorDyeRecipeFiller.java | 87 ++++++++++++++ .../filler/BannerDuplicateRecipeFiller.java | 70 +++++++++++ .../filler/BookCloningRecipeFiller.java | 104 +++++++++++++++++ .../crafting/filler/CraftingRecipeFiller.java | 92 +++++++++++++++ .../filler/FireworkRocketRecipeFiller.java | 78 +++++++++++++ .../filler/MapCloningRecipeFiller.java | 52 +++++++++ .../filler/MapExtendingRecipeFiller.java | 85 ++++++++++++++ .../filler/ShieldDecorationRecipeFiller.java | 109 ++++++++++++++++++ .../filler/ShulkerBoxColoringFiller.java | 60 ++++++++++ .../filler/SuspiciousStewRecipeFiller.java | 63 ++++++++++ .../filler/TippedArrowRecipeFiller.java | 8 +- .../rei/plugin/common/DefaultPlugin.java | 1 + .../assets/roughlyenoughitems/lang/en_us.json | 2 + .../roughlyenoughitems/textures/gui/info.png | Bin 0 -> 4958 bytes 15 files changed, 830 insertions(+), 4 deletions(-) create mode 100644 default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/ArmorDyeRecipeFiller.java create mode 100644 default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/BannerDuplicateRecipeFiller.java create mode 100644 default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/BookCloningRecipeFiller.java create mode 100644 default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/CraftingRecipeFiller.java create mode 100644 default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/FireworkRocketRecipeFiller.java create mode 100644 default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/MapCloningRecipeFiller.java create mode 100644 default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/MapExtendingRecipeFiller.java create mode 100644 default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/ShieldDecorationRecipeFiller.java create mode 100644 default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/ShulkerBoxColoringFiller.java create mode 100644 default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/SuspiciousStewRecipeFiller.java create mode 100644 runtime/src/main/resources/assets/roughlyenoughitems/textures/gui/info.png diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java index 9c2216d9f..335c9cb63 100644 --- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java @@ -52,7 +52,7 @@ import me.shedaniel.rei.plugin.client.categories.beacon.DefaultBeaconPaymentCategory; import me.shedaniel.rei.plugin.client.categories.cooking.DefaultCookingCategory; import me.shedaniel.rei.plugin.client.categories.crafting.DefaultCraftingCategory; -import me.shedaniel.rei.plugin.client.categories.crafting.filler.TippedArrowRecipeFiller; +import me.shedaniel.rei.plugin.client.categories.crafting.filler.*; import me.shedaniel.rei.plugin.client.categories.tag.DefaultTagCategory; import me.shedaniel.rei.plugin.client.exclusionzones.DefaultPotionEffectExclusionZones; import me.shedaniel.rei.plugin.client.exclusionzones.DefaultRecipeBookExclusionZones; @@ -108,6 +108,19 @@ @Environment(EnvType.CLIENT) @ApiStatus.Internal public class DefaultClientPlugin implements REIClientPlugin, BuiltinClientPlugin { + private static final CraftingRecipeFiller[] CRAFTING_RECIPE_FILLERS = new CraftingRecipeFiller[]{ + new TippedArrowRecipeFiller(), + new ShulkerBoxColoringFiller(), + new BannerDuplicateRecipeFiller(), + new ShieldDecorationRecipeFiller(), + new SuspiciousStewRecipeFiller(), + new BookCloningRecipeFiller(), + new FireworkRocketRecipeFiller(), + new ArmorDyeRecipeFiller(), + new MapCloningRecipeFiller(), + new MapExtendingRecipeFiller() + }; + public DefaultClientPlugin() { ClientInternals.attachInstance((Supplier) () -> this, "builtinClientPlugin"); } @@ -190,6 +203,10 @@ public void registerCategories(CategoryRegistry registry) { return EventResult.pass(); }); + for (CraftingRecipeFiller filler : CRAFTING_RECIPE_FILLERS) { + filler.registerCategories(registry); + } + Set axes = Sets.newHashSet(), hoes = Sets.newHashSet(), shovels = Sets.newHashSet(); EntryRegistry.getInstance().getEntryStacks().filter(stack -> stack.getValueType() == ItemStack.class).map(stack -> ((ItemStack) stack.getValue()).getItem()).forEach(item -> { if (item instanceof AxeItem && axes.add(item)) { @@ -250,7 +267,9 @@ public void registerDisplays(DisplayRegistry registry) { for (Map.Entry entry : AbstractFurnaceBlockEntity.getFuel().entrySet()) { registry.add(new DefaultFuelDisplay(Collections.singletonList(EntryIngredients.of(entry.getKey())), Collections.emptyList(), entry.getValue())); } - registry.registerRecipesFiller(TippedArrowRecipe.class, RecipeType.CRAFTING, new TippedArrowRecipeFiller()::apply); + for (CraftingRecipeFiller filler : CRAFTING_RECIPE_FILLERS) { + filler.registerDisplays(registry); + } if (ComposterBlock.COMPOSTABLES.isEmpty()) { ComposterBlock.bootStrap(); } diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/ArmorDyeRecipeFiller.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/ArmorDyeRecipeFiller.java new file mode 100644 index 000000000..ab3f38ce7 --- /dev/null +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/ArmorDyeRecipeFiller.java @@ -0,0 +1,87 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.plugin.client.categories.crafting.filler; + +import me.shedaniel.rei.api.client.registry.entry.EntryRegistry; +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.util.EntryIngredients; +import me.shedaniel.rei.plugin.common.displays.crafting.DefaultCustomShapelessDisplay; +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.item.DyeItem; +import net.minecraft.world.item.DyeableLeatherItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.ArmorDyeRecipe; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Random; + +public class ArmorDyeRecipeFiller implements CraftingRecipeFiller { + @Override + public Collection apply(ArmorDyeRecipe recipe) { + List displays = new ArrayList<>(); + List> toDye = EntryRegistry.getInstance().getEntryStacks().filter(entry -> entry.getValueType() == ItemStack.class && entry.castValue().getItem() instanceof DyeableLeatherItem).toList(); + DyeColor[] colors = DyeColor.values(); + + for (EntryStack armor : toDye) { + ItemStack armorStack = armor.castValue(); + for (DyeColor color : colors) { + ItemStack output = armorStack.copy(); + DyeItem dyeItem = DyeItem.byColor(color); + output = DyeableLeatherItem.dyeArmor(output, List.of(dyeItem)); + displays.add(new DefaultCustomShapelessDisplay(recipe, + List.of(EntryIngredient.of(armor.copy()), + EntryIngredients.of(dyeItem)), + List.of(EntryIngredients.of(output)))); + } + + for (int i = 0; i < 9; i++) { + int dyes = new Random().nextInt(2) + 2; + List inputs = new ArrayList<>(); + List dyeItems = new ArrayList<>(); + inputs.add(EntryIngredient.of(armor.copy())); + for (int j = 0; j < dyes; j++) { + DyeColor color = colors[new Random().nextInt(colors.length)]; + DyeItem dyeItem = DyeItem.byColor(color); + dyeItems.add(dyeItem); + inputs.add(EntryIngredients.of(dyeItem)); + } + ItemStack output = armorStack.copy(); + output = DyeableLeatherItem.dyeArmor(output, dyeItems); + displays.add(new DefaultCustomShapelessDisplay(recipe, + inputs, List.of(EntryIngredients.of(output)))); + } + } + + return displays; + } + + @Override + public Class getRecipeClass() { + return ArmorDyeRecipe.class; + } +} diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/BannerDuplicateRecipeFiller.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/BannerDuplicateRecipeFiller.java new file mode 100644 index 000000000..ac37fa0e4 --- /dev/null +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/BannerDuplicateRecipeFiller.java @@ -0,0 +1,70 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.plugin.client.categories.crafting.filler; + +import com.mojang.datafixers.util.Pair; +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.util.EntryStacks; +import me.shedaniel.rei.plugin.common.displays.crafting.DefaultCustomShapelessDisplay; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.BannerDuplicateRecipe; + +import java.util.*; + +public class BannerDuplicateRecipeFiller implements CraftingRecipeFiller { + @Override + public Collection apply(BannerDuplicateRecipe recipe) { + List displays = new ArrayList<>(); + Map>> displayMap = new HashMap<>(); + + for (Pair pair : ShieldDecorationRecipeFiller.randomizeBanners()) { + Optional bannerOptional = Registry.ITEM.getOptional(new ResourceLocation(pair.getFirst().getName() + "_banner")); + if (bannerOptional.isEmpty()) continue; + Pair> builderPair = displayMap.computeIfAbsent(pair.getFirst(), color -> Pair.of(EntryIngredient.builder(), EntryStacks.of(bannerOptional.get()))); + builderPair.getFirst().add(EntryStacks.of(pair.getSecond())); + } + + for (Pair> pair : displayMap.values()) { + EntryIngredient inputsFirst = pair.getFirst().build(); + EntryStack inputsSecond = pair.getSecond(); + EntryIngredient.unifyFocuses(inputsFirst); + displays.add(new DefaultCustomShapelessDisplay(recipe, + List.of(inputsFirst, EntryIngredient.of(inputsSecond)), + List.of(inputsFirst))); + } + + return displays; + } + + @Override + public Class getRecipeClass() { + return BannerDuplicateRecipe.class; + } +} diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/BookCloningRecipeFiller.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/BookCloningRecipeFiller.java new file mode 100644 index 000000000..25a11cadb --- /dev/null +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/BookCloningRecipeFiller.java @@ -0,0 +1,104 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.plugin.client.categories.crafting.filler; + +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.util.CollectionUtils; +import me.shedaniel.rei.api.common.util.EntryStacks; +import me.shedaniel.rei.plugin.common.displays.crafting.DefaultCustomShapelessDisplay; +import net.minecraft.nbt.IntTag; +import net.minecraft.nbt.StringTag; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.WrittenBookItem; +import net.minecraft.world.item.crafting.BookCloningRecipe; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Random; + +public class BookCloningRecipeFiller implements CraftingRecipeFiller { + private static final String[] TITLES = new String[]{ + "Adventurer's Dreams", "Adventurer's Diary", "The Lost Journal", + "The Lost Diary", "The Lost Book", "The Lost Tome", "The Lost Codex", + "The Last Journal", "The Last Diary", "The Last Book", "The Last Tome", + "Secrets of the World", "Secrets of the Universe", "Secrets of the Cosmos", + "Myths of the World", "Myths of the Universe", "Myths of the Cosmos", + "Old Tales of the World", "Old Tales of the Universe", "Old Tales of the Cosmos", + "The World of the Legends", "The Universe of the Heroes", "The Cosmos of the Gods", + "Diary of a Villager", "Diary of a Farmer", "Diary of a Fisherman", + "Dungeon Journal", "Dungeon Diary", "Dungeon Book", "Dungeon Tome", + "Dunk Memes", "Top 10 Memes of 2019", "Top 10 Memes of 2020", + "Plastic Memories", "Kizumonogatari" + }; + private static final String[] AUTHORS = new String[]{ + "shedaniel", "Steve", "Alex", "Notch", "Herobrine", "God", + "Santa Claus", "The Easter Bunny", "The Tooth Fairy" + }; + + @Override + public Collection apply(BookCloningRecipe recipe) { + List displays = new ArrayList<>(); + + for (int i = 1; i <= 8; i++) { + EntryIngredient.Builder[] inputs = new EntryIngredient.Builder[9]; + for (int j = 0; j < 9; j++) { + inputs[j] = EntryIngredient.builder(); + } + EntryIngredient.Builder output = EntryIngredient.builder(); + for (int j = 0; j < 10; j++) { + ItemStack writtenBook = generateBook(); + ItemStack bookAndQuill = new ItemStack(Items.WRITABLE_BOOK); + inputs[0].add(EntryStacks.of(writtenBook)); + for (int k = 0; k < i; k++) { + inputs[k + 1].add(EntryStacks.of(bookAndQuill)); + } + ItemStack cloned = writtenBook.copy(); + cloned.addTagElement(WrittenBookItem.TAG_GENERATION, IntTag.valueOf(1)); + cloned.setCount(i); + output.add(EntryStacks.of(cloned)); + } + displays.add(new DefaultCustomShapelessDisplay(recipe, + CollectionUtils.map(inputs, EntryIngredient.Builder::build), + List.of(output.build()))); + } + + return displays; + } + + private ItemStack generateBook() { + ItemStack stack = new ItemStack(Items.WRITTEN_BOOK); + stack.addTagElement(WrittenBookItem.TAG_AUTHOR, StringTag.valueOf(AUTHORS[new Random().nextInt(AUTHORS.length)])); + stack.addTagElement(WrittenBookItem.TAG_TITLE, StringTag.valueOf(TITLES[new Random().nextInt(TITLES.length)])); + stack.addTagElement(WrittenBookItem.TAG_GENERATION, IntTag.valueOf(0)); + return stack; + } + + @Override + public Class getRecipeClass() { + return BookCloningRecipe.class; + } +} diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/CraftingRecipeFiller.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/CraftingRecipeFiller.java new file mode 100644 index 000000000..ad4353e52 --- /dev/null +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/CraftingRecipeFiller.java @@ -0,0 +1,92 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.plugin.client.categories.crafting.filler; + +import me.shedaniel.math.Point; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.DisplayRenderer; +import me.shedaniel.rei.api.client.gui.widgets.Widget; +import me.shedaniel.rei.api.client.gui.widgets.Widgets; +import me.shedaniel.rei.api.client.registry.category.CategoryRegistry; +import me.shedaniel.rei.api.client.registry.display.DisplayCategoryView; +import me.shedaniel.rei.api.client.registry.display.DisplayRegistry; +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.plugin.common.BuiltinPlugin; +import me.shedaniel.rei.plugin.common.displays.crafting.DefaultCraftingDisplay; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.crafting.CraftingRecipe; +import net.minecraft.world.item.crafting.RecipeType; + +import java.util.Collection; +import java.util.List; +import java.util.function.Function; + +public interface CraftingRecipeFiller extends Function> { + default void registerCategories(CategoryRegistry registry) { + } + + default void registerExtension(CategoryRegistry registry, ExtensionCallback callback) { + registry.get(BuiltinPlugin.CRAFTING).registerExtension((display, category, lastView) -> { + if (getRecipeClass().isInstance(display.getOptionalRecipe().orElse(null))) { + return new DisplayCategoryView<>() { + @Override + public DisplayRenderer getDisplayRenderer(DefaultCraftingDisplay display) { + return lastView.getDisplayRenderer(display); + } + + @Override + public List setupDisplay(DefaultCraftingDisplay display, Rectangle bounds) { + List widgets = lastView.setupDisplay(display, bounds); + callback.accept(bounds, widgets, display); + return widgets; + } + }; + } else { + return lastView; + } + }); + } + + default void registerDisplays(DisplayRegistry registry) { + registry.registerRecipesFiller(getRecipeClass(), RecipeType.CRAFTING, this::apply); + } + + default Widget createInfoWidget(Rectangle rectangle, DefaultCraftingDisplay display, Component... texts) { + Point point = new Point(rectangle.getMaxX() - 4, rectangle.y + 4); + Rectangle bounds = new Rectangle(point.getX() - 9, point.getY() + 1, 8, 8); + if (display.isShapeless()) { + bounds.x -= 10; + } + Widget widget = Widgets.createTexturedWidget(new ResourceLocation("roughlyenoughitems:textures/gui/info.png"), bounds.getX(), bounds.getY(), 0, 0, bounds.getWidth(), bounds.getHeight(), 1, 1, 1, 1); + return Widgets.withTooltip(Widgets.withBounds(widget, bounds), texts); + } + + Class getRecipeClass(); + + @FunctionalInterface + interface ExtensionCallback { + void accept(Rectangle bounds, List widgets, DefaultCraftingDisplay display); + } +} diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/FireworkRocketRecipeFiller.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/FireworkRocketRecipeFiller.java new file mode 100644 index 000000000..715fd61cf --- /dev/null +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/FireworkRocketRecipeFiller.java @@ -0,0 +1,78 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.plugin.client.categories.crafting.filler; + +import me.shedaniel.rei.api.client.registry.category.CategoryRegistry; +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.util.EntryIngredients; +import me.shedaniel.rei.api.common.util.EntryStacks; +import me.shedaniel.rei.plugin.common.displays.crafting.DefaultCustomShapelessDisplay; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.FireworkRocketRecipe; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class FireworkRocketRecipeFiller implements CraftingRecipeFiller { + @Override + public Collection apply(FireworkRocketRecipe recipe) { + List displays = new ArrayList<>(); + { + EntryIngredient[] inputs = new EntryIngredient[4]; + inputs[0] = EntryIngredients.of(Items.GUNPOWDER); + inputs[1] = EntryIngredients.of(Items.PAPER); + inputs[2] = EntryIngredient.of(EntryStack.empty().cast(), EntryStacks.of(Items.GUNPOWDER), EntryStacks.of(Items.GUNPOWDER)); + inputs[3] = EntryIngredient.of(EntryStack.empty().cast(), EntryStack.empty().cast(), EntryStacks.of(Items.GUNPOWDER)); + EntryStack[] outputs = new EntryStack[3]; + for (int i = 0; i < 3; i++) { + outputs[i] = EntryStacks.of(new ItemStack(Items.FIREWORK_ROCKET, 3)); + CompoundTag tag = outputs[i].getValue().getOrCreateTagElement("Fireworks"); + tag.putByte("Flight", (byte) (i + 1)); + } + displays.add(new DefaultCustomShapelessDisplay(recipe, + List.of(inputs), + List.of(EntryIngredient.of(outputs)))); + } + + return displays; + } + + @Override + public Class getRecipeClass() { + return FireworkRocketRecipe.class; + } + + @Override + public void registerCategories(CategoryRegistry registry) { + registerExtension(registry, (bounds, widgets, display) -> { + widgets.add(createInfoWidget(bounds, display, new TranslatableComponent("text.rei.crafting.firework.gunpowder.amount"))); + }); + } +} diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/MapCloningRecipeFiller.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/MapCloningRecipeFiller.java new file mode 100644 index 000000000..5e85b41d0 --- /dev/null +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/MapCloningRecipeFiller.java @@ -0,0 +1,52 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.plugin.client.categories.crafting.filler; + +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.api.common.util.EntryIngredients; +import me.shedaniel.rei.plugin.common.displays.crafting.DefaultCustomShapelessDisplay; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.MapCloningRecipe; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class MapCloningRecipeFiller implements CraftingRecipeFiller { + @Override + public Collection apply(MapCloningRecipe recipe) { + List displays = new ArrayList<>(); + + displays.add(new DefaultCustomShapelessDisplay(recipe, + List.of(EntryIngredients.of(Items.FILLED_MAP), EntryIngredients.of(Items.MAP)), + List.of(EntryIngredients.of(Items.FILLED_MAP, 2)))); + + return displays; + } + + @Override + public Class getRecipeClass() { + return MapCloningRecipe.class; + } +} diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/MapExtendingRecipeFiller.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/MapExtendingRecipeFiller.java new file mode 100644 index 000000000..0341f2e2a --- /dev/null +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/MapExtendingRecipeFiller.java @@ -0,0 +1,85 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.plugin.client.categories.crafting.filler; + +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.util.EntryIngredients; +import me.shedaniel.rei.plugin.common.displays.crafting.DefaultCustomDisplay; +import net.minecraft.ChatFormatting; +import net.minecraft.client.resources.language.I18n; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.MapExtendingRecipe; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class MapExtendingRecipeFiller implements CraftingRecipeFiller { + @Override + public Collection apply(MapExtendingRecipe recipe) { + List displays = new ArrayList<>(); + + for (int i = 0; i < 4; i++) { + EntryIngredient[] inputs = new EntryIngredient[9]; + for (int j = 0; j < 9; j++) { + if (j == 4) { + inputs[j] = mapWith("X", i, 1); + } else { + inputs[j] = EntryIngredients.of(Items.PAPER); + } + } + + displays.add(new DefaultCustomDisplay(recipe, + List.of(inputs), + List.of(mapWith("X", i + 1, 1)))); + } + + return displays; + } + + @Override + public Class getRecipeClass() { + return MapExtendingRecipe.class; + } + + public static EntryIngredient mapWith(String mapId, int scale, int count) { + EntryIngredient stacks = EntryIngredients.of(Items.FILLED_MAP, count); + String unknown = I18n.get("filled_map.unknown"); + for (EntryStack stack : stacks) { + stack.tooltipProcessor(($, tooltip) -> { + tooltip.entries().removeIf(entry -> entry.isText() && entry.getAsText().getString().equals(unknown)); + return tooltip; + }); + stack.tooltip( + new TranslatableComponent("filled_map.id", mapId).withStyle(ChatFormatting.GRAY), + new TranslatableComponent("filled_map.scale", (1 << scale)).withStyle(ChatFormatting.GRAY), + new TranslatableComponent("filled_map.level", scale, 4).withStyle(ChatFormatting.GRAY) + ); + } + return stacks; + } +} diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/ShieldDecorationRecipeFiller.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/ShieldDecorationRecipeFiller.java new file mode 100644 index 000000000..4af46ffdf --- /dev/null +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/ShieldDecorationRecipeFiller.java @@ -0,0 +1,109 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.plugin.client.categories.crafting.filler; + +import com.google.common.base.MoreObjects; +import com.mojang.datafixers.util.Pair; +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.util.EntryIngredients; +import me.shedaniel.rei.api.common.util.EntryStacks; +import me.shedaniel.rei.plugin.common.displays.crafting.DefaultCustomShapelessDisplay; +import net.minecraft.core.Registry; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.*; +import net.minecraft.world.item.crafting.ShieldDecorationRecipe; +import net.minecraft.world.level.block.entity.BannerPattern; +import net.minecraft.world.level.block.entity.BlockEntityType; + +import java.util.*; + +public class ShieldDecorationRecipeFiller implements CraftingRecipeFiller { + static List> randomizeBanners() { + List> out = new ArrayList<>(); + DyeColor[] colors = DyeColor.values(); + Random random = new Random(); + + for (DyeColor color : colors) { + Optional bannerOptional = Registry.ITEM.getOptional(new ResourceLocation(color.getName() + "_banner")); + if (bannerOptional.isEmpty()) continue; + out.add(Pair.of(color, new ItemStack(bannerOptional.get()))); + + for (int i = 0; i < 2; i++) { + BannerPattern.Builder patternBuilder = new BannerPattern.Builder(); + BannerPattern[] allPatterns = BannerPattern.values(); + for (int j = 0; j < 2; j++) { + BannerPattern pattern = allPatterns[random.nextInt(allPatterns.length - 1) + 1]; + patternBuilder.addPattern(pattern, colors[random.nextInt(colors.length)]); + } + ItemStack banner = new ItemStack(bannerOptional.get()); + CompoundTag newTag = new CompoundTag(); + newTag.put("Patterns", patternBuilder.toListTag()); + banner.addTagElement("BlockEntityTag", newTag); + out.add(Pair.of(color, banner)); + } + } + + return out; + } + + @Override + public Collection apply(ShieldDecorationRecipe recipe) { + List displays = new ArrayList<>(); + EntryIngredient shield = EntryIngredients.of(Items.SHIELD); + EntryIngredient.Builder inputsBuilder = EntryIngredient.builder(); + EntryIngredient.Builder outputsBuilder = EntryIngredient.builder(); + + for (Pair pair : randomizeBanners()) { + inputsBuilder.add(EntryStacks.of(pair.getSecond())); + outputsBuilder.add(createOutput(pair.getFirst(), pair.getSecond())); + } + + EntryIngredient inputs = inputsBuilder.build(); + EntryIngredient outputs = outputsBuilder.build(); + + EntryIngredient.unifyFocuses(inputs, outputs); + + displays.add(new DefaultCustomShapelessDisplay(recipe, + List.of(inputs, shield), + List.of(outputs))); + + return displays; + } + + private static EntryStack createOutput(DyeColor color, ItemStack banner) { + ItemStack output = new ItemStack(Items.SHIELD); + CompoundTag beTag = MoreObjects.firstNonNull(BlockItem.getBlockEntityData(banner), new CompoundTag()); + beTag.putInt("Base", color.getId()); + BlockItem.setBlockEntityData(output, BlockEntityType.BANNER, beTag); + return EntryStacks.of(output); + } + + @Override + public Class getRecipeClass() { + return ShieldDecorationRecipe.class; + } +} diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/ShulkerBoxColoringFiller.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/ShulkerBoxColoringFiller.java new file mode 100644 index 000000000..4dcbebf7d --- /dev/null +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/ShulkerBoxColoringFiller.java @@ -0,0 +1,60 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.plugin.client.categories.crafting.filler; + +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.util.EntryIngredients; +import me.shedaniel.rei.plugin.common.displays.crafting.DefaultCustomShapelessDisplay; +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.item.DyeItem; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.ShulkerBoxColoring; +import net.minecraft.world.level.block.ShulkerBoxBlock; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class ShulkerBoxColoringFiller implements CraftingRecipeFiller { + @Override + public Collection apply(ShulkerBoxColoring recipe) { + List displays = new ArrayList<>(); + EntryIngredient shulkerBox = EntryIngredients.of(Items.SHULKER_BOX); + + for (DyeColor color : DyeColor.values()) { + DyeItem dyeItem = DyeItem.byColor(color); + displays.add(new DefaultCustomShapelessDisplay(recipe, + List.of(EntryIngredients.of(dyeItem), shulkerBox), + List.of(EntryIngredients.of(ShulkerBoxBlock.getColoredItemStack(color))))); + } + + return displays; + } + + @Override + public Class getRecipeClass() { + return ShulkerBoxColoring.class; + } +} diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/SuspiciousStewRecipeFiller.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/SuspiciousStewRecipeFiller.java new file mode 100644 index 000000000..9afc74f26 --- /dev/null +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/SuspiciousStewRecipeFiller.java @@ -0,0 +1,63 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.plugin.client.categories.crafting.filler; + +import me.shedaniel.rei.api.client.registry.category.CategoryRegistry; +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.api.common.util.EntryIngredients; +import me.shedaniel.rei.plugin.common.displays.crafting.DefaultCustomShapelessDisplay; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.tags.ItemTags; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.SuspiciousStewRecipe; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class SuspiciousStewRecipeFiller implements CraftingRecipeFiller { + @Override + public Collection apply(SuspiciousStewRecipe recipe) { + List displays = new ArrayList<>(); + + displays.add(new DefaultCustomShapelessDisplay(recipe, + List.of(EntryIngredients.of(Items.BROWN_MUSHROOM), EntryIngredients.of(Items.RED_MUSHROOM), + EntryIngredients.of(Items.BOWL), EntryIngredients.ofItemTag(ItemTags.SMALL_FLOWERS)), + List.of(EntryIngredients.of(Items.SUSPICIOUS_STEW)))); + + return displays; + } + + @Override + public Class getRecipeClass() { + return SuspiciousStewRecipe.class; + } + + @Override + public void registerCategories(CategoryRegistry registry) { + registerExtension(registry, (bounds, widgets, display) -> { + widgets.add(createInfoWidget(bounds, display, new TranslatableComponent("text.rei.crafting.suspicious_stew"))); + }); + } +} diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/TippedArrowRecipeFiller.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/TippedArrowRecipeFiller.java index 014799f6f..b560c9d7e 100644 --- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/TippedArrowRecipeFiller.java +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/TippedArrowRecipeFiller.java @@ -40,9 +40,8 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.function.Function; -public class TippedArrowRecipeFiller implements Function> { +public class TippedArrowRecipeFiller implements CraftingRecipeFiller { @Override public Collection apply(TippedArrowRecipe recipe) { EntryIngredient arrowStack = EntryIngredient.of(EntryStacks.of(Items.ARROW)); @@ -68,4 +67,9 @@ public Collection apply(TippedArrowRecipe recipe) { return displays; } + + @Override + public Class getRecipeClass() { + return TippedArrowRecipe.class; + } } diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/DefaultPlugin.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/DefaultPlugin.java index c3465adff..a7a3066cf 100644 --- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/DefaultPlugin.java +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/DefaultPlugin.java @@ -82,6 +82,7 @@ public void registerItemComparators(ItemComparatorRegistry registry) { registry.registerNbt(Items.SPLASH_POTION); registry.registerNbt(Items.LINGERING_POTION); registry.registerNbt(Items.TIPPED_ARROW); + registry.register((context, stack) -> 0, Items.FIREWORK_ROCKET, Items.FILLED_MAP); } @Override diff --git a/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json b/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json index 54aa533c2..d0cb485ea 100755 --- a/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json +++ b/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json @@ -80,6 +80,8 @@ "text.rei.performance": "Performance Analysis", "text.rei.addons": "REI Addons", "text.rei.shapeless": "Shapeless", + "text.rei.crafting.firework.gunpowder.amount": "The amount of gunpowder affects the flight duration of the firework.", + "text.rei.crafting.suspicious_stew": "The resultant stew will have a random effect.", "text.rei.input.methods": "Input Methods", "text.rei.input.methods.reload.progress": "Progress: %s%%", "text.rei.input.methods.default": "Default", diff --git a/runtime/src/main/resources/assets/roughlyenoughitems/textures/gui/info.png b/runtime/src/main/resources/assets/roughlyenoughitems/textures/gui/info.png new file mode 100644 index 0000000000000000000000000000000000000000..50ef593ec7d5f36d3ee601d1b7b5c6f14df7ff7c GIT binary patch literal 4958 zcmeHKc~leU7LQ<+Ra{V16w-hK$|RYY?1G8}A!-mXB2=F;nM`1SEGB~qSdfZROF@J_ zTo89aMG-4i1gRB;wh9$0F4#pBQR|9WT#AbCOF+f*dd@qZ^ZK93nPk5E-TV9Q{oN&* zFG7L??QO=|&}cM!Nsu@Ud|R0=t3lwi*5UY!wht-PNO8_2|AUiCFq2a zRMKe1Uk-=It?%-*df7NhX>HMl3uj&zmZwGbEc!D)xX5Km!iCy-HQ^RcOnLK*#?~!8 zC*6WqSJye}tcGMaPMuxjUisLoe)Efze{iY>Q?O+mHhfFR9w;n7>bba!*0z^aat4S+<6)PLY)sJ2z}{movfw zHq;e{9+HKex%0zSW@tH2di4kGmYdT;a^W$rE?H9_f3hQH-Q6+m zEj-JhVT+tk99%iz;PAH22!rZQ{kUx`Fkp z5;!Ou8_QX_dH+X>M9rRUe~gITvoW7v9`$oBG1)K8VbqK@7^iMHHz{M3eV!YWWFW&83fQism4<+dX!9%~?8Y-qu+Gf611VrjLy) zsa!u%>f9Y@3mrMHn~XMk7F}-SeJ(spp4H#>Jbd7Ma)nFMy}h><54p(ugmvBiq7j#l zDo&UCM4XDvJZ9~3zjjbG-LAqatyADR-LL*?!-OY`2kFz$4S{9ofFS1ru1n@;e$&b$ zZf%*8oA-0gZ-LdJT^?83D;j>@{y=*3K=toi9^-1Mr5$eX)HvceX6u25zjw}^(jtTSD|ZYmvV`1+GuPT{esh0!w?OG^Ku=el57 z-DhmJwe4mdY<+ZW$M2~ENjI(bv{N#zO;*=copNBStEAiUbdP;3n<{C;~ z7EC9?zxQxZQ%H3=cg=4S>W2W<;as~U9YUyG<&okKOc8{{LuL~F5K=2 zPq{q7AnESqOy#2@h$s z0jo)W{}744|LZOVy;+c);~R8p`sno5;#ptHL@hhk_^01d_{nNROCko^7L_)Yq@6BW z(Ny@cWa(1JMYcnFyu-&YDo9AsjvQFyIyBJ3Bf!b4^H^aMa#eWN zUS;dR?Xl}~Bok{t#pc^pGgf(?&99&yF+I;GdJ!pjYI7$aS6SoPA zokw*J>TD=3(qHjddoZJL=(Z8r&XiwU;DLJPcT1U5ydO5K$*FG`5xAyK=TPt4Fe!bO zk96ETS=OV~)%7;FptG^1HKM2OEW441^Sm#SS@bU^6s}9R8e=aDOTGtm2DNiqYOQltk9Rr(Q$$xd-H9g8HhOc`5yyeKR9;vU! z96eXnlVrQ`rTe#+FUSL@8=a3HeGvP|MO$ep-bS5XH}3S@*`9f+PtopT3pQnIx4$y^ zZo&1g0Y8S8t=FWc`A6-abNQ}I$B-va?ziR#ze=G6mFU+0(3y*Zak`8IV>3cJM}%us zOiZDX6HKE@3&tvq<}=Nx#qcd0VqQ|P z3{Q%~g$l;BsWv`F5dcsT6h=3y;?;VQ(U)Py6@hz`n8l!*Rj4>$Muaqk?yu1ibPkil zWJ3W)av8#yYD4$YDU_lx@ytF5u<~WZP?T20Vi^nurU7MYbkQtWC={~T2n#_VpaJO< z)f8rg)Ot4)L@$Pz(BnE%OOYBi-GqtBH3^h2g8}yGul-YLrP4R>YJDFIfDe`t)3RVD zo262*`djF!fMo!r&!NAy(96KD4=aq&YZ7!g5wMI+0^m#%;K&iakRyOO5G>>&00JW*AzvwgI4H))5CMv?F}NSZTpbCj5{vKe zl?h4#pilu%fO6$LNQlBX#6jc&NX}8B5Sxc$Fq_Zi$qB>^rNBiqH98dr(n+eYXo96x zN1HcHgp2$_B)$xU$$l#diN`1}Lm=Yrb;Q(qeQ>6j`Gc1Tk8o70Ln%X5sZisjtoIX2v>x{li30hyPv*BK`Imfm$s>W=svwk4; zx2NV2OM6$n%XreOU-Ha=uqN3JhWOO&Ce&oIINanEJ?sMEmRMDy!6YbnOz34F(ya4Z2`=i|3r8N40 VQ9RGpP2IqnCJ6`@AD9uf@;?JvR+Rt% literal 0 HcmV?d00001