Fix #652 Bottler liquid dupe bug on server

This commit is contained in:
mezz committed 2015-05-09 17:39:01 -07:00
1 parent 7b476b39c2
commit d5296fbc60
2 files changed
+51 -111

No files matched your search

@@ -15,7 +15,6 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Stack;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
@@ -23,7 +22,6 @@ import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
@@ -59,9 +57,9 @@ import buildcraft.api.statements.ITriggerExternal;
public class MachineBottler extends TilePowered implements ISidedInventory, ILiquidTankContainer {
/* CONSTANTS */
public static final short SLOT_RESOURCE = 0;
public static final short SLOT_PRODUCT = 1;
public static final short SLOT_CAN = 2;
public static final short SLOT_INPUT_EMPTY_CAN = 0;
public static final short SLOT_OUTPUT = 1;
public static final short SLOT_INPUT_FULL_CAN = 2;
public static final short CYCLES_FILLING_DEFAULT = 5;
@@ -94,7 +92,7 @@ public class MachineBottler extends TilePowered implements ISidedInventory, ILiq
*/
public static Recipe findMatchingRecipe(FluidStack res, ItemStack empty) {
// We need both ingredients
if (res == null || empty == null) {
if (res == null || empty == null || !FluidHelper.isEmptyContainer(empty)) {
return null;
}
@@ -105,13 +103,11 @@ public class MachineBottler extends TilePowered implements ISidedInventory, ILiq
}
// No recipe matched. See if the liquid dictionary has anything.
if (FluidHelper.isEmptyContainer(empty)) {
ItemStack filled = FluidHelper.getFilledContainer(res, empty);
if (filled != null) {
Recipe recipe = new Recipe(CYCLES_FILLING_DEFAULT, res, empty, filled);
recipes.add(recipe);
return recipe;
}
ItemStack filled = FluidHelper.getFilledContainer(res, empty);
if (filled != null) {
Recipe recipe = new Recipe(CYCLES_FILLING_DEFAULT, res, empty, filled);
recipes.add(recipe);
return recipe;
}
return null;
@@ -142,33 +138,14 @@ public class MachineBottler extends TilePowered implements ISidedInventory, ILiq
public final StandardTank resourceTank;
private final TankManager tankManager;
private boolean productPending = false;
private Recipe currentRecipe;
private final Stack<ItemStack> pendingProducts = new Stack<ItemStack>();
private int fillingTime;
private int fillingTotalTime;
public MachineBottler() {
super(1100, 50, 4000);
setInternalInventory(new TileInventoryAdapter(this, 3, "Items") {
@Override
public boolean canSlotAccept(int slotIndex, ItemStack itemStack) {
if (slotIndex == SLOT_RESOURCE) {
return FluidContainerRegistry.isEmptyContainer(itemStack);
} else if (slotIndex == SLOT_CAN) {
FluidStack fluidStack = FluidHelper.getFluidStackInContainer(itemStack);
return RecipeManager.isInput(fluidStack);
}
return false;
}
@Override
public boolean canExtractItem(int slotIndex, ItemStack itemstack, int side) {
return slotIndex == SLOT_PRODUCT;
}
});
setInternalInventory(new BottlerInventoryAdapter(this));
setHints(Config.hints.get("bottler"));
resourceTank = new StandardTank(Defaults.PROCESSOR_TANK_CAPACITY);
@@ -187,21 +164,8 @@ public class MachineBottler extends TilePowered implements ISidedInventory, ILiq
nbttagcompound.setInteger("FillingTime", fillingTime);
nbttagcompound.setInteger("FillingTotalTime", fillingTotalTime);
nbttagcompound.setBoolean("ProductPending", productPending);
tankManager.writeTanksToNBT(nbttagcompound);
NBTTagList nbttaglist = new NBTTagList();
ItemStack[] offspring = pendingProducts.toArray(new ItemStack[pendingProducts.size()]);
for (int i = 0; i < offspring.length; i++) {
if (offspring[i] != null) {
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
nbttagcompound1.setByte("Slot", (byte) i);
offspring[i].writeToNBT(nbttagcompound1);
nbttaglist.appendTag(nbttagcompound1);
}
}
nbttagcompound.setTag("PendingProducts", nbttaglist);
}
@Override
@@ -210,16 +174,9 @@ public class MachineBottler extends TilePowered implements ISidedInventory, ILiq
fillingTime = nbttagcompound.getInteger("FillingTime");
fillingTotalTime = nbttagcompound.getInteger("FillingTotalTime");
productPending = nbttagcompound.getBoolean("ProductPending");
tankManager.readTanksFromNBT(nbttagcompound);
NBTTagList nbttaglist = nbttagcompound.getTagList("PendingProducts", 10);
for (int i = 0; i < nbttaglist.tagCount(); i++) {
NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i);
pendingProducts.add(ItemStack.loadItemStackFromNBT(nbttagcompound1));
}
checkRecipe();
}
@@ -229,75 +186,56 @@ public class MachineBottler extends TilePowered implements ISidedInventory, ILiq
return;
}
IInventoryAdapter inventory = getInternalInventory();
// Check if we have suitable items waiting in the item slot
if (inventory.getStackInSlot(SLOT_CAN) != null) {
FluidHelper.drainContainers(tankManager, inventory, SLOT_CAN);
if (getStackInSlot(SLOT_INPUT_FULL_CAN) != null) {
FluidHelper.drainContainers(tankManager, this, SLOT_INPUT_FULL_CAN);
}
checkRecipe();
if (getErrorState() == EnumErrorCode.NORECIPE && currentRecipe != null) {
setErrorState(EnumErrorCode.OK);
}
}
@Override
public boolean workCycle() {
checkRecipe();
// If we add pending products, we skip to the next work cycle.
if (tryAddPending()) {
return false;
}
if (!pendingProducts.isEmpty()) {
return false;
}
// Continue work if nothing needs to be added
if (fillingTime <= 0) {
return false;
}
if (currentRecipe == null) {
setErrorState(EnumErrorCode.NORECIPE);
return false;
}
if (!InvTools.tryAddStack(this, currentRecipe.bottled, SLOT_OUTPUT, 1, true, false)) {
setErrorState(EnumErrorCode.NOSPACE);
return false;
}
fillingTime--;
// Still not done, return
if (fillingTime > 0) {
setErrorState(EnumErrorCode.OK);
return true;
}
// We are done, add products to queue and remove resources
pendingProducts.push(currentRecipe.bottled.copy());
FluidHelper.fillContainers(tankManager, this, SLOT_INPUT_EMPTY_CAN, SLOT_OUTPUT, currentRecipe.input.getFluid());
IInventoryAdapter inventory = getInternalInventory();
inventory.decrStackSize(SLOT_RESOURCE, 1);
resourceTank.drain(currentRecipe.input.amount, true);
checkRecipe();
resetRecipe();
while (tryAddPending()) {
;
}
return true;
}
public void checkRecipe() {
IInventoryAdapter inventory = getInternalInventory();
Recipe sameRec = RecipeManager.findMatchingRecipe(resourceTank.getFluid(), inventory.getStackInSlot(SLOT_RESOURCE));
ItemStack emptyCan = getStackInSlot(SLOT_INPUT_EMPTY_CAN);
Recipe recipe = RecipeManager.findMatchingRecipe(resourceTank.getFluid(), emptyCan);
if (sameRec == null) {
if (recipe == null) {
setErrorState(EnumErrorCode.NORECIPE);
} else {
setErrorState(EnumErrorCode.OK);
}
if (currentRecipe != sameRec) {
currentRecipe = sameRec;
if (currentRecipe != recipe) {
currentRecipe = recipe;
resetRecipe();
}
}
@@ -313,25 +251,6 @@ public class MachineBottler extends TilePowered implements ISidedInventory, ILiq
fillingTotalTime = currentRecipe.cyclesPerUnit;
}
private boolean tryAddPending() {
if (pendingProducts.isEmpty()) {
return false;
}
ItemStack next = pendingProducts.peek();
if (addProduct(next, true)) {
pendingProducts.pop();
return true;
}
setErrorState(EnumErrorCode.NOSPACE);
return false;
}
private boolean addProduct(ItemStack product, boolean all) {
return InvTools.tryAddStack(getInternalInventory(), product, SLOT_PRODUCT, 1, all);
}
// / STATE INFORMATION
@Override
public boolean isWorking() {
@@ -341,11 +260,11 @@ public class MachineBottler extends TilePowered implements ISidedInventory, ILiq
@Override
public boolean hasResourcesMin(float percentage) {
IInventoryAdapter inventory = getInternalInventory();
if (inventory.getStackInSlot(SLOT_RESOURCE) == null) {
if (inventory.getStackInSlot(SLOT_INPUT_EMPTY_CAN) == null) {
return false;
}
return ((float) inventory.getStackInSlot(SLOT_RESOURCE).stackSize / (float) inventory.getStackInSlot(SLOT_RESOURCE).getMaxStackSize()) > percentage;
return ((float) inventory.getStackInSlot(SLOT_INPUT_EMPTY_CAN).stackSize / (float) inventory.getStackInSlot(SLOT_INPUT_EMPTY_CAN).getMaxStackSize()) > percentage;
}
@Override
@@ -438,4 +357,25 @@ public class MachineBottler extends TilePowered implements ISidedInventory, ILiq
return res;
}
private static class BottlerInventoryAdapter extends TileInventoryAdapter {
public BottlerInventoryAdapter(MachineBottler machineBottler) {
super(machineBottler, 3, "Items");
}
@Override
public boolean canSlotAccept(int slotIndex, ItemStack itemStack) {
if (slotIndex == SLOT_INPUT_EMPTY_CAN) {
return FluidContainerRegistry.isEmptyContainer(itemStack);
} else if (slotIndex == SLOT_INPUT_FULL_CAN) {
FluidStack fluidStack = FluidHelper.getFluidStackInContainer(itemStack);
return RecipeManager.isInput(fluidStack);
}
return false;
}
@Override
public boolean canExtractItem(int slotIndex, ItemStack itemstack, int side) {
return slotIndex == SLOT_OUTPUT;
}
}
}
@@ -27,9 +27,9 @@ public class ContainerBottler extends ContainerLiquidTanks {
this.tile = tile;
this.addSlotToContainer(new SlotFiltered(tile, MachineBottler.SLOT_RESOURCE, 116, 19));
this.addSlotToContainer(new SlotOutput(tile, MachineBottler.SLOT_PRODUCT, 116, 55));
this.addSlotToContainer(new SlotFiltered(tile, MachineBottler.SLOT_CAN, 26, 38));
this.addSlotToContainer(new SlotFiltered(tile, MachineBottler.SLOT_INPUT_EMPTY_CAN, 116, 19));
this.addSlotToContainer(new SlotOutput(tile, MachineBottler.SLOT_OUTPUT, 116, 55));
this.addSlotToContainer(new SlotFiltered(tile, MachineBottler.SLOT_INPUT_FULL_CAN, 26, 38));
int var3;
for (var3 = 0; var3 < 3; ++var3) {