From 6d63e460a585186b5c84844e1bdad5791320a8c1 Mon Sep 17 00:00:00 2001 From: brachy84 Date: Sat, 6 Jul 2024 18:11:53 +0200 Subject: [PATCH] cleanup ItemStackMixin & add transformer helpers --- examples/postInit/vanilla.groovy | 4 +- .../compat/vanilla/ItemStackExpansion.java | 34 +++ .../vanilla/ItemStackMixinExpansion.java | 212 ++++++++++++++++++ .../compat/vanilla/ItemStackTransformer.java | 8 + .../vanilla/RarityItemStackExpansion.java | 12 - .../compat/vanilla/VanillaModule.java | 2 +- .../core/mixin/ItemStackMixin.java | 194 +++------------- 7 files changed, 286 insertions(+), 180 deletions(-) create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/vanilla/ItemStackExpansion.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/vanilla/ItemStackMixinExpansion.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/vanilla/ItemStackTransformer.java delete mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/vanilla/RarityItemStackExpansion.java diff --git a/examples/postInit/vanilla.groovy b/examples/postInit/vanilla.groovy index d0444e27e..e05d7251c 100644 --- a/examples/postInit/vanilla.groovy +++ b/examples/postInit/vanilla.groovy @@ -34,7 +34,7 @@ crafting.shapedBuilder() crafting.shapedBuilder() .name('gold_v_to_clay') .output(item('minecraft:clay')) - .shape([[item('minecraft:gold_ingot'),null,item('minecraft:gold_ingot')],[null,item('minecraft:gold_ingot'),null]]) + .shape([[item('minecraft:gold_ingot'),null,item('minecraft:gold_ingot')],[null,item('minecraft:stone_pickaxe').transformDamage(2).whenAnyDamage(),null]]) .register() //crafting.addShaped(resource('example:resource_location'), item('minecraft:clay'), [[item('minecraft:cobblestone')],[item('minecraft:nether_star')],[item('minecraft:cobblestone')]]) @@ -131,7 +131,7 @@ def presetKeys = [ T: item('minecraft:tnt'), D: item('minecraft:diamond'), S: ore('netherStar').reuse(), - '!': item('minecraft:tnt').transform({ _ -> item('minecraft:diamond') }), + '!': item('minecraft:tnt').transform(item('minecraft:diamond')), G: ore('ingotGold'), W: fluid('water') * 1000, // Any tank that contains >= 1000 mb and can be reduced by 1000. '0': item('minecraft:diamond_sword').withNbt([display:[Name:'Sword with Specific NBT data']]) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/ItemStackExpansion.java b/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/ItemStackExpansion.java new file mode 100644 index 000000000..885eff559 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/ItemStackExpansion.java @@ -0,0 +1,34 @@ +package com.cleanroommc.groovyscript.compat.vanilla; + +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.helper.ingredient.OreDictIngredient; +import net.minecraft.item.ItemStack; +import net.minecraft.util.text.TextFormatting; + +public class ItemStackExpansion { + + public static ItemStack setRarity(ItemStack self, TextFormatting color) { + VanillaModule.rarity.set(color, self); + return self; + } + + public static void addOreDict(ItemStack self, OreDictIngredient ingredient) { + VanillaModule.oreDict.add(ingredient.getOreDict(), self); + } + + public static void removeOreDict(ItemStack self, OreDictIngredient ingredient) { + VanillaModule.oreDict.remove(ingredient.getOreDict(), self); + } + + public static boolean leftShift(ItemStack self, IIngredient ingredient) { + return ingredient.isCase(self) && ingredient.getAmount() >= self.getCount(); + } + + public static boolean isSameExact(ItemStack self, ItemStack itemStack) { + return ItemStack.areItemStacksEqual(self, itemStack); + } + + public static boolean isSame(ItemStack self, ItemStack itemStack, boolean ignoreNbt) { + return ItemStack.areItemsEqual(self, itemStack) && (ignoreNbt || ItemStack.areItemStackTagsEqual(self, itemStack)); + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/ItemStackMixinExpansion.java b/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/ItemStackMixinExpansion.java new file mode 100644 index 000000000..a3992785d --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/ItemStackMixinExpansion.java @@ -0,0 +1,212 @@ +package com.cleanroommc.groovyscript.compat.vanilla; + +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.IMarkable; +import com.cleanroommc.groovyscript.api.INBTResourceStack; +import com.cleanroommc.groovyscript.api.INbtIngredient; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.ingredient.NbtHelper; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.ForgeHooks; +import net.minecraftforge.oredict.OreDictionary; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Predicate; +import java.util.function.UnaryOperator; + +public interface ItemStackMixinExpansion extends IIngredient, INbtIngredient, IMarkable { + + static ItemStackMixinExpansion of(ItemStack stack) { + return (ItemStackMixinExpansion) (Object) stack; + } + + ItemStack grs$getItemStack(); + + @Nullable + ItemStackTransformer grs$getTransformer(); + + @Nullable + Predicate grs$getNbtMatcher(); + + @Nullable + Predicate grs$getMatcher(); + + void grs$setTransformer(ItemStackTransformer transformer); + + void grs$setNbtMatcher(Predicate matcher); + + void grs$setMatcher(Predicate matcher); + + default boolean grs$isEmpty() { + return grs$getItemStack().isEmpty(); + } + + @Override + default ItemStackMixinExpansion exactCopy() { + if (grs$isEmpty()) { + return (ItemStackMixinExpansion) (Object) ItemStack.EMPTY; + } + ItemStackMixinExpansion copy = of(grs$getItemStack().copy()); + copy.setMark(getMark()); + copy.grs$setTransformer(grs$getTransformer()); + copy.grs$setMatcher(grs$getMatcher()); + copy.grs$setNbtMatcher(grs$getNbtMatcher()); + return copy; + } + + @Override + default boolean test(ItemStack stack) { + if (!OreDictionary.itemMatches(grs$getItemStack(), stack, false) && + (grs$getMatcher() == null || !grs$getMatcher().test(stack))) { + return false; + } + if (grs$getNbtMatcher() != null) { + NBTTagCompound nbt = stack.getTagCompound(); + return nbt != null && grs$getNbtMatcher().test(nbt); + } + return true; + } + + default ItemStack when(Predicate matchCondition) { + ItemStackMixinExpansion fresh = exactCopy(); + fresh.grs$setMatcher(matchCondition); + return fresh.grs$getItemStack(); + } + + default ItemStack whenAnyDamage() { + return when(stack -> stack.getItem() == grs$getItemStack().getItem()); + } + + default ItemStack whenAnyMeta() { + return whenAnyDamage(); + } + + default ItemStack transform(ItemStackTransformer transformer) { + ItemStackMixinExpansion fresh = exactCopy(); + fresh.grs$setTransformer(transformer); + return fresh.grs$getItemStack(); + } + + default ItemStack reuse() { + return transform(self -> self); + } + + default ItemStack noreturn() { + return transform(self -> ItemStack.EMPTY); + } + + default ItemStack transform(ItemStack stack) { + return transform(self -> stack); + } + + default ItemStack transformDamage(int amount) { + return transform(self -> of(self).withDamage(Math.min(32767, Items.DIAMOND.getDamage(self) + amount))); + } + + default ItemStack transformDamage() { + return transformDamage(1); + } + + default ItemStack transformNbt(UnaryOperator transformer) { + return transform(self -> { + of(self).exactCopy().grs$getItemStack().setTagCompound(transformer.apply(self.getTagCompound())); + return self; + }); + } + + @Override + default ItemStack applyTransform(ItemStack matchedInput) { + if (grs$getTransformer() != null) { + ItemStack result = grs$getTransformer().transform(matchedInput); + if (result == null) return ItemStack.EMPTY; + return result.copy(); + } + return ForgeHooks.getContainerItem(matchedInput); + } + + @Override + default Ingredient toMcIngredient() { + return Ingredient.fromStacks(grs$getItemStack()); + } + + @Override + default ItemStack[] getMatchingStacks() { + return new ItemStack[]{IngredientHelper.toItemStack(exactCopy())}; + } + + @Override + default int getAmount() { + return grs$getItemStack().getCount(); + } + + @Override + default void setAmount(int amount) { + grs$getItemStack().setCount(amount); + } + + + @Override + default @Nullable NBTTagCompound getNbt() { + return grs$getItemStack().getTagCompound(); + } + + @Override + default void setNbt(NBTTagCompound nbt) { + grs$getItemStack().setTagCompound(nbt); + } + + @Override + default INBTResourceStack withNbt(NBTTagCompound nbt) { + ItemStackMixinExpansion itemStackMixin = (ItemStackMixinExpansion) INbtIngredient.super.withNbt(nbt); + itemStackMixin.grs$setNbtMatcher(nbt1 -> nbt.isEmpty() || NbtHelper.containsNbt(nbt1, nbt)); + return itemStackMixin; + } + + @Override + default INbtIngredient withNbtExact(NBTTagCompound nbt) { + ItemStackMixinExpansion itemStackMixin = (ItemStackMixinExpansion) INbtIngredient.super.withNbt(nbt); + if (nbt == null) { + itemStackMixin.grs$setNbtMatcher(null); + } else { + itemStackMixin.grs$setNbtMatcher(nbt1 -> nbt.isEmpty() || nbt1.equals(nbt)); + } + return itemStackMixin; + } + + default INbtIngredient withNbtFilter(Predicate nbtFilter) { + this.grs$setNbtMatcher(nbtFilter == null ? nbt -> true : nbtFilter); + return this; + } + + default INbtIngredient whenNoNbt() { + setNbt(null); + grs$setMatcher(self -> { + NBTTagCompound nbt = self.getTagCompound(); + return nbt == null || nbt.isEmpty(); + }); + return this; + } + + default INbtIngredient whenAnyNbt() { + setNbt(new NBTTagCompound()); + grs$setMatcher(self -> { + NBTTagCompound nbt = self.getTagCompound(); + return nbt != null && !nbt.isEmpty(); + }); + return this; + } + + default ItemStack withMeta(int meta) { + ItemStack itemStack = exactCopy().grs$getItemStack(); + // reliably set itemDamage field of item stack + Items.DIAMOND.setDamage(itemStack, meta); + return itemStack; + } + + default ItemStack withDamage(int meta) { + return withMeta(meta); + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/ItemStackTransformer.java b/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/ItemStackTransformer.java new file mode 100644 index 000000000..f9795cee7 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/ItemStackTransformer.java @@ -0,0 +1,8 @@ +package com.cleanroommc.groovyscript.compat.vanilla; + +import net.minecraft.item.ItemStack; + +public interface ItemStackTransformer { + + ItemStack transform(ItemStack self); +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/RarityItemStackExpansion.java b/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/RarityItemStackExpansion.java deleted file mode 100644 index 0a39d7d47..000000000 --- a/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/RarityItemStackExpansion.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.cleanroommc.groovyscript.compat.vanilla; - -import net.minecraft.item.ItemStack; -import net.minecraft.util.text.TextFormatting; - -public class RarityItemStackExpansion { - - public static ItemStack setRarity(ItemStack item, TextFormatting color) { - VanillaModule.rarity.set(color, item); - return item; - } -} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/VanillaModule.java b/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/VanillaModule.java index a4a96112b..08edb6574 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/VanillaModule.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/VanillaModule.java @@ -36,7 +36,7 @@ public static void initializeBinding() { GroovyScript.getSandbox().registerBinding(rarity); GroovyScript.getSandbox().registerBinding(inWorldCrafting); - ExpansionHelper.mixinClass(ItemStack.class, RarityItemStackExpansion.class); + ExpansionHelper.mixinClass(ItemStack.class, ItemStackExpansion.class); } @Override diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/ItemStackMixin.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/ItemStackMixin.java index bac59449d..96004614f 100644 --- a/src/main/java/com/cleanroommc/groovyscript/core/mixin/ItemStackMixin.java +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/ItemStackMixin.java @@ -1,212 +1,76 @@ package com.cleanroommc.groovyscript.core.mixin; -import com.cleanroommc.groovyscript.api.IIngredient; -import com.cleanroommc.groovyscript.api.IMarkable; -import com.cleanroommc.groovyscript.api.INBTResourceStack; -import com.cleanroommc.groovyscript.api.INbtIngredient; -import com.cleanroommc.groovyscript.compat.vanilla.VanillaModule; -import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; -import com.cleanroommc.groovyscript.helper.ingredient.NbtHelper; -import com.cleanroommc.groovyscript.helper.ingredient.OreDictIngredient; -import com.cleanroommc.groovyscript.sandbox.ClosureHelper; -import com.cleanroommc.groovyscript.sandbox.expand.LambdaClosure; - +import com.cleanroommc.groovyscript.compat.vanilla.ItemStackMixinExpansion; +import com.cleanroommc.groovyscript.compat.vanilla.ItemStackTransformer; import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.Ingredient; import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.common.ForgeHooks; -import net.minecraftforge.oredict.OreDictionary; - -import groovy.lang.Closure; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; -@Mixin(value = ItemStack.class) -public abstract class ItemStackMixin implements IIngredient, INbtIngredient, IMarkable { +import java.util.function.Predicate; - @Override - @Shadow - public abstract boolean isEmpty(); +@Mixin(value = ItemStack.class) +public abstract class ItemStackMixin implements ItemStackMixinExpansion { @Unique - protected Closure matchCondition; + protected Predicate groovyScript$matchCondition; @Unique - protected Closure transformer; + protected ItemStackTransformer groovyScript$transformer; @Unique - protected Closure nbtMatcher; + protected Predicate groovyScript$nbtMatcher; @Unique - protected String mark; - - private ItemStack groovyscript$getThis() { - return (ItemStack) (Object) this; - } - - @Override - public int getAmount() { - return groovyscript$getThis().getCount(); - } - - @Override - public void setAmount(int amount) { - groovyscript$getThis().setCount(amount); - } + protected String groovyScript$mark; @Override - public @Nullable NBTTagCompound getNbt() { - return groovyscript$getThis().getTagCompound(); + public ItemStack grs$getItemStack() { + return (ItemStack) (Object) this; } @Override - public void setNbt(NBTTagCompound nbt) { - groovyscript$getThis().setTagCompound(nbt); + public ItemStackTransformer grs$getTransformer() { + return groovyScript$transformer; } @Override - public IIngredient exactCopy() { - ItemStackMixin copy = (ItemStackMixin) (Object) groovyscript$getThis().copy(); - copy.setMark(getMark()); - copy.transformer = transformer; - copy.matchCondition = matchCondition; - copy.nbtMatcher = nbtMatcher; - return copy; + public Predicate grs$getMatcher() { + return groovyScript$matchCondition; } @Override - public Ingredient toMcIngredient() { - return Ingredient.fromStacks(groovyscript$getThis()); + public Predicate grs$getNbtMatcher() { + return groovyScript$nbtMatcher; } @Override - public ItemStack[] getMatchingStacks() { - return new ItemStack[]{IngredientHelper.toItemStack(exactCopy())}; + public void grs$setTransformer(ItemStackTransformer transformer) { + if (grs$getItemStack() != ItemStack.EMPTY) { + this.groovyScript$transformer = transformer; + } } @Override - public boolean test(ItemStack stack) { - if (!OreDictionary.itemMatches(groovyscript$getThis(), stack, false) || - (matchCondition != null && !ClosureHelper.call(true, matchCondition, stack))) { - return false; - } - if (nbtMatcher != null) { - NBTTagCompound nbt = stack.getTagCompound(); - return nbt != null && ClosureHelper.call(true, nbtMatcher, nbt); + public void grs$setMatcher(Predicate matcher) { + if (grs$getItemStack() != ItemStack.EMPTY) { + this.groovyScript$matchCondition = matcher; } - return true; - } - - public ItemStack when(Closure matchCondition) { - ItemStackMixin fresh = (ItemStackMixin) exactCopy(); - fresh.matchCondition = matchCondition; - return (ItemStack) (Object) fresh; - } - - public ItemStack transform(Closure transformer) { - ItemStackMixin fresh = (ItemStackMixin) exactCopy(); - fresh.transformer = transformer; - return (ItemStack) (Object) fresh; - } - - public ItemStack reuse() { - return transform(IngredientHelper.REUSE); - } - - public ItemStack noreturn() { - return transform(IngredientHelper.NO_RETURN); } @Override - public ItemStack applyTransform(ItemStack matchedInput) { - if (transformer != null) { - return ClosureHelper.call(ItemStack.EMPTY, transformer, matchedInput).copy(); + public void grs$setNbtMatcher(Predicate nbtMatcher) { + if (grs$getItemStack() != ItemStack.EMPTY) { + this.groovyScript$nbtMatcher = nbtMatcher; } - return ForgeHooks.getContainerItem(matchedInput); } @Nullable @Override public String getMark() { - return mark; + return groovyScript$mark; } @Override public void setMark(String mark) { - this.mark = mark; - } - - @Override - public INBTResourceStack withNbt(NBTTagCompound nbt) { - ItemStackMixin itemStackMixin = (ItemStackMixin) INbtIngredient.super.withNbt(nbt); - itemStackMixin.nbtMatcher = NbtHelper.makeNbtPredicate(nbt1 -> nbt.isEmpty() || NbtHelper.containsNbt(nbt1, nbt)); - return itemStackMixin; - } - - @Override - public INbtIngredient withNbtExact(NBTTagCompound nbt) { - ItemStackMixin itemStackMixin = (ItemStackMixin) INbtIngredient.super.withNbt(nbt); - if (nbt == null) { - itemStackMixin.nbtMatcher = null; - } else { - itemStackMixin.nbtMatcher = NbtHelper.makeNbtPredicate(nbt1 -> nbt.isEmpty() || nbt1.equals(nbt)); - } - return itemStackMixin; - } - - public INbtIngredient withNbtFilter(Closure nbtFilter) { - this.nbtMatcher = nbtFilter == null ? IngredientHelper.MATCH_ANY : nbtFilter; - return this; - } - - public INbtIngredient whenNoNbt() { - setNbt(null); - this.matchCondition = new LambdaClosure<>(args -> { - NBTTagCompound nbt = ((ItemStack) args[0]).getTagCompound(); - return nbt == null || nbt.isEmpty(); - }); - return this; - } - - public INbtIngredient whenAnyNbt() { - setNbt(new NBTTagCompound()); - this.matchCondition = new LambdaClosure<>(args -> { - NBTTagCompound nbt = ((ItemStack) args[0]).getTagCompound(); - return nbt != null && !nbt.isEmpty(); - }); - return this; - } - - public IIngredient withMeta(int meta) { - ItemStack t = groovyscript$getThis(); - ItemStackMixin itemStack = (ItemStackMixin) (Object) new ItemStack(t.getItem(), t.getCount(), meta); - itemStack.setMark(getMark()); - itemStack.transformer = transformer; - itemStack.matchCondition = matchCondition; - itemStack.nbtMatcher = nbtMatcher; - return itemStack; - } - - public IIngredient withDamage(int meta) { - return withMeta(meta); - } - - public void addOreDict(OreDictIngredient ingredient) { - VanillaModule.oreDict.add(ingredient.getOreDict(), groovyscript$getThis()); - } - - public void removeOreDict(OreDictIngredient ingredient) { - VanillaModule.oreDict.remove(ingredient.getOreDict(), groovyscript$getThis()); - } - - public boolean leftShift(IIngredient ingredient) { - return ingredient.isCase(groovyscript$getThis()) && ingredient.getAmount() >= getAmount(); - } - - public boolean isSameExact(ItemStack itemStack) { - return ItemStack.areItemStacksEqual(groovyscript$getThis(), itemStack); - } - - public boolean isSame(ItemStack itemStack, boolean ignoreNbt) { - return ItemStack.areItemsEqual(groovyscript$getThis(), itemStack) && (ignoreNbt || ItemStack.areItemStackTagsEqual(groovyscript$getThis(), itemStack)); + this.groovyScript$mark = mark; } }