Nearly finished new recipe system

- Added wiremill to working condition
- Fixed bugs in new recipe logic
- Optimized a bit recipe searching and caching
This commit is contained in:
TheDarkDnKTv 2021-01-31 09:53:14 +02:00
parent e26d0f5ec8
commit 6612f3c058
7 changed files with 138 additions and 54 deletions

View file

@ -1,4 +1,4 @@
### A port of GregTech 4 to Minecraft 1.7.10
# A port of GregTech 4 to Minecraft 1.7.10
Our website [click](https://nukepowered.info)

View file

@ -97,7 +97,7 @@ public abstract class GT_MetaTileEntity_BasicMachine extends MetaTileEntity {
bHasBeenUpdated = true;
getBaseMetaTileEntity().setFrontFacing(getBaseMetaTileEntity().getBackFacing());
}
recipeLogic.update();
// if (mMaxProgresstime > 0) {
// if (mProgresstime < 0 || getBaseMetaTileEntity().decreaseStoredEnergyUnits(mEUt*(int)Math.pow(4, getBaseMetaTileEntity().getOverclockerUpgradeCount()), false)) {
@ -135,7 +135,7 @@ public abstract class GT_MetaTileEntity_BasicMachine extends MetaTileEntity {
}
}
if (mInventory[3] == null && mInventory[4] == null) bOutputBlocked = false;
if (mInventory[3] == null && mInventory[4] == null) bOutputBlocked = false; // FIXME output blocked wtf
// if (getBaseMetaTileEntity().isAllowedToWork()) {
// if (mMaxProgresstime <= 0 && (tSucceeded || getBaseMetaTileEntity().hasInventoryBeenModified() || getBaseMetaTileEntity().getTimer()%600 == 0 || getBaseMetaTileEntity().hasWorkJustBeenEnabled()) && getBaseMetaTileEntity().isUniversalEnergyStored(getMinimumStoredEU()-100)) {
@ -195,11 +195,11 @@ public abstract class GT_MetaTileEntity_BasicMachine extends MetaTileEntity {
}
public int[] getInputSlots() {
return new int[] {1};
return new int[] {1, 2};
}
public int[] getOutputSlots() {
return new int[] {2};
return new int[] {3, 4};
}
/** Fallback to the regular Machine Outside Texture */

View file

@ -55,16 +55,22 @@ public class Recipe {
public ItemStack[][] getRepresentativeInputs() {
ItemStack[][] copy = new ItemStack[mInputs.length][];
System.arraycopy(mInputs, 0, copy, 0, mInputs.length);
for (int i = 0; i < mInputs.length; i++) {
ItemStack[] copy1 = new ItemStack[mInputs[i].length];
for (int j = 0; j < mInputs[i].length; j++) {
copy1[j] = mInputs[i][j].copy();
}
copy[i] = copy1;
}
return copy;
}
public ItemStack[] getOutputs() {
ItemStack[] copy = Arrays.stream(mOutputs).filter(e -> e != null).map(stack -> stack.copy()).toArray(i -> new ItemStack[i]);
// ItemStack[] copy = new ItemStack[mOutputs.length];
// System.arraycopy(mOutputs, 0, copy, 0, copy.length);
return copy;
return Arrays.stream(mOutputs)
.filter(e -> e != null)
.map(stack -> stack.copy())
.toArray(i -> new ItemStack[i]);
}
public boolean match(ItemStack...machineInputs) {
@ -94,9 +100,9 @@ public class Recipe {
for (int slot : inputSlots) { // Iterating machine's input
ItemStack slotStack = tile.getStackInSlot(slot);
if (slotStack != null) {
if (slotStack != null && isItemStackMatch(slotStack, validItem)) {
if (isItemStackMatch(slotStack, validItem)) {
decreaseMap.put(slot, validItem);
} else return false;
}
} else continue;
}
}
@ -110,6 +116,8 @@ public class Recipe {
}
private boolean isItemStackMatch(ItemStack invStack, ItemStack recipeStack) {
if (invStack == null || recipeStack == null)
return false;
return invStack.getItem() == recipeStack.getItem() &&
invStack.getItemDamage() == recipeStack.getItemDamage() &&
(invStack.hasTagCompound() ? invStack.getTagCompound().equals(recipeStack.getTagCompound()) : true) &&
@ -117,19 +125,21 @@ public class Recipe {
}
private final void addToMap(HashMap<Integer, List<Recipe>> aMap) {
// for (ItemStack tStack : mInputs) if (tStack != null) {
// Integer tIntStack = GT_Utility.stackToInt(tStack);
// List<GT_Recipe> tList = aMap.get(tIntStack);
// if (tList == null) aMap.put(tIntStack, tList = new ArrayList<GT_Recipe>(2));
// tList.add(this);
// }
for (ItemStack[] tStacks : mInputs) {
for (ItemStack tStack : tStacks) if (tStack != null) {
Integer tIntStack = GT_Utility.stackToInt(tStack);
List<Recipe> tList = aMap.get(tIntStack);
if (tList == null) aMap.put(tIntStack, tList = new ArrayList<Recipe>(2));
tList.add(this);
}
}
}
private final void addToLists(List<Recipe> aList) {
// HashMap<Integer, List<GT_Recipe>> aMap = sRecipeMappings.get(aList);
// if (aMap == null) sRecipeMappings.put(aList, aMap = new HashMap<Integer, List<GT_Recipe>>());
// aList.add(this);
// addToMap(aMap);
HashMap<Integer, List<Recipe>> aMap = sRecipeMappings.get(aList);
if (aMap == null) sRecipeMappings.put(aList, aMap = new HashMap<Integer, List<Recipe>>());
aList.add(this);
addToMap(aMap);
}
public static Recipe findEqualRecipe(boolean aShapeless, boolean aNotUnificated, List<Recipe> aList, ItemStack...aInputs) {
@ -178,8 +188,8 @@ public class Recipe {
}
public static boolean addRecipe(List<Recipe> aList, boolean aShapeless, Recipe aRecipe) {
// if (findEqualRecipe(aShapeless, false, aList, aRecipe.mInputs) != null) return false;
// aRecipe.addToLists(aList);
if (aList.contains(aRecipe)) return false;
aRecipe.addToLists(aList);
return true;
}
@ -480,4 +490,31 @@ public class Recipe {
addToLists(sChemicalRecipes);
}
}
@Override
public int hashCode() {
int res = 0;
for (ItemStack[] stacks : mInputs)
res += GT_Utility.stackArrayToInt(stacks);
return (mDuration * mEUt * mStartEU) + res + GT_Utility.stackArrayToInt(mOutputs);
}
@Override
public boolean equals(Object o) {
if (o instanceof Recipe) {
Recipe r = (Recipe) o;
return r == this ||
(r.mDuration == this.mDuration &&
r.mEUt == this.mEUt &&
GT_Utility.doesStackArraysSame(r.mOutputs, this.mOutputs)) &&
GT_Utility.doesRecipeInputsSame(r.mInputs, this.mInputs);
}
return false;
}
@Override
public String toString() {
return "Recipe[inputs=" + mInputs.length + ",outputs=" + mOutputs.length + ",EUt=" + mEUt + ",duration=" + mDuration + ",startEU=" + mStartEU + ",enabled=" + mEnabled + "]";
}
}

View file

@ -27,6 +27,7 @@ public class RecipeLogic {
private int overclockersCount;
private Recipe previousRecipe;
private boolean needRecipeRecheck;
public RecipeLogic(List<Recipe> recipeMap, GT_MetaTileEntity_BasicMachine machine) {
@ -36,17 +37,29 @@ public class RecipeLogic {
EUt = 0;
overclockersCount = 0;
metaTileEntity = new WeakReference<>(machine);
needRecipeRecheck = true;
}
public void update() {
overclockersCount = getMachine().getBaseMetaTileEntity().getOverclockerUpgradeCount();
moveItems();
if (getMachine().getBaseMetaTileEntity().isAllowedToWork()) {
if (getMachine().getBaseMetaTileEntity().hasInventoryBeenModified() || getMachine().getBaseMetaTileEntity().hasWorkJustBeenEnabled())
needRecipeRecheck = true;
if (progressTime > 0) {
updateRecipeProgress();
}
if (progressTime == 0) {
trySerachRecipe();
if (progressTime == 0 && needRecipeRecheck) {
if (isInputNonEmpty()) {
trySerachRecipe();
} else {
previousRecipe = null;
needRecipeRecheck = false;
getMachine().getBaseMetaTileEntity().setActive(false);
}
}
}
}
@ -67,13 +80,18 @@ public class RecipeLogic {
}
} else {
getMachine().getBaseMetaTileEntity().setActive(false);
if (!getMachine().bStuttering) {
getMachine().stutterProcess();
if (getMachine().useStandardStutterSound()) getMachine().sendSound((byte)8);
getMachine().bStuttering = true;
}
}
}
protected void trySerachRecipe() {
if (getMachine().allowToCheckRecipe()) {
if (previousRecipe != null) {
if (previousRecipe.match(true, getMachine().getBaseMetaTileEntity(), getMachineInputs())) { // TODO add I/O item handlers to MTE
if (previousRecipe.match(false, getMachine().getBaseMetaTileEntity(), getMachineInputs())) { // TODO add I/O item handlers to MTE
startRecipe(previousRecipe);
} else {
previousRecipe = null;
@ -83,11 +101,13 @@ public class RecipeLogic {
// find new recipe
Recipe resRec = recipeHandler != null ? recipeHandler.get() :
recipeMap.stream()
.filter(rec -> rec.match(true, getMachine().getBaseMetaTileEntity(), getMachineInputs()))
.filter(rec -> rec.match(false, getMachine().getBaseMetaTileEntity(), getMachineInputs()))
.findFirst().orElse(null);
if (resRec != null)
startRecipe(resRec);
}
needRecipeRecheck = false;
}
}
@ -106,12 +126,15 @@ public class RecipeLogic {
}
protected void startRecipe(Recipe recipe) {
previousRecipe = recipe;
maxProgressTime = recipe.mDuration;
progressTime = 1;
EUt = recipe.mEUt;
getMachine().getBaseMetaTileEntity().setActive(true);
getMachine().startProcess();
if (getMachine().spaceForOutput(recipe.getOutputs()[0], recipe.getOutputs().length > 1 ? recipe.getOutputs()[1] : null)) {
previousRecipe = recipe;
maxProgressTime = recipe.mDuration;
progressTime = 1;
EUt = recipe.mEUt;
recipe.match(true, getMachine().getBaseMetaTileEntity(), getMachineInputs());
getMachine().getBaseMetaTileEntity().setActive(true);
getMachine().startProcess();
}
}
protected void endRecipe(Recipe recipe) {
@ -128,9 +151,20 @@ public class RecipeLogic {
GT_Log.log.catching(new IllegalStateException("Found recipe with more items output machine has slots!"));
}
getMachine().bStuttering = false;
getMachine().endProcess();
}
private boolean isInputNonEmpty() {
for (int i : getMachineInputs()) {
ItemStack s = getMachine().getStackInSlot(i);
if (s != null && s.stackSize > 0) return true;
}
return false;
}
/**
* Specify machine input slots
*/

View file

@ -23,6 +23,7 @@ import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
@ -795,6 +796,34 @@ public class GT_Utility {
return Item.getIdFromItem(aStack.getItem()) | (Items.feather.getDamage(aStack) << 16);
}
public static int stackArrayToInt(ItemStack[] stacks) {
int result = 0;
for (ItemStack stack : stacks) result += stackToInt(stack);
return result;
}
public static boolean doesStackArraysSame(ItemStack[] stacks1, ItemStack[] stacks2) {
List<ItemStackKey> l1 = Arrays.stream(stacks1).map(stk -> ItemStackKey.from(stk)).collect(Collectors.toList());
List<ItemStackKey> l2 = Arrays.stream(stacks2).map(stk -> ItemStackKey.from(stk)).collect(Collectors.toList());
return l1.size() == l2.size() && l1.containsAll(l2);
}
public static boolean doesRecipeInputsSame(ItemStack[][] s1, ItemStack[][] s2) {
if (s1.length == s2.length) {
List<List<ItemStackKey>> l1 = Arrays.stream(s1)
.map(arr -> Arrays.stream(arr).map(stack -> ItemStackKey.from(stack)).sorted().collect(Collectors.toList()))
.sorted()
.collect(Collectors.toList());
List<List<ItemStackKey>> l2 = Arrays.stream(s2)
.map(arr -> Arrays.stream(arr).map(stack -> ItemStackKey.from(stack)).sorted().collect(Collectors.toList()))
.sorted()
.collect(Collectors.toList());
return l1.containsAll(l2);
}
return false;
}
public static int stackToWildcard(ItemStack aStack) {
if (isStackInvalid(aStack)) return 0;
return Item.getIdFromItem(aStack.getItem()) | (GregTech_API.ITEM_WILDCARD_DAMAGE << 16);

View file

@ -7,6 +7,7 @@ import gregtechmod.api.enums.OrePrefixes;
import gregtechmod.api.interfaces.IGT_RecipeAdder;
import gregtechmod.api.items.GT_Tool_Item;
import gregtechmod.api.recipe.Recipe;
import gregtechmod.api.recipe.RecipeMaps;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
@ -342,7 +343,7 @@ public class GT_RecipeAdder implements IGT_RecipeAdder {
if (!GregTech_API.sRecipeFile.get("forgehammer", aOutput1, true)) {
return false;
} else {
Recipe.addRecipe(Recipe.sHammerRecipes, true, aInput1, null, aOutput1, null, null, null, aDuration, aEUt, 0);
Recipe.addRecipe(RecipeMaps.sHammerRecipes, true, aInput1, null, aOutput1, null, null, null, aDuration, aEUt, 0);
return true;
}
} else {

View file

@ -6,7 +6,7 @@ import gregtechmod.api.interfaces.IGregTechTileEntity;
import gregtechmod.api.metatileentity.MetaTileEntity;
import gregtechmod.api.metatileentity.implementations.GT_MetaTileEntity_BasicMachine;
import gregtechmod.api.recipe.Recipe;
import gregtechmod.api.util.GT_Utility;
import net.minecraft.entity.player.EntityPlayer;
public class GT_MetaTileEntity_Wiremill extends GT_MetaTileEntity_BasicMachine {
@ -26,23 +26,6 @@ public class GT_MetaTileEntity_Wiremill extends GT_MetaTileEntity_BasicMachine {
return new GT_MetaTileEntity_Wiremill(recipeLogic.recipeMap);
}
@Override
public void checkRecipe() {
GT_Utility.moveStackFromSlotAToSlotB(this.getBaseMetaTileEntity(), this.getBaseMetaTileEntity(), 1, 2, (byte) 64, (byte) 1, (byte) 64, (byte) 1);
GT_Utility.moveStackFromSlotAToSlotB(this.getBaseMetaTileEntity(), this.getBaseMetaTileEntity(), 3, 4, (byte) 64, (byte) 1, (byte) 64, (byte) 1);
if (super.mInventory[2] != null && super.mInventory[2].stackSize > 0) {
Recipe tRecipe = Recipe.findEqualRecipe(true, false, Recipe.sWiremillRecipes, mInventory[2]);
if (tRecipe != null && this.spaceForOutput(tRecipe.getOutput(0), null) && tRecipe.isRecipeInputEqual(true, true, mInventory[2])) {
super.mEUt = tRecipe.mEUt;
super.mMaxProgresstime = tRecipe.mDuration;
super.mOutputItem1 = tRecipe.getOutput(0);
return;
}
}
mOutputItem1 = null;
}
@Override
public int getTopFacingInactive() {
return 235;