Change the way the rolling machine balances itemstacks

This commit is contained in:
modmuss50 2018-04-07 20:22:42 +01:00
parent 415d303245
commit 0bf602f89e
No known key found for this signature in database
GPG key ID: 773D17BE8BF49C82

View file

@ -50,6 +50,7 @@ import techreborn.lib.ModInfo;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
//TODO add tick and power bars.
@ -76,6 +77,7 @@ public class TileRollingMachine extends TilePowerAcceptor
public IRecipe currentRecipe;
private int outputSlot;
public boolean locked = false;
public int balanceSlot = 0;
public TileRollingMachine() {
super();
@ -115,6 +117,12 @@ public class TileRollingMachine extends TilePowerAcceptor
InventoryCrafting craftMatrix = getCraftingMatrix();
this.currentRecipe = RollingMachineRecipe.instance.findMatchingRecipe(craftMatrix, this.world);
if (this.currentRecipe != null) {
if (world.getTotalWorldTime() % 2 == 0) {
Optional<InventoryCrafting> balanceResult = balanceRecipe(craftMatrix);
if (balanceResult.isPresent()) {
craftMatrix = balanceResult.get();
}
}
this.currentRecipeOutput = currentRecipe.getCraftingResult(craftMatrix);
} else {
this.currentRecipeOutput = ItemStack.EMPTY;
@ -164,6 +172,68 @@ public class TileRollingMachine extends TilePowerAcceptor
}
}
public Optional<InventoryCrafting> balanceRecipe(InventoryCrafting craftCache) {
if (currentRecipe == null) {
return Optional.empty();
}
if (world.isRemote) {
return Optional.empty();
}
if (!locked) {
return Optional.empty();
}
if (craftCache.isEmpty()) {
return Optional.empty();
}
balanceSlot++;
if (balanceSlot > craftCache.getSizeInventory()) {
balanceSlot = 0;
}
//Find the best slot for each item in a recipe, and move it if needed
ItemStack sourceStack = inventory.getStackInSlot(balanceSlot);
if (sourceStack.isEmpty()) {
return Optional.empty();
}
List<Integer> possibleSlots = new ArrayList<>();
for (int s = 0; s < currentRecipe.getIngredients().size(); s++) {
ItemStack stackInSlot = inventory.getStackInSlot(s);
Ingredient ingredient = currentRecipe.getIngredients().get(s);
if (ingredient != Ingredient.EMPTY && ingredient.apply(sourceStack)) {
if (stackInSlot.isEmpty()) {
possibleSlots.add(s);
} else if (stackInSlot.getItem() == sourceStack.getItem() && stackInSlot.getItemDamage() == sourceStack.getItemDamage()) {
possibleSlots.add(s);
}
}
}
//Slot, count
Pair<Integer, Integer> bestSlot = null;
for (Integer slot : possibleSlots) {
ItemStack slotStack = inventory.getStackInSlot(slot);
if (slotStack.isEmpty()) {
bestSlot = Pair.of(slot, 0);
}
if (bestSlot == null) {
bestSlot = Pair.of(slot, slotStack.getCount());
} else if (bestSlot.getRight() >= slotStack.getCount()) {
bestSlot = Pair.of(slot, slotStack.getCount());
}
}
if (bestSlot == null
|| bestSlot.getLeft() == balanceSlot
|| bestSlot.getRight() == sourceStack.getCount()
|| inventory.getStackInSlot(bestSlot.getLeft()).isEmpty()
|| !ItemUtils.isItemEqual(sourceStack, inventory.getStackInSlot(bestSlot.getLeft()), true, true, true)) {
return Optional.empty();
}
sourceStack.shrink(1);
inventory.getStackInSlot(bestSlot.getLeft()).grow(1);
inventory.hasChanged = true;
return Optional.of(getCraftingMatrix());
}
private InventoryCrafting getCraftingMatrix() {
if (craftCache == null) {
craftCache = new InventoryCrafting(new RollingTileContainer(), 3, 3);
@ -279,65 +349,6 @@ public class TileRollingMachine extends TilePowerAcceptor
return 0;
}
public boolean isItemValidForRecipeSlot(IRecipe recipe, ItemStack stack, int slotID) {
if (recipe == null) {
return true;
}
int bestSlot = findBestSlotForStack(recipe, stack);
if (bestSlot != -1) {
return bestSlot == slotID;
}
return true;
}
@Override
public boolean isItemValidForSlot(int index, ItemStack stack) {
if(locked && currentRecipe != null){
int bestSlot = findBestSlotForStack(currentRecipe, stack);
if (bestSlot != -1) {
return index == bestSlot;
}
}
return super.isItemValidForSlot(index, stack);
}
public int findBestSlotForStack(IRecipe recipe, ItemStack stack) {
if (recipe == null) {
return -1;
}
List<Integer> possibleSlots = new ArrayList<>();
for (int i = 0; i < recipe.getIngredients().size(); i++) {
ItemStack stackInSlot = inventory.getStackInSlot(i);
Ingredient ingredient = recipe.getIngredients().get(i);
if (ingredient != Ingredient.EMPTY && ingredient.apply(stack)) {
if (stackInSlot.isEmpty()) {
possibleSlots.add(i);
} else if (stackInSlot.getItem() == stack.getItem() && stackInSlot.getItemDamage() == stack.getItemDamage()) {
if (stackInSlot.getMaxStackSize() >= stackInSlot.getCount() + stack.getCount()) {
possibleSlots.add(i);
}
}
}
}
//Slot, count
Pair<Integer, Integer> smallestCount = null;
for (Integer slot : possibleSlots) {
ItemStack slotStack = inventory.getStackInSlot(slot);
if (slotStack.isEmpty()) {
return slot;
}
if (smallestCount == null) {
smallestCount = Pair.of(slot, slotStack.getCount());
} else if (smallestCount.getRight() >= slotStack.getCount()) {
smallestCount = Pair.of(slot, slotStack.getCount());
}
}
if (smallestCount != null) {
return smallestCount.getLeft();
}
return -1;
}
private static class RollingTileContainer extends Container {
@Override