From 0550a6ac249c5801281bafdb2e5527a6933570ce Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Tue, 15 Jul 2025 03:01:40 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E5=AE=8C=E5=96=84=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common-files/src/main/resources/config.yml | 2 + .../resources/internal/configuration/gui.yml | 8 +- .../font/gui/custom/brewing_recipe.png | Bin 0 -> 1566 bytes .../craftengine/core/block/BlockSettings.java | 24 ++- .../core/pack/AbstractPackManager.java | 1 + .../gui/category/ItemBrowserManager.java | 2 + .../gui/category/ItemBrowserManagerImpl.java | 170 ++++++++++++++++++ gradle.properties | 2 +- 8 files changed, 201 insertions(+), 8 deletions(-) create mode 100644 common-files/src/main/resources/resources/internal/resourcepack/assets/minecraft/textures/font/gui/custom/brewing_recipe.png 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 0000000000000000000000000000000000000000..3942cd518d4231acec99a59c6f70696b40780115 GIT binary patch literal 1566 zcmV+(2I2XMP)RCwC# zor{{IAPh#KwM6#)A9yh!0&G-)7QIBgFSzz z`8%)JGs$>RJ5YuEXO2=?UiGnepJSryF6j8!)y-K6Tl?A7 zv#Pj`wmG6Ro{1#cj}Nd#omp&k-8_P=WxG7V@t8-BXJ6WgUH$PSY!$cXu5p`yEv0!; zrVX*ZI?z9E2WFw-*!C^5h;73YKImXM>2*56`Gr|E#2IV&i!J)*e~{rJvKHx z5?hVCpMf2KKE&IY*m$6}uj1~FZDevbd{1ojw7rAzvB6TWI=7Gh3>v*1QXB3wu@(1%t@8!#*kNr%nVgEfOs6jMm+jba2ez4WSI43$0IJ*7*n*0! zArsgxI1Gg?lh~`B?rkBOnwtdn8o^J&7G!Lh6A1*^FaWm5V(UiU$L>;1iP!=@Yd1UP z?azSTR#3Sr>0)<{g;bG1wn|=wEt;yNkZ?dG-LM4>8wC!ruGG-jM&SF7E5xfLjDfuh zd^b$cfl*_F?Y#7efMjgpb^`rDnd#6X_BuQs1lt5|w@(#}eqC=5BNDA^zYPT407(zK zZ$g$V67X|UHZ$dUJ7%P2zDt!fXV|n(=EtTz8iaMMRMBSA$G?;m~imlo6z=2*s>XWRkb)6x5vO1kw_A@ zl3ujC8QWAw(^O`)y^6fPlDWQ{`)TMWoYmz z^-03Kn;k@S^0uU4N3;zdw%6PM5PGq@jB6t{dM@bV>5JH~Au^O`bU7Ita2x~axf@^G zo#uDQ*xT%0d4Tj_lA*U_*zzXq zOzLuE>?&^$D3a8?q%#16@vxz05+s*Qz6Coy!RJjmjpyyU3BJL+t+SD7k-*l~E>F1* z5lK9tRJ3W}?%BA)ahEU6=5yDEuSwB0jQY+Sy`h}fH;t8r)v2eUs3`_Zr){_4=) z14Lk4QOthw>hIk&dt3AB_1op(!On1ob_VA*e~{r{bI+9N;R%| zfb-AFW3yD_ngzJvteX9|2ecRa#r~(Ur^nfXUH^Xqz9(Bf$&dXWX@3P604HM&Yk`-8 Ql>h($07*qoM6N<$f>+}YDgXcg literal 0 HcmV?d00001 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