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

Improve the recipe function #218

Merged
merged 7 commits into from
Aug 15, 2024
Merged
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
13 changes: 13 additions & 0 deletions examples/postInit/custom/vanilla.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,19 @@ crafting.shapedBuilder()
.replaceByName()
.register()

// recipeFunction example

crafting.shapelessBuilder()
.output(item('minecraft:wooden_shovel'))
.input(ore('logWood').reuse(),item('minecraft:wooden_shovel:*').mark('tool')) // We mark shovel with 'tool'
.recipeFunction { output, inputs, info ->
def item = inputs['tool'] // Using the getAt operator
// inputs.findMarked('tool') can also be used

output.withDamage(item.getItemDamage() - 1) // Decrease damage by 1
}
.register()


// The recipe builder also has some additional features, including
// The abilty to input a string and a set of keys, significantly improving readability.
Expand Down
23 changes: 22 additions & 1 deletion src/main/java/com/cleanroommc/groovyscript/api/IIngredient.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
/**
* Base ingredient class for every ingredient. Most useful for item stacks and ore dicts.
*/
public interface IIngredient extends IResourceStack, Predicate<ItemStack> {
public interface IIngredient extends IResourceStack, Predicate<ItemStack>, IMarkable {

@Override
IIngredient exactCopy();
Expand Down Expand Up @@ -62,6 +62,7 @@ default IIngredient withAmount(int amount) {
* An empty ingredient with stack size 0, that matches empty item stacks
*/
IIngredient EMPTY = new IIngredient() {

@Override
public int getAmount() {
return 0;
Expand Down Expand Up @@ -95,6 +96,16 @@ public ItemStack[] getMatchingStacks() {
public boolean test(ItemStack stack) {
return stack.isEmpty();
}

@Nullable
@Override
public String getMark() {
return null;
}

@Override
public void setMark(String mark) {
}
};

/**
Expand Down Expand Up @@ -140,5 +151,15 @@ public void setAmount(int amount) {
public boolean test(ItemStack stack) {
return true;
}

@Nullable
@Override
public String getMark() {
return null;
}

@Override
public void setMark(String mark) {
}
juraj-hrivnak marked this conversation as resolved.
Show resolved Hide resolved
};
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package com.cleanroommc.groovyscript.compat.vanilla;

import com.cleanroommc.groovyscript.api.IIngredient;
import com.cleanroommc.groovyscript.api.IMarkable;
import com.cleanroommc.groovyscript.core.mixin.InventoryCraftingAccess;
import com.cleanroommc.groovyscript.core.mixin.SlotCraftingAccess;
import com.cleanroommc.groovyscript.sandbox.ClosureHelper;
import groovy.lang.Closure;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.InventoryCrafting;
Expand All @@ -23,6 +21,8 @@
import java.util.ArrayList;
import java.util.List;

import static java.util.stream.Collectors.toCollection;

public abstract class CraftingRecipe extends IForgeRegistryEntry.Impl<IRecipe> implements IRecipe, ICraftingRecipe {

protected final ItemStack output;
Expand All @@ -49,23 +49,19 @@ public CraftingRecipe(ItemStack output, List<IIngredient> input, @Nullable Closu

@Override
public @NotNull ItemStack getCraftingResult(@NotNull InventoryCrafting inv) {
ItemStack result = output.copy();
if (recipeFunction != null) {
MatchList matchList = getMatchingList(inv);
Object2ObjectOpenHashMap<String, ItemStack> marks = new Object2ObjectOpenHashMap<>();
for (SlotMatchResult matchResult : matchList) {
if (matchResult.getRecipeIngredient() instanceof IMarkable markable) {
if (!input.isEmpty() && markable.hasMark()) {
marks.put(markable.getMark(), matchResult.getGivenInput().copy());
}
}
}
result = ClosureHelper.call(recipeFunction, result, marks, new CraftingInfo(inv, getPlayerFromInventory(inv)));
if (result == null) {
result = ItemStack.EMPTY;
}
ItemStack output = this.output.copy();

if (recipeFunction == null || input.isEmpty()) return output;

InputList inputs = new InputList();
for (SlotMatchResult slotMatchResult : getMatchingList(inv)) {
ItemStack givenInput = slotMatchResult.getGivenInput();
inputs.add(givenInput);
}
return result;

// Call recipe function
ItemStack recipeFunctionResult = ClosureHelper.call(recipeFunction, output, inputs, new CraftingInfo(inv, getPlayerFromInventory(inv)));
return recipeFunctionResult == null ? output : recipeFunctionResult;
}

@Override
Expand Down Expand Up @@ -155,14 +151,46 @@ public IIngredient getRecipeIngredient() {
}

public ItemStack getGivenInput() {
return givenInput;
// Copy mark from recipeIngredient to givenInput
ItemStackMixinExpansion itemStack = ItemStackMixinExpansion.of(givenInput);
String mark = recipeIngredient.getMark();
if (mark != null) itemStack.setMark(mark);
return itemStack.grs$getItemStack();
}

public int getSlotIndex() {
return slotIndex;
}
}

public static class InputList extends ArrayList<ItemStack> {

// groovy [] operator
@Nullable
public ItemStack getAt(String mark) {
brachy84 marked this conversation as resolved.
Show resolved Hide resolved
return findMarked(mark);
}

@Nullable
public ItemStack findMarked(String mark) {
if (isEmpty()) return null;
for (ItemStack itemStack : this) {
if (mark.equals(ItemStackMixinExpansion.of(itemStack).getMark())) {
return itemStack;
}
}
return null;
}

public ItemStack findMarkedOrEmpty(String mark) {
if (isEmpty()) return ItemStack.EMPTY;
for (ItemStack itemStack : this) {
if (mark.equals(ItemStackMixinExpansion.of(itemStack).getMark())) return itemStack;
}
return ItemStack.EMPTY;
}
}

// TODO
private static EntityPlayer getPlayerFromInventory(InventoryCrafting inventory) {
Container eventHandler = ((InventoryCraftingAccess) inventory).getEventHandler();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
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;
Expand All @@ -17,7 +16,7 @@
import java.util.function.Predicate;
import java.util.function.UnaryOperator;

public interface ItemStackMixinExpansion extends IIngredient, INbtIngredient, IMarkable {
public interface ItemStackMixinExpansion extends IIngredient, INbtIngredient {

static ItemStackMixinExpansion of(ItemStack stack) {
return (ItemStackMixinExpansion) (Object) stack;
Expand All @@ -40,6 +39,11 @@ static ItemStackMixinExpansion of(ItemStack stack) {

void grs$setMatcher(Predicate<ItemStack> matcher);

@Nullable
String grs$getMark();

void grs$setMark(String mark);

default boolean grs$isEmpty() {
return grs$getItemStack().isEmpty();
}
Expand Down Expand Up @@ -103,6 +107,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)));
}

Expand Down Expand Up @@ -209,4 +214,15 @@ default ItemStack withMeta(int meta) {
default ItemStack withDamage(int meta) {
return withMeta(meta);
}

@Nullable
@Override
default String getMark() {
return grs$getMark();
}

@Override
default void setMark(String mark) {
grs$setMark(mark);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public abstract class FluidStackMixin implements IIngredient, INbtIngredient, IN
protected Closure<Object> transformer;
@Unique
protected Closure<Object> nbtMatcher;
@Unique
protected String groovyScript$mark;

@Override
public IIngredient exactCopy() {
Expand Down Expand Up @@ -179,4 +181,15 @@ public int getAmount() {
public void setAmount(int amount) {
this.amount = amount;
}

@Nullable
@Override
public String getMark() {
return groovyScript$mark;
}

@Override
public void setMark(String mark) {
this.groovyScript$mark = mark;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@ public abstract class ItemStackMixin implements ItemStackMixinExpansion {

@Nullable
@Override
public String getMark() {
public String grs$getMark() {
return groovyScript$mark;
}

@Override
public void setMark(String mark) {
public void grs$setMark(String mark) {
this.groovyScript$mark = mark;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
import mekanism.api.gas.GasStack;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.Ingredient;
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 = GasStack.class, remap = false)
public abstract class GasStackMixin implements IIngredient, IResourceStack {
Expand All @@ -17,6 +19,9 @@ public abstract class GasStackMixin implements IIngredient, IResourceStack {
@Shadow
public abstract GasStack copy();

@Unique
protected String groovyScript$mark;

@Override
public int getAmount() {
return amount;
Expand Down Expand Up @@ -46,4 +51,15 @@ public ItemStack[] getMatchingStacks() {
public boolean test(ItemStack stack) {
return false;
}

@Nullable
@Override
public String getMark() {
return groovyScript$mark;
}

@Override
public void setMark(String mark) {
this.groovyScript$mark = mark;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
import groovy.lang.Closure;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.ForgeHooks;
import org.jetbrains.annotations.Nullable;

public abstract class IngredientBase implements IIngredient {

protected Closure<Object> matchCondition;
protected Closure<Object> transformer;
protected String mark;

public IngredientBase when(Closure<Object> matchCondition) {
IngredientBase fresh = (IngredientBase) this.exactCopy();
Expand Down Expand Up @@ -45,4 +47,15 @@ public ItemStack applyTransform(ItemStack matchedInput) {
}
return ForgeHooks.getContainerItem(matchedInput);
}

@Nullable
@Override
public String getMark() {
return mark;
}

@Override
public void setMark(String mark) {
this.mark = mark;
}
}