-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GroovyScript Fixed Shaped Conversion Recipes
- Loading branch information
1 parent
5085109
commit e718775
Showing
8 changed files
with
226 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import com.nomiceu.nomilabs.groovy.ShapedConversionRecipe | ||
|
||
// Use a Custom Recipe Class in Shaped Recipes! | ||
|
||
// Using Key Based Matrix | ||
crafting.shapedBuilder() | ||
.output(metaitem('dye.white') * 2) | ||
.matrix('D') | ||
.key('D', item('minecraft:dye', 15)) | ||
// Two Options: | ||
// ItemStack output, int width, int height, List<IIngredient> ingredients | ||
// ItemStack output, int width, int height, List<IIngredient> ingredients, boolean mirrored, Closure<ItemStack> recipeFunction, Closure<Void> recipeAction | ||
.recipeClassFunction((output, width, height, ingredients, mirrored, recipeFunction, recipeAction) -> new ShapedConversionRecipe(output, ingredients, width, height, mirrored, recipeFunction, recipeAction)) | ||
.register() | ||
|
||
|
||
// Using Ingredient Matrix | ||
crafting.shapedBuilder() | ||
.output(metaitem('dye.white')) | ||
.matrix([[null, null], [item('minecraft:dye', 15), null]]) | ||
// Two Options: | ||
// ItemStack output, int width, int height, List<IIngredient> ingredients | ||
// ItemStack output, int width, int height, List<IIngredient> ingredients, boolean mirrored, Closure<ItemStack> recipeFunction, Closure<Void> recipeAction | ||
.recipeClassFunction((output, width, height, ingredients) -> new ShapedConversionRecipe(output, ingredients, width, height)) | ||
.register() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
src/main/java/com/nomiceu/nomilabs/groovy/ShapedConversionRecipe.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package com.nomiceu.nomilabs.groovy; | ||
|
||
import com.cleanroommc.groovyscript.api.GroovyLog; | ||
import com.cleanroommc.groovyscript.api.IIngredient; | ||
import com.cleanroommc.groovyscript.compat.vanilla.ShapedCraftingRecipe; | ||
import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; | ||
import groovy.lang.Closure; | ||
import net.minecraft.inventory.InventoryCrafting; | ||
import net.minecraft.item.ItemStack; | ||
import net.minecraft.world.World; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
import java.util.List; | ||
import java.util.function.Consumer; | ||
import java.util.function.Predicate; | ||
|
||
/** | ||
* A shaped conversion recipe where there must be only one input. | ||
*/ | ||
@SuppressWarnings("unused") | ||
public class ShapedConversionRecipe extends ShapedCraftingRecipe { | ||
private int recipeInputLocation; | ||
private int trueInputLocation; | ||
|
||
private Integer[] cache; | ||
|
||
public ShapedConversionRecipe(ItemStack output, List<IIngredient> input, int width, int height) { | ||
this(output, input, width, height, false, null, null); | ||
} | ||
|
||
public ShapedConversionRecipe(ItemStack output, List<IIngredient> input, int width, int height, boolean mirrored, @Nullable Closure<ItemStack> recipeFunction, @Nullable Closure<Void> recipeAction) { | ||
super(output, input, width, height, mirrored, recipeFunction, recipeAction); | ||
recipeInputLocation = -1; | ||
if (width != height) { | ||
GroovyLog.get() | ||
.exception(new IllegalArgumentException("Shaped Conversion Recipes must have the same width and height!")); | ||
return; | ||
} | ||
for (int i = 0; i < input.size(); i++) { | ||
var ing = input.get(i); | ||
if (IngredientHelper.isEmpty(ing)) continue; | ||
if (recipeInputLocation != -1) { | ||
GroovyLog.get() | ||
.exception(new IllegalArgumentException("Shaped Conversion Recipes can only have one non-empty input!")); | ||
return; | ||
} | ||
recipeInputLocation = i; | ||
} | ||
trueInputLocation = recipeInputLocation; | ||
if (width == 1) { | ||
// Default to center | ||
recipeInputLocation = 4; | ||
} | ||
else if (width == 2) { | ||
if (recipeInputLocation > 1) { | ||
recipeInputLocation++; | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public boolean matches(@NotNull InventoryCrafting inv, @NotNull World worldIn) { | ||
return matchesShaped(inv, recipeInputLocation, (stack) -> input.get(trueInputLocation).test(stack), cache, (cache1) -> cache = cache1); | ||
} | ||
|
||
public static boolean matchesShaped(@NotNull InventoryCrafting inv, int inputLocation, Predicate<ItemStack> accepts, Integer[] cache, Consumer<Integer[]> setCache) { | ||
if (inv.getWidth() < 2 || inv.getWidth() > 3 || inv.getHeight() < 2 || inv.getHeight() > 3 || inv.getWidth() != inv.getHeight()) return false; | ||
if (inputLocation == -1) return false; | ||
var location = getLocationForDim(inv.getWidth(), inputLocation, cache, setCache); | ||
if (location == -1) return false; | ||
|
||
int locationX = location % inv.getWidth(); | ||
int locationY = location / inv.getWidth(); | ||
|
||
// Not using inv.stackList, as the stackList may not be correct for a given invCrafting. | ||
for (int x = 0; x < inv.getWidth(); x++) { | ||
for (int y = 0; y < inv.getHeight(); y++) { | ||
if (x == locationX && y == locationY) { | ||
if (!accepts.test(inv.getStackInRowAndColumn(x, y))) return false; | ||
continue; | ||
} | ||
if (!inv.getStackInRowAndColumn(x, y).isEmpty()) return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
private static int getLocationForDim(int dim, int inputLocation, Integer[] cache, Consumer<Integer[]> setCache) { | ||
if (cache == null) { | ||
cache = new Integer[2]; | ||
|
||
cache[0] = inputLocation; | ||
if (inputLocation > 4 || inputLocation == 2) cache[0] = -1; // Not in 2x2 square | ||
else if (inputLocation > 2) cache[0] = inputLocation - 1; | ||
|
||
cache[1] = inputLocation; | ||
setCache.accept(cache); | ||
} | ||
// 0 when cache is 2, 1 when cache is 3 | ||
return cache[dim - 2]; | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
src/main/java/com/nomiceu/nomilabs/groovy/mixinhelper/ShapedRecipeClassFunction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.nomiceu.nomilabs.groovy.mixinhelper; | ||
|
||
import com.cleanroommc.groovyscript.api.IIngredient; | ||
import com.cleanroommc.groovyscript.compat.vanilla.ShapedCraftingRecipe; | ||
import groovy.lang.Closure; | ||
import net.minecraft.item.ItemStack; | ||
|
||
import java.util.List; | ||
|
||
@FunctionalInterface | ||
public interface ShapedRecipeClassFunction { | ||
ShapedCraftingRecipe createRecipe(ItemStack output, int width, int height, List<IIngredient> ingredients, boolean mirrored, Closure<ItemStack> recipeFunction, Closure<Void> recipeAction); | ||
} |
12 changes: 12 additions & 0 deletions
12
...ain/java/com/nomiceu/nomilabs/groovy/mixinhelper/ShapedRecipeClassFunctionSimplified.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.nomiceu.nomilabs.groovy.mixinhelper; | ||
|
||
import com.cleanroommc.groovyscript.api.IIngredient; | ||
import com.cleanroommc.groovyscript.compat.vanilla.ShapedCraftingRecipe; | ||
import net.minecraft.item.ItemStack; | ||
|
||
import java.util.List; | ||
|
||
@FunctionalInterface | ||
public interface ShapedRecipeClassFunctionSimplified { | ||
ShapedCraftingRecipe createRecipe(ItemStack output, int width, int height, List<IIngredient> ingredients); | ||
} |
56 changes: 56 additions & 0 deletions
56
src/main/java/com/nomiceu/nomilabs/mixin/groovyscript/ShapedRecipeBuilderMixin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package com.nomiceu.nomilabs.mixin.groovyscript; | ||
|
||
import com.cleanroommc.groovyscript.api.GroovyLog; | ||
import com.cleanroommc.groovyscript.api.IIngredient; | ||
import com.cleanroommc.groovyscript.compat.vanilla.CraftingRecipeBuilder; | ||
import com.nomiceu.nomilabs.groovy.mixinhelper.ShapedRecipeClassFunction; | ||
import com.nomiceu.nomilabs.groovy.mixinhelper.ShapedRecipeClassFunctionSimplified; | ||
import it.unimi.dsi.fastutil.chars.Char2ObjectOpenHashMap; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.Shadow; | ||
import org.spongepowered.asm.mixin.Unique; | ||
import org.spongepowered.asm.mixin.injection.At; | ||
import org.spongepowered.asm.mixin.injection.Redirect; | ||
|
||
import java.util.List; | ||
|
||
@Mixin(value = CraftingRecipeBuilder.Shaped.class, remap = false) | ||
@SuppressWarnings("unused") | ||
public abstract class ShapedRecipeBuilderMixin extends CraftingRecipeBuilder { | ||
@Shadow | ||
protected boolean mirrored; | ||
|
||
@Unique | ||
private ShapedRecipeClassFunction recipeClassFunction = null; | ||
|
||
/** | ||
* Default Ignored Constructor | ||
*/ | ||
public ShapedRecipeBuilderMixin(int width, int height) { | ||
super(width, height); | ||
} | ||
|
||
@Unique | ||
public CraftingRecipeBuilder.Shaped recipeClassFunction(ShapedRecipeClassFunction recipeClassFunction) { | ||
this.recipeClassFunction = recipeClassFunction; | ||
return (CraftingRecipeBuilder.Shaped) (Object) this; | ||
} | ||
|
||
@Unique | ||
public CraftingRecipeBuilder.Shaped recipeClassFunction(ShapedRecipeClassFunctionSimplified recipeClassFunction) { | ||
this.recipeClassFunction = (output1, width1, height1, ingredients, _mirrored, _recipeFunction, _recipeAction) -> recipeClassFunction.createRecipe(output1, width1, height1, ingredients); | ||
return (CraftingRecipeBuilder.Shaped) (Object) this; | ||
} | ||
|
||
@Redirect(method = "register()Lnet/minecraft/item/crafting/IRecipe;", at = @At(value = "INVOKE", target = "Lcom/cleanroommc/groovyscript/compat/vanilla/CraftingRecipeBuilder$Shaped;validateShape(Lcom/cleanroommc/groovyscript/api/GroovyLog$Msg;Ljava/util/List;[Ljava/lang/String;Lit/unimi/dsi/fastutil/chars/Char2ObjectOpenHashMap;Lcom/cleanroommc/groovyscript/compat/vanilla/CraftingRecipeBuilder$IRecipeCreator;)Ljava/lang/Object;"), require = 1) | ||
public Object registerWithClassFunction1(Shaped instance, GroovyLog.Msg msg, List<String> errors, String[] keyBasedMatrix, Char2ObjectOpenHashMap<IIngredient> keyMap, IRecipeCreator<?> recipeCreator) { | ||
if (recipeClassFunction == null) return validateShape(msg, errors, keyBasedMatrix, keyMap, recipeCreator); | ||
return validateShape(msg, errors, keyBasedMatrix, keyMap, (width1, height1, ingredients) -> recipeClassFunction.createRecipe(output, width1, height1, ingredients, mirrored, recipeFunction, recipeAction)); | ||
} | ||
|
||
@Redirect(method = "register()Lnet/minecraft/item/crafting/IRecipe;", at = @At(value = "INVOKE", target = "Lcom/cleanroommc/groovyscript/compat/vanilla/CraftingRecipeBuilder$Shaped;validateShape(Lcom/cleanroommc/groovyscript/api/GroovyLog$Msg;Ljava/util/List;Lcom/cleanroommc/groovyscript/compat/vanilla/CraftingRecipeBuilder$IRecipeCreator;)Ljava/lang/Object;"), require = 1) | ||
public Object registerWithClassFunction2(Shaped instance, GroovyLog.Msg msg, List<List<IIngredient>> ingredientMatrix, IRecipeCreator<?> recipeCreator) { | ||
if (recipeClassFunction == null) return validateShape(msg, ingredientMatrix, recipeCreator); | ||
return validateShape(msg, ingredientMatrix, (width1, height1, ingredients) -> recipeClassFunction.createRecipe(output, width1, height1, ingredients, mirrored, recipeFunction, recipeAction)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"package": "com.nomiceu.nomilabs.mixin.groovyscript", | ||
"refmap": "mixins.nomilabs.refmap.json", | ||
"target": "@env(DEFAULT)", | ||
"minVersion": "0.8", | ||
"compatibilityLevel": "JAVA_8", | ||
"mixins": [ | ||
"ShapedRecipeBuilderMixin" | ||
], | ||
"client": [], | ||
"server": [] | ||
} |