From 90b9a029e0bb57174bb52751fed45442a23e347b Mon Sep 17 00:00:00 2001 From: LatvianModder Date: Wed, 24 Jul 2024 14:07:39 +0300 Subject: [PATCH] Removed KJS' TagIngredient and rewrote how tags are applied. This should now work much better --- .../kubejs/bindings/IngredientWrapper.java | 17 ++- .../custom/MultipartShapedBlockBuilder.java | 2 - .../mods/kubejs/core/IngredientKJS.java | 12 ++ .../core/mixin/IngredientTagValueMixin.java | 38 ------ .../core/mixin/TagEmptyConditionMixin.java | 29 ----- .../kubejs/ingredient/KubeJSIngredients.java | 1 - .../mods/kubejs/ingredient/TagIngredient.java | 108 ------------------ .../latvian/mods/kubejs/item/ItemStackJS.java | 4 +- .../kubejs/item/ingredient/IngredientJS.java | 4 +- .../mods/kubejs/recipe/CachedTagLookup.java | 18 +++ .../mods/kubejs/recipe/RecipesKubeEvent.java | 3 - .../kubejs/server/ServerScriptManager.java | 7 +- .../kubejs/util/RegistryAccessContainer.java | 16 ++- src/main/resources/kubejs.mixins.json | 2 - 14 files changed, 66 insertions(+), 195 deletions(-) delete mode 100644 src/main/java/dev/latvian/mods/kubejs/core/mixin/IngredientTagValueMixin.java delete mode 100644 src/main/java/dev/latvian/mods/kubejs/core/mixin/TagEmptyConditionMixin.java delete mode 100644 src/main/java/dev/latvian/mods/kubejs/ingredient/TagIngredient.java diff --git a/src/main/java/dev/latvian/mods/kubejs/bindings/IngredientWrapper.java b/src/main/java/dev/latvian/mods/kubejs/bindings/IngredientWrapper.java index 266cd7253..cd5e44b14 100644 --- a/src/main/java/dev/latvian/mods/kubejs/bindings/IngredientWrapper.java +++ b/src/main/java/dev/latvian/mods/kubejs/bindings/IngredientWrapper.java @@ -1,6 +1,5 @@ package dev.latvian.mods.kubejs.bindings; -import dev.latvian.mods.kubejs.ingredient.TagIngredient; import dev.latvian.mods.kubejs.ingredient.WildcardIngredient; import dev.latvian.mods.kubejs.typings.Info; import net.minecraft.tags.TagKey; @@ -43,10 +42,22 @@ static ItemStack first(Ingredient ingredient) { static TagKey tagKeyOf(Ingredient in) { if (!in.isCustom() && in.getValues().length == 1 && in.getValues()[0] instanceof Ingredient.TagValue value) { return value.tag(); - } else if (in.getCustomIngredient() instanceof TagIngredient tin) { - return tin.tagKey; } else { return null; } } + + static boolean containsAnyTag(Ingredient in) { + if (in.isCustom()) { + return false; + } + + for (var value : in.getValues()) { + if (value instanceof Ingredient.TagValue) { + return true; + } + } + + return false; + } } \ No newline at end of file diff --git a/src/main/java/dev/latvian/mods/kubejs/block/custom/MultipartShapedBlockBuilder.java b/src/main/java/dev/latvian/mods/kubejs/block/custom/MultipartShapedBlockBuilder.java index af32fe10f..9ebce310d 100644 --- a/src/main/java/dev/latvian/mods/kubejs/block/custom/MultipartShapedBlockBuilder.java +++ b/src/main/java/dev/latvian/mods/kubejs/block/custom/MultipartShapedBlockBuilder.java @@ -30,8 +30,6 @@ public void generateAssets(KubeAssetGenerator generator) { generator.itemModel(itemBuilder.id, this::generateItemModelJson); } } - - } protected abstract void generateMultipartBlockStateJson(MultipartBlockStateGenerator bs); diff --git a/src/main/java/dev/latvian/mods/kubejs/core/IngredientKJS.java b/src/main/java/dev/latvian/mods/kubejs/core/IngredientKJS.java index 971cf8579..d9cededfc 100644 --- a/src/main/java/dev/latvian/mods/kubejs/core/IngredientKJS.java +++ b/src/main/java/dev/latvian/mods/kubejs/core/IngredientKJS.java @@ -13,12 +13,15 @@ import dev.latvian.mods.kubejs.util.WithCodec; import dev.latvian.mods.rhino.Context; import dev.latvian.mods.rhino.util.RemapPrefixForJS; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; import net.neoforged.neoforge.common.crafting.CompoundIngredient; import net.neoforged.neoforge.common.crafting.DifferenceIngredient; import net.neoforged.neoforge.common.crafting.IntersectionIngredient; import net.neoforged.neoforge.common.crafting.SizedIngredient; +import org.jetbrains.annotations.Nullable; @RemapPrefixForJS("kjs$") public interface IngredientKJS extends ItemPredicate, Replaceable, WithCodec, ItemMatch { @@ -123,4 +126,13 @@ default boolean matches(Context cx, Ingredient in, boolean exact) { return false; } + + @Nullable + default TagKey kjs$getTagKey() { + return IngredientWrapper.tagKeyOf(kjs$self()); + } + + default boolean kjs$containsAnyTag() { + return IngredientWrapper.containsAnyTag(kjs$self()); + } } diff --git a/src/main/java/dev/latvian/mods/kubejs/core/mixin/IngredientTagValueMixin.java b/src/main/java/dev/latvian/mods/kubejs/core/mixin/IngredientTagValueMixin.java deleted file mode 100644 index edfefe500..000000000 --- a/src/main/java/dev/latvian/mods/kubejs/core/mixin/IngredientTagValueMixin.java +++ /dev/null @@ -1,38 +0,0 @@ -package dev.latvian.mods.kubejs.core.mixin; - -import dev.latvian.mods.kubejs.error.EmptyTagException; -import dev.latvian.mods.kubejs.recipe.RecipesKubeEvent; -import net.minecraft.tags.TagKey; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.Ingredient; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.Collection; - -@Mixin(Ingredient.TagValue.class) -public abstract class IngredientTagValueMixin { - @Shadow - @Final - private TagKey tag; - - @Inject(method = "getItems", at = @At("HEAD"), cancellable = true) - private void kjs$getItems(CallbackInfoReturnable> info) { - var lookup = RecipesKubeEvent.TEMP_ITEM_TAG_LOOKUP.getValue(); - - if (lookup != null) { - var values = lookup.values(tag); - - if (values.isEmpty()) { - throw new EmptyTagException(tag); - } else { - info.setReturnValue(values.stream().map(ItemStack::new).toList()); - } - } - } -} diff --git a/src/main/java/dev/latvian/mods/kubejs/core/mixin/TagEmptyConditionMixin.java b/src/main/java/dev/latvian/mods/kubejs/core/mixin/TagEmptyConditionMixin.java deleted file mode 100644 index 37c683ab8..000000000 --- a/src/main/java/dev/latvian/mods/kubejs/core/mixin/TagEmptyConditionMixin.java +++ /dev/null @@ -1,29 +0,0 @@ -package dev.latvian.mods.kubejs.core.mixin; - -import dev.latvian.mods.kubejs.recipe.RecipesKubeEvent; -import net.minecraft.tags.TagKey; -import net.minecraft.world.item.Item; -import net.neoforged.neoforge.common.conditions.ICondition; -import net.neoforged.neoforge.common.conditions.TagEmptyCondition; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(value = TagEmptyCondition.class, remap = false) -public abstract class TagEmptyConditionMixin { - @Shadow - @Final - private TagKey tag; - - @Inject(method = "test", at = @At("HEAD"), cancellable = true, remap = false) - private void kjs$test(ICondition.IContext ctx, CallbackInfoReturnable cir) { - var lookup = RecipesKubeEvent.TEMP_ITEM_TAG_LOOKUP.getValue(); - - if (lookup != null) { - cir.setReturnValue(lookup.isEmpty(tag)); - } - } -} diff --git a/src/main/java/dev/latvian/mods/kubejs/ingredient/KubeJSIngredients.java b/src/main/java/dev/latvian/mods/kubejs/ingredient/KubeJSIngredients.java index a08455bdd..014f4b68b 100644 --- a/src/main/java/dev/latvian/mods/kubejs/ingredient/KubeJSIngredients.java +++ b/src/main/java/dev/latvian/mods/kubejs/ingredient/KubeJSIngredients.java @@ -11,7 +11,6 @@ public interface KubeJSIngredients { DeferredRegister> REGISTRY = DeferredRegister.create(NeoForgeRegistries.Keys.INGREDIENT_TYPES, KubeJS.MOD_ID); Supplier> WILDCARD = REGISTRY.register("wildcard", () -> new IngredientType<>(WildcardIngredient.CODEC, WildcardIngredient.STREAM_CODEC)); - Supplier> TAG = REGISTRY.register("tag", () -> new IngredientType<>(TagIngredient.CODEC, TagIngredient.STREAM_CODEC)); Supplier> NAMESPACE = REGISTRY.register("namespace", () -> new IngredientType<>(NamespaceIngredient.CODEC, NamespaceIngredient.STREAM_CODEC)); Supplier> REGEX = REGISTRY.register("regex", () -> new IngredientType<>(RegExIngredient.CODEC, RegExIngredient.STREAM_CODEC)); Supplier> CREATIVE_TAB = REGISTRY.register("creative_tab", () -> new IngredientType<>(CreativeTabIngredient.CODEC, CreativeTabIngredient.STREAM_CODEC)); diff --git a/src/main/java/dev/latvian/mods/kubejs/ingredient/TagIngredient.java b/src/main/java/dev/latvian/mods/kubejs/ingredient/TagIngredient.java deleted file mode 100644 index 7d58da6ab..000000000 --- a/src/main/java/dev/latvian/mods/kubejs/ingredient/TagIngredient.java +++ /dev/null @@ -1,108 +0,0 @@ -package dev.latvian.mods.kubejs.ingredient; - -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.latvian.mods.kubejs.error.EmptyTagException; -import dev.latvian.mods.kubejs.recipe.CachedTagLookup; -import dev.latvian.mods.kubejs.recipe.RecipesKubeEvent; -import io.netty.buffer.ByteBuf; -import net.minecraft.core.component.DataComponents; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.core.registries.Registries; -import net.minecraft.network.chat.Component; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.ItemTags; -import net.minecraft.tags.TagKey; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.neoforged.neoforge.common.crafting.IngredientType; -import org.jetbrains.annotations.Nullable; - -import java.util.HashSet; -import java.util.Set; -import java.util.stream.Stream; - -public final class TagIngredient implements KubeJSIngredient { - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - TagKey.codec(Registries.ITEM).fieldOf("tag").forGetter(t -> t.tagKey) - ).apply(instance, tagKey -> new TagIngredient(null, tagKey))); - - public static final StreamCodec STREAM_CODEC = ResourceLocation.STREAM_CODEC.map(id -> new TagIngredient(null, ItemTags.create(id)), in -> in.tagKey.location()); - - public final @Nullable CachedTagLookup lookup; - public final TagKey tagKey; - private Set cachedItems; - - public TagIngredient(@Nullable CachedTagLookup lookup, TagKey tagKey) { - this.lookup = lookup; - this.tagKey = tagKey; - } - - @Override - public IngredientType getType() { - return KubeJSIngredients.TAG.get(); - } - - public Set kjs$getItems() { - if (cachedItems == null) { - if (lookup != null) { - cachedItems = lookup.values(tagKey); - } else { - cachedItems = new HashSet<>(); - - for (var item : BuiltInRegistries.ITEM) { - if (item.builtInRegistryHolder().is(tagKey)) { - cachedItems.add(item); - } - } - } - - cachedItems = Set.copyOf(cachedItems); - } - - return cachedItems; - } - - @Override - public boolean test(@Nullable ItemStack stack) { - if (lookup != null) { - return stack != null && kjs$getItems().contains(stack.getItem()); - } else { - return stack != null && stack.is(tagKey); - } - } - - @Override - public Stream getItems() { - var set = kjs$getItems(); - - if (set.isEmpty()) { - if (RecipesKubeEvent.TEMP_ITEM_TAG_LOOKUP.getValue() != null) { - throw new EmptyTagException(tagKey); - } else { - var error = new ItemStack(Items.BARRIER); - error.set(DataComponents.CUSTOM_NAME, Component.literal("Empty Tag: " + tagKey.location())); - return Stream.of(error); - } - } - - return set.stream().map(ItemStack::new); - } - - @Override - public boolean equals(Object obj) { - return obj == this || obj instanceof TagIngredient i && tagKey == i.tagKey; - } - - @Override - public int hashCode() { - return tagKey.hashCode(); - } - - @Override - public String toString() { - return "KubeJSItemTagIngredient[" + tagKey.location() + "]"; - } -} diff --git a/src/main/java/dev/latvian/mods/kubejs/item/ItemStackJS.java b/src/main/java/dev/latvian/mods/kubejs/item/ItemStackJS.java index 2be04098e..1316b1d06 100644 --- a/src/main/java/dev/latvian/mods/kubejs/item/ItemStackJS.java +++ b/src/main/java/dev/latvian/mods/kubejs/item/ItemStackJS.java @@ -8,7 +8,6 @@ import com.mojang.serialization.JsonOps; import dev.latvian.mods.kubejs.bindings.DataComponentWrapper; import dev.latvian.mods.kubejs.ingredient.RegExIngredient; -import dev.latvian.mods.kubejs.ingredient.TagIngredient; import dev.latvian.mods.kubejs.util.ID; import dev.latvian.mods.kubejs.util.Lazy; import dev.latvian.mods.kubejs.util.MapJS; @@ -157,7 +156,8 @@ static ItemStack wrap(RegistryAccessContainer registries, @Nullable Object o) { return stack; } else if (map.containsKey("tag")) { - var stack = new TagIngredient(registries.cachedItemTags, ItemTags.create(ID.mc(map.get("tag")))).toVanilla().kjs$getFirst(); + // var stack = new TagIngredient(registries.cachedItemTags, ItemTags.create(ID.mc(map.get("tag")))).toVanilla().kjs$getFirst(); + var stack = Ingredient.of(ItemTags.create(ID.mc(map.get("tag")))).kjs$getFirst(); if (map.containsKey("count")) { stack.setCount(UtilsJS.parseInt(map.get("count"), 1)); diff --git a/src/main/java/dev/latvian/mods/kubejs/item/ingredient/IngredientJS.java b/src/main/java/dev/latvian/mods/kubejs/item/ingredient/IngredientJS.java index f3893c7f0..e2d3f2d52 100644 --- a/src/main/java/dev/latvian/mods/kubejs/item/ingredient/IngredientJS.java +++ b/src/main/java/dev/latvian/mods/kubejs/item/ingredient/IngredientJS.java @@ -13,7 +13,6 @@ import dev.latvian.mods.kubejs.ingredient.CreativeTabIngredient; import dev.latvian.mods.kubejs.ingredient.NamespaceIngredient; import dev.latvian.mods.kubejs.ingredient.RegExIngredient; -import dev.latvian.mods.kubejs.ingredient.TagIngredient; import dev.latvian.mods.kubejs.item.ItemStackJS; import dev.latvian.mods.kubejs.util.ListJS; import dev.latvian.mods.kubejs.util.MapJS; @@ -145,7 +144,8 @@ static Ingredient read(RegistryAccessContainer registries, StringReader reader) } case '#' -> { reader.skip(); - yield new TagIngredient(registries.cachedItemTags, ItemTags.create(ResourceLocation.read(reader))).toVanilla(); + // yield new TagIngredient(registries.cachedItemTags, ItemTags.create(ResourceLocation.read(reader))).toVanilla(); + yield Ingredient.of(ItemTags.create(ResourceLocation.read(reader))); } case '@' -> { reader.skip(); diff --git a/src/main/java/dev/latvian/mods/kubejs/recipe/CachedTagLookup.java b/src/main/java/dev/latvian/mods/kubejs/recipe/CachedTagLookup.java index 8883d0967..cda0134ab 100644 --- a/src/main/java/dev/latvian/mods/kubejs/recipe/CachedTagLookup.java +++ b/src/main/java/dev/latvian/mods/kubejs/recipe/CachedTagLookup.java @@ -2,6 +2,7 @@ import com.mojang.datafixers.util.Either; import dev.latvian.mods.kubejs.KubeJS; +import net.minecraft.core.Holder; import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; @@ -122,4 +123,21 @@ public Set> keys(T value) { return valueToKey.getOrDefault(value, Set.of()); } + + public Map, List>> bindingMap() { + var k2v = keyToValue(); + var map = new IdentityHashMap, List>>(k2v.size()); + + for (var entry : k2v.entrySet()) { + var list = new ArrayList>(entry.getValue().size()); + + for (var value : entry.getValue()) { + list.add(registry.wrapAsHolder(value)); + } + + map.put(entry.getKey(), list); + } + + return map; + } } diff --git a/src/main/java/dev/latvian/mods/kubejs/recipe/RecipesKubeEvent.java b/src/main/java/dev/latvian/mods/kubejs/recipe/RecipesKubeEvent.java index 7d1e9e418..8251232ad 100644 --- a/src/main/java/dev/latvian/mods/kubejs/recipe/RecipesKubeEvent.java +++ b/src/main/java/dev/latvian/mods/kubejs/recipe/RecipesKubeEvent.java @@ -43,7 +43,6 @@ import net.minecraft.world.item.crafting.Recipe; import net.minecraft.world.item.crafting.RecipeHolder; import net.minecraft.world.item.crafting.RecipeSerializer; -import org.apache.commons.lang3.mutable.MutableObject; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -69,8 +68,6 @@ import java.util.stream.Stream; public class RecipesKubeEvent implements KubeEvent { - public static final MutableObject TEMP_ITEM_TAG_LOOKUP = new MutableObject<>(null); - public static final Pattern POST_SKIP_ERROR = Pattern.compile("dev\\.latvian\\.mods\\.kubejs\\.recipe\\.RecipesKubeEvent\\.post"); public static final Pattern CREATE_RECIPE_SKIP_ERROR = Pattern.compile("dev\\.latvian\\.mods\\.kubejs\\.recipe\\.RecipesKubeEvent\\.createRecipe"); private static final Predicate RECIPE_NOT_REMOVED = r -> r != null && !r.removed; diff --git a/src/main/java/dev/latvian/mods/kubejs/server/ServerScriptManager.java b/src/main/java/dev/latvian/mods/kubejs/server/ServerScriptManager.java index 9685f0488..c04454a7c 100644 --- a/src/main/java/dev/latvian/mods/kubejs/server/ServerScriptManager.java +++ b/src/main/java/dev/latvian/mods/kubejs/server/ServerScriptManager.java @@ -222,7 +222,11 @@ public boolean recipes(RecipeManagerKJS recipeManager, ResourceManager resourceM } boolean result = false; - RecipesKubeEvent.TEMP_ITEM_TAG_LOOKUP.setValue(getRegistries().cachedItemTags); + + for (var entry : getRegistries().cachedRegistryTags.values()) { + entry.getLeft().bindTags((Map) entry.getRight().bindingMap()); + } + recipeSchemaStorage.fireEvents(getRegistries(), resourceManager); SpecialRecipeSerializerManager.INSTANCE.reset(); @@ -234,7 +238,6 @@ public boolean recipes(RecipeManagerKJS recipeManager, ResourceManager resourceM } serverData = new SyncServerDataPayload(KubeServerData.collect()); - RecipesKubeEvent.TEMP_ITEM_TAG_LOOKUP.setValue(null); return result; } diff --git a/src/main/java/dev/latvian/mods/kubejs/util/RegistryAccessContainer.java b/src/main/java/dev/latvian/mods/kubejs/util/RegistryAccessContainer.java index 94b45badb..d863c28e8 100644 --- a/src/main/java/dev/latvian/mods/kubejs/util/RegistryAccessContainer.java +++ b/src/main/java/dev/latvian/mods/kubejs/util/RegistryAccessContainer.java @@ -21,11 +21,14 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagLoader; import net.minecraft.world.damagesource.DamageSources; -import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.material.Fluid; +import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.ApiStatus; import java.util.HashMap; +import java.util.IdentityHashMap; import java.util.List; import java.util.Map; @@ -46,9 +49,10 @@ public static RegistryAccessContainer of(Context cx) { private final RegistryOps java; private DamageSources damageSources; private final Map itemStackParseCache; + public Map, Pair, CachedTagLookup>> cachedRegistryTags; public CachedItemTagLookup cachedItemTags; - public CachedTagLookup cachedBlockTags; - public CachedTagLookup cachedFluidTags; + public CachedTagLookup cachedBlockTags; + public CachedTagLookup cachedFluidTags; private Map cachedRegistryWrappers; public RegistryAccessContainer(RegistryAccess.Frozen access) { @@ -58,6 +62,7 @@ public RegistryAccessContainer(RegistryAccess.Frozen access) { this.java = access.createSerializationContext(JavaOps.INSTANCE); this.damageSources = null; this.itemStackParseCache = new HashMap<>(); + this.cachedRegistryTags = new IdentityHashMap<>(); } public RegistryAccess.Frozen access() { @@ -94,10 +99,15 @@ public void cacheTags(Registry registry, Map(registry, map)); + cachedRegistryTags.put(key1, Pair.of(registry, cachedBlockTags)); } else if (key1 == Registries.FLUID) { cachedFluidTags = Cast.to(new CachedTagLookup<>(registry, map)); + cachedRegistryTags.put(key1, Pair.of(registry, cachedFluidTags)); + } else { + cachedRegistryTags.put(key1, Pair.of(registry, new CachedTagLookup<>(registry, map))); } } diff --git a/src/main/resources/kubejs.mixins.json b/src/main/resources/kubejs.mixins.json index fb467228c..4154e16ab 100644 --- a/src/main/resources/kubejs.mixins.json +++ b/src/main/resources/kubejs.mixins.json @@ -30,7 +30,6 @@ "GameRulesMixin", "IItemHandlerMixin", "IngredientMixin", - "IngredientTagValueMixin", "ItemEntityMixin", "ItemFrameEntityMixin", "ItemMixin", @@ -57,7 +56,6 @@ "SizedIngredientMixin", "StringRepresentableMixin", "StringTagMixin", - "TagEmptyConditionMixin", "TagLoaderMixin", "TagManagerMixin", "TextColorMixin",