Add ore dictionary support for Inscriber recipes in JEI (#430)

This commit is contained in:
zeng-git
2024-05-24 18:51:37 +08:00
committed by GitHub
parent 08a7aff600
commit 59edb38208
10 changed files with 127 additions and 108 deletions
@@ -19,12 +19,11 @@
package appeng.api.features;
import java.util.List;
import java.util.Optional;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
import java.util.List;
import java.util.Optional;
/**
@@ -57,21 +56,35 @@ public interface IInscriberRecipe
@Nonnull
ItemStack getOutput();
@Nonnull
List<ItemStack> getTopInputs();
/**
* gets the top optional
*
* @return item which is used top
*/
@Deprecated
@Nonnull
Optional<ItemStack> getTopOptional();
default Optional<ItemStack> getTopOptional(){
return getTopInputs().isEmpty() ? Optional.empty() : Optional.of(getTopInputs().get(0));
}
@Nonnull
List<ItemStack> getBottomInputs();
/**
* gets the bottom optional
*
* @return item which is used bottom
*/
@Deprecated
@Nonnull
Optional<ItemStack> getBottomOptional();
default Optional<ItemStack> getBottomOptional() {
return getBottomInputs().isEmpty() ? Optional.empty() : Optional.of(getBottomInputs().get(0));
}
/**
* type of inscriber process
@@ -19,11 +19,11 @@
package appeng.api.features;
import java.util.Collection;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
import java.util.Collection;
import java.util.Collections;
/**
@@ -66,7 +66,7 @@ public interface IInscriberRecipeBuilder
* @return currently used builder
*/
@Nonnull
IInscriberRecipeBuilder withTopOptional( @Nonnull ItemStack topOptional );
IInscriberRecipeBuilder withTopOptional(@Nonnull Collection<ItemStack> topOptional );
/**
* Creates an inscriber recipe with bot.
@@ -77,7 +77,7 @@ public interface IInscriberRecipeBuilder
* @return currently used builder
*/
@Nonnull
IInscriberRecipeBuilder withBottomOptional( @Nonnull ItemStack bottomOptional );
IInscriberRecipeBuilder withBottomOptional( @Nonnull Collection<ItemStack> bottomOptional );
/**
* Creates an inscriber recipe with type.
@@ -104,4 +104,14 @@ public interface IInscriberRecipeBuilder
*/
@Nonnull
IInscriberRecipe build();
@Deprecated
default IInscriberRecipeBuilder withTopOptional(@Nonnull ItemStack topOptional){
return withTopOptional(Collections.singleton(topOptional));
}
@Deprecated
default IInscriberRecipeBuilder withBottomOptional(@Nonnull ItemStack bottomOptional){
return withBottomOptional(Collections.singleton(bottomOptional));
}
}
@@ -116,15 +116,19 @@ public class ContainerInscriber extends ContainerUpgradeable implements IProgres
boolean matches = false;
for (final IInscriberRecipe recipe : AEApi.instance().registries().inscriber().getRecipes()) {
final boolean matchA = !top
.isEmpty() && (Platform.itemComparisons().isSameItem(top, recipe.getTopOptional().orElse(ItemStack.EMPTY)) || Platform
.itemComparisons()
.isSameItem(top, recipe.getBottomOptional().orElse(ItemStack.EMPTY)));
final boolean matchB = !bot
.isEmpty() && (Platform.itemComparisons().isSameItem(bot, recipe.getTopOptional().orElse(ItemStack.EMPTY)) || Platform
.itemComparisons()
.isSameItem(bot, recipe.getBottomOptional().orElse(ItemStack.EMPTY)));
// Check if plateA matches any item in the list of top components of the recipe
final boolean matchA = top.isEmpty() && recipe.getTopInputs().isEmpty() ||
recipe.getTopInputs().stream().anyMatch(topItem -> Platform.itemComparisons().isSameItem(top, topItem)) &&
(bot.isEmpty() && recipe.getBottomInputs().isEmpty() ||
recipe.getBottomInputs().stream().anyMatch(bottomItem -> Platform.itemComparisons().isSameItem(bot, bottomItem)));
// Check if plateB matches any item in the list of top components of the recipe
final boolean matchB = bot.isEmpty() && recipe.getTopInputs().isEmpty() ||
recipe.getTopInputs().stream().anyMatch(topItem -> Platform.itemComparisons().isSameItem(bot, topItem)) &&
(top.isEmpty() && recipe.getBottomInputs().isEmpty() ||
recipe.getBottomInputs().stream().anyMatch(bottomItem -> Platform.itemComparisons().isSameItem(top, bottomItem)));
// If either matchA or matchB is true, iterate through the recipe's inputs
if (matchA || matchB) {
matches = true;
for (final ItemStack option : recipe.getInputs()) {
@@ -152,10 +156,22 @@ public class ContainerInscriber extends ContainerUpgradeable implements IProgres
// everything else
for (final IInscriberRecipe recipe : AEApi.instance().registries().inscriber().getRecipes()) {
boolean isValid = false;
if (Platform.itemComparisons().isSameItem(otherSlot, recipe.getTopOptional().orElse(ItemStack.EMPTY))) {
isValid = Platform.itemComparisons().isSameItem(is, recipe.getBottomOptional().orElse(ItemStack.EMPTY));
} else if (Platform.itemComparisons().isSameItem(otherSlot, recipe.getBottomOptional().orElse(ItemStack.EMPTY))) {
isValid = Platform.itemComparisons().isSameItem(is, recipe.getTopOptional().orElse(ItemStack.EMPTY));
// Check if otherSlot matches any item in the top component list
boolean matchTop = recipe.getTopInputs().stream()
.anyMatch(topItem -> Platform.itemComparisons().isSameItem(otherSlot, topItem));
// Check if otherSlot matches any item in the bottom component list
boolean matchBottom = recipe.getBottomInputs().stream()
.anyMatch(bottomItem -> Platform.itemComparisons().isSameItem(otherSlot, bottomItem));
if (matchTop) {
// If otherSlot matches a top component, check if 'is' matches any item in the bottom component list
isValid = recipe.getBottomInputs().stream()
.anyMatch(bottomItem -> Platform.itemComparisons().isSameItem(is, bottomItem));
} else if (matchBottom) {
// If otherSlot matches a bottom component, check if 'is' matches any item in the top component list
isValid = recipe.getTopInputs().stream()
.anyMatch(topItem -> Platform.itemComparisons().isSameItem(is, topItem));
}
if (isValid) {
@@ -25,6 +25,7 @@ import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
/**
@@ -35,7 +36,7 @@ import java.util.Collection;
* @since rv2
*/
public class InscriberInscribeRecipe extends InscriberRecipe {
InscriberInscribeRecipe(@Nonnull final Collection<ItemStack> inputs, @Nonnull final ItemStack output, @Nullable final ItemStack top, @Nullable final ItemStack bot) {
InscriberInscribeRecipe(@Nonnull final Collection<ItemStack> inputs, @Nonnull final ItemStack output, @Nullable final List<ItemStack> top, @Nullable final List<ItemStack> bot) {
super(inputs, output, top, bot, InscriberProcessType.INSCRIBE);
}
}
@@ -28,7 +28,6 @@ import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
/**
@@ -46,21 +45,21 @@ public class InscriberRecipe implements IInscriberRecipe {
private final ItemStack output;
@Nonnull
private final Optional<ItemStack> maybeTop;
private final List<ItemStack> maybeTop;
@Nonnull
private final Optional<ItemStack> maybeBot;
private final List<ItemStack> maybeBot;
@Nonnull
private final InscriberProcessType type;
InscriberRecipe(@Nonnull final Collection<ItemStack> inputs, @Nonnull final ItemStack output, @Nullable final ItemStack top, @Nullable final ItemStack bot, @Nonnull final InscriberProcessType type) {
InscriberRecipe(@Nonnull final Collection<ItemStack> inputs, @Nonnull final ItemStack output, @Nullable final List<ItemStack> top, @Nullable final List<ItemStack> bot, @Nonnull final InscriberProcessType type) {
this.inputs = new ArrayList<>(inputs.size());
this.inputs.addAll(inputs);
this.output = output;
this.maybeTop = Optional.ofNullable(top);
this.maybeBot = Optional.ofNullable(bot);
this.maybeTop = top;
this.maybeBot = bot;
this.type = type;
}
@@ -79,13 +78,13 @@ public class InscriberRecipe implements IInscriberRecipe {
@Nonnull
@Override
public final Optional<ItemStack> getTopOptional() {
public final List<ItemStack> getTopInputs() {
return this.maybeTop;
}
@Nonnull
@Override
public final Optional<ItemStack> getBottomOptional() {
public final List<ItemStack> getBottomInputs() {
return this.maybeBot;
}
@@ -112,10 +111,10 @@ public class InscriberRecipe implements IInscriberRecipe {
if (!this.output.equals(that.getOutput())) {
return false;
}
if (!this.maybeTop.equals(that.getTopOptional())) {
if (!this.maybeTop.equals(that.getTopInputs())) {
return false;
}
if (!this.maybeBot.equals(that.getBottomOptional())) {
if (!this.maybeBot.equals(that.getBottomInputs())) {
return false;
}
return this.type == that.getProcessType();
@@ -130,4 +129,6 @@ public class InscriberRecipe implements IInscriberRecipe {
result = 31 * result + this.type.hashCode();
return result;
}
}
@@ -75,9 +75,8 @@ public final class InscriberRegistry implements IInscriberRegistry {
Preconditions.checkNotNull(recipe, "Tried to add (null) as inscriber recipe to the registry.");
if (this.recipes.add(recipe)) {
recipe.getTopOptional().ifPresent(this.optionals::add);
recipe.getBottomOptional().ifPresent(this.optionals::add);
this.optionals.addAll(recipe.getTopInputs());
this.optionals.addAll(recipe.getBottomInputs());
this.inputs.addAll(recipe.getInputs());
return true;
@@ -110,8 +109,8 @@ public final class InscriberRegistry implements IInscriberRegistry {
private static final class Builder implements IInscriberRecipeBuilder {
private List<ItemStack> inputs;
private ItemStack output;
private ItemStack topOptional;
private ItemStack bottomOptional;
private List<ItemStack> topOptional;
private List<ItemStack> bottomOptional;
private InscriberProcessType type;
@Nonnull
@@ -139,22 +138,22 @@ public final class InscriberRegistry implements IInscriberRegistry {
@Nonnull
@Override
public Builder withTopOptional(@Nonnull final ItemStack topOptional) {
public Builder withTopOptional(@Nonnull final Collection<ItemStack> topOptional) {
Preconditions.checkNotNull(topOptional);
Preconditions.checkArgument(!topOptional.isEmpty());
this.topOptional = topOptional;
this.topOptional = new ArrayList<>(topOptional.size());
this.topOptional.addAll(topOptional);
return this;
}
@Nonnull
@Override
public Builder withBottomOptional(@Nonnull final ItemStack bottomOptional) {
public Builder withBottomOptional(@Nonnull final Collection<ItemStack> bottomOptional) {
Preconditions.checkNotNull(bottomOptional);
Preconditions.checkArgument(!bottomOptional.isEmpty());
this.bottomOptional = bottomOptional;
this.bottomOptional = new ArrayList<>(bottomOptional.size());
this.bottomOptional.addAll(bottomOptional);
return this;
}
@@ -31,9 +31,7 @@ import net.minecraft.item.ItemStack;
import stanhebben.zenscript.annotations.ZenClass;
import stanhebben.zenscript.annotations.ZenMethod;
import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;
@@ -49,25 +47,15 @@ public class InscriberRecipes {
return;
}
Collection<ItemStack> topList = CTModule.toStacks(top).orElse(Collections.singleton(ItemStack.EMPTY));
Collection<ItemStack> bottomList = CTModule.toStacks(bottom).orElse(Collections.singleton(ItemStack.EMPTY));
for (ItemStack topStack : topList) {
for (ItemStack bottomStack : bottomList) {
final IInscriberRecipeBuilder builder = AEApi.instance().registries().inscriber().builder();
builder.withProcessType(inscribe ? InscriberProcessType.INSCRIBE : InscriberProcessType.PRESS)
.withOutput(CTModule.toStack(output))
.withInputs(inStacks.get());
if (!topStack.isEmpty()) {
builder.withTopOptional(topStack);
}
if (!bottomStack.isEmpty()) {
builder.withBottomOptional(bottomStack);
}
CTModule.MODIFICATIONS.add(new Add(builder.build()));
}
}
List<ItemStack> topList = new ArrayList<>(CTModule.toStacks(top).orElse(Collections.singleton(ItemStack.EMPTY)));
List<ItemStack> bottomList = new ArrayList<>(CTModule.toStacks(bottom).orElse(Collections.singleton(ItemStack.EMPTY)));
final IInscriberRecipeBuilder builder = AEApi.instance().registries().inscriber().builder();
builder.withProcessType(inscribe ? InscriberProcessType.INSCRIBE : InscriberProcessType.PRESS).
withTopOptional(topList).
withBottomOptional(bottomList).
withOutput(CTModule.toStack(output))
.withInputs(inStacks.get());
CTModule.MODIFICATIONS.add(new Add(builder.build()));
}
@ZenMethod
@@ -21,11 +21,11 @@ package appeng.integration.modules.jei;
import appeng.api.features.IInscriberRecipe;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.ingredients.VanillaTypes;
import mezz.jei.api.recipe.IRecipeWrapper;
import net.minecraft.item.ItemStack;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -40,11 +40,10 @@ class InscriberRecipeWrapper implements IRecipeWrapper {
@Override
public void getIngredients(IIngredients ingredients) {
List<List<ItemStack>> inputSlots = new ArrayList<>(3);
inputSlots.add(Collections.singletonList(this.recipe.getTopOptional().orElse(ItemStack.EMPTY)));
inputSlots.add(this.recipe.getTopInputs());
inputSlots.add(this.recipe.getInputs());
inputSlots.add(Collections.singletonList(this.recipe.getBottomOptional().orElse(ItemStack.EMPTY)));
ingredients.setInputLists(ItemStack.class, inputSlots);
ingredients.setOutput(ItemStack.class, this.recipe.getOutput());
inputSlots.add(this.recipe.getBottomInputs());
ingredients.setInputLists(VanillaTypes.ITEM, inputSlots);
ingredients.setOutput(VanillaTypes.ITEM, this.recipe.getOutput());
}
}
@@ -14,6 +14,7 @@ import net.minecraftforge.common.crafting.CraftingHelper;
import net.minecraftforge.common.crafting.JsonContext;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -27,34 +28,25 @@ public class InscriberHandler implements IAERecipeFactory {
JsonObject ingredients = JsonUtils.getJsonObject(json, "ingredients");
List<ItemStack> middle = Arrays.asList(CraftingHelper.getIngredient(ingredients.get("middle"), ctx).getMatchingStacks());
ItemStack[] top = new ItemStack[]{null};
List<ItemStack> top = Collections.emptyList();
if (ingredients.has("top")) {
top = CraftingHelper.getIngredient(JsonUtils.getJsonObject(ingredients, "top"), ctx).getMatchingStacks();
top = Arrays.asList(CraftingHelper.getIngredient(JsonUtils.getJsonObject(ingredients, "top"), ctx).getMatchingStacks());
}
ItemStack[] bottom = new ItemStack[]{null};
List<ItemStack> bottom = Collections.emptyList();
if (ingredients.has("bottom")) {
bottom = CraftingHelper.getIngredient(JsonUtils.getJsonObject(ingredients, "bottom"), ctx).getMatchingStacks();
bottom = Arrays.asList(CraftingHelper.getIngredient(JsonUtils.getJsonObject(ingredients, "bottom"), ctx).getMatchingStacks());
}
final IInscriberRegistry reg = AEApi.instance().registries().inscriber();
for (int i = 0; i < top.length; ++i) {
for (int j = 0; j < bottom.length; ++j) {
final IInscriberRecipeBuilder builder = reg.builder();
builder.withOutput(result);
builder.withProcessType("press".equals(mode) ? InscriberProcessType.PRESS : InscriberProcessType.INSCRIBE);
builder.withInputs(middle);
if (top[i] != null) {
builder.withTopOptional(top[i]);
}
if (bottom[j] != null) {
builder.withBottomOptional(bottom[j]);
}
reg.addRecipe(builder.build());
}
if (!top.isEmpty() || !bottom.isEmpty()) {
final IInscriberRecipeBuilder builder = reg.builder();
builder.withOutput(result);
builder.withProcessType("press".equals(mode) ? InscriberProcessType.PRESS : InscriberProcessType.INSCRIBE);
builder.withTopOptional(top);
builder.withInputs(middle);
builder.withBottomOptional(bottom);
reg.addRecipe(builder.build());
}
}
}
@@ -65,6 +65,7 @@ import net.minecraftforge.items.IItemHandlerModifiable;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
@@ -281,20 +282,19 @@ public class TileInscriber extends AENetworkPowerTile implements IGridTickable,
for (final IInscriberRecipe recipe : AEApi.instance().registries().inscriber().getRecipes()) {
final boolean matchA = (plateA.isEmpty() && !recipe.getTopOptional().isPresent()) || (Platform.itemComparisons()
.isSameItem(plateA,
recipe.getTopOptional().orElse(ItemStack.EMPTY))) && // and...
((plateB.isEmpty() && !recipe.getBottomOptional().isPresent()) || (Platform.itemComparisons()
.isSameItem(plateB,
recipe.getBottomOptional().orElse(ItemStack.EMPTY))));
// Check if plateA matches any item in the list of top components of the recipe
final boolean matchA = plateA.isEmpty() && recipe.getTopInputs().isEmpty() ||
recipe.getTopInputs().stream().anyMatch(topItem -> Platform.itemComparisons().isSameItem(plateA, topItem)) &&
(plateB.isEmpty() && recipe.getBottomInputs().isEmpty() ||
recipe.getBottomInputs().stream().anyMatch(bottomItem -> Platform.itemComparisons().isSameItem(plateB, bottomItem)));
final boolean matchB = (plateB.isEmpty() && !recipe.getTopOptional().isPresent()) || (Platform.itemComparisons()
.isSameItem(plateB,
recipe.getTopOptional().orElse(ItemStack.EMPTY))) && // and...
((plateA.isEmpty() && !recipe.getBottomOptional().isPresent()) || (Platform.itemComparisons()
.isSameItem(plateA,
recipe.getBottomOptional().orElse(ItemStack.EMPTY))));
// Check if plateB matches any item in the list of top components of the recipe
final boolean matchB = plateB.isEmpty() && recipe.getTopInputs().isEmpty() ||
recipe.getTopInputs().stream().anyMatch(topItem -> Platform.itemComparisons().isSameItem(plateB, topItem)) &&
(plateA.isEmpty() && recipe.getBottomInputs().isEmpty() ||
recipe.getBottomInputs().stream().anyMatch(bottomItem -> Platform.itemComparisons().isSameItem(plateA, bottomItem)));
// If either matchA or matchB is true, iterate through the recipe's inputs
if (matchA || matchB) {
for (final ItemStack option : recipe.getInputs()) {
if (Platform.itemComparisons().isSameItem(input, option)) {
@@ -476,11 +476,11 @@ public class TileInscriber extends AENetworkPowerTile implements IGridTickable,
builder.withInputs(inputs).withOutput(renamedItem).withProcessType(type);
if (!plateA.isEmpty()) {
builder.withTopOptional(plateA);
builder.withTopOptional(Collections.singletonList(plateA));
}
if (!plateB.isEmpty()) {
builder.withBottomOptional(plateB);
builder.withBottomOptional(Collections.singletonList(plateB));
}
return builder.build();