Compare commits

...
10 Commits
10 changed files with 179 additions and 39 deletions

No files matched your search

@@ -8,7 +8,6 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -129,8 +128,8 @@ public class FavoriteRecipes {
}
protected List<PositionedStack> getOutputs(IRecipeHandler handler, int recipeIndex) {
final PositionedStack pStackResult = handler.getResultStack(recipeIndex);
return pStackResult != null ? Collections.singletonList(pStackResult) : handler.getOtherStacks(recipeIndex);
final List<PositionedStack> pStackResults = handler.getResultStacks(recipeIndex);
return !pStackResults.isEmpty() ? pStackResults : handler.getOtherStacks(recipeIndex);
}
};
@@ -89,9 +89,9 @@ public class PresetsList {
return false;
}
final PositionedStack result = handler.getResultStack(recipeIndex);
final List<PositionedStack> results = handler.getResultStacks(recipeIndex);
if (result != null && matchPositionedStack(result)) {
if (!results.isEmpty() && matchPositionedStack(results, true)) {
return true;
}
@@ -101,7 +101,13 @@ public class PresetsList {
return true;
}
return result == null && others.isEmpty();
final List<PositionedStack> extraInputs = handler.getCatalystStacks(recipeIndex);
if (!extraInputs.isEmpty() && matchPositionedStack(extraInputs, true)) {
return true;
}
return results.isEmpty() && others.isEmpty();
}
private boolean matchPositionedStack(List<PositionedStack> items, boolean dir) {
@@ -24,6 +24,12 @@ public class AllOthersRecipeFilter implements IRecipeFilter {
}
}
for (PositionedStack pStack : handler.getCatalystStacks(recipeIndex)) {
if (!match(pStack)) {
return false;
}
}
return true;
}
@@ -24,6 +24,12 @@ public class AnyOthersRecipeFilter implements IRecipeFilter {
}
}
for (PositionedStack pStack : handler.getCatalystStacks(recipeIndex)) {
if (match(pStack)) {
return true;
}
}
return false;
}
@@ -48,9 +48,7 @@ public class RecipeFilter implements IRecipeFilter {
}
if (this.context == FilterContext.ANY || this.context == FilterContext.OUTPUT) {
final PositionedStack result = handler.getResultStack(recipeIndex);
if (result != null && matchPositionedStack(result) == this.anyMatch) {
if (matchPositionedStack(handler.getResultStacks(recipeIndex), this.anyMatch)) {
return this.anyMatch;
}
@@ -58,6 +56,10 @@ public class RecipeFilter implements IRecipeFilter {
return this.anyMatch;
}
if (matchPositionedStack(handler.getCatalystStacks(recipeIndex), this.anyMatch)) {
return this.anyMatch;
}
}
return !this.anyMatch;
@@ -38,6 +38,11 @@ public class FuelRecipeHandler extends FurnaceRecipeHandler {
public PositionedStack getOtherStack() {
return fuel.stack;
}
@Override
public PositionedStack getCatalyst() {
return fuel.stack;
}
}
private final ArrayList<SmeltingPair> mfurnace = new ArrayList<>();
@@ -1,5 +1,6 @@
package codechicken.nei.recipe;
import java.util.Collections;
import java.util.List;
import net.minecraft.client.gui.inventory.GuiContainer;
@@ -82,15 +83,38 @@ public interface IRecipeHandler {
* @return A list of the other {@link PositionedStack}s in this recipe relative to the top left corner of your
* recipe drawing space. For example fuel in furnaces.
*/
default List<PositionedStack> getCatalystStacks(int recipe) {
return Collections.emptyList();
}
/**
* Legacy API, define either {@link #getCatalystStacks(int)} or {@link #getResultStacks(int)}
*
* @param recipe The recipe index to get items for.
* @return A list of the other {@link PositionedStack}s in this recipe relative to the top left corner of your
* recipe drawing space. For example fuel in furnaces.
*/
List<PositionedStack> getOtherStacks(int recipe);
/**
* Legacy API, use {@link #getResultStacks(int) getResultStacks.get(0)} if you want the primary result
*
* @param recipe The recipe index to get the result for.
* @return The recipe result {@link PositionedStack} relative to the top left corner of your recipe drawing space.
*/
PositionedStack getResultStack(int recipe);
/**
*
* @param recipe The recipe index to get the result for.
* @return A list of the result {@link PositionedStack}s relative to the top left corner of your recipe drawing
* space.
*/
default List<PositionedStack> getResultStacks(int recipe) {
final PositionedStack result = getResultStack(recipe);
return result != null ? Collections.singletonList(result) : Collections.emptyList();
}
/**
* A tick function called for updating progress bars and cycling damage items.
*/
@@ -6,6 +6,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.function.Function;
import java.util.stream.Stream;
@@ -36,6 +37,7 @@ import codechicken.nei.recipe.GuiRecipeButton.UpdateRecipeButtonsEvent;
import codechicken.nei.recipe.Recipe.RecipeId;
import codechicken.nei.recipe.debug.DebugHandlerWidget;
import codechicken.nei.util.NEIMouseUtils;
import it.unimi.dsi.fastutil.longs.LongArraySet;
public class NEIRecipeWidget extends Widget {
@@ -54,6 +56,9 @@ public class NEIRecipeWidget extends Widget {
protected boolean showAsWidget = false;
protected List<GuiRecipeButton> recipeButtons = null;
// Handles re-draws for catalysts-outputs duplication to preserve full backward compatibility for otherStacks
private final Set<Long> drawnSlots = new LongArraySet();
public NEIRecipeWidget(RecipeHandlerRef handlerRef) {
this.handlerRef = handlerRef;
this.handlerInfo = GuiRecipeTab.getHandlerInfo(this.handlerRef.handler);
@@ -193,28 +198,40 @@ public class NEIRecipeWidget extends Widget {
GuiContainerManager.enableMatrixStackLogging();
for (PositionedStack pStack : getInputs()) {
final List<PositionedStack> inputs = getInputs();
final List<PositionedStack> catalysts = getCatalysts();
final List<PositionedStack> outputs = getOutputs();
if (!this.permutations.containsKey(pStack)) {
updatePermutationsFor(pStack);
}
drawItem(pStack, mouseX, mouseY, yShift, true);
}
for (PositionedStack pStack : getCatalysts()) {
if (!this.permutations.containsKey(pStack)) {
updatePermutationsFor(pStack);
}
drawItem(pStack, mouseX, mouseY, yShift, true);
}
for (PositionedStack pStack : getOutputs()) {
drawnSlots.clear();
for (PositionedStack pStack : inputs) {
drawnSlots.add(slotKey(pStack));
drawItem(pStack, mouseX, mouseY, yShift, false);
}
for (PositionedStack pStack : catalysts) {
if (!drawnSlots.add(slotKey(pStack))) {
continue;
}
if (!this.permutations.containsKey(pStack)) {
updatePermutationsFor(pStack);
}
drawItem(pStack, mouseX, mouseY, yShift, true);
}
for (PositionedStack pStack : outputs) {
if (!drawnSlots.add(slotKey(pStack))) {
continue;
}
if (!this.permutations.containsKey(pStack)) {
updatePermutationsFor(pStack);
}
drawItem(pStack, mouseX, mouseY, yShift, true);
}
GuiContainerManager.disableMatrixStackLogging();
this.handlerRef.handler.drawForeground(this.handlerRef.recipeIndex);
@@ -246,6 +263,10 @@ public class NEIRecipeWidget extends Widget {
DebugHandlerWidget.instance.drawGuiPlaceholder(this);
}
private static long slotKey(PositionedStack pStack) {
return ((long) pStack.relx << 32) ^ (pStack.rely & 0xFFFFFFFFL);
}
protected void drawItem(PositionedStack pStack, int mouseX, int mouseY, int yShift, boolean input) {
GuiContainerManager.drawItem(pStack.relx, pStack.rely, pStack.item);
@@ -656,13 +677,19 @@ public class NEIRecipeWidget extends Widget {
}
protected List<PositionedStack> getOutputs() {
final PositionedStack pStackResult = this.handlerRef.handler.getResultStack(this.handlerRef.recipeIndex);
return pStackResult != null ? Arrays.asList(pStackResult)
final List<PositionedStack> pStackResults = this.handlerRef.handler
.getResultStacks(this.handlerRef.recipeIndex);
return !pStackResults.isEmpty() ? pStackResults
: this.handlerRef.handler.getOtherStacks(this.handlerRef.recipeIndex);
}
protected List<PositionedStack> getCatalysts() {
if (this.handlerRef.handler.getResultStack(this.handlerRef.recipeIndex) == null) {
List<PositionedStack> catalysts = this.handlerRef.handler.getCatalystStacks(this.handlerRef.recipeIndex);
if (!catalysts.isEmpty()) {
return catalysts;
}
if (this.handlerRef.handler.getResultStacks(this.handlerRef.recipeIndex).isEmpty()) {
return Collections.emptyList();
}
return this.handlerRef.handler.getOtherStacks(this.handlerRef.recipeIndex);
@@ -54,19 +54,26 @@ public class Recipe {
public static RecipeId of(IRecipeHandler handler, int recipeIndex) {
final List<PositionedStack> ingredients = handler.getIngredientStacks(recipeIndex);
final String handlerName = GuiRecipeTab.getHandlerInfo(handler).getHandlerName();
PositionedStack pStackResult = handler.getResultStack(recipeIndex);
// Use getResultStacks even though getResult could work because if a handler, like GT for example, doesn't
// return anything from getResult, but will define all the outputs in getResultStacks we can still pick up
// the results here. If a handler still doesn't define getResultStacks, then it will naturally fall back to
// getResult anyway
List<PositionedStack> pStackResults = handler.getResultStacks(recipeIndex);
if (pStackResult == null) {
if (pStackResults.isEmpty()) {
for (PositionedStack otherStack : handler.getOtherStacks(recipeIndex)) {
if (!FluidContainerRegistry.isContainer(otherStack.items[0])
|| StackInfo.getFluid(otherStack.items[0]) != null) {
pStackResult = otherStack;
pStackResults.add(otherStack);
break;
}
}
}
return new RecipeId(extractItem(pStackResult), handlerName, extractIngredients(ingredients));
return new RecipeId(
extractItem(!pStackResults.isEmpty() ? pStackResults.get(0) : null),
handlerName,
extractIngredients(ingredients));
}
public static RecipeId of(JsonObject json) {
@@ -389,8 +396,12 @@ public class Recipe {
ingredients.add(RecipeIngredient.of(positionedStack));
}
if (handler.getResultStack(recipeIndex) != null) {
results.add(RecipeIngredient.of(handler.getResultStack(recipeIndex)));
final List<PositionedStack> resultStacks = handler.getResultStacks(recipeIndex);
if (!resultStacks.isEmpty()) {
for (PositionedStack positionedStack : resultStacks) {
results.add(RecipeIngredient.of(positionedStack));
}
} else {
for (PositionedStack positionedStack : handler.getOtherStacks(recipeIndex)) {
results.add(RecipeIngredient.of(positionedStack));
@@ -4,6 +4,7 @@ import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
@@ -132,7 +133,48 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
public abstract PositionedStack getResult();
/**
* The ingredients required to produce the result Use this if you have more than one ingredient
* The multiple items produced by this recipe, with position
*
* @return A list of positioned ingredient items.
*/
public List<PositionedStack> getResults() {
ArrayList<PositionedStack> stacks = new ArrayList<>();
try {
PositionedStack stack = getResult();
if (stack != null) stacks.add(stack);
} catch (ArithmeticException e) {
NEIClientConfig.logger.error("Error in getOtherStacks: " + e);
}
return stacks;
}
/**
* Return extra items that are not directly involved in the ingredient->result relationship. Eg fuels.
*
* @return A list of positioned ingredient items.
*/
public List<PositionedStack> getCatalysts() {
ArrayList<PositionedStack> stacks = new ArrayList<>();
try {
PositionedStack stack = getCatalyst();
if (stack != null) stacks.add(stack);
} catch (ArithmeticException e) {
NEIClientConfig.logger.error("Error in getCatalysts: " + e);
}
return stacks;
}
/**
* Simple utility
*
* @return The another positioned stack
*/
public PositionedStack getCatalyst() {
return null;
}
/**
* The ingredients required to produce the result. Use this if you have more than one ingredient
*
* @return A list of positioned ingredient items.
*/
@@ -151,6 +193,8 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
}
/**
* Legacy API
*
* Return extra items that are not directly involved in the ingredient->result relationship. Eg fuels. Use this
* if you have more than one other stack
*
@@ -625,13 +669,23 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
}
public PositionedStack getResultStack(int recipe) {
List<PositionedStack> results = getResultStacks(recipe);
if (results == null || results.isEmpty()) return null;
return results.get(0);
}
public List<PositionedStack> getResultStacks(int recipe) {
try {
return arecipes.get(recipe).getResult();
return arecipes.get(recipe).getResults();
} catch (ArrayIndexOutOfBoundsException ignored) {
return null;
return Collections.emptyList();
}
}
public List<PositionedStack> getCatalystStacks(int recipe) {
return arecipes.get(recipe).getCatalysts();
}
public List<PositionedStack> getOtherStacks(int recipe) {
return arecipes.get(recipe).getOtherStacks();
}