Added saving, liquid wooden pipes no longer allow liquid to go back into the tank, fixed so it works with iron liquid pipe

This commit is contained in:
Krapht 2012-07-21 23:55:45 +02:00
parent 500aab5925
commit 40d96a1602
2 changed files with 160 additions and 123 deletions

View file

@ -20,6 +20,8 @@ import net.minecraft.src.buildcraft.api.Orientations;
import net.minecraft.src.buildcraft.api.liquids.ITankContainer; import net.minecraft.src.buildcraft.api.liquids.ITankContainer;
import net.minecraft.src.buildcraft.api.tools.IToolWrench; import net.minecraft.src.buildcraft.api.tools.IToolWrench;
import net.minecraft.src.buildcraft.core.Utils; import net.minecraft.src.buildcraft.core.Utils;
import net.minecraft.src.buildcraft.transport.pipes.PipeLiquidsVoid;
import net.minecraft.src.buildcraft.transport.pipes.PipeLiquidsWood;
public class PipeLogicWood extends PipeLogic { public class PipeLogicWood extends PipeLogic {
@ -118,4 +120,13 @@ public class PipeLogicWood extends PipeLogic {
if (!APIProxy.isClient(worldObj)) if (!APIProxy.isClient(worldObj))
switchSourceIfNeeded(); switchSourceIfNeeded();
} }
@Override
public boolean outputOpen(Orientations to) {
if (this.container.pipe instanceof PipeLiquidsWood){
int meta = worldObj.getBlockMetadata(xCoord, yCoord, zCoord);
return meta != to.ordinal();
}
return super.outputOpen(to);
}
} }

View file

@ -10,7 +10,7 @@
package net.minecraft.src.buildcraft.transport; package net.minecraft.src.buildcraft.transport;
import net.minecraft.src.BuildCraftCore; import net.minecraft.src.BuildCraftCore;
import net.minecraft.src.EntityItem; import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.TileEntity; import net.minecraft.src.TileEntity;
import net.minecraft.src.buildcraft.api.APIProxy; import net.minecraft.src.buildcraft.api.APIProxy;
import net.minecraft.src.buildcraft.api.BuildCraftAPI; import net.minecraft.src.buildcraft.api.BuildCraftAPI;
@ -26,19 +26,6 @@ import net.minecraft.src.buildcraft.core.Utils;
public class PipeTransportLiquids extends PipeTransport implements ITankContainer { public class PipeTransportLiquids extends PipeTransport implements ITankContainer {
/**
* The amount of liquid contained by a pipe section. For simplicity, all
* pipe sections are assumed to be of the same volume.
*/
public static int LIQUID_IN_PIPE = BuildCraftAPI.BUCKET_VOLUME / 4;
public short travelDelay = 12;
public short flowRate = 20;
private final PipeSection[] internalTanks = new PipeSection[Orientations.values().length];
//public final short[] renderAmmount = new short[] {0,0,0,0,0,0,0};
public final LiquidStack[] renderCache = new LiquidStack[Orientations.values().length];
public class PipeSection extends LiquidTank { public class PipeSection extends LiquidTank {
@ -48,7 +35,6 @@ public class PipeTransportLiquids extends PipeTransport implements ITankContaine
private short[] incomming = new short[travelDelay]; private short[] incomming = new short[travelDelay];
//Tracks how much is currently available (has spent it's inbound delaytime) //Tracks how much is currently available (has spent it's inbound delaytime)
private short available;
public PipeSection() { public PipeSection() {
super(null, PipeTransportLiquids.LIQUID_IN_PIPE); super(null, PipeTransportLiquids.LIQUID_IN_PIPE);
@ -56,41 +42,33 @@ public class PipeTransportLiquids extends PipeTransport implements ITankContaine
@Override @Override
public int fill(LiquidStack resource, boolean doFill) { public int fill(LiquidStack resource, boolean doFill) {
int interalAmmount = this.getLiquid() != null ? this.getLiquid().amount : 0; int maxToFill = Math.min(resource.amount, flowRate - incomming[currentTime]);
int maxToFill = Math.min(resource.amount, Math.min(flowRate - incomming[currentTime], this.getCapacity() - interalAmmount ));
if (maxToFill <= 0) return 0; if (maxToFill <= 0) return 0;
LiquidStack stackToFill = resource.copy(); LiquidStack stackToFill = resource.copy();
stackToFill.amount = maxToFill; stackToFill.amount = maxToFill;
int filled = super.fill(stackToFill, doFill); int filled = super.fill(stackToFill, doFill);
if (doFill) { if (doFill) {
incomming[currentTime] += filled; incomming[currentTime] += filled;
} }
return filled; return filled;
} }
@Override @Override
public LiquidStack drain(int maxDrain, boolean doDrain) { public LiquidStack drain(int maxDrain, boolean doDrain) {
int maxToDrain = Math.min(maxDrain, Math.min(flowRate, available)); int maxToDrain = Math.min(maxDrain, Math.min(flowRate, getAvailable()));
if (maxToDrain < 0) return null; if (maxToDrain < 0) return null;
LiquidStack drained = super.drain(maxToDrain, doDrain); LiquidStack drained = super.drain(maxToDrain, doDrain);
if (drained == null) return null; if (drained == null) return null;
if (doDrain){
available -= drained.amount;
if (this.getLiquid() == null){
int xxxx = 1+1;
}
}
return drained; return drained;
} }
public void moveLiquids() { public void moveLiquids() {
//Processes the inbound liquid //Processes the inbound liquid
available += incomming[currentTime];
incomming[currentTime] = 0; incomming[currentTime] = 0;
} }
@ -100,38 +78,89 @@ public class PipeTransportLiquids extends PipeTransport implements ITankContaine
public void reset(){ public void reset(){
this.setLiquid(null); this.setLiquid(null);
available = 0;
incomming = new short[travelDelay]; incomming = new short[travelDelay];
} }
public int getAvailable(){ public int getAvailable(){
return available; int all = this.getLiquid() != null ? this.getLiquid().amount : 0;
for(short slot : incomming){
all -= slot;
}
return all;
}
public void readFromNBT(NBTTagCompound compoundTag) {
this.setCapacity(compoundTag.getInteger("capacity"));
for (int i = 0; i < travelDelay; ++i) {
incomming[i] = compoundTag.getShort("in[" + i + "]");
}
setLiquid(LiquidStack.loadLiquidStackFromNBT(compoundTag));
}
public void writeToNBT(NBTTagCompound subTag) {
subTag.setInteger("capacity", this.getCapacity());
for (int i = 0; i < travelDelay; ++i) {
incomming[i] = subTag.getShort("in[" + i + "]");
}
if (this.getLiquid() != null){
this.getLiquid().writeToNBT(subTag);
}
} }
} }
boolean[] isInput = new boolean[] { false, false, false, false, false, false, false }; public enum TransferState {
None, Input, Output
}
// Computed at each update
boolean isOutput[] = new boolean[] { false, false, false, false, false, false, false };
short bounceCount[] = new short[] { 0, 0, 0, 0, 0, 0 }; /**
* The amount of liquid contained by a pipe section. For simplicity, all
* pipe sections are assumed to be of the same volume.
*/
public static int LIQUID_IN_PIPE = BuildCraftAPI.BUCKET_VOLUME / 4;
public static short INPUT_TTL = 60; //100
public static short OUTPUT_TTL = 80; //80
public static short OUTPUT_COOLDOWN = 30; //30
public short travelDelay = 12;
public short flowRate = 20;
public final LiquidStack[] renderCache = new LiquidStack[Orientations.values().length];
private final PipeSection[] internalTanks = new PipeSection[Orientations.values().length];
private final TransferState[] transferState = new TransferState[Orientations.dirs().length];
private final short[] inputTTL = new short[] { 0, 0, 0, 0, 0, 0 };
private final short[] outputTTL = new short[] { OUTPUT_TTL, OUTPUT_TTL, OUTPUT_TTL, OUTPUT_TTL, OUTPUT_TTL, OUTPUT_TTL };
private final short[] outputCooldown = new short[] {0, 0, 0, 0, 0, 0 };
public PipeTransportLiquids() { public PipeTransportLiquids() {
for (Orientations direction : Orientations.values()) { for (Orientations direction : Orientations.values()) {
internalTanks[direction.ordinal()] = new PipeSection(); internalTanks[direction.ordinal()] = new PipeSection();
isInput[direction.ordinal()] = false; if (direction != Orientations.Unknown){
transferState[direction.ordinal()] = TransferState.None;
}
} }
} }
public boolean canReceiveLiquid(Orientations o) { public boolean canReceiveLiquid(Orientations o) {
TileEntity entity = container.getTile(o); TileEntity entity = container.getTile(o);
if (isInput[o.ordinal()])
return false;
if (!Utils.checkPipesConnections(container, entity)) if (!Utils.checkPipesConnections(container, entity))
return false; return false;
if (entity instanceof TileGenericPipe){
if (!((TileGenericPipe)entity).pipe.inputOpen(o.reverse())){
return false;
}
}
if (entity instanceof IPipeEntry || entity instanceof ITankContainer) if (entity instanceof IPipeEntry || entity instanceof ITankContainer)
return true; return true;
@ -158,7 +187,11 @@ public class PipeTransportLiquids extends PipeTransport implements ITankContaine
} }
if (renderCache[direction.ordinal()] != null){ if (renderCache[direction.ordinal()] != null){
renderCache[direction.ordinal()].amount = (short) ((renderCache[direction.ordinal()].amount * 39 + (liquid != null ? liquid.amount : 0)) / 40); int currentLiquid = liquid != null ? liquid.amount : 0;
renderCache[direction.ordinal()].amount = (short) Math.min(LIQUID_IN_PIPE, ((renderCache[direction.ordinal()].amount * 9 + currentLiquid) / 10));
if (renderCache[direction.ordinal()].amount == 0 && currentLiquid > 0){
renderCache[direction.ordinal()].amount = currentLiquid;
}
//Uncomment to disable the avaraging //Uncomment to disable the avaraging
//renderCache[direction.ordinal()].amount = (liquid != null ? liquid.amount : 0); //renderCache[direction.ordinal()].amount = (liquid != null ? liquid.amount : 0);
@ -174,47 +207,33 @@ public class PipeTransportLiquids extends PipeTransport implements ITankContaine
this.container.synchronizeIfDelay(1 * BuildCraftCore.updateFactor); this.container.synchronizeIfDelay(1 * BuildCraftCore.updateFactor);
} }
// @Override @Override
// public void readFromNBT(NBTTagCompound nbttagcompound) { public void readFromNBT(NBTTagCompound nbttagcompound) {
// super.readFromNBT(nbttagcompound); super.readFromNBT(nbttagcompound);
//
// for (int i = 0; i < 6; ++i) {
// if (nbttagcompound.hasKey("side[" + i + "]"))
// side[i].readFromNBT(nbttagcompound.getCompoundTag("side[" + i + "]"));
//
// isInput[i] = nbttagcompound.getBoolean("isInput[" + i + "]");
// }
//
// if (nbttagcompound.hasKey("center"))
// center.readFromNBT(nbttagcompound.getCompoundTag("center"));
//
// NBTTagCompound sub = new NBTTagCompound();
// center.writeToNBT(sub);
// nbttagcompound.setTag("center", sub);
// }
// @Override
// public void writeToNBT(NBTTagCompound nbttagcompound) {
// super.writeToNBT(nbttagcompound);
//
// for (int i = 0; i < 6; ++i) {
// NBTTagCompound sub = new NBTTagCompound();
// side[i].writeToNBT(sub);
// nbttagcompound.setTag("side[" + i + "]", sub);
//
// nbttagcompound.setBoolean("isInput[" + i + "]", isInput[i]);
// }
//
// NBTTagCompound sub = new NBTTagCompound();
// center.writeToNBT(sub);
// nbttagcompound.setTag("center", sub);
// }
public void onDropped(EntityItem item) {
for (Orientations direction : Orientations.values()) {
if (nbttagcompound.hasKey("tank[" + direction.ordinal() + "]")){
internalTanks[direction.ordinal()].readFromNBT(nbttagcompound.getCompoundTag("tank[" + direction.ordinal() + "]"));
}
if (direction != Orientations.Unknown){
transferState[direction.ordinal()] = TransferState.values()[nbttagcompound.getShort("transferState[" + direction.ordinal() + "]")];
}
}
} }
int lockedTime = 0; @Override
public void writeToNBT(NBTTagCompound nbttagcompound) {
super.writeToNBT(nbttagcompound);
for (Orientations direction : Orientations.values()) {
NBTTagCompound subTag = new NBTTagCompound();
internalTanks[direction.ordinal()].writeToNBT(subTag);
nbttagcompound.setTag("tank[" + direction.ordinal() + "]", subTag);
if (direction != Orientations.Unknown){
nbttagcompound.setShort("transferState[" + direction.ordinal() + "]", (short)transferState[direction.ordinal()].ordinal());
}
}
}
private void moveLiquids() { private void moveLiquids() {
short newTimeSlot = (short) (worldObj.getWorldTime() % travelDelay); short newTimeSlot = (short) (worldObj.getWorldTime() % travelDelay);
@ -223,41 +242,28 @@ public class PipeTransportLiquids extends PipeTransport implements ITankContaine
for (Orientations direction : Orientations.values()){ for (Orientations direction : Orientations.values()){
internalTanks[direction.ordinal()].setTime(newTimeSlot); internalTanks[direction.ordinal()].setTime(newTimeSlot);
internalTanks[direction.ordinal()].moveLiquids(); internalTanks[direction.ordinal()].moveLiquids();
} }
for (Orientations direction : Orientations.dirs()){
if (transferState[direction.ordinal()] == TransferState.Input){
if ((inputTTL[direction.ordinal()]--) < 1){
transferState[direction.ordinal()] = TransferState.None;
}
}
}
short outputCount = computeOutputs(); short outputCount = computeOutputs();
if (outputCount == 0) {
lockedTime++;
} else {
lockedTime = 0;
}
//If enough time has passed, previous input sides are now valid destinations
if (lockedTime > 20) {
for (int i = 0; i < 6; ++i) {
isInput[i] = false;
}
outputCount = computeOutputs();
}
moveFromPipe(outputCount); moveFromPipe(outputCount);
moveToCenter();
moveFromCenter(); moveFromCenter();
moveToCenter();
} }
private void moveFromPipe(short outputCount) { private void moveFromPipe(short outputCount) {
//Move liquid from the non-center to the connected output blocks //Move liquid from the non-center to the connected output blocks
if (outputCount > 0){ if (outputCount > 0){
for (Orientations o : Orientations.dirs()){ for (Orientations o : Orientations.dirs()){
if (isOutput[o.ordinal()]){ if (transferState[o.ordinal()] == TransferState.Output){
TileEntity target = this.container.getTile(o); TileEntity target = this.container.getTile(o);
if (!(target instanceof ITankContainer)) continue; if (!(target instanceof ITankContainer)) continue;
@ -265,13 +271,8 @@ public class PipeTransportLiquids extends PipeTransport implements ITankContaine
if (liquidToPush != null && liquidToPush.amount > 0) { if (liquidToPush != null && liquidToPush.amount > 0) {
int filled = ((ITankContainer)target).fill(o.reverse(), liquidToPush, true); int filled = ((ITankContainer)target).fill(o.reverse(), liquidToPush, true);
internalTanks[o.ordinal()].drain(filled, true); internalTanks[o.ordinal()].drain(filled, true);
if (filled == 0){ if (filled <= 0){
for (Orientations direction : Orientations.dirs()){ outputTTL[o.ordinal()]--;
if (bounceCount[direction.ordinal()]++ > 30){
bounceCount[direction.ordinal()] = 0;
isInput[direction.ordinal()] = true;
}
}
} }
} }
} }
@ -284,22 +285,23 @@ public class PipeTransportLiquids extends PipeTransport implements ITankContaine
int[] maxOutput = new int[] {0,0,0,0,0,0}; int[] maxOutput = new int[] {0,0,0,0,0,0};
int transferOutCount = 0; int transferOutCount = 0;
LiquidStack pushStack = internalTanks[Orientations.Unknown.ordinal()].getLiquid(); LiquidStack pushStack = internalTanks[Orientations.Unknown.ordinal()].getLiquid();
int totalAvailable = internalTanks[Orientations.Unknown.ordinal()].getAvailable() / 2; int totalAvailable = internalTanks[Orientations.Unknown.ordinal()].getAvailable();
if (totalAvailable < 1) return;
if (pushStack != null){ if (pushStack != null){
LiquidStack testStack = pushStack.copy(); LiquidStack testStack = pushStack.copy();
testStack.amount = flowRate; testStack.amount = flowRate;
for (Orientations direction : Orientations.dirs()){ for (Orientations direction : Orientations.dirs()){
if (!isOutput[direction.ordinal()]) continue; if (transferState[direction.ordinal()] != TransferState.Output ) continue;
maxOutput[direction.ordinal()] = internalTanks[direction.ordinal()].fill(testStack, false); maxOutput[direction.ordinal()] = internalTanks[direction.ordinal()].fill(testStack, false);
if(maxOutput[direction.ordinal()] > 0){ if(maxOutput[direction.ordinal()] > 0){
transferOutCount++; transferOutCount++;
} }
} }
if (transferOutCount <= 0) return;
//Move liquid from the center to the output sides //Move liquid from the center to the output sides
for (Orientations direction : Orientations.dirs()) { for (Orientations direction : Orientations.dirs()) {
if (!container.pipe.outputOpen(direction)) continue; if (transferState[direction.ordinal()] == TransferState.Output) {
if (isOutput[direction.ordinal()]) {
if (maxOutput[direction.ordinal()] == 0) continue; if (maxOutput[direction.ordinal()] == 0) continue;
int ammountToPush = (int) ((double) maxOutput[direction.ordinal()] / (double) flowRate / (double) transferOutCount * (double) Math.min(flowRate, totalAvailable)); int ammountToPush = (int) ((double) maxOutput[direction.ordinal()] / (double) flowRate / (double) transferOutCount * (double) Math.min(flowRate, totalAvailable));
if (ammountToPush < 1) ammountToPush++; if (ammountToPush < 1) ammountToPush++;
@ -325,17 +327,16 @@ public class PipeTransportLiquids extends PipeTransport implements ITankContaine
for (Orientations direction : Orientations.dirs()){ for (Orientations direction : Orientations.dirs()){
if (!container.pipe.outputOpen(direction)) continue;
LiquidStack testStack = internalTanks[direction.ordinal()].drain(flowRate, false); LiquidStack testStack = internalTanks[direction.ordinal()].drain(flowRate, false);
if (testStack == null) continue; if (testStack == null) continue;
if (stackInCenter != null && !stackInCenter.isLiquidEqual(testStack)) continue; if (stackInCenter != null && !stackInCenter.isLiquidEqual(testStack)) continue;
maxInput[direction.ordinal()] = testStack.amount; maxInput[direction.ordinal()] = testStack.amount;
transferInCount++; transferInCount++;
} }
for (Orientations direction : Orientations.dirs()){ for (Orientations direction : Orientations.dirs()){
//Move liquid from non output sides to the center //Move liquid from input sides to the center
if (!isOutput[direction.ordinal()] && maxInput[direction.ordinal()] > 0){ if (transferState[direction.ordinal()] != TransferState.Output && maxInput[direction.ordinal()] > 0){
int ammountToDrain = (int) ((double) maxInput[direction.ordinal()] / (double) flowRate / (double) transferInCount * (double) Math.min(flowRate, spaceAvailable)); int ammountToDrain = (int) ((double) maxInput[direction.ordinal()] / (double) flowRate / (double) transferInCount * (double) Math.min(flowRate, spaceAvailable));
if (ammountToDrain < 1){ if (ammountToDrain < 1){
@ -355,8 +356,25 @@ public class PipeTransportLiquids extends PipeTransport implements ITankContaine
short outputCount = 0; short outputCount = 0;
for (Orientations o : Orientations.dirs()) { for (Orientations o : Orientations.dirs()) {
isOutput[o.ordinal()] = container.pipe.outputOpen(o) && canReceiveLiquid(o) && !isInput[o.ordinal()]; if (transferState[o.ordinal()] == TransferState.Input) continue;
if (isOutput[o.ordinal()]){ if (!container.pipe.outputOpen(o)){
transferState[o.ordinal()] = TransferState.None;
continue;
}
if (outputCooldown[o.ordinal()] > 0){
outputCooldown[o.ordinal()]--;
continue;
}
if (outputTTL[o.ordinal()] <= 0){
transferState[o.ordinal()] = TransferState.None;
outputCooldown[o.ordinal()] = OUTPUT_COOLDOWN;
outputTTL[o.ordinal()] = OUTPUT_TTL;
continue;
}
if (canReceiveLiquid(o)) {
transferState[o.ordinal()] = TransferState.Output;
outputCount++; outputCount++;
} }
} }
@ -368,10 +386,11 @@ public class PipeTransportLiquids extends PipeTransport implements ITankContaine
public void onNeighborBlockChange(int blockId) { public void onNeighborBlockChange(int blockId) {
super.onNeighborBlockChange(blockId); super.onNeighborBlockChange(blockId);
for (int i = 0; i < 6; ++i){ for (Orientations direction : Orientations.dirs()){
if (!Utils.checkPipesConnections(container.getTile(Orientations.values()[i]), container)) { if (!Utils.checkPipesConnections(container.getTile(Orientations.values()[direction.ordinal()]), container)) {
internalTanks[i].reset(); internalTanks[direction.ordinal()].reset();
renderCache[i] = null; transferState[direction.ordinal()] = TransferState.None;
renderCache[direction.ordinal()] = null;
} }
} }
} }
@ -406,11 +425,18 @@ public class PipeTransportLiquids extends PipeTransport implements ITankContaine
@Override @Override
public int fill(int tankIndex, LiquidStack resource, boolean doFill) { public int fill(int tankIndex, LiquidStack resource, boolean doFill) {
isInput[tankIndex] = true; int filled;
if (this.container.pipe instanceof IPipeTransportLiquidsHook) if (this.container.pipe instanceof IPipeTransportLiquidsHook)
return ((IPipeTransportLiquidsHook) this.container.pipe).fill(Orientations.values()[tankIndex], resource, doFill); filled = ((IPipeTransportLiquidsHook) this.container.pipe).fill(Orientations.values()[tankIndex], resource, doFill);
else else
return internalTanks[tankIndex].fill(resource, doFill); filled = internalTanks[tankIndex].fill(resource, doFill);
if (filled > 0 && doFill && tankIndex != Orientations.Unknown.ordinal()){
transferState[tankIndex] = TransferState.Input;
inputTTL[tankIndex] = INPUT_TTL;
}
return filled;
} }
@Override @Override