Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix item transforms #281

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package com.cleanroommc.groovyscript.compat.vanilla;

import com.cleanroommc.groovyscript.api.GroovyBlacklist;
import com.cleanroommc.groovyscript.api.IIngredient;
import com.cleanroommc.groovyscript.api.INBTResourceStack;
import com.cleanroommc.groovyscript.api.INbtIngredient;
import com.cleanroommc.groovyscript.api.*;
import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper;
import com.cleanroommc.groovyscript.helper.ingredient.NbtHelper;
import net.minecraft.entity.player.EntityPlayer;
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.event.ForgeEventFactory;
import net.minecraftforge.oredict.OreDictionary;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -101,7 +100,7 @@ default ItemStack reuse() {
return transform(self -> self);
}

default ItemStack noreturn() {
default ItemStack noReturn() {
return transform(self -> ItemStack.EMPTY);
}

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

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

default ItemStack transformDamage() {
Expand All @@ -130,6 +129,10 @@ default ItemStack applyTransform(ItemStack matchedInput) {
if (grs$getTransformer() != null) {
ItemStack result = grs$getTransformer().transform(matchedInput);
if (result == null) return ItemStack.EMPTY;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be

Suggested change
if (result == null) return ItemStack.EMPTY;
if (result == null || result.isEmpty()) return ItemStack.EMPTY;

if (result.isItemStackDamageable() && result.getMetadata() > result.getMaxDamage()) {
ForgeEventFactory.onPlayerDestroyItem(ForgeHooks.getCraftingPlayer(), result, null);
return ItemStack.EMPTY;
}
return result.copy();
}
return ForgeHooks.getContainerItem(matchedInput);
Expand Down Expand Up @@ -220,6 +223,17 @@ default ItemStack withDamage(int meta) {
return withMeta(meta);
}

default ItemStack destroy() {
brachy84 marked this conversation as resolved.
Show resolved Hide resolved
if (grs$getItemStack().isEmpty()) return ItemStack.EMPTY;
EntityPlayer player = ForgeHooks.getCraftingPlayer();
if (player != null) {
ForgeEventFactory.onPlayerDestroyItem(player, grs$getItemStack(), null);
return ItemStack.EMPTY;
}
GroovyLog.get().error("Should only destroy item during crafting!");
return grs$getItemStack();
}

@Override
default @Nullable String getMark() {
return grs$getMark();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,49 +1,80 @@
package com.cleanroommc.groovyscript.helper.ingredient;

import com.cleanroommc.groovyscript.api.IIngredient;
import com.cleanroommc.groovyscript.sandbox.ClosureHelper;
import groovy.lang.Closure;
import com.cleanroommc.groovyscript.compat.vanilla.ItemStackMixinExpansion;
import com.cleanroommc.groovyscript.compat.vanilla.ItemStackTransformer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.event.ForgeEventFactory;
import org.jetbrains.annotations.Nullable;

import java.util.function.Predicate;
import java.util.function.UnaryOperator;

public abstract class IngredientBase implements IIngredient {

protected Closure<Object> matchCondition;
protected Closure<Object> transformer;
protected Predicate<ItemStack> matchCondition;
protected ItemStackTransformer transformer;
protected String mark;

public IngredientBase when(Closure<Object> matchCondition) {
public IngredientBase when(Predicate<ItemStack> matchCondition) {
IngredientBase fresh = (IngredientBase) this.exactCopy();
fresh.matchCondition = matchCondition;
return fresh;
}

public IngredientBase transform(Closure<Object> transformer) {
public IngredientBase transform(ItemStackTransformer transformer) {
IngredientBase fresh = (IngredientBase) this.exactCopy();
fresh.transformer = transformer;
return fresh;
}

public IngredientBase transformDamage(int amount) {
// reliably set itemDamage field of item stack
return transform(self -> IngredientHelper.damageItem(self, amount));
}

public IngredientBase transformDamage() {
return transformDamage(1);
}

public IngredientBase transformNbt(UnaryOperator<NBTTagCompound> transformer) {
return transform(self -> {
ItemStackMixinExpansion.of(self).exactCopy().grs$getItemStack().setTagCompound(transformer.apply(self.getTagCompound()));
return self;
});
}

public IngredientBase reuse() {
return transform(IngredientHelper.REUSE);
return transform(self -> self);
}

public IngredientBase noReturn() {
return transform(IngredientHelper.NO_RETURN);
return transform(self -> ItemStack.EMPTY);
}

public IngredientBase transform(ItemStack stack) {
return transform(self -> stack);
}

@Override
public boolean test(ItemStack itemStack) {
return (matchCondition == null || ClosureHelper.call(true, matchCondition, itemStack)) && matches(itemStack);
return (this.matchCondition == null || this.matchCondition.test(itemStack)) && matches(itemStack);
}

public abstract boolean matches(ItemStack itemStack);

@Override
public ItemStack applyTransform(ItemStack matchedInput) {
if (transformer != null) {
return ClosureHelper.call(ItemStack.EMPTY, transformer, matchedInput);
if (this.transformer != null) {
ItemStack result = this.transformer.transform(matchedInput);
if (result == null || result.isEmpty()) return ItemStack.EMPTY;
if (result.isItemStackDamageable() && result.getMetadata() > result.getMaxDamage()) {
ForgeEventFactory.onPlayerDestroyItem(ForgeHooks.getCraftingPlayer(), result, null);
return ItemStack.EMPTY;
}
return result.copy();
}
return ForgeHooks.getContainerItem(matchedInput);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import com.cleanroommc.groovyscript.GroovyScriptConfig;
import com.cleanroommc.groovyscript.api.IIngredient;
import com.cleanroommc.groovyscript.compat.vanilla.ItemStackMixinExpansion;
import com.cleanroommc.groovyscript.sandbox.expand.LambdaClosure;
import groovy.lang.Closure;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.Ingredient;
import net.minecraft.nbt.NBTTagCompound;
Expand All @@ -25,6 +27,12 @@ public class IngredientHelper {
public static final Closure<Object> NO_RETURN = new LambdaClosure<>(args -> ItemStack.EMPTY);
public static final Closure<Object> MATCH_NBT = new LambdaClosure<>(args -> ItemStack.EMPTY);

public static ItemStack damageItem(ItemStack stack, int damage) {
// Short.MAX_VALUE is meta wildcard
// Items.DIAMOND.getDamage(stack) is guaranteed to return the value of the damage field of stack
return ItemStackMixinExpansion.of(stack).withMeta(Math.min(Short.MAX_VALUE - 1, Items.DIAMOND.getDamage(stack) + damage));
}

public static boolean isFluid(IIngredient ingredient) {
return ingredient instanceof FluidStack;
}
Expand Down