diff --git a/src/main/java/gregtechmod/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java b/src/main/java/gregtechmod/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java index 200ad66..89cc717 100644 --- a/src/main/java/gregtechmod/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java +++ b/src/main/java/gregtechmod/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java @@ -1,6 +1,5 @@ package gregtechmod.api.metatileentity.implementations; -import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -9,10 +8,12 @@ import gregtechmod.api.interfaces.IRecipeWorkable; import gregtechmod.api.metatileentity.MetaTileEntity; import gregtechmod.api.recipe.Recipe; import gregtechmod.api.recipe.RecipeLogic; +import gregtechmod.api.recipe.RecipeMap; import gregtechmod.api.util.GT_OreDictUnificator; import gregtechmod.api.util.GT_Utility; import gregtechmod.api.util.InfoBuilder; import gregtechmod.api.util.ListAdapter; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -31,12 +32,12 @@ public abstract class GT_MetaTileEntity_BasicMachine extends MetaTileEntity impl protected RecipeLogic recipeLogic; - public GT_MetaTileEntity_BasicMachine(int aID, String aName, List recipeMap) { + public GT_MetaTileEntity_BasicMachine(int aID, String aName, RecipeMap recipeMap) { super(aID, aName); initRecipeLogic(recipeMap); } - public GT_MetaTileEntity_BasicMachine(List recipeMap) { + public GT_MetaTileEntity_BasicMachine(RecipeMap recipeMap) { initRecipeLogic(recipeMap); } @@ -67,7 +68,7 @@ public abstract class GT_MetaTileEntity_BasicMachine extends MetaTileEntity impl @Override public boolean isLiquidInput (byte aSide) {return aSide != mMainFacing;} @Override public boolean isLiquidOutput(byte aSide) {return aSide != mMainFacing;} - protected void initRecipeLogic(List recipeMap) { + protected void initRecipeLogic(RecipeMap recipeMap) { recipeLogic = new RecipeLogic(recipeMap, this); } @@ -137,18 +138,15 @@ public abstract class GT_MetaTileEntity_BasicMachine extends MetaTileEntity impl @Override public boolean spaceForOutput(Recipe recipe) { - ItemStack[] outputs = recipe.getOutputs(); - if (outputs.length <= getOutputItems().length) { - List slots = new ArrayList<>(); - for (int i : getOutputItems()) slots.add(mInventory[i]); - for (int i = 0; i < outputs.length && i < slots.size(); i++) { - if (slots.get(i) != null && outputs[i] != null) { - if (!GT_Utility.areStacksEqual(slots.get(i), outputs[i]) || slots.get(i).stackSize + outputs[i].stackSize > slots.get(i).getMaxStackSize()) { - return false; - } - } - } - } else return false; + List outputSlots = this.getOutputItems(); + List allOutputs = recipe.getAllOutputs(); + for (int i = 0; i < allOutputs.size(); i++) { + ItemStack slot = outputSlots.get(i); + ItemStack recipeStack = allOutputs.get(i); + if (slot == null || recipeStack == null || (GT_Utility.areStacksEqual(slot, recipeStack) && slot.stackSize + recipeStack.stackSize >= slot.getMaxStackSize())) + continue; + return false; + } return true; } diff --git a/src/main/java/gregtechmod/api/recipe/Recipe.java b/src/main/java/gregtechmod/api/recipe/Recipe.java index 90d9b8b..dbf48cb 100644 --- a/src/main/java/gregtechmod/api/recipe/Recipe.java +++ b/src/main/java/gregtechmod/api/recipe/Recipe.java @@ -12,6 +12,7 @@ import java.util.stream.Collectors; import org.apache.commons.lang3.tuple.Pair; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; /** * NEVER INCLUDE THIS FILE IN YOUR MOD!!! @@ -170,10 +171,13 @@ public class Recipe { } /** - * @return list containing only 100% chanced outputs + * @return list containing all possible outputs */ public List getAllOutputs() { - return Collections.unmodifiableList(outputs); + List stacks = new ArrayList<>(); + stacks.addAll(outputs); + chancedOutputs.forEach(ch -> stacks.add(ch.getStack())); + return Collections.unmodifiableList(stacks); } /** @@ -183,6 +187,13 @@ public class Recipe { return Collections.unmodifiableList(chancedOutputs); } + /** + * @return list containing only 100% chanced outputs + */ + public List getOutputs() { + return Collections.unmodifiableList(outputs); + } + /** * @return list of all recipe inputs */ @@ -232,23 +243,6 @@ public class Recipe { // return true; // } // -// public void writeToNBT(NBTTagCompound data) { -// data.setInteger("recipeHash", this.hashCode()); -// } -// -// public static Recipe loadFromNBT(List recipeMap, NBTTagCompound data) { -// if (data.hasKey("recipeHash")) { -// int hash = data.getInteger("recipeHash"); -// for (Recipe res : recipeMap) { -// if (res.hashCode() == hash) { -// return res; -// } -// } -// } -// -// return null; -// } -// // /** // * Default constructor, will create simple recipe // * @param aInput1 @@ -441,6 +435,23 @@ public class Recipe { // } // } + public void writeToNBT(NBTTagCompound data) { + data.setInteger("recipeHash", this.hashCode()); + } + + public static Recipe loadFromNBT(RecipeMap recipeMap, NBTTagCompound data) { + if (data.hasKey("recipeHash")) { + int hash = data.getInteger("recipeHash"); + for (Recipe res : recipeMap.getRecipes()) { + if (res.hashCode() == hash) { + return res; + } + } + } + + return null; + } + @Override public int hashCode() { return (startEU * EUt * duration) + (shaped ? 1 : 0) + inputs.hashCode() + outputs.hashCode() + chancedOutputs.hashCode(); diff --git a/src/main/java/gregtechmod/api/recipe/RecipeLogic.java b/src/main/java/gregtechmod/api/recipe/RecipeLogic.java index df433bf..29e3fca 100644 --- a/src/main/java/gregtechmod/api/recipe/RecipeLogic.java +++ b/src/main/java/gregtechmod/api/recipe/RecipeLogic.java @@ -2,6 +2,7 @@ package gregtechmod.api.recipe; import java.lang.ref.WeakReference; import java.util.List; +import java.util.Random; import java.util.function.Supplier; import gregtechmod.api.interfaces.IGregTechTileEntity; @@ -9,7 +10,6 @@ import gregtechmod.api.interfaces.IRecipeWorkable; import gregtechmod.api.util.GT_Log; import gregtechmod.api.util.GT_Utility; -import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -19,11 +19,12 @@ import net.minecraft.nbt.NBTTagCompound; * */ public class RecipeLogic { + public static final Random recipeRandom = new Random(); + public final WeakReference metaTileEntity; - public final List recipeMap; + public final RecipeMap recipeMap; public int batterySlot = 5; - public boolean moveItems = true; /** Do not consume inputs on custom recipe provider, it is only should provide a recipe instance */ protected Supplier customRecipeProvider; protected int maxProgressTime; @@ -35,7 +36,14 @@ public class RecipeLogic { private boolean stuttering; private boolean wasNoEnergy; - public RecipeLogic(List recipeMap, IRecipeWorkable machine) { + public RecipeLogic(RecipeMap recipeMap, IRecipeWorkable machine) { + int inputs = machine.getInputItems().size(); + int outputs = machine.getOutputItems().size(); + + if (inputs < recipeMap.minInputs || inputs > recipeMap.maxInputs || outputs < recipeMap.minOutputs || outputs > recipeMap.maxOutputs) { + throw new IllegalArgumentException("Wrong recipe map was supplied to machine!\n" + "inputs: " + inputs + "; outputs=" + outputs + "\n" + recipeMap.toString()); + } + this.recipeMap = recipeMap; maxProgressTime = 0; progressTime = 0; @@ -50,7 +58,6 @@ public class RecipeLogic { boolean success = false; IGregTechTileEntity base = getMachine().getBaseMetaTileEntity(); overclockersCount = base.getOverclockerUpgradeCount(); - if (moveItems) moveItems(); if (base.isAllowedToWork()) { if (progressTime > 0) { @@ -63,7 +70,7 @@ public class RecipeLogic { if (progressTime == 0) { if (base.hasInventoryBeenModified() || base.hasWorkJustBeenEnabled() || success || base.getTimer() % 600 == 0 || wasNoEnergy) { - if (isInputNonEmpty() && base.isUniversalEnergyStored(getMachine().getMinimumStoredEU() - 100)) { + if (!getMachine().getInputItems().isEmpty() && base.isUniversalEnergyStored(getMachine().getMinimumStoredEU() - 100)) { trySerachRecipe(); wasNoEnergy = false; } else { @@ -123,38 +130,24 @@ public class RecipeLogic { protected Recipe findRecipe() { if (customRecipeProvider == null) { - return Recipe.findEqualRecipe(true, recipeMap, getMachine().getBaseMetaTileEntity(), getMachine().getInputItems()); + return recipeMap.findRecipe(getMachine().getInputItems()); } else return customRecipeProvider.get(); } protected boolean match(Recipe recipe) { - return recipe.match(false, getMachine().getBaseMetaTileEntity(), getMachine().getInputItems()); + return recipe.matches(false, getMachine().getInputItems()); } protected void consumeInputs(Recipe recipe) { - recipe.match(true, getMachine().getBaseMetaTileEntity(), getMachine().getInputItems()); - } - - protected void moveItems() { - // Slot 0 = HoloSlot - // Slot 1 = Left Input - // Slot 2 = right Input - // Slot 3 = left Output - // Slot 4 = right Output - // Slot 5 = battery Slot in most cases - IInventory inv = getMachine().getBaseMetaTileEntity(); - int[] in = getMachine().getInputItems(); - int[] out = getMachine().getOutputItems(); - if (in.length > 1) GT_Utility.moveStackFromSlotAToSlotB(inv, inv, in[0], in[1], (byte)64, (byte)1, (byte)64, (byte)1); - if (out.length > 1) GT_Utility.moveStackFromSlotAToSlotB(inv, inv, out[0], out[1], (byte)64, (byte)1, (byte)64, (byte)1); + recipe.matches(true, getMachine().getInputItems()); } protected void startRecipe(Recipe recipe) { if (getMachine().spaceForOutput(recipe)) { previousRecipe = recipe; - maxProgressTime = GT_Utility.isDebugItem(getMachine().getStackInSlot(batterySlot)) ? 1 : recipe.mDuration; + maxProgressTime = GT_Utility.isDebugItem(getMachine().getStackInSlot(batterySlot)) ? 1 : recipe.getDuration(); progressTime = 1; - EUt = recipe.mEUt; + EUt = recipe.getEUt(); consumeInputs(recipe); getMachine().getBaseMetaTileEntity().setActive(true); getMachine().startProcess(); @@ -163,33 +156,39 @@ public class RecipeLogic { } } + /** + * Will put outputs to machine and execute machine's end recipe callbacks + * @param recipe + */ protected void endRecipe(Recipe recipe) { - ItemStack[] outputs = recipe.getOutputs(); - if (outputs.length <= getMachine().getOutputItems().length) { - for (ItemStack out : outputs) { - for (int i : getMachine().getOutputItems()) { - if (out != null && getMachine().getBaseMetaTileEntity().addStackToSlot(i, out.copy())) { - break; - } + List outputs = getMachine().getOutputItems(); + List recipeOutputs = recipe.getResults(recipeRandom); + + for (ItemStack recipeOut : recipeOutputs) { + int amount = recipeOut.stackSize; + for (int i = 0; i < outputs.size(); i++) { + ItemStack slot = outputs.get(i); + if (slot == null) { + outputs.set(i, recipeOut.copy()); + amount = 0; + } else if (GT_Utility.areStacksEqual(recipeOut, slot)) { + int newSize = Math.min(slot.getMaxStackSize(), slot.stackSize + amount); + slot.stackSize = newSize; + amount -= newSize; } + + if (amount == 0) + break; } - } else { - GT_Log.log.catching(new IllegalStateException("Found recipe with more items output machine has slots!")); + + if (amount > 0) + GT_Log.log.error("Output overflow detected! Left items: " + amount + " for output stack: " + recipeOut); } stuttering = false; getMachine().endProcess(); } - protected boolean isInputNonEmpty() { - for (int i : getMachine().getInputItems()) { - ItemStack s = getMachine().getStackInSlot(i); - if (s != null && s.stackSize > 0) return true; - } - - return false; - } - private IRecipeWorkable getMachine() { return metaTileEntity.get(); } diff --git a/src/main/java/gregtechmod/common/recipe/SimpleRecipeFactory.java b/src/main/java/gregtechmod/common/recipe/SimpleRecipeFactory.java index 1a8df33..4a5e4b6 100644 --- a/src/main/java/gregtechmod/common/recipe/SimpleRecipeFactory.java +++ b/src/main/java/gregtechmod/common/recipe/SimpleRecipeFactory.java @@ -63,7 +63,7 @@ public class SimpleRecipeFactory extends RecipeFactory { @Override public SimpleRecipeFactory chanced(ItemStack stack, int chance) { - super.chanced(new ChancedStack(stack, chance)); + super.chanced(new ChancedStack(stack.copy(), chance)); return this; } diff --git a/src/main/java/gregtechmod/mistaqur/nei/GT_RecipeHandler.java b/src/main/java/gregtechmod/mistaqur/nei/GT_RecipeHandler.java index 995e4dc..f2f41ed 100644 --- a/src/main/java/gregtechmod/mistaqur/nei/GT_RecipeHandler.java +++ b/src/main/java/gregtechmod/mistaqur/nei/GT_RecipeHandler.java @@ -64,7 +64,7 @@ public abstract class GT_RecipeHandler extends TemplateRecipeHandler { } int offset = 0; - List outputs = recipe.getAllOutputs(); + List outputs = recipe.getOutputs(); for (offset = 0; offset < outputs.size(); offset++) { Pair offsets = getOutputAligment(offset); products.add(new PositionedStack(outputs.get(offset), offsets.getKey(), offsets.getValue()));