9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-19 15:09:15 +00:00

添加视觉配方结果

This commit is contained in:
XiaoMoMi
2025-08-27 18:12:38 +08:00
parent 23c37ac3e9
commit b97f1c0b64
8 changed files with 106 additions and 14 deletions

View File

@@ -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<Recipe<ItemStack>> optionalRecipe = this.recipeManager.recipeById(recipeId);
// 也许是其他插件注册的配方,直接无视
if (optionalRecipe.isEmpty()) {
return;
}
CraftingInventory inventory = event.getInventory();
if (!(optionalRecipe.get() instanceof CustomCraftingTableRecipe<ItemStack> craftingTableRecipe)) {
return;
}
if (!craftingTableRecipe.hasVisualResult()) {
return;
}
CraftingInput<ItemStack> 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)));
}

View File

@@ -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<T, R extends Recipe<T>> implement
return recipeCategory;
}
@NotNull
@SuppressWarnings({"unchecked"})
protected CustomRecipeResult<T> parseResult(Map<String, Object> arguments) {
Map<String, Object> resultMap = MiscUtils.castToMap(arguments.get("result"), true);
Map<String, Object> 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<T, R extends Recipe<T>> implement
);
}
@Nullable
@SuppressWarnings({"unchecked"})
protected CustomRecipeResult<T> parseVisualResult(Map<String, Object> arguments) {
Map<String, Object> 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<T> resultItem = (BuildableItem<T>) 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<PostProcessor<T>> 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<T> parseResult(DatapackRecipeResult recipeResult) {
Item<T> result = (Item<T>) CraftEngine.instance().itemManager().build(recipeResult);

View File

@@ -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<T> extends AbstractGroupedRecipe<T> {
protected final CraftingRecipeCategory category;
private final CustomRecipeResult<T> visualResult;
protected CustomCraftingTableRecipe(Key id, boolean showNotification, CustomRecipeResult<T> result, String group, CraftingRecipeCategory category) {
protected CustomCraftingTableRecipe(Key id, boolean showNotification, CustomRecipeResult<T> result, @Nullable CustomRecipeResult<T> 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<T> extends AbstractGroupedRecipe
public RecipeType type() {
return RecipeType.CRAFTING;
}
public CustomRecipeResult<T> 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<T> buildVisualOrActualResult(ItemBuildContext context) {
if (this.visualResult != null) {
return this.visualResult.buildItem(context);
} else {
return super.result.buildItem(context);
}
}
}

View File

@@ -21,10 +21,11 @@ public class CustomShapedRecipe<T> extends CustomCraftingTableRecipe<T> {
public CustomShapedRecipe(Key id,
boolean showNotification,
CustomRecipeResult<T> result,
CustomRecipeResult<T> visualResult,
String group,
CraftingRecipeCategory category,
Pattern<T> 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<T> extends CustomCraftingTableRecipe<T> {
}
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<T> extends CustomCraftingTableRecipe<T> {
Map<Character, Ingredient<A>> 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)
);
}

View File

@@ -20,10 +20,11 @@ public class CustomShapelessRecipe<T> extends CustomCraftingTableRecipe<T> {
public CustomShapelessRecipe(Key id,
boolean showNotification,
CustomRecipeResult<T> result,
CustomRecipeResult<T> visualResult,
String group,
CraftingRecipeCategory category,
List<Ingredient<T>> 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<T> extends CustomCraftingTableRecipe<T> {
}
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<T> extends CustomCraftingTableRecipe<T> {
public CustomShapelessRecipe<A> 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()
);
}

View File

@@ -19,7 +19,7 @@ public class UniqueIdItem<T> {
@NotNull
public UniqueKey id() {
return uniqueId;
return this.uniqueId;
}
@NotNull
@@ -37,6 +37,6 @@ public class UniqueIdItem<T> {
@Override
public String toString() {
return "UniqueIdItem[" + "uniqueId=" + uniqueId + ", item=" + rawItem.getItem() + ']';
return "UniqueIdItem[" + "uniqueId=" + this.uniqueId + ", item=" + this.rawItem.getItem() + ']';
}
}

View File

@@ -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",

View File

@@ -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