diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java index d412110b2..bcefff087 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java @@ -84,7 +84,7 @@ public class BukkitRecipeManager implements RecipeManager { if (ceRecipe.category() != null) { shapelessRecipe.setCategory(CraftingBookCategory.valueOf(Objects.requireNonNull(ceRecipe.category()).name())); } - for (Ingredient ingredient : ceRecipe.ingredients()) { + for (Ingredient ingredient : ceRecipe.ingredientsInUse()) { shapelessRecipe.addIngredient(new RecipeChoice.MaterialChoice(ingredientToBukkitMaterials(ingredient))); } try { @@ -207,6 +207,7 @@ public class BukkitRecipeManager implements RecipeManager { private final Map>> byType; private final Map> byId; private final Map>> byResult; + private final Map>> byIngredient; private final VanillaRecipeReader recipeReader; private final List injectedDataPackRecipes; private final List registeredCustomRecipes; @@ -220,6 +221,7 @@ public class BukkitRecipeManager implements RecipeManager { this.plugin = plugin; this.byType = new HashMap<>(); this.byId = new HashMap<>(); + this.byIngredient = new HashMap<>(); this.byResult = new HashMap<>(); this.injectedDataPackRecipes = new ArrayList<>(); this.registeredCustomRecipes = new ArrayList<>(); @@ -285,6 +287,7 @@ public class BukkitRecipeManager implements RecipeManager { this.byType.clear(); this.byId.clear(); this.byResult.clear(); + this.byIngredient.clear(); this.dataPackRecipes.clear(); try { @@ -338,9 +341,7 @@ public class BukkitRecipeManager implements RecipeManager { BUKKIT_RECIPE_FACTORIES.get(recipe.type()).accept(key, recipe); try { this.registeredCustomRecipes.add(key); - this.byType.computeIfAbsent(recipe.type(), k -> new ArrayList<>()).add(recipe); - this.byId.put(id, recipe); - this.byResult.computeIfAbsent(recipe.result().item().id(), k -> new ArrayList<>()).add(recipe); + addInternalRecipe(id, recipe); } catch (Exception e) { plugin.logger().warn("Failed to add custom recipe " + id, e); } @@ -356,11 +357,20 @@ public class BukkitRecipeManager implements RecipeManager { return this.byResult.getOrDefault(result, List.of()); } - // example: stone button - public void addVanillaInternalRecipe(Key id, Recipe recipe) { + @Override + public List> getRecipeByIngredient(Key ingredient) { + return this.byIngredient.getOrDefault(ingredient, List.of()); + } + + private void addInternalRecipe(Key id, Recipe recipe) { this.byType.computeIfAbsent(recipe.type(), k -> new ArrayList<>()).add(recipe); this.byId.put(id, recipe); this.byResult.computeIfAbsent(recipe.result().item().id(), k -> new ArrayList<>()).add(recipe); + for (Ingredient ingredient : recipe.ingredientsInUse()) { + for (Holder holder : ingredient.items()) { + this.byIngredient.computeIfAbsent(holder.value(), k -> new ArrayList<>()).add(recipe); + } + } } @Nullable @@ -561,7 +571,7 @@ public class BukkitRecipeManager implements RecipeManager { }); this.injectedDataPackRecipes.add(key); } - this.addVanillaInternalRecipe(id, ceRecipe); + this.addInternalRecipe(id, ceRecipe); } private void handleDataPackStoneCuttingRecipe(Key id, VanillaStoneCuttingRecipe recipe) { @@ -583,7 +593,7 @@ public class BukkitRecipeManager implements RecipeManager { Ingredient.of(holders), new CustomRecipeResult<>(new CloneableConstantItem(recipe.result().isCustom() ? Key.of("!internal:custom") : Key.of(recipe.result().id()), result), recipe.result().count()) ); - this.addVanillaInternalRecipe(id, ceRecipe); + this.addInternalRecipe(id, ceRecipe); } private void handleDataPackShapedRecipe(Key id, VanillaShapedRecipe recipe, Consumer callback) { @@ -641,7 +651,7 @@ public class BukkitRecipeManager implements RecipeManager { }); this.injectedDataPackRecipes.add(key); } - this.addVanillaInternalRecipe(id, ceRecipe); + this.addInternalRecipe(id, ceRecipe); } private void handleDataPackCookingRecipe(Key id, @@ -701,7 +711,7 @@ public class BukkitRecipeManager implements RecipeManager { }); this.injectedDataPackRecipes.add(key); } - this.addVanillaInternalRecipe(id, ceRecipe); + this.addInternalRecipe(id, ceRecipe); } private List tagToMaterials(Key tag) { @@ -802,7 +812,7 @@ public class BukkitRecipeManager implements RecipeManager { @SuppressWarnings("unchecked") private static void injectShapelessRecipe(Key id, CustomShapelessRecipe recipe) throws ReflectiveOperationException { - List> actualIngredients = recipe.ingredients(); + List> actualIngredients = recipe.ingredientsInUse(); Object shapelessRecipe = getNMSRecipe(id); recipeToMcRecipeHolder.put(recipe, shapelessRecipe); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomCookingRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomCookingRecipe.java index 84f8ec7a8..971e51a34 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomCookingRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomCookingRecipe.java @@ -4,6 +4,8 @@ import net.momirealms.craftengine.core.item.recipe.input.RecipeInput; import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput; import net.momirealms.craftengine.core.util.Key; +import java.util.List; + public abstract class CustomCookingRecipe extends AbstractRecipe { protected final CookingRecipeCategory category; protected final Ingredient ingredient; @@ -49,4 +51,9 @@ public abstract class CustomCookingRecipe extends AbstractRecipe { public int cookingTime() { return cookingTime; } + + @Override + public List> ingredientsInUse() { + return List.of(ingredient); + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomShapedRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomShapedRecipe.java index 509d67f68..d5e4b7877 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomShapedRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomShapedRecipe.java @@ -32,6 +32,11 @@ public class CustomShapedRecipe extends CustomCraftingTableRecipe { return this.parsedPattern.matches((CraftingInput) input); } + @Override + public List> ingredientsInUse() { + return new ArrayList<>(this.pattern.ingredients().values()); + } + @Override public @NotNull Key type() { return RecipeTypes.SHAPED; diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomShapelessRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomShapelessRecipe.java index 83fd18b03..f0bb3cc87 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomShapelessRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomShapelessRecipe.java @@ -26,7 +26,8 @@ public class CustomShapelessRecipe extends CustomCraftingTableRecipe { return placementInfo; } - public List> ingredients() { + @Override + public List> ingredientsInUse() { return ingredients; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomStoneCuttingRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomStoneCuttingRecipe.java index 0a10b1dbd..1c14ee66e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomStoneCuttingRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomStoneCuttingRecipe.java @@ -29,6 +29,11 @@ public class CustomStoneCuttingRecipe extends AbstractRecipe { return this.ingredient.test(((SingleItemInput) input).input()); } + @Override + public List> ingredientsInUse() { + return List.of(ingredient); + } + @Override public @NotNull Key type() { return RecipeTypes.STONE_CUTTING; diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/Recipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/Recipe.java index c3e835ca5..1e99f00ca 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/Recipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/Recipe.java @@ -6,6 +6,8 @@ import net.momirealms.craftengine.core.util.Key; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; + public interface Recipe { boolean matches(RecipeInput input); @@ -14,6 +16,8 @@ public interface Recipe { CustomRecipeResult result(); + List> ingredientsInUse(); + @NotNull Key type(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeManager.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeManager.java index f84742cf5..ccdbcb228 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeManager.java @@ -28,6 +28,8 @@ public interface RecipeManager extends Reloadable, ConfigSectionParser { List> getRecipeByResult(Key result); + List> getRecipeByIngredient(Key ingredient); + @Nullable Recipe getRecipe(Key type, RecipeInput input); diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java index 8da62a276..178af26ec 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java @@ -237,12 +237,20 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { c.setItemOnCursor(newItem); return; } - List> inRecipes = this.plugin.recipeManager().getRecipeByResult(itemId); - player.playSound(Constants.SOUND_CLICK_BUTTON); - if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), itemId, e.gui(), inRecipes, 0, 0); - } else { - openNoRecipePage(player, itemId, e.gui()); + if (LEFT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().getRecipeByResult(itemId); + player.playSound(Constants.SOUND_CLICK_BUTTON); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0); + } else { + openNoRecipePage(player, itemId, e.gui(), 0); + } + } else if (RIGHT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().getRecipeByIngredient(itemId); + player.playSound(Constants.SOUND_CLICK_BUTTON); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0); + } } }); } @@ -262,7 +270,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { .open(player); } - public void openNoRecipePage(Player player, Key result, Gui parentGui) { + public void openNoRecipePage(Player player, Key result, Gui parentGui, int depth) { GuiLayout layout = new GuiLayout( " ", " ", @@ -277,6 +285,12 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { Item item = this.plugin.itemManager().createWrappedItem(result, player); item.count(item.maxStackSize()); c.setItemOnCursor(item); + } else if (RIGHT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().getRecipeByIngredient(result); + player.playSound(Constants.SOUND_CLICK_BUTTON); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1); + } } })) .addIngredient('^', player.hasPermission(GET_ITEM_PERMISSION) ? GuiElement.constant(this.plugin.itemManager().createWrappedItem(Constants.RECIPE_GET_ITEM, player), (e, c) -> { @@ -312,28 +326,29 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { .open(player); } - public void openRecipePage(Player player, Key result, Gui parentGui, List> recipes, int index, int depth) { + public void openRecipePage(Player player, Gui parentGui, List> recipes, int index, int depth) { if (index >= recipes.size()) return; if (depth > MAX_RECIPE_DEPTH) return; Recipe recipe = recipes.get(index); Key recipeType = recipe.type(); if (recipeType == RecipeTypes.SHAPELESS || recipeType == RecipeTypes.SHAPED) { - openCraftingRecipePage(player, result, (CustomCraftingTableRecipe) recipe, parentGui, recipes, index, depth); + openCraftingRecipePage(player, (CustomCraftingTableRecipe) recipe, parentGui, recipes, index, depth); return; } if (recipeType == RecipeTypes.BLASTING || recipeType == RecipeTypes.CAMPFIRE_COOKING || recipeType == RecipeTypes.SMOKING || recipeType == RecipeTypes.SMELTING) { - openCookingRecipePage(player, result, (CustomCookingRecipe) recipe, parentGui, recipes, index, depth); + openCookingRecipePage(player, (CustomCookingRecipe) recipe, parentGui, recipes, index, depth); return; } if (recipeType == RecipeTypes.STONE_CUTTING) { - openStoneCuttingRecipePage(player, result, (CustomStoneCuttingRecipe) recipe, parentGui, recipes, index, depth); + openStoneCuttingRecipePage(player, (CustomStoneCuttingRecipe) recipe, parentGui, recipes, index, depth); return; } } - public void openStoneCuttingRecipePage(Player player, Key result, CustomStoneCuttingRecipe recipe, Gui parentGui, List> recipes, int index, int depth) { + public void openStoneCuttingRecipePage(Player player, CustomStoneCuttingRecipe recipe, Gui parentGui, List> recipes, int index, int depth) { Key previous = index > 0 ? Constants.RECIPE_PREVIOUS_PAGE_AVAILABLE : Constants.RECIPE_PREVIOUS_PAGE_BLOCK; Key next = index + 1 < recipes.size() ? Constants.RECIPE_NEXT_PAGE_AVAILABLE : Constants.RECIPE_NEXT_PAGE_BLOCK; + Key result = recipe.result().item().id(); List> ingredients = new ArrayList<>(); net.momirealms.craftengine.core.item.recipe.Ingredient ingredient = recipe.ingredient(); @@ -354,6 +369,24 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { Item item = this.plugin.itemManager().createWrappedItem(result, player); item.count(item.maxStackSize()); c.setItemOnCursor(item); + return; + } + if (LEFT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().getRecipeByResult(result); + if (inRecipes == recipes) return; + player.playSound(Constants.SOUND_CLICK_BUTTON); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0); + } else { + openNoRecipePage(player, result, e.gui(), 0); + } + } else if (RIGHT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().getRecipeByIngredient(result); + if (inRecipes == recipes) return; + player.playSound(Constants.SOUND_CLICK_BUTTON); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0); + } } })) .addIngredient('^', player.hasPermission(GET_ITEM_PERMISSION) ? GuiElement.constant(this.plugin.itemManager().createWrappedItem(Constants.RECIPE_GET_ITEM, player), (e, c) -> { @@ -374,10 +407,22 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { c.setItemOnCursor(item); return; } - List> inRecipes = plugin.recipeManager().getRecipeByResult(e.item().id()); - if (!inRecipes.isEmpty()) { + if (LEFT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().getRecipeByResult(e.item().id()); + if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); - openRecipePage(player, e.item().id(), e.gui(), inRecipes, 0, depth + 1); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0); + } else { + openNoRecipePage(player, e.item().id(), e.gui(), 0); + } + } else if (RIGHT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().getRecipeByIngredient(e.item().id()); + if (inRecipes == recipes) return; + player.playSound(Constants.SOUND_CLICK_BUTTON); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0); + } } })) .addIngredient('=', GuiElement.constant(this.plugin.itemManager().getCustomItem(Constants.RECIPE_BACK) @@ -399,7 +444,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { c.cancel(); if (index + 1 < recipes.size()) { player.playSound(Constants.SOUND_CHANGE_PAGE, 0.25f, 1); - openRecipePage(player, result, parentGui, recipes, index + 1, depth); + openRecipePage(player, parentGui, recipes, index + 1, depth); } })) .addIngredient('<', GuiElement.constant(this.plugin.itemManager() @@ -412,7 +457,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { c.cancel(); if (index > 0) { player.playSound(Constants.SOUND_CHANGE_PAGE, 0.25f, 1); - openRecipePage(player, result, parentGui, recipes, index - 1, depth); + openRecipePage(player, parentGui, recipes, index - 1, depth); } })); @@ -429,9 +474,10 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { .open(player); } - public void openCookingRecipePage(Player player, Key result, CustomCookingRecipe recipe, Gui parentGui, List> recipes, int index, int depth) { + public void openCookingRecipePage(Player player, CustomCookingRecipe recipe, Gui parentGui, List> recipes, int index, int depth) { Key previous = index > 0 ? Constants.RECIPE_PREVIOUS_PAGE_AVAILABLE : Constants.RECIPE_PREVIOUS_PAGE_BLOCK; Key next = index + 1 < recipes.size() ? Constants.RECIPE_NEXT_PAGE_AVAILABLE : Constants.RECIPE_NEXT_PAGE_BLOCK; + Key result = recipe.result().item().id(); List> ingredients = new ArrayList<>(); net.momirealms.craftengine.core.item.recipe.Ingredient ingredient = recipe.ingredient(); @@ -452,6 +498,24 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { Item item = this.plugin.itemManager().createWrappedItem(result, player); item.count(item.maxStackSize()); c.setItemOnCursor(item); + return; + } + if (LEFT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().getRecipeByResult(result); + if (inRecipes == recipes) return; + player.playSound(Constants.SOUND_CLICK_BUTTON); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0); + } else { + openNoRecipePage(player, result, e.gui(), 0); + } + } else if (RIGHT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().getRecipeByIngredient(result); + if (inRecipes == recipes) return; + player.playSound(Constants.SOUND_CLICK_BUTTON); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0); + } } })) .addIngredient('?', GuiElement.constant(this.plugin.itemManager().getCustomItem(Constants.RECIPE_COOKING_INFO) @@ -478,10 +542,22 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { c.setItemOnCursor(item); return; } - List> inRecipes = plugin.recipeManager().getRecipeByResult(e.item().id()); - if (!inRecipes.isEmpty()) { + if (LEFT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().getRecipeByResult(e.item().id()); + if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); - openRecipePage(player, e.item().id(), e.gui(), inRecipes, 0, depth + 1); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0); + } else { + openNoRecipePage(player, e.item().id(), e.gui(), 0); + } + } else if (RIGHT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().getRecipeByIngredient(e.item().id()); + if (inRecipes == recipes) return; + player.playSound(Constants.SOUND_CLICK_BUTTON); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0); + } } })) .addIngredient('=', GuiElement.constant(this.plugin.itemManager().getCustomItem(Constants.RECIPE_BACK) @@ -503,7 +579,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { c.cancel(); if (index + 1 < recipes.size()) { player.playSound(Constants.SOUND_CHANGE_PAGE, 0.25f, 1); - openRecipePage(player, result, parentGui, recipes, index + 1, depth); + openRecipePage(player, parentGui, recipes, index + 1, depth); } })) .addIngredient('<', GuiElement.constant(this.plugin.itemManager() @@ -516,7 +592,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { c.cancel(); if (index > 0) { player.playSound(Constants.SOUND_CHANGE_PAGE, 0.25f, 1); - openRecipePage(player, result, parentGui, recipes, index - 1, depth); + openRecipePage(player, parentGui, recipes, index - 1, depth); } })); @@ -544,9 +620,10 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { .open(player); } - public void openCraftingRecipePage(Player player, Key result, CustomCraftingTableRecipe recipe, Gui parentGui, List> recipes, int index, int depth) { + public void openCraftingRecipePage(Player player, CustomCraftingTableRecipe recipe, Gui parentGui, List> recipes, int index, int depth) { Key previous = index > 0 ? Constants.RECIPE_PREVIOUS_PAGE_AVAILABLE : Constants.RECIPE_PREVIOUS_PAGE_BLOCK; Key next = index + 1 < recipes.size() ? Constants.RECIPE_NEXT_PAGE_AVAILABLE : Constants.RECIPE_NEXT_PAGE_BLOCK; + Key result = recipe.result().item().id(); GuiLayout layout = new GuiLayout( " ", @@ -559,18 +636,36 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { .addIngredient('X', GuiElement.constant(this.plugin.itemManager().createWrappedItem(result, player).count(recipe.result().count()), (e, c) -> { c.cancel(); if (MIDDLE_CLICK.contains(c.type()) && player.isCreativeMode() && player.hasPermission(GET_ITEM_PERMISSION) && c.itemOnCursor() == null) { - Item item = this.plugin.itemManager().createWrappedItem(result, player); + Item item = this.plugin.itemManager().createWrappedItem(recipe.result().item().id(), player); item.count(item.maxStackSize()); c.setItemOnCursor(item); + return; + } + if (LEFT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().getRecipeByResult(result); + if (inRecipes == recipes) return; + player.playSound(Constants.SOUND_CLICK_BUTTON); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0); + } else { + openNoRecipePage(player, result, e.gui(), 0); + } + } else if (RIGHT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().getRecipeByIngredient(result); + if (inRecipes == recipes) return; + player.playSound(Constants.SOUND_CLICK_BUTTON); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0); + } } })) .addIngredient('^', player.hasPermission(GET_ITEM_PERMISSION) ? GuiElement.constant(this.plugin.itemManager().createWrappedItem(Constants.RECIPE_GET_ITEM, player), (e, c) -> { c.cancel(); player.playSound(Constants.SOUND_PICK_ITEM); if (LEFT_CLICK.contains(c.type())) { - player.giveItem(this.plugin.itemManager().createWrappedItem(result, player)); + player.giveItem(this.plugin.itemManager().createWrappedItem(recipe.result().item().id(), player)); } else if (RIGHT_CLICK.contains(c.type())) { - Item item = this.plugin.itemManager().createWrappedItem(result, player); + Item item = this.plugin.itemManager().createWrappedItem(recipe.result().item().id(), player); player.giveItem(item.count(item.maxStackSize())); } }) : GuiElement.EMPTY) @@ -593,7 +688,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { c.cancel(); if (index + 1 < recipes.size()) { player.playSound(Constants.SOUND_CHANGE_PAGE, 0.25f, 1); - openRecipePage(player, result, parentGui, recipes, index + 1, depth); + openRecipePage(player, parentGui, recipes, index + 1, depth); } })) .addIngredient('<', GuiElement.constant(this.plugin.itemManager() @@ -606,7 +701,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { c.cancel(); if (index > 0) { player.playSound(Constants.SOUND_CHANGE_PAGE, 0.25f, 1); - openRecipePage(player, result, parentGui, recipes, index - 1, depth); + openRecipePage(player, parentGui, recipes, index - 1, depth); } })); @@ -634,10 +729,22 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { c.setItemOnCursor(item); return; } - List> inRecipes = this.plugin.recipeManager().getRecipeByResult(e.item().id()); - if (!inRecipes.isEmpty()) { + if (LEFT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().getRecipeByResult(e.item().id()); + if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); - openRecipePage(player, e.item().id(), e.gui(), inRecipes, 0, depth + 1); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0); + } else { + openNoRecipePage(player, e.item().id(), e.gui(), 0); + } + } else if (RIGHT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().getRecipeByIngredient(e.item().id()); + if (inRecipes == recipes) return; + player.playSound(Constants.SOUND_CLICK_BUTTON); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0); + } } })); } @@ -647,7 +754,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { } } } else { - List> ingredients = ((CustomShapelessRecipe) recipe).ingredients(); + List> ingredients = recipe.ingredientsInUse(); int i = 0; for (int x = 0; x < 3; x++) { for (int y = 0; y < 3; y++) { @@ -665,10 +772,22 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { c.setItemOnCursor(item); return; } - List> inRecipes = this.plugin.recipeManager().getRecipeByResult(e.item().id()); - if (!inRecipes.isEmpty()) { + if (LEFT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().getRecipeByResult(e.item().id()); + if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); - openRecipePage(player, e.item().id(), e.gui(), inRecipes, 0, depth + 1); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0); + } else { + openNoRecipePage(player, e.item().id(), e.gui(), 0); + } + } else if (RIGHT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().getRecipeByIngredient(e.item().id()); + if (inRecipes == recipes) return; + player.playSound(Constants.SOUND_CLICK_BUTTON); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0); + } } })); } else { diff --git a/gradle.properties b/gradle.properties index a01763f8f..269c7bc63 100644 --- a/gradle.properties +++ b/gradle.properties @@ -38,7 +38,7 @@ geantyref_version=1.3.16 zstd_version=1.5.6-9 commons_io_version=2.17.0 sparrow_nbt_version=0.3 -sparrow_util_version=0.21 +sparrow_util_version=0.22 fastutil_version=8.5.15 netty_version=4.1.119.Final joml_version=1.10.8