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 463e37e25..b4eb96104 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 @@ -55,7 +55,20 @@ public class BukkitRecipeManager implements RecipeManager { static { BUKKIT_RECIPE_FACTORIES.put(RecipeTypes.SMITHING_TRANSFORM, (key, recipe) -> { - + CustomSmithingTransformRecipe ceRecipe = (CustomSmithingTransformRecipe) recipe; + SmithingTransformRecipe transformRecipe = new SmithingTransformRecipe( + key, ceRecipe.result(ItemBuildContext.EMPTY), + ingredientToBukkitRecipeChoice(ceRecipe.template()), + ingredientToBukkitRecipeChoice(ceRecipe.base()), + ingredientToBukkitRecipeChoice(ceRecipe.addition()), + false + ); + try { + Object craftRecipe = Reflections.method$CraftSmithingTransformRecipe$fromBukkitRecipe.invoke(null, transformRecipe); + Reflections.method$CraftRecipe$addToCraftingManager.invoke(craftRecipe); + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to convert smithing transform recipe", e); + } }); BUKKIT_RECIPE_FACTORIES.put(RecipeTypes.SHAPED, (key, recipe) -> { CustomShapedRecipe ceRecipe = (CustomShapedRecipe) recipe; @@ -68,7 +81,7 @@ public class BukkitRecipeManager implements RecipeManager { } shapedRecipe.shape(ceRecipe.pattern().pattern()); for (Map.Entry> entry : ceRecipe.pattern().ingredients().entrySet()) { - shapedRecipe.setIngredient(entry.getKey(), new RecipeChoice.MaterialChoice(ingredientToBukkitMaterials(entry.getValue()))); + shapedRecipe.setIngredient(entry.getKey(), ingredientToBukkitRecipeChoice(entry.getValue())); } try { Object craftRecipe = Reflections.method$CraftShapedRecipe$fromBukkitRecipe.invoke(null, shapedRecipe); @@ -88,7 +101,7 @@ public class BukkitRecipeManager implements RecipeManager { shapelessRecipe.setCategory(CraftingBookCategory.valueOf(Objects.requireNonNull(ceRecipe.category()).name())); } for (Ingredient ingredient : ceRecipe.ingredientsInUse()) { - shapelessRecipe.addIngredient(new RecipeChoice.MaterialChoice(ingredientToBukkitMaterials(ingredient))); + shapelessRecipe.addIngredient(ingredientToBukkitRecipeChoice(ingredient)); } try { Object craftRecipe = Reflections.method$CraftShapelessRecipe$fromBukkitRecipe.invoke(null, shapelessRecipe); @@ -102,7 +115,7 @@ public class BukkitRecipeManager implements RecipeManager { CustomSmeltingRecipe ceRecipe = (CustomSmeltingRecipe) recipe; FurnaceRecipe furnaceRecipe = new FurnaceRecipe( key, ceRecipe.result(ItemBuildContext.EMPTY), - new RecipeChoice.MaterialChoice(ingredientToBukkitMaterials(ceRecipe.ingredient())), + ingredientToBukkitRecipeChoice(ceRecipe.ingredient()), ceRecipe.experience(), ceRecipe.cookingTime() ); if (ceRecipe.group() != null) { @@ -123,7 +136,7 @@ public class BukkitRecipeManager implements RecipeManager { CustomSmokingRecipe ceRecipe = (CustomSmokingRecipe) recipe; SmokingRecipe smokingRecipe = new SmokingRecipe( key, ceRecipe.result(ItemBuildContext.EMPTY), - new RecipeChoice.MaterialChoice(ingredientToBukkitMaterials(ceRecipe.ingredient())), + ingredientToBukkitRecipeChoice(ceRecipe.ingredient()), ceRecipe.experience(), ceRecipe.cookingTime() ); if (ceRecipe.group() != null) { @@ -144,7 +157,7 @@ public class BukkitRecipeManager implements RecipeManager { CustomBlastingRecipe ceRecipe = (CustomBlastingRecipe) recipe; BlastingRecipe blastingRecipe = new BlastingRecipe( key, ceRecipe.result(ItemBuildContext.EMPTY), - new RecipeChoice.MaterialChoice(ingredientToBukkitMaterials(ceRecipe.ingredient())), + ingredientToBukkitRecipeChoice(ceRecipe.ingredient()), ceRecipe.experience(), ceRecipe.cookingTime() ); if (ceRecipe.group() != null) { @@ -165,7 +178,7 @@ public class BukkitRecipeManager implements RecipeManager { CustomCampfireRecipe ceRecipe = (CustomCampfireRecipe) recipe; CampfireRecipe campfireRecipe = new CampfireRecipe( key, ceRecipe.result(ItemBuildContext.EMPTY), - new RecipeChoice.MaterialChoice(ingredientToBukkitMaterials(ceRecipe.ingredient())), + ingredientToBukkitRecipeChoice(ceRecipe.ingredient()), ceRecipe.experience(), ceRecipe.cookingTime() ); if (ceRecipe.group() != null) { @@ -495,6 +508,10 @@ public class BukkitRecipeManager implements RecipeManager { VanillaStoneCuttingRecipe recipe = this.recipeReader.readStoneCutting(jsonObject); handleDataPackStoneCuttingRecipe(id, recipe); } + case "minecraft:smithing_transform" -> { + VanillaSmithingTransformRecipe recipe = this.recipeReader.readSmithingTransform(jsonObject); + handleDataPackSmithingTransform(id, recipe, (injectLogics::add)); + } } } } @@ -520,6 +537,29 @@ public class BukkitRecipeManager implements RecipeManager { return future; } + private boolean readVanillaIngredients(boolean hasCustomItemInTag, List ingredients, Consumer materialConsumer, Consumer> holderConsumer) { + for (String item : ingredients) { + if (item.charAt(0) == '#') { + Key tag = Key.from(item.substring(1)); + for (Material material : tagToMaterials(tag)) { + materialConsumer.accept(material); + } + if (!hasCustomItemInTag) { + if (!plugin.itemManager().tagToCustomItems(tag).isEmpty()) { + hasCustomItemInTag = true; + } + } + for (Holder holder : plugin.itemManager().tagToItems(tag)) { + holderConsumer.accept(holder); + } + } else { + materialConsumer.accept(MaterialUtils.getMaterial(item)); + holderConsumer.accept(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.from(item)).orElseThrow()); + } + } + return hasCustomItemInTag; + } + private void handleDataPackShapelessRecipe(Key id, VanillaShapelessRecipe recipe, Consumer callback) { NamespacedKey key = new NamespacedKey(id.namespace(), id.value()); ItemStack result = createResultStack(recipe.result()); @@ -669,22 +709,7 @@ public class BukkitRecipeManager implements RecipeManager { Set materials = new HashSet<>(); Set> holders = new HashSet<>(); - boolean hasCustomItemInTag = false; - for (String item : recipe.ingredient()) { - if (item.charAt(0) == '#') { - Key tag = Key.from(item.substring(1)); - materials.addAll(tagToMaterials(tag)); - if (!hasCustomItemInTag) { - if (!plugin.itemManager().tagToCustomItems(tag).isEmpty()) { - hasCustomItemInTag = true; - } - } - holders.addAll(plugin.itemManager().tagToItems(tag)); - } else { - materials.add(MaterialUtils.getMaterial(item)); - holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.from(item)).orElseThrow()); - } - } + boolean hasCustomItemInTag = readVanillaIngredients(false, recipe.ingredient(), materials::add, holders::add); org.bukkit.inventory.CookingRecipe cookingRecipe = constructor1.apply(key, result, new RecipeChoice.MaterialChoice(new ArrayList<>(materials)), recipe.experience(), recipe.cookingTime()); if (recipe.group() != null) { cookingRecipe.setGroup(recipe.group()); @@ -717,6 +742,52 @@ public class BukkitRecipeManager implements RecipeManager { this.addInternalRecipe(id, ceRecipe); } + private void handleDataPackSmithingTransform(Key id, VanillaSmithingTransformRecipe recipe, Consumer callback) { + NamespacedKey key = new NamespacedKey(id.namespace(), id.value()); + ItemStack result = createResultStack(recipe.result()); + boolean hasCustomItemInTag; + + Set additionMaterials = new HashSet<>(); + Set> additionHolders = new HashSet<>(); + hasCustomItemInTag = readVanillaIngredients(false, recipe.addition(), additionMaterials::add, additionHolders::add); + + Set templateMaterials = new HashSet<>(); + Set> templateHolders = new HashSet<>(); + hasCustomItemInTag = readVanillaIngredients(hasCustomItemInTag, recipe.template(), templateMaterials::add, templateHolders::add); + + Set baseMaterials = new HashSet<>(); + Set> baseHolders = new HashSet<>(); + hasCustomItemInTag = readVanillaIngredients(hasCustomItemInTag, recipe.base(), baseMaterials::add, baseHolders::add); + + CustomSmithingTransformRecipe ceRecipe = new CustomSmithingTransformRecipe<>( + id, + Ingredient.of(baseHolders), + Ingredient.of(templateHolders), + Ingredient.of(additionHolders), + new CustomRecipeResult<>(new CloneableConstantItem(recipe.result().isCustom() ? Key.of("!internal:custom") : Key.of(recipe.result().id()), result), recipe.result().count()) + ); + + SmithingTransformRecipe transformRecipe = new SmithingTransformRecipe(key, result, + new RecipeChoice.MaterialChoice(new ArrayList<>(templateMaterials)), + new RecipeChoice.MaterialChoice(new ArrayList<>(baseMaterials)), + new RecipeChoice.MaterialChoice(new ArrayList<>(additionMaterials)), + true + ); + + if (hasCustomItemInTag) { + callback.accept(() -> { + try { + unregisterRecipe(key); + Reflections.method$CraftRecipe$addToCraftingManager.invoke(Reflections.method$CraftSmithingTransformRecipe$fromBukkitRecipe.invoke(null, transformRecipe)); + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to convert smelting recipe", e); + } + }); + this.injectedDataPackRecipes.add(key); + } + this.addInternalRecipe(id, ceRecipe); + } + private List tagToMaterials(Key tag) { Set materials = new HashSet<>(); List> holders = this.plugin.itemManager().tagToVanillaItems(tag); @@ -766,12 +837,16 @@ public class BukkitRecipeManager implements RecipeManager { return Key.of(prefix, fileName); } - private static List ingredientToBukkitMaterials(Ingredient ingredient) { - Set materials = new HashSet<>(); - for (Holder holder : ingredient.items()) { - materials.add(getMaterialById(holder.value())); + private static RecipeChoice ingredientToBukkitRecipeChoice(Ingredient ingredient) { + if (ingredient == null) { + return EmptyRecipeChoice.INSTANCE; + } else { + Set materials = new HashSet<>(); + for (Holder holder : ingredient.items()) { + materials.add(getMaterialById(holder.value())); + } + return new RecipeChoice.MaterialChoice(new ArrayList<>(materials)); } - return new ArrayList<>(materials); } private static Material getMaterialById(Key key) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/EmptyRecipeChoice.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/EmptyRecipeChoice.java new file mode 100644 index 000000000..382b2c0de --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/EmptyRecipeChoice.java @@ -0,0 +1,35 @@ +package net.momirealms.craftengine.bukkit.item.recipe; + +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.RecipeChoice; +import org.jetbrains.annotations.NotNull; + +record EmptyRecipeChoice() implements RecipeChoice { + + static final RecipeChoice INSTANCE = new EmptyRecipeChoice(); + + @Override + @NotNull + public ItemStack getItemStack() { + throw new UnsupportedOperationException("This is an empty RecipeChoice"); + } + + @SuppressWarnings("MethodDoesntCallSuperMethod") + @Override + @NotNull + public RecipeChoice clone() { + return this; + } + + @Override + public boolean test(final @NotNull ItemStack itemStack) { + return false; + } + + @Override + @NotNull + public RecipeChoice validate(final boolean allowEmptyRecipes) { + if (allowEmptyRecipes) return this; + throw new IllegalArgumentException("empty RecipeChoice isn't allowed here"); + } +} 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 7a0443a12..bbf3ed9dd 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 @@ -838,5 +838,13 @@ public class RecipeEventListener implements Listener { SmithingInventory inventory = event.getInventory(); if (!(inventory.getRecipe() instanceof SmithingTransformRecipe recipe)) return; + Key recipeId = Key.of(recipe.getKey().namespace(), recipe.getKey().value()); + boolean isCustom = this.recipeManager.isCustomRecipe(recipeId); + // Maybe it's recipe from other plugins, then we ignore it + if (!isCustom) { + return; + } + + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java index 7e267118f..3e6506c61 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java @@ -4125,6 +4125,18 @@ public class Reflections { ) ); + public static final Class clazz$CraftSmithingTransformRecipe = requireNonNull( + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleCBClass("inventory.CraftSmithingTransformRecipe") + ) + ); + + public static final Method method$CraftSmithingTransformRecipe$fromBukkitRecipe = requireNonNull( + ReflectionUtils.getStaticMethod( + clazz$CraftSmithingTransformRecipe, clazz$CraftSmithingTransformRecipe, SmithingTransformRecipe.class + ) + ); + public static final Class clazz$FeatureFlagSet = requireNonNull( ReflectionUtils.getClazz( BukkitReflectionUtils.assembleMCClass("world.flag.FeatureFlagSet") diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomBlastingRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomBlastingRecipe.java index 673212f9a..8d80181ec 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomBlastingRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomBlastingRecipe.java @@ -21,11 +21,11 @@ public class CustomBlastingRecipe extends CustomCookingRecipe { return RecipeTypes.BLASTING; } - public static class Factory implements RecipeFactory> { + public static class Factory implements RecipeFactory { @SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"}) @Override - public Recipe> create(Key id, Map arguments) { + public Recipe create(Key id, Map arguments) { CookingRecipeCategory recipeCategory = arguments.containsKey("category") ? CookingRecipeCategory.valueOf(arguments.get("category").toString().toUpperCase(Locale.ENGLISH)) : null; String group = arguments.containsKey("group") ? arguments.get("group").toString() : null; int cookingTime = MiscUtils.getAsInt(arguments.getOrDefault("time", 80)); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomCampfireRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomCampfireRecipe.java index 7045774fb..fd3220981 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomCampfireRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomCampfireRecipe.java @@ -21,11 +21,11 @@ public class CustomCampfireRecipe extends CustomCookingRecipe { return RecipeTypes.CAMPFIRE_COOKING; } - public static class Factory implements RecipeFactory> { + public static class Factory implements RecipeFactory { @SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"}) @Override - public Recipe> create(Key id, Map arguments) { + public Recipe create(Key id, Map arguments) { CookingRecipeCategory recipeCategory = arguments.containsKey("category") ? CookingRecipeCategory.valueOf(arguments.get("category").toString().toUpperCase(Locale.ENGLISH)) : null; String group = arguments.containsKey("group") ? arguments.get("group").toString() : null; int cookingTime = MiscUtils.getAsInt(arguments.getOrDefault("time", 80)); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmeltingRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmeltingRecipe.java index dbc3c5039..7f4fed503 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmeltingRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmeltingRecipe.java @@ -21,11 +21,11 @@ public class CustomSmeltingRecipe extends CustomCookingRecipe { return RecipeTypes.SMELTING; } - public static class Factory implements RecipeFactory> { + public static class Factory implements RecipeFactory { @SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"}) @Override - public Recipe> create(Key id, Map arguments) { + public Recipe create(Key id, Map arguments) { CookingRecipeCategory recipeCategory = arguments.containsKey("category") ? CookingRecipeCategory.valueOf(arguments.get("category").toString().toUpperCase(Locale.ENGLISH)) : null; String group = arguments.containsKey("group") ? arguments.get("group").toString() : null; int cookingTime = MiscUtils.getAsInt(arguments.getOrDefault("time", 80)); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java index e3eedc4bb..9f878670d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java @@ -2,39 +2,69 @@ package net.momirealms.craftengine.core.item.recipe; import net.momirealms.craftengine.core.item.ItemBuildContext; import net.momirealms.craftengine.core.item.recipe.input.RecipeInput; +import net.momirealms.craftengine.core.item.recipe.input.SmithingInput; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.registry.BuiltInRegistries; +import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.MiscUtils; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.util.List; +import java.util.*; public class CustomSmithingTransformRecipe implements Recipe { + public static final Factory FACTORY = new Factory<>(); private final Key id; private final CustomRecipeResult result; - private final Ingredient template; private final Ingredient base; + private final Ingredient template; private final Ingredient addition; public CustomSmithingTransformRecipe(Key id, - CustomRecipeResult result, - Ingredient template, - Ingredient base, - Ingredient addition + @Nullable Ingredient addition, + @Nullable Ingredient base, + @Nullable Ingredient template, + CustomRecipeResult result ) { this.id = id; this.result = result; - this.template = template; this.base = base; + this.template = template; this.addition = addition; } + @SuppressWarnings("unchecked") @Override public boolean matches(RecipeInput input) { - return false; + SmithingInput smithingInput = (SmithingInput) input; + return checkIngredient(this.base, smithingInput.base()) + && checkIngredient(this.template, smithingInput.template()) + && checkIngredient(this.addition, smithingInput.addition()); + } + + private boolean checkIngredient(Ingredient ingredient, OptimizedIDItem item) { + if (ingredient != null) { + if (item == null) { + return false; + } + return ingredient.test(item); + } else { + return item == null; + } } @Override public List> ingredientsInUse() { - return List.of(); + List> ingredients = new ArrayList<>(); + ingredients.add(this.base); + if (this.template != null) { + ingredients.add(this.template); + } + if (this.addition != null) { + ingredients.add(this.addition); + } + return ingredients; } @Override @@ -56,4 +86,46 @@ public class CustomSmithingTransformRecipe implements Recipe { public CustomRecipeResult result() { return this.result; } + + @Nullable + public Ingredient base() { + return base; + } + + @Nullable + public Ingredient template() { + return template; + } + + @Nullable + public Ingredient addition() { + return addition; + } + + @SuppressWarnings({"DuplicatedCode"}) + public static class Factory implements RecipeFactory { + + @Override + public Recipe create(Key id, Map arguments) { + List base = MiscUtils.getAsStringList(arguments.get("base")); + List addition = MiscUtils.getAsStringList(arguments.get("addition")); + List template = MiscUtils.getAsStringList(arguments.get("template")); + return new CustomSmithingTransformRecipe<>( + id, + toIngredient(addition), toIngredient(base), toIngredient(template), parseResult(arguments) + ); + } + + private Ingredient toIngredient(List items) { + Set> holders = new HashSet<>(); + for (String item : items) { + if (item.charAt(0) == '#') { + holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1)))); + } else { + holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(() -> new IllegalArgumentException("Invalid vanilla/custom item: " + item))); + } + } + return Ingredient.of(holders); + } + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmokingRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmokingRecipe.java index bb243c90d..2976836e0 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmokingRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmokingRecipe.java @@ -21,11 +21,11 @@ public class CustomSmokingRecipe extends CustomCookingRecipe { return RecipeTypes.SMOKING; } - public static class Factory implements RecipeFactory> { + public static class Factory implements RecipeFactory { @SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"}) @Override - public Recipe> create(Key id, Map arguments) { + public Recipe create(Key id, Map arguments) { CookingRecipeCategory recipeCategory = arguments.containsKey("category") ? CookingRecipeCategory.valueOf(arguments.get("category").toString().toUpperCase(Locale.ENGLISH)) : null; String group = arguments.containsKey("group") ? arguments.get("group").toString() : null; int cookingTime = MiscUtils.getAsInt(arguments.getOrDefault("time", 80)); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeTypes.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeTypes.java index fb81f5678..523470030 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeTypes.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeTypes.java @@ -18,6 +18,7 @@ public class RecipeTypes { public static final Key CAMPFIRE_COOKING = Key.of("minecraft:campfire_cooking"); public static final Key STONE_CUTTING = Key.of("minecraft:stone_cutting"); public static final Key SMITHING_TRANSFORM = Key.of("minecraft:smithing_transform"); + public static final Key SMITHING_TRIM = Key.of("minecraft:smithing_trim"); static { register(SHAPED, CustomShapedRecipe.FACTORY); @@ -27,6 +28,7 @@ public class RecipeTypes { register(BLASTING, CustomBlastingRecipe.FACTORY); register(CAMPFIRE_COOKING, CustomCampfireRecipe.FACTORY); register(STONE_CUTTING, CustomStoneCuttingRecipe.FACTORY); + register(SMITHING_TRANSFORM, CustomSmithingTransformRecipe.FACTORY); } public static void register(Key key, RecipeFactory factory) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/input/SmithingInput.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/input/SmithingInput.java new file mode 100644 index 000000000..29764fcb5 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/input/SmithingInput.java @@ -0,0 +1,33 @@ +package net.momirealms.craftengine.core.item.recipe.input; + +import net.momirealms.craftengine.core.item.recipe.OptimizedIDItem; +import org.jetbrains.annotations.Nullable; + +public class SmithingInput implements RecipeInput { + private final OptimizedIDItem base; + private final OptimizedIDItem template; + private final OptimizedIDItem addition; + + public SmithingInput(@Nullable OptimizedIDItem base, + @Nullable OptimizedIDItem template, + @Nullable OptimizedIDItem addition) { + this.base = base; + this.template = template; + this.addition = addition; + } + + @Nullable + public OptimizedIDItem base() { + return base; + } + + @Nullable + public OptimizedIDItem template() { + return template; + } + + @Nullable + public OptimizedIDItem addition() { + return addition; + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaBlastingRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaBlastingRecipe.java index 9e6775d69..a78b6bb0c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaBlastingRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaBlastingRecipe.java @@ -1,6 +1,8 @@ package net.momirealms.craftengine.core.item.recipe.vanilla; import net.momirealms.craftengine.core.item.recipe.CookingRecipeCategory; +import net.momirealms.craftengine.core.item.recipe.RecipeTypes; +import net.momirealms.craftengine.core.util.Key; import java.util.List; @@ -9,4 +11,9 @@ public class VanillaBlastingRecipe extends VanillaCookingRecipe { public VanillaBlastingRecipe(CookingRecipeCategory category, String group, RecipeResult result, List ingredient, float experience, int cookingTime) { super(category, group, result, ingredient, experience, cookingTime); } + + @Override + public Key type() { + return RecipeTypes.BLASTING; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaCampfireRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaCampfireRecipe.java index b2d8cae30..aa12d79db 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaCampfireRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaCampfireRecipe.java @@ -1,6 +1,8 @@ package net.momirealms.craftengine.core.item.recipe.vanilla; import net.momirealms.craftengine.core.item.recipe.CookingRecipeCategory; +import net.momirealms.craftengine.core.item.recipe.RecipeTypes; +import net.momirealms.craftengine.core.util.Key; import java.util.List; @@ -9,4 +11,9 @@ public class VanillaCampfireRecipe extends VanillaCookingRecipe { public VanillaCampfireRecipe(CookingRecipeCategory category, String group, RecipeResult result, List ingredient, float experience, int cookingTime) { super(category, group, result, ingredient, experience, cookingTime); } + + @Override + public Key type() { + return RecipeTypes.CAMPFIRE_COOKING; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaCookingRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaCookingRecipe.java index 594d372ac..93d91f943 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaCookingRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaCookingRecipe.java @@ -4,7 +4,7 @@ import net.momirealms.craftengine.core.item.recipe.CookingRecipeCategory; import java.util.List; -public abstract class VanillaCookingRecipe extends VanillaRecipe { +public abstract class VanillaCookingRecipe extends VanillaGroupedRecipe { protected final List ingredient; protected final CookingRecipeCategory category; protected final float experience; diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaCraftingRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaCraftingRecipe.java index 2ba1d3c09..d8cd3bdb5 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaCraftingRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaCraftingRecipe.java @@ -2,7 +2,7 @@ package net.momirealms.craftengine.core.item.recipe.vanilla; import net.momirealms.craftengine.core.item.recipe.CraftingRecipeCategory; -public class VanillaCraftingRecipe extends VanillaRecipe { +public abstract class VanillaCraftingRecipe extends VanillaGroupedRecipe { protected final CraftingRecipeCategory category; protected VanillaCraftingRecipe(CraftingRecipeCategory category, String group, RecipeResult result) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaGroupedRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaGroupedRecipe.java new file mode 100644 index 000000000..813a35e34 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaGroupedRecipe.java @@ -0,0 +1,20 @@ +package net.momirealms.craftengine.core.item.recipe.vanilla; + +public abstract class VanillaGroupedRecipe implements VanillaRecipe { + protected final String group; + protected final RecipeResult result; + + protected VanillaGroupedRecipe(String group, RecipeResult result) { + this.group = group; + this.result = result; + } + + public String group() { + return group; + } + + @Override + public RecipeResult result() { + return result; + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaRecipe.java index 000077538..d020f5a69 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaRecipe.java @@ -1,19 +1,10 @@ package net.momirealms.craftengine.core.item.recipe.vanilla; -public abstract class VanillaRecipe { - protected final String group; - protected final RecipeResult result; +import net.momirealms.craftengine.core.util.Key; - protected VanillaRecipe(String group, RecipeResult result) { - this.group = group; - this.result = result; - } +public interface VanillaRecipe { - public String group() { - return group; - } + Key type(); - public RecipeResult result() { - return result; - } + RecipeResult result(); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaRecipeReader.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaRecipeReader.java index 2f534efb1..f75e42eea 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaRecipeReader.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaRecipeReader.java @@ -17,4 +17,6 @@ public interface VanillaRecipeReader { VanillaCampfireRecipe readCampfire(JsonObject json); VanillaStoneCuttingRecipe readStoneCutting(JsonObject json); + + VanillaSmithingTransformRecipe readSmithingTransform(JsonObject json); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaShapedRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaShapedRecipe.java index 3b8f5d127..753590f5c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaShapedRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaShapedRecipe.java @@ -1,6 +1,8 @@ package net.momirealms.craftengine.core.item.recipe.vanilla; import net.momirealms.craftengine.core.item.recipe.CraftingRecipeCategory; +import net.momirealms.craftengine.core.item.recipe.RecipeTypes; +import net.momirealms.craftengine.core.util.Key; import java.util.List; import java.util.Map; @@ -26,4 +28,9 @@ public class VanillaShapedRecipe extends VanillaCraftingRecipe { public String[] pattern() { return pattern; } + + @Override + public Key type() { + return RecipeTypes.SHAPED; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaShapelessRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaShapelessRecipe.java index 613a2f7e8..2e06b2988 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaShapelessRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaShapelessRecipe.java @@ -1,6 +1,8 @@ package net.momirealms.craftengine.core.item.recipe.vanilla; import net.momirealms.craftengine.core.item.recipe.CraftingRecipeCategory; +import net.momirealms.craftengine.core.item.recipe.RecipeTypes; +import net.momirealms.craftengine.core.util.Key; import java.util.List; @@ -15,4 +17,9 @@ public class VanillaShapelessRecipe extends VanillaCraftingRecipe { public List> ingredients() { return ingredients; } + + @Override + public Key type() { + return RecipeTypes.SHAPELESS; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaSmeltingRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaSmeltingRecipe.java index 5aa346c26..ebbed4b21 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaSmeltingRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaSmeltingRecipe.java @@ -1,6 +1,8 @@ package net.momirealms.craftengine.core.item.recipe.vanilla; import net.momirealms.craftengine.core.item.recipe.CookingRecipeCategory; +import net.momirealms.craftengine.core.item.recipe.RecipeTypes; +import net.momirealms.craftengine.core.util.Key; import java.util.List; @@ -9,4 +11,9 @@ public class VanillaSmeltingRecipe extends VanillaCookingRecipe { public VanillaSmeltingRecipe(CookingRecipeCategory category, String group, RecipeResult result, List ingredient, float experience, int cookingTime) { super(category, group, result, ingredient, experience, cookingTime); } + + @Override + public Key type() { + return RecipeTypes.SMELTING; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaSmithingTransformRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaSmithingTransformRecipe.java new file mode 100644 index 000000000..5e4713622 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaSmithingTransformRecipe.java @@ -0,0 +1,42 @@ +package net.momirealms.craftengine.core.item.recipe.vanilla; + +import net.momirealms.craftengine.core.item.recipe.RecipeTypes; +import net.momirealms.craftengine.core.util.Key; + +import java.util.List; + +public class VanillaSmithingTransformRecipe implements VanillaRecipe { + private final RecipeResult result; + private final List base; + private final List template; + private final List addition; + + public VanillaSmithingTransformRecipe(List addition, List base, List template, RecipeResult result) { + this.result = result; + this.base = base; + this.template = template; + this.addition = addition; + } + + @Override + public Key type() { + return RecipeTypes.SMITHING_TRANSFORM; + } + + @Override + public RecipeResult result() { + return result; + } + + public List base() { + return base; + } + + public List template() { + return template; + } + + public List addition() { + return addition; + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaSmokingRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaSmokingRecipe.java index df919f810..736a3fd5e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaSmokingRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaSmokingRecipe.java @@ -1,6 +1,8 @@ package net.momirealms.craftengine.core.item.recipe.vanilla; import net.momirealms.craftengine.core.item.recipe.CookingRecipeCategory; +import net.momirealms.craftengine.core.item.recipe.RecipeTypes; +import net.momirealms.craftengine.core.util.Key; import java.util.List; @@ -9,4 +11,9 @@ public class VanillaSmokingRecipe extends VanillaCookingRecipe { public VanillaSmokingRecipe(CookingRecipeCategory category, String group, RecipeResult result, List ingredient, float experience, int cookingTime) { super(category, group, result, ingredient, experience, cookingTime); } + + @Override + public Key type() { + return RecipeTypes.SMOKING; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaStoneCuttingRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaStoneCuttingRecipe.java index 79ab56d86..bd032294d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaStoneCuttingRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/VanillaStoneCuttingRecipe.java @@ -1,8 +1,11 @@ package net.momirealms.craftengine.core.item.recipe.vanilla; +import net.momirealms.craftengine.core.item.recipe.RecipeTypes; +import net.momirealms.craftengine.core.util.Key; + import java.util.List; -public class VanillaStoneCuttingRecipe extends VanillaRecipe { +public class VanillaStoneCuttingRecipe extends VanillaGroupedRecipe { private final List ingredient; public VanillaStoneCuttingRecipe(String group, RecipeResult result, List ingredient) { @@ -13,4 +16,9 @@ public class VanillaStoneCuttingRecipe extends VanillaRecipe { public List ingredient() { return ingredient; } + + @Override + public Key type() { + return RecipeTypes.STONE_CUTTING; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/reader/VanillaRecipeReader1_20.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/reader/VanillaRecipeReader1_20.java index c6897a43c..ff836a317 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/reader/VanillaRecipeReader1_20.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/reader/VanillaRecipeReader1_20.java @@ -91,6 +91,16 @@ public class VanillaRecipeReader1_20 extends AbstractRecipeReader { ); } + @Override + public VanillaSmithingTransformRecipe readSmithingTransform(JsonObject json) { + return new VanillaSmithingTransformRecipe( + readSingleIngredient(json.get("base")), + readSingleIngredient(json.get("template")), + readSingleIngredient(json.get("addition")), + readSmithingResult(json.getAsJsonObject("result")) + ); + } + protected List readSingleIngredient(JsonElement json) { List ingredients = new ArrayList<>(); if (json.isJsonObject()) { @@ -126,6 +136,12 @@ public class VanillaRecipeReader1_20 extends AbstractRecipeReader { return new RecipeResult(item, count, null); } + @NotNull + protected RecipeResult readSmithingResult(JsonObject object) { + String item = object.get("item").getAsString(); + return new RecipeResult(item, 1, null); + } + protected List> readShapelessIngredients(JsonArray json) { List> ingredients = new ArrayList<>(); for (JsonElement element : json) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/reader/VanillaRecipeReader1_20_5.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/reader/VanillaRecipeReader1_20_5.java index 727ba41cb..3bd399f96 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/reader/VanillaRecipeReader1_20_5.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/vanilla/reader/VanillaRecipeReader1_20_5.java @@ -26,4 +26,9 @@ public class VanillaRecipeReader1_20_5 extends VanillaRecipeReader1_20 { protected RecipeResult readStoneCuttingResult(JsonObject json) { return readCraftingResult(json.getAsJsonObject("result")); } + + @Override + protected @NotNull RecipeResult readSmithingResult(JsonObject object) { + return readCraftingResult(object.getAsJsonObject()); + } }