diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java index 251f73c61..78bf6203f 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java @@ -613,6 +613,35 @@ public class RecipeEventListener implements Listener { if (input == null) return; Player player = InventoryUtils.getPlayerFromInventoryEvent(event); BukkitServerPlayer serverPlayer = BukkitAdaptors.adapt(player); + if (craftingTableRecipe.hasVisualResult()) { + inventory.setResult(craftingTableRecipe.assembleVisual(input, new ItemBuildContext(serverPlayer, ContextHolder.EMPTY))); + } else { + inventory.setResult(craftingTableRecipe.assemble(input, new ItemBuildContext(serverPlayer, ContextHolder.EMPTY))); + } + } + + @EventHandler(ignoreCancelled = true) + public void onCraftingFinish(CraftItemEvent event) { + if (!Config.enableRecipeSystem()) return; + org.bukkit.inventory.Recipe recipe = event.getRecipe(); + if (!(recipe instanceof CraftingRecipe craftingRecipe)) return; + Key recipeId = Key.of(craftingRecipe.getKey().namespace(), craftingRecipe.getKey().value()); + Optional> optionalRecipe = this.recipeManager.recipeById(recipeId); + // 也许是其他插件注册的配方,直接无视 + if (optionalRecipe.isEmpty()) { + return; + } + CraftingInventory inventory = event.getInventory(); + if (!(optionalRecipe.get() instanceof CustomCraftingTableRecipe craftingTableRecipe)) { + return; + } + if (!craftingTableRecipe.hasVisualResult()) { + return; + } + CraftingInput input = getCraftingInput(inventory); + if (input == null) return; + Player player = InventoryUtils.getPlayerFromInventoryEvent(event); + BukkitServerPlayer serverPlayer = BukkitAdaptors.adapt(player); inventory.setResult(craftingTableRecipe.assemble(input, new ItemBuildContext(serverPlayer, ContextHolder.EMPTY))); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeSerializer.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeSerializer.java index 3087306b1..6d9162d8d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeSerializer.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeSerializer.java @@ -11,6 +11,7 @@ import net.momirealms.craftengine.core.item.recipe.result.PostProcessors; 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.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -61,9 +62,10 @@ public abstract class AbstractRecipeSerializer> implement return recipeCategory; } + @NotNull @SuppressWarnings({"unchecked"}) protected CustomRecipeResult parseResult(Map arguments) { - Map resultMap = MiscUtils.castToMap(arguments.get("result"), true); + Map resultMap = ResourceConfigUtils.getAsMapOrNull(arguments.get("result"), "result"); if (resultMap == null) { throw new LocalizedResourceConfigException("warning.config.recipe.missing_result"); } @@ -81,6 +83,27 @@ public abstract class AbstractRecipeSerializer> implement ); } + @Nullable + @SuppressWarnings({"unchecked"}) + protected CustomRecipeResult parseVisualResult(Map arguments) { + Map resultMap = ResourceConfigUtils.getAsMapOrNull(arguments.get("visual-result"), "visual-result"); + if (resultMap == null) { + return null; + } + String id = ResourceConfigUtils.requireNonEmptyStringOrThrow(resultMap.get("id"), "warning.config.recipe.visual_result.missing_id"); + int count = ResourceConfigUtils.getAsInt(resultMap.getOrDefault("count", 1), "count"); + BuildableItem resultItem = (BuildableItem) CraftEngine.instance().itemManager().getBuildableItem(Key.of(id)).orElseThrow(() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_visual_result", id)); + if (resultItem.isEmpty()) { + throw new LocalizedResourceConfigException("warning.config.recipe.invalid_visual_result", id); + } + List> processors = ResourceConfigUtils.parseConfigAsList(resultMap.get("post-processors"), PostProcessors::fromMap); + return new CustomRecipeResult<>( + resultItem, + count, + processors.isEmpty() ? null : processors.toArray(new PostProcessor[0]) + ); + } + @SuppressWarnings("unchecked") protected CustomRecipeResult parseResult(DatapackRecipeResult recipeResult) { Item result = (Item) CraftEngine.instance().itemManager().build(recipeResult); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomCraftingTableRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomCraftingTableRecipe.java index 2adf21dc3..655f40ea4 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomCraftingTableRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomCraftingTableRecipe.java @@ -1,14 +1,20 @@ package net.momirealms.craftengine.core.item.recipe; +import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.item.ItemBuildContext; +import net.momirealms.craftengine.core.item.recipe.input.RecipeInput; import net.momirealms.craftengine.core.item.recipe.result.CustomRecipeResult; import net.momirealms.craftengine.core.util.Key; +import org.jetbrains.annotations.Nullable; public abstract class CustomCraftingTableRecipe extends AbstractGroupedRecipe { protected final CraftingRecipeCategory category; + private final CustomRecipeResult visualResult; - protected CustomCraftingTableRecipe(Key id, boolean showNotification, CustomRecipeResult result, String group, CraftingRecipeCategory category) { + protected CustomCraftingTableRecipe(Key id, boolean showNotification, CustomRecipeResult result, @Nullable CustomRecipeResult visualResult, String group, CraftingRecipeCategory category) { super(id, showNotification, result, group); this.category = category == null ? CraftingRecipeCategory.MISC : category; + this.visualResult = visualResult; } public CraftingRecipeCategory category() { @@ -19,4 +25,28 @@ public abstract class CustomCraftingTableRecipe extends AbstractGroupedRecipe public RecipeType type() { return RecipeType.CRAFTING; } + + public CustomRecipeResult visualResult() { + return visualResult; + } + + public boolean hasVisualResult() { + return visualResult != null; + } + + public T assembleVisual(RecipeInput input, ItemBuildContext context) { + if (this.visualResult != null) { + return this.visualResult.buildItemStack(context); + } else { + throw new IllegalStateException("No visual result available"); + } + } + + public Item buildVisualOrActualResult(ItemBuildContext context) { + if (this.visualResult != null) { + return this.visualResult.buildItem(context); + } else { + return super.result.buildItem(context); + } + } } 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 70faa1450..40af56a0f 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 @@ -21,10 +21,11 @@ public class CustomShapedRecipe extends CustomCraftingTableRecipe { public CustomShapedRecipe(Key id, boolean showNotification, CustomRecipeResult result, + CustomRecipeResult visualResult, String group, CraftingRecipeCategory category, Pattern pattern) { - super(id, showNotification, result, group, category); + super(id, showNotification, result, visualResult, group, category); this.pattern = pattern; this.parsedPattern = pattern.parse(); } @@ -165,7 +166,9 @@ public class CustomShapedRecipe extends CustomCraftingTableRecipe { } return new CustomShapedRecipe(id, showNotification(arguments), - parseResult(arguments), arguments.containsKey("group") ? arguments.get("group").toString() : null, craftingRecipeCategory(arguments), + parseResult(arguments), + parseVisualResult(arguments), + arguments.containsKey("group") ? arguments.get("group").toString() : null, craftingRecipeCategory(arguments), new Pattern<>(pattern.toArray(new String[0]), ingredients) ); } @@ -175,7 +178,10 @@ public class CustomShapedRecipe extends CustomCraftingTableRecipe { Map> ingredients = Maps.transformValues(VANILLA_RECIPE_HELPER.shapedIngredientMap(json.getAsJsonObject("key")), this::toIngredient); return new CustomShapedRecipe<>(id, true, - parseResult(VANILLA_RECIPE_HELPER.craftingResult(json.getAsJsonObject("result"))), VANILLA_RECIPE_HELPER.readGroup(json), VANILLA_RECIPE_HELPER.craftingCategory(json), + parseResult(VANILLA_RECIPE_HELPER.craftingResult(json.getAsJsonObject("result"))), + null, + VANILLA_RECIPE_HELPER.readGroup(json), + VANILLA_RECIPE_HELPER.craftingCategory(json), new Pattern<>(VANILLA_RECIPE_HELPER.craftingShapedPattern(json), ingredients) ); } 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 d8ca669ef..678c75543 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 @@ -20,10 +20,11 @@ public class CustomShapelessRecipe extends CustomCraftingTableRecipe { public CustomShapelessRecipe(Key id, boolean showNotification, CustomRecipeResult result, + CustomRecipeResult visualResult, String group, CraftingRecipeCategory category, List> ingredients) { - super(id, showNotification, result, group, category); + super(id, showNotification, result, visualResult, group, category); this.ingredients = ingredients; this.placementInfo = PlacementInfo.create(ingredients); } @@ -84,7 +85,9 @@ public class CustomShapelessRecipe extends CustomCraftingTableRecipe { } return new CustomShapelessRecipe(id, showNotification(arguments), - parseResult(arguments), arguments.containsKey("group") ? arguments.get("group").toString() : null, craftingRecipeCategory(arguments), + parseResult(arguments), + parseVisualResult(arguments), + arguments.containsKey("group") ? arguments.get("group").toString() : null, craftingRecipeCategory(arguments), ingredients ); } @@ -93,7 +96,9 @@ public class CustomShapelessRecipe extends CustomCraftingTableRecipe { public CustomShapelessRecipe readJson(Key id, JsonObject json) { return new CustomShapelessRecipe<>(id, true, - parseResult(VANILLA_RECIPE_HELPER.craftingResult(json.getAsJsonObject("result"))), VANILLA_RECIPE_HELPER.readGroup(json), VANILLA_RECIPE_HELPER.craftingCategory(json), + parseResult(VANILLA_RECIPE_HELPER.craftingResult(json.getAsJsonObject("result"))), + null, + VANILLA_RECIPE_HELPER.readGroup(json), VANILLA_RECIPE_HELPER.craftingCategory(json), VANILLA_RECIPE_HELPER.shapelessIngredients(json.getAsJsonArray("ingredients")).stream().map(this::toIngredient).toList() ); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/UniqueIdItem.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/UniqueIdItem.java index 7e60308d1..9594a764e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/UniqueIdItem.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/UniqueIdItem.java @@ -19,7 +19,7 @@ public class UniqueIdItem { @NotNull public UniqueKey id() { - return uniqueId; + return this.uniqueId; } @NotNull @@ -37,6 +37,6 @@ public class UniqueIdItem { @Override public String toString() { - return "UniqueIdItem[" + "uniqueId=" + uniqueId + ", item=" + rawItem.getItem() + ']'; + return "UniqueIdItem[" + "uniqueId=" + this.uniqueId + ", item=" + this.rawItem.getItem() + ']'; } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/dependency/Dependencies.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/dependency/Dependencies.java index 2eb14be4f..37eae795e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/dependency/Dependencies.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/dependency/Dependencies.java @@ -420,7 +420,6 @@ public class Dependencies { List.of(Relocation.of("jimfs", "com{}google{}common{}jimfs")) ); - public static final Dependency AMAZON_AWSSDK_S3 = new Dependency( "amazon-sdk-s3", "software{}amazon{}awssdk", diff --git a/gradle.properties b/gradle.properties index f91eb949b..3c65f77b5 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.62.4 +project_version=0.0.62.5 config_version=45 lang_version=25 project_group=net.momirealms @@ -42,7 +42,7 @@ commons_lang3_version=3.17.0 sparrow_nbt_version=0.9.4 sparrow_util_version=0.50.9 fastutil_version=8.5.15 -netty_version=4.1.121.Final +netty_version=4.1.124.Final joml_version=1.10.8 datafixerupper_version=8.0.16 mojang_brigadier_version=1.0.18 @@ -50,7 +50,7 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.4 anti_grief_version=0.19 -nms_helper_version=1.0.66 +nms_helper_version=1.0.67 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.31.23