From 195045b00b0ec9a3250fac89c7fa65365b090879 Mon Sep 17 00:00:00 2001 From: IzzelAliz Date: Tue, 12 Apr 2022 21:11:55 +0800 Subject: [PATCH] Add support for non vanilla ingredients --- .../common/mixin/bukkit/CraftRecipeMixin.java | 81 +++++++++++++++++++ .../inventory/ArclightSpecialIngredient.java | 58 +++++++++++++ .../resources/mixins.arclight.bukkit.json | 1 + 3 files changed, 140 insertions(+) create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftRecipeMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mod/inventory/ArclightSpecialIngredient.java diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftRecipeMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftRecipeMixin.java new file mode 100644 index 00000000..b5edb864 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftRecipeMixin.java @@ -0,0 +1,81 @@ +package io.izzel.arclight.common.mixin.bukkit; + +import io.izzel.arclight.common.bridge.core.item.crafting.IngredientBridge; +import io.izzel.arclight.common.mod.inventory.ArclightSpecialIngredient; +import net.minecraft.world.item.crafting.Ingredient; +import org.bukkit.craftbukkit.v.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v.inventory.CraftRecipe; +import org.bukkit.craftbukkit.v.util.CraftMagicNumbers; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.RecipeChoice; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +import java.util.ArrayList; +import java.util.List; + +@Mixin(value = CraftRecipe.class, remap = false) +public interface CraftRecipeMixin { + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + default Ingredient toNMS(RecipeChoice bukkit, boolean requireNotEmpty) { + Ingredient stack; + if (bukkit == null) { + stack = Ingredient.EMPTY; + } else if (bukkit instanceof RecipeChoice.MaterialChoice) { + stack = new Ingredient(((RecipeChoice.MaterialChoice) bukkit).getChoices().stream().map((mat) -> { + return new Ingredient.ItemValue(CraftItemStack.asNMSCopy(new ItemStack(mat))); + })); + } else if (bukkit instanceof RecipeChoice.ExactChoice) { + stack = new Ingredient(((RecipeChoice.ExactChoice) bukkit).getChoices().stream().map((mat) -> { + return new Ingredient.ItemValue(CraftItemStack.asNMSCopy(mat)); + })); + ((IngredientBridge) stack).bridge$setExact(true); + } else if (bukkit instanceof ArclightSpecialIngredient) { + stack = ((ArclightSpecialIngredient) bukkit).getIngredient(); + } else { + throw new IllegalArgumentException("Unknown recipe stack instance " + bukkit); + } + + stack.dissolve(); + if (stack.isVanilla() && requireNotEmpty && stack.getItems().length == 0) { + throw new IllegalArgumentException("Recipe requires at least one non-air choice!"); + } else { + return stack; + } + } + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + static RecipeChoice toBukkit(Ingredient list) { + list.dissolve(); + if (!list.isVanilla()) { + return new ArclightSpecialIngredient(list); + } + net.minecraft.world.item.ItemStack[] items = list.getItems(); + if (items.length == 0) { + return null; + } else { + if (((IngredientBridge) list).bridge$isExact()) { + List choices = new ArrayList<>(items.length); + for (net.minecraft.world.item.ItemStack i : items) { + choices.add(CraftItemStack.asBukkitCopy(i)); + } + return new RecipeChoice.ExactChoice(choices); + } else { + List choices = new ArrayList<>(items.length); + for (net.minecraft.world.item.ItemStack i : items) { + choices.add(CraftMagicNumbers.getMaterial(i.getItem())); + } + return new RecipeChoice.MaterialChoice(choices); + } + } + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/inventory/ArclightSpecialIngredient.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/inventory/ArclightSpecialIngredient.java new file mode 100644 index 00000000..74cacaf5 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/inventory/ArclightSpecialIngredient.java @@ -0,0 +1,58 @@ +package io.izzel.arclight.common.mod.inventory; + +import net.minecraft.world.item.crafting.Ingredient; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v.inventory.CraftItemStack; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.RecipeChoice; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; + +public class ArclightSpecialIngredient implements RecipeChoice { + + private final Ingredient ingredient; + + public ArclightSpecialIngredient(Ingredient ingredient) { + this.ingredient = ingredient; + } + + public Ingredient getIngredient() { + return ingredient; + } + + @NotNull + @Override + public ItemStack getItemStack() { + net.minecraft.world.item.ItemStack[] items = ingredient.getItems(); + return items.length > 0 ? CraftItemStack.asCraftMirror(items[0]) : new ItemStack(Material.AIR, 0); + } + + @NotNull + @Override + public RecipeChoice clone() { + try { + return (RecipeChoice) super.clone(); + } catch (CloneNotSupportedException e) { + throw new AssertionError(e); + } + } + + @Override + public boolean test(@NotNull ItemStack itemStack) { + return ingredient.test(CraftItemStack.asNMSCopy(itemStack)); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ArclightSpecialIngredient that = (ArclightSpecialIngredient) o; + return Objects.equals(ingredient, that.ingredient); + } + + @Override + public int hashCode() { + return Objects.hash(ingredient); + } +} diff --git a/arclight-common/src/main/resources/mixins.arclight.bukkit.json b/arclight-common/src/main/resources/mixins.arclight.bukkit.json index 91307403..a627a7f4 100644 --- a/arclight-common/src/main/resources/mixins.arclight.bukkit.json +++ b/arclight-common/src/main/resources/mixins.arclight.bukkit.json @@ -31,6 +31,7 @@ "CraftMetaItemMixin", "CraftPlayerMixin", "CraftPotionUtilMixin", + "CraftRecipeMixin", "CraftRegionAccessorMixin", "CraftSchedulerMixin", "CraftServerMixin",