Skip to content

Commit de31ca1

Browse files
authored
Fix item transforms (#281)
* add transform methods to `IngredientBase` & properly destroy items * reviews * review
1 parent 4a6cf12 commit de31ca1

File tree

3 files changed

+71
-18
lines changed

3 files changed

+71
-18
lines changed

src/main/java/com/cleanroommc/groovyscript/compat/vanilla/ItemStackMixinExpansion.java

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
package com.cleanroommc.groovyscript.compat.vanilla;
22

3-
import com.cleanroommc.groovyscript.api.GroovyBlacklist;
4-
import com.cleanroommc.groovyscript.api.IIngredient;
5-
import com.cleanroommc.groovyscript.api.INBTResourceStack;
6-
import com.cleanroommc.groovyscript.api.INbtIngredient;
3+
import com.cleanroommc.groovyscript.api.*;
74
import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper;
85
import com.cleanroommc.groovyscript.helper.ingredient.NbtHelper;
6+
import net.minecraft.entity.player.EntityPlayer;
97
import net.minecraft.init.Items;
108
import net.minecraft.item.ItemStack;
119
import net.minecraft.item.crafting.Ingredient;
1210
import net.minecraft.nbt.NBTTagCompound;
1311
import net.minecraftforge.common.ForgeHooks;
12+
import net.minecraftforge.event.ForgeEventFactory;
1413
import net.minecraftforge.oredict.OreDictionary;
1514
import org.jetbrains.annotations.Nullable;
1615

@@ -101,7 +100,7 @@ default ItemStack reuse() {
101100
return transform(self -> self);
102101
}
103102

104-
default ItemStack noreturn() {
103+
default ItemStack noReturn() {
105104
return transform(self -> ItemStack.EMPTY);
106105
}
107106

@@ -111,7 +110,7 @@ default ItemStack transform(ItemStack stack) {
111110

112111
default ItemStack transformDamage(int amount) {
113112
// reliably set itemDamage field of item stack
114-
return transform(self -> of(self).withDamage(Math.min(32767, Items.DIAMOND.getDamage(self) + amount)));
113+
return transform(self -> IngredientHelper.damageItem(self, amount));
115114
}
116115

117116
default ItemStack transformDamage() {
@@ -129,7 +128,11 @@ default ItemStack transformNbt(UnaryOperator<NBTTagCompound> transformer) {
129128
default ItemStack applyTransform(ItemStack matchedInput) {
130129
if (grs$getTransformer() != null) {
131130
ItemStack result = grs$getTransformer().transform(matchedInput);
132-
if (result == null) return ItemStack.EMPTY;
131+
if (result == null || result.isEmpty()) return ItemStack.EMPTY;
132+
if (result.isItemStackDamageable() && result.getMetadata() > result.getMaxDamage()) {
133+
ForgeEventFactory.onPlayerDestroyItem(ForgeHooks.getCraftingPlayer(), result, null);
134+
return ItemStack.EMPTY;
135+
}
133136
return result.copy();
134137
}
135138
return ForgeHooks.getContainerItem(matchedInput);
@@ -220,6 +223,17 @@ default ItemStack withDamage(int meta) {
220223
return withMeta(meta);
221224
}
222225

226+
default ItemStack destroy() {
227+
if (grs$getItemStack().isEmpty()) return ItemStack.EMPTY;
228+
EntityPlayer player = ForgeHooks.getCraftingPlayer();
229+
if (player != null) {
230+
ForgeEventFactory.onPlayerDestroyItem(player, grs$getItemStack(), null);
231+
return ItemStack.EMPTY;
232+
}
233+
GroovyLog.get().error("Should only destroy item during crafting!");
234+
return grs$getItemStack();
235+
}
236+
223237
@Override
224238
default @Nullable String getMark() {
225239
return grs$getMark();

src/main/java/com/cleanroommc/groovyscript/helper/ingredient/IngredientBase.java

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,80 @@
11
package com.cleanroommc.groovyscript.helper.ingredient;
22

33
import com.cleanroommc.groovyscript.api.IIngredient;
4-
import com.cleanroommc.groovyscript.sandbox.ClosureHelper;
5-
import groovy.lang.Closure;
4+
import com.cleanroommc.groovyscript.compat.vanilla.ItemStackMixinExpansion;
5+
import com.cleanroommc.groovyscript.compat.vanilla.ItemStackTransformer;
66
import net.minecraft.item.ItemStack;
7+
import net.minecraft.nbt.NBTTagCompound;
78
import net.minecraftforge.common.ForgeHooks;
9+
import net.minecraftforge.event.ForgeEventFactory;
810
import org.jetbrains.annotations.Nullable;
911

12+
import java.util.function.Predicate;
13+
import java.util.function.UnaryOperator;
14+
1015
public abstract class IngredientBase implements IIngredient {
1116

12-
protected Closure<Object> matchCondition;
13-
protected Closure<Object> transformer;
17+
protected Predicate<ItemStack> matchCondition;
18+
protected ItemStackTransformer transformer;
1419
protected String mark;
1520

16-
public IngredientBase when(Closure<Object> matchCondition) {
21+
public IngredientBase when(Predicate<ItemStack> matchCondition) {
1722
IngredientBase fresh = (IngredientBase) this.exactCopy();
1823
fresh.matchCondition = matchCondition;
1924
return fresh;
2025
}
2126

22-
public IngredientBase transform(Closure<Object> transformer) {
27+
public IngredientBase transform(ItemStackTransformer transformer) {
2328
IngredientBase fresh = (IngredientBase) this.exactCopy();
2429
fresh.transformer = transformer;
2530
return fresh;
2631
}
2732

33+
public IngredientBase transformDamage(int amount) {
34+
// reliably set itemDamage field of item stack
35+
return transform(self -> IngredientHelper.damageItem(self, amount));
36+
}
37+
38+
public IngredientBase transformDamage() {
39+
return transformDamage(1);
40+
}
41+
42+
public IngredientBase transformNbt(UnaryOperator<NBTTagCompound> transformer) {
43+
return transform(self -> {
44+
ItemStackMixinExpansion.of(self).exactCopy().grs$getItemStack().setTagCompound(transformer.apply(self.getTagCompound()));
45+
return self;
46+
});
47+
}
48+
2849
public IngredientBase reuse() {
29-
return transform(IngredientHelper.REUSE);
50+
return transform(self -> self);
3051
}
3152

3253
public IngredientBase noReturn() {
33-
return transform(IngredientHelper.NO_RETURN);
54+
return transform(self -> ItemStack.EMPTY);
55+
}
56+
57+
public IngredientBase transform(ItemStack stack) {
58+
return transform(self -> stack);
3459
}
3560

3661
@Override
3762
public boolean test(ItemStack itemStack) {
38-
return (matchCondition == null || ClosureHelper.call(true, matchCondition, itemStack)) && matches(itemStack);
63+
return (this.matchCondition == null || this.matchCondition.test(itemStack)) && matches(itemStack);
3964
}
4065

4166
public abstract boolean matches(ItemStack itemStack);
4267

4368
@Override
4469
public ItemStack applyTransform(ItemStack matchedInput) {
45-
if (transformer != null) {
46-
return ClosureHelper.call(ItemStack.EMPTY, transformer, matchedInput);
70+
if (this.transformer != null) {
71+
ItemStack result = this.transformer.transform(matchedInput);
72+
if (result == null || result.isEmpty()) return ItemStack.EMPTY;
73+
if (result.isItemStackDamageable() && result.getMetadata() > result.getMaxDamage()) {
74+
ForgeEventFactory.onPlayerDestroyItem(ForgeHooks.getCraftingPlayer(), result, null);
75+
return ItemStack.EMPTY;
76+
}
77+
return result.copy();
4778
}
4879
return ForgeHooks.getContainerItem(matchedInput);
4980
}

src/main/java/com/cleanroommc/groovyscript/helper/ingredient/IngredientHelper.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
import com.cleanroommc.groovyscript.GroovyScriptConfig;
44
import com.cleanroommc.groovyscript.api.IIngredient;
5+
import com.cleanroommc.groovyscript.compat.vanilla.ItemStackMixinExpansion;
56
import com.cleanroommc.groovyscript.sandbox.expand.LambdaClosure;
67
import groovy.lang.Closure;
78
import net.minecraft.block.state.IBlockState;
9+
import net.minecraft.init.Items;
810
import net.minecraft.item.ItemStack;
911
import net.minecraft.item.crafting.Ingredient;
1012
import net.minecraft.nbt.NBTTagCompound;
@@ -25,6 +27,12 @@ public class IngredientHelper {
2527
public static final Closure<Object> NO_RETURN = new LambdaClosure<>(args -> ItemStack.EMPTY);
2628
public static final Closure<Object> MATCH_NBT = new LambdaClosure<>(args -> ItemStack.EMPTY);
2729

30+
public static ItemStack damageItem(ItemStack stack, int damage) {
31+
// Short.MAX_VALUE is meta wildcard
32+
// Items.DIAMOND.getDamage(stack) is guaranteed to return the value of the damage field of stack
33+
return ItemStackMixinExpansion.of(stack).withMeta(Math.min(Short.MAX_VALUE - 1, Items.DIAMOND.getDamage(stack) + damage));
34+
}
35+
2836
public static boolean isFluid(IIngredient ingredient) {
2937
return ingredient instanceof FluidStack;
3038
}

0 commit comments

Comments
 (0)