diff --git a/common-files/src/main/resources/config.yml b/common-files/src/main/resources/config.yml index 0e96af5e6..5acc916c1 100644 --- a/common-files/src/main/resources/config.yml +++ b/common-files/src/main/resources/config.yml @@ -354,6 +354,8 @@ gui: title: "" smithing-transform: title: "" + brewing: + title: "" performance: # Maximum chain update depth when fixing client visuals diff --git a/common-files/src/main/resources/resources/internal/configuration/gui.yml b/common-files/src/main/resources/resources/internal/configuration/gui.yml index e5955723a..344d37d55 100644 --- a/common-files/src/main/resources/resources/internal/configuration/gui.yml +++ b/common-files/src/main/resources/resources/internal/configuration/gui.yml @@ -59,12 +59,18 @@ images: font: minecraft:gui file: minecraft:font/gui/custom/smithing_transform_recipe.png char: \ub009 + internal:brewing_recipe: + height: 142 + ascent: 20 + font: minecraft:gui + file: minecraft:font/gui/custom/brewing_recipe.png + char: \ub00a internal:no_recipe: height: 140 ascent: 18 font: minecraft:gui file: minecraft:font/gui/custom/no_recipe.png - char: \ub00a + char: \ub00b templates: internal:icon/2d: material: arrow diff --git a/common-files/src/main/resources/resources/internal/resourcepack/assets/minecraft/textures/font/gui/custom/brewing_recipe.png b/common-files/src/main/resources/resources/internal/resourcepack/assets/minecraft/textures/font/gui/custom/brewing_recipe.png new file mode 100644 index 000000000..3942cd518 Binary files /dev/null and b/common-files/src/main/resources/resources/internal/resourcepack/assets/minecraft/textures/font/gui/custom/brewing_recipe.png differ diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockSettings.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockSettings.java index 005fbfd7c..1cfb119f9 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/BlockSettings.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockSettings.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.block; +import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.*; import org.jetbrains.annotations.Nullable; @@ -34,7 +35,7 @@ public class BlockSettings { Key itemId; Set tags = Set.of(); float incorrectToolSpeed = 0.3f; - Set correctTools = Set.of(); + LazyReference> correctTools = LazyReference.lazyReference(Set::of); String name; String supportShapeBlockState; @@ -148,7 +149,7 @@ public class BlockSettings { } public boolean requireCorrectTool() { - return requireCorrectTools || !correctTools.isEmpty(); + return requireCorrectTools || !correctTools.get().isEmpty(); } public String name() { @@ -196,7 +197,7 @@ public class BlockSettings { } public boolean isCorrectTool(Key key) { - return this.correctTools.contains(key); + return this.correctTools.get().contains(key); } public boolean respectToolComponent() { @@ -215,7 +216,7 @@ public class BlockSettings { return useShapeForLightOcclusion; } - public BlockSettings correctTools(Set correctTools) { + public BlockSettings correctTools(LazyReference> correctTools) { this.correctTools = correctTools; return this; } @@ -417,7 +418,10 @@ public class BlockSettings { })); registerFactory("tags", (value -> { List tags = MiscUtils.getAsStringList(value); - return settings -> settings.tags(tags.stream().map(Key::of).collect(Collectors.toSet())); + return settings -> settings.tags(tags.stream().map(it -> { + if (it.charAt(0) == '#') return Key.of(it.substring(1)); + else return Key.of(it); + }).collect(Collectors.toSet())); })); registerFactory("burn-chance", (value -> { int intValue = ResourceConfigUtils.getAsInt(value, "burn-chance"); @@ -457,7 +461,15 @@ public class BlockSettings { })); registerFactory("correct-tools", (value -> { List tools = MiscUtils.getAsStringList(value); - return settings -> settings.correctTools(tools.stream().map(Key::of).collect(Collectors.toSet())); + LazyReference> correctTools = LazyReference.lazyReference(() -> { + Set ids = new HashSet<>(); + for (String tool : tools) { + if (tool.charAt(0) == '#') ids.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(tool.substring(1))).stream().map(UniqueKey::key).toList()); + else ids.add(Key.of(tool)); + } + return ids; + }); + return settings -> settings.correctTools(correctTools); })); registerFactory("require-correct-tools", (value -> { boolean booleanValue = ResourceConfigUtils.getAsBoolean(value, "require-correct-tools"); diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java index 855c47836..395f6af8e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java @@ -369,6 +369,7 @@ public abstract class AbstractPackManager implements PackManager { plugin.saveResource("resources/internal/resourcepack/assets/minecraft/textures/font/gui/custom/smithing_transform_recipe.png"); plugin.saveResource("resources/internal/resourcepack/assets/minecraft/textures/font/gui/custom/cooking_recipe.png"); plugin.saveResource("resources/internal/resourcepack/assets/minecraft/textures/font/gui/custom/crafting_recipe.png"); + plugin.saveResource("resources/internal/resourcepack/assets/minecraft/textures/font/gui/custom/brewing_recipe.png"); plugin.saveResource("resources/internal/resourcepack/assets/minecraft/textures/font/gui/custom/no_recipe.png"); plugin.saveResource("resources/internal/resourcepack/assets/minecraft/textures/item/custom/gui/get_item.png"); plugin.saveResource("resources/internal/resourcepack/assets/minecraft/textures/item/custom/gui/next_page_0.png"); diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManager.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManager.java index 9d6b9732b..fbe722e1b 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManager.java @@ -56,6 +56,7 @@ public interface ItemBrowserManager extends Manageable { public static String RECIPE_CRAFTING_TITLE; public static String RECIPE_STONECUTTING_TITLE; public static String RECIPE_SMITHING_TRANSFORM_TITLE; + public static String RECIPE_BREWING_TITLE; public static Key RECIPE_BACK; public static Key RECIPE_EXIT; public static Key RECIPE_NEXT_PAGE_AVAILABLE; @@ -95,6 +96,7 @@ public interface ItemBrowserManager extends Manageable { RECIPE_CRAFTING_TITLE = getOrThrow(section, "recipe.crafting.title"); RECIPE_STONECUTTING_TITLE = getOrThrow(section, "recipe.stonecutting.title"); RECIPE_SMITHING_TRANSFORM_TITLE = getOrThrow(section, "recipe.smithing-transform.title"); + RECIPE_BREWING_TITLE = getOrThrow(section, "recipe.brewing.title"); RECIPE_BACK = Key.of(getOrThrow(section, "recipe.page-navigation.return")); RECIPE_EXIT = Key.of(getOrThrow(section, "recipe.page-navigation.exit")); RECIPE_NEXT_PAGE_AVAILABLE = Key.of(getOrThrow(section, "recipe.page-navigation.next.available")); 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 499b9bc3c..e51058d2f 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 @@ -409,6 +409,176 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { openSmithingTransformRecipePage(player, (CustomSmithingTransformRecipe) recipe, parentGui, recipes, index, depth, canOpenNoRecipePage); return; } + if (recipeType == RecipeTypes.BREWING) { + openBrewingRecipePage(player, (CustomBrewingRecipe) recipe, parentGui, recipes, index, depth, canOpenNoRecipePage); + return; + } + } + + public void openBrewingRecipePage(Player player, CustomBrewingRecipe recipe, Gui parentGui, List> recipes, int index, int depth, boolean canOpenNoRecipePage) { + 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(); + for (UniqueKey in : ingredient.items()) { + ingredients.add(this.plugin.itemManager().createWrappedItem(in.key(), player)); + } + + List> containers = new ArrayList<>(); + net.momirealms.craftengine.core.item.recipe.Ingredient container = recipe.container(); + for (UniqueKey in : container.items()) { + containers.add(this.plugin.itemManager().createWrappedItem(in.key(), player)); + } + + GuiLayout layout = new GuiLayout( + " ", + " A ", + " ", + " B X ", + " ^ ", + " < = > " + ) + .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.count(item.maxStackSize()); + c.setItemOnCursor(item); + return; + } + if (LEFT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().recipeByResult(result); + if (inRecipes == recipes) return; + player.playSound(Constants.SOUND_CLICK_BUTTON); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); + } else if (canOpenNoRecipePage) { + openNoRecipePage(player, result, e.gui(), 0); + } + } else if (RIGHT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().recipeByIngredient(result); + if (inRecipes == recipes) return; + player.playSound(Constants.SOUND_CLICK_BUTTON); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); + } + } + })) + .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)); + } else if (RIGHT_CLICK.contains(c.type())) { + Item item = this.plugin.itemManager().createWrappedItem(result, player); + player.giveItem(item.count(item.maxStackSize())); + } + }) : GuiElement.EMPTY) + .addIngredient('=', GuiElement.constant(this.plugin.itemManager().getCustomItem(parentGui != null ? Constants.RECIPE_BACK : Constants.RECIPE_EXIT) + .map(it -> it.buildItem(ItemBuildContext.of(player))) + .orElseThrow(() -> new GuiElementMissingException("Can't find gui element " + (parentGui != null ? Constants.RECIPE_BACK : Constants.RECIPE_EXIT))), + ((element, click) -> { + click.cancel(); + player.playSound(Constants.SOUND_RETURN_PAGE, 0.25f, 1); + if (parentGui != null) { + parentGui.open(player); + } else { + player.closeInventory(); + } + })) + ) + .addIngredient('>', GuiElement.constant(this.plugin.itemManager() + .getCustomItem(next) + .map(it -> it.buildItem(ItemBuildContext.of(player, ContextHolder.builder() + .withParameter(GuiParameters.CURRENT_PAGE, String.valueOf(index + 1)) + .withParameter(GuiParameters.MAX_PAGE, String.valueOf(recipes.size())) + ))) + .orElseThrow(() -> new GuiElementMissingException("Can't find gui element " + next)), (e, c) -> { + c.cancel(); + if (index + 1 < recipes.size()) { + player.playSound(Constants.SOUND_CHANGE_PAGE, 0.25f, 1); + openRecipePage(player, parentGui, recipes, index + 1, depth, canOpenNoRecipePage); + } + })) + .addIngredient('<', GuiElement.constant(this.plugin.itemManager() + .getCustomItem(previous) + .map(it -> it.buildItem(ItemBuildContext.of(player, ContextHolder.builder() + .withParameter(GuiParameters.CURRENT_PAGE, String.valueOf(index + 1)) + .withParameter(GuiParameters.MAX_PAGE, String.valueOf(recipes.size())) + ))) + .orElseThrow(() -> new GuiElementMissingException("Can't find gui element " + previous)), (e, c) -> { + c.cancel(); + if (index > 0) { + player.playSound(Constants.SOUND_CHANGE_PAGE, 0.25f, 1); + openRecipePage(player, parentGui, recipes, index - 1, depth, canOpenNoRecipePage); + } + })) + .addIngredient('A', GuiElement.recipeIngredient(ingredients, (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(e.item().id(), player); + item.count(item.maxStackSize()); + c.setItemOnCursor(item); + return; + } + if (LEFT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().recipeByResult(e.item().id()); + if (inRecipes == recipes) return; + player.playSound(Constants.SOUND_CLICK_BUTTON); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); + } else if (canOpenNoRecipePage) { + openNoRecipePage(player, e.item().id(), e.gui(), 0); + } + } else if (RIGHT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().recipeByIngredient(e.item().id()); + if (inRecipes == recipes) return; + player.playSound(Constants.SOUND_CLICK_BUTTON); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); + } + } + })) + .addIngredient('B', GuiElement.recipeIngredient(containers, (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(e.item().id(), player); + item.count(item.maxStackSize()); + c.setItemOnCursor(item); + return; + } + if (LEFT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().recipeByResult(e.item().id()); + if (inRecipes == recipes) return; + player.playSound(Constants.SOUND_CLICK_BUTTON); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); + } else if (canOpenNoRecipePage) { + openNoRecipePage(player, e.item().id(), e.gui(), 0); + } + } else if (RIGHT_CLICK.contains(c.type())) { + List> inRecipes = this.plugin.recipeManager().recipeByIngredient(e.item().id()); + if (inRecipes == recipes) return; + player.playSound(Constants.SOUND_CLICK_BUTTON); + if (!inRecipes.isEmpty()) { + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); + } + } + })); + + BasicGui.builder() + .layout(layout) + .inventoryClickConsumer(c -> { + if (MOVE_TO_OTHER_INV.contains(c.type()) || DOUBLE_CLICK.contains(c.type())) { + c.cancel(); + } + }) + .build() + .title(AdventureHelper.miniMessage().deserialize(Constants.RECIPE_BREWING_TITLE, PlayerOptionalContext.of(player).tagResolvers())) + .refresh() + .open(player); } public void openSmithingTransformRecipePage(Player player, CustomSmithingTransformRecipe recipe, Gui parentGui, List> recipes, int index, int depth, boolean canOpenNoRecipePage) { diff --git a/gradle.properties b/gradle.properties index f397c7222..6c5b9b256 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.60.1 +project_version=0.0.60.2 config_version=42 lang_version=22 project_group=net.momirealms