Skip to content

Commit

Permalink
Fix two conditions where PAs could get stuck (#176)
Browse files Browse the repository at this point in the history
* Fixes PA not starting after inserting machines in the hatch if it already contains the necessary ingredients.

* Fixes checking for machine changes updating the cached fluids, resulting in fluid-only changes to the PA being ignored, resulting in a stall.
  • Loading branch information
PrototypeTrousers authored Aug 20, 2022
1 parent 433f36c commit 39f8f29
Showing 1 changed file with 38 additions and 74 deletions.
112 changes: 38 additions & 74 deletions src/main/java/gregicadditions/machines/TileEntityProcessingArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,7 @@ protected static class ProcessingArrayWorkable extends MultiblockRecipeLogic {
int machineTier;
int numberOfMachines = 0;
int numberOfOperations = 0;
ItemStack machineItemStack = null;
ItemStack oldMachineStack = null;
ItemStack machineItemStack = ItemStack.EMPTY;
RecipeMap<?> recipeMap = null;
// Fields used for distinct mode
protected int lastRecipeIndex = 0;
Expand All @@ -196,9 +195,6 @@ protected Recipe findRecipe(long maxVoltage,
IItemHandlerModifiable inputs,
IMultipleTankHandler fluidInputs) {

//Update the machine stack and recipe map
findMachineStack();

// Avoid crashing during load, when GTCE initializes its multiblock previews
if(machineItemStack.isEmpty() || this.recipeMap == null) {
return null;
Expand Down Expand Up @@ -400,6 +396,12 @@ protected void multiplyInputsAndOutputs(List<CountableIngredient> newRecipeInput

public void invalidate() {
this.lastRecipeIndex = 0;
this.machineItemStack = ItemStack.EMPTY;
this.recipeMap = null;
this.machineVoltage = 0L;
this.machineTier = 0;
this.numberOfMachines = 0;
this.numberOfOperations = 0;
}

//Finds the Recipe Map of the passed Machine Stack and checks if it is a valid Recipe Map
Expand Down Expand Up @@ -469,25 +471,30 @@ protected static boolean findMachineInBlacklist(String unlocalizedName) {
}

public void findMachineStack() {

RecipeMapMultiblockController controller = (RecipeMapMultiblockController) this.metaTileEntity;

//The Processing Array is limited to 1 Machine Interface per multiblock, and only has 1 slot
ItemStack machine = controller.getAbilities(GACapabilities.PA_MACHINE_CONTAINER).get(0).getStackInSlot(0);
ItemStack currentMachine = controller.getAbilities(GACapabilities.PA_MACHINE_CONTAINER).get(0).getStackInSlot(0);

RecipeMap<?> rmap = findRecipeMapAndCheckValid(machine);
if (!ItemStack.areItemStacksEqual(this.machineItemStack, currentMachine)) {
RecipeMap<?> rmap = findRecipeMapAndCheckValid(currentMachine);

MetaTileEntity mte = MachineItemBlock.getMetaTileEntity(machine);
MetaTileEntity mte = MachineItemBlock.getMetaTileEntity(currentMachine);

//Find the voltage tier of the machine.
this.machineTier = mte instanceof ITieredMetaTileEntity
? ((ITieredMetaTileEntity) mte).getTier()
: 0;
//Find the voltage tier of the machine.
this.machineTier = mte instanceof ITieredMetaTileEntity
? ((ITieredMetaTileEntity) mte).getTier()
: 0;

this.machineVoltage = GTValues.V[this.machineTier];
this.machineVoltage = GTValues.V[this.machineTier];

this.machineItemStack = machine;
this.recipeMap = rmap;
// invalidate the previous recipe
previousRecipe = null;

//we make a copy here to account for changes in the amount of machines in the hatch
this.machineItemStack = currentMachine.copy();
this.recipeMap = rmap;
}
}

/**
Expand Down Expand Up @@ -571,73 +578,50 @@ protected boolean haveEnoughPowerToProceed(Recipe recipe, long voltageTier, int
return enoughPower;
}

/**
* Will check if the previous machine stack and the current machine stack are different
* @param newMachineStack - The current machine stack
* @return - true if the machine stacks are not equal, false if they are equal
*/
protected boolean didMachinesChange(ItemStack newMachineStack) {
if(newMachineStack == null || this.oldMachineStack == null)
return newMachineStack != this.oldMachineStack;

return !ItemStack.areItemStacksEqual(this.oldMachineStack, newMachineStack);
}

@Override
protected void trySearchNewRecipe() {
//Update the stored machine stack and recipe map variables
findMachineStack();
if (machineItemStack.isEmpty()) return;
if(metaTileEntity instanceof TileEntityProcessingArray &&
getInputInventory().getSlots() > 0 &&
((TileEntityProcessingArray) metaTileEntity).isDistinctInputBusMode) {
trySearchNewRecipeDistinct();
}
else {
} else {
trySearchNewRecipeCombined();
}
}

private void trySearchNewRecipeCombined() {
long maxVoltage = getMaxVoltage();
Recipe currentRecipe;
Recipe currentRecipe = null;
Recipe multipliedRecipe = null;
IItemHandlerModifiable importInventory = getInputInventory();
IMultipleTankHandler importFluids = getInputTank();

//Update the stored machine stack and recipe map variables
findMachineStack();

boolean dirty = checkRecipeInputsDirty(importInventory, importFluids);
if(dirty || forceRecipeRecheck) {
//Check if the machine that the PA is operating on has changed
if(didMachinesChange(machineItemStack)) {
previousRecipe = null;
oldMachineStack = null;
}
}

if(previousRecipe != null &&
previousRecipe.matches(false, importInventory, importFluids)) {
if (previousRecipe != null &&
previousRecipe.matches(false, importInventory, importFluids)) {
currentRecipe = previousRecipe;
}
else {

boolean dirty = checkRecipeInputsDirty(importInventory, importFluids);
if (dirty || forceRecipeRecheck) {
this.forceRecipeRecheck = false;
//If the previous recipe was null, or does not match the current recipe, search for a new recipe
currentRecipe = findRecipe(maxVoltage, importInventory, importFluids);
oldMachineStack = null;

//Update the previous recipe
if(currentRecipe != null) {
if (currentRecipe != null) {
this.previousRecipe = currentRecipe;
}

this.forceRecipeRecheck = false;
}

if(currentRecipe != null) {
if (currentRecipe != null) {
multipliedRecipe = multiplyRecipe(importInventory, importFluids, currentRecipe, machineItemStack, recipeMap);
}

//Attempts to run the current recipe, if it is not null
if(multipliedRecipe != null && setupAndConsumeRecipeInputs(multipliedRecipe)) {
oldMachineStack = machineItemStack;
if (multipliedRecipe != null && setupAndConsumeRecipeInputs(multipliedRecipe)) {
setupRecipe(multipliedRecipe);
}
}
Expand All @@ -651,41 +635,22 @@ private void trySearchNewRecipeDistinct() {
Recipe multipliedRecipe = null;
List<IItemHandlerModifiable> importInventory = getInputBuses();
IMultipleTankHandler importFluids = getInputTank();
RecipeMapMultiblockController controller = (RecipeMapMultiblockController) this.metaTileEntity;
IItemHandlerModifiable machineBus = controller.getAbilities(GACapabilities.PA_MACHINE_CONTAINER).get(0);

//Update the stored machine stack and recipe map variables
findMachineStack();

// Cache the old fluid inputs
final FluidStack[] cachedLastFluids =
(lastFluidInputs == null) ? null : Arrays.copyOf(this.lastFluidInputs, lastFluidInputs.length);

//Check to see if the machine stack has changed first
//TODO Could this machine bus specific check be used in the combined code?
boolean machineDirty = checkRecipeInputsDirty(machineBus, importFluids);
if(machineDirty || forceRecipeRecheck) {
//Check if the machine that the PA is operating on has changed
//TODO Is this check needed if machineDirty is true?
if(didMachinesChange(machineItemStack)) {
previousRecipe = null;
oldMachineStack = null;
}
}

//Check if the previous recipe is null, to avoid having to iterate the distinct inputs
if(previousRecipe != null && previousRecipe.matches(false, importInventory.get(lastRecipeIndex), importFluids)) {
currentRecipe = previousRecipe;
multipliedRecipe = multiplyRecipe(importInventory.get(lastRecipeIndex), importFluids, currentRecipe, machineItemStack, recipeMap);
if(setupAndConsumeRecipeInputs(multipliedRecipe, lastRecipeIndex)) {
setupRecipe(multipliedRecipe);
oldMachineStack = machineItemStack;
return;
}
}

//If the machine stack changed, or the previous recipe is null, check for a new recipe
oldMachineStack = null;
//If the previous recipe is null, check for a new recipe
for (int i = 0; i < importInventory.size(); i++) {
IItemHandlerModifiable bus = importInventory.get(i);
// Restore the cached fluid inputs before each per-bus dirty check to prevent false negatives
Expand All @@ -706,7 +671,6 @@ private void trySearchNewRecipeDistinct() {
if(multipliedRecipe != null && setupAndConsumeRecipeInputs(multipliedRecipe, i)) {
lastRecipeIndex = i;
setupRecipe(multipliedRecipe);
oldMachineStack = machineItemStack;
break;
}
}
Expand Down

0 comments on commit 39f8f29

Please sign in to comment.