Refactored TileTank and fixed NPE in Pipes

This commit is contained in:
CovertJaguar 2012-07-28 10:50:13 -07:00
parent 3ab29dcfad
commit 093d5229e2
6 changed files with 258 additions and 310 deletions

View file

@ -25,7 +25,6 @@ import org.lwjgl.opengl.GL11;
import buildcraft.api.liquids.LiquidStack;
import buildcraft.core.RenderEntityBlock;
import buildcraft.core.RenderEntityBlock.BlockInterface;
import buildcraft.factory.TileTank;
public class RenderTank extends TileEntitySpecialRenderer {
@ -72,7 +71,7 @@ public class RenderTank extends TileEntitySpecialRenderer {
TileTank tank = ((TileTank) tileentity);
LiquidStack liquid = tank.getLiquid();
LiquidStack liquid = tank.tank.getLiquid();
if (liquid == null || liquid.amount <= 0
|| liquid.itemID <= 0)
@ -97,7 +96,7 @@ public class RenderTank extends TileEntitySpecialRenderer {
GL11.glTranslatef((float) x + 0.5F, (float) y + 0.5F, (float) z + 0.5F);
GL11.glCallList(displayList[(int) ((float) liquid.amount / (float) (tank.getTankCapacity()) * (displayStages - 1))]);
GL11.glCallList(displayList[(int) ((float) liquid.amount / (float) (tank.tank.getCapacity()) * (displayStages - 1))]);
GL11.glEnable(2896 /* GL_LIGHTING */);
GL11.glPopMatrix();

View file

@ -78,8 +78,7 @@ public abstract class TileBuildCraft extends TileEntity implements ISynchronized
}
public void sendNetworkUpdate() {
if (this instanceof ISynchronizedTile)
CoreProxy.sendToPlayers(((ISynchronizedTile) this).getUpdatePacket(), worldObj, xCoord, yCoord, zCoord,
CoreProxy.sendToPlayers(getUpdatePacket(), worldObj, xCoord, yCoord, zCoord,
DefaultProps.NETWORK_UPDATE_RANGE, mod_BuildCraftCore.instance);
}

View file

@ -113,6 +113,7 @@ public class BlockTank extends BlockContainer implements ITextureProvider {
} else {
LiquidStack available = tank.getTanks()[0].getLiquid();
if(available != null){
ItemStack filled = LiquidManager.fillLiquidContainer(available, current);
liquid = LiquidManager.getLiquidForFilledItem(filled);
@ -135,6 +136,7 @@ public class BlockTank extends BlockContainer implements ITextureProvider {
}
}
}
}
return false;
}

View file

@ -6,11 +6,9 @@
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.factory;
import buildcraft.BuildCraftCore;
import buildcraft.BuildCraftFactory;
import buildcraft.api.APIProxy;
import buildcraft.api.core.BuildCraftAPI;
import buildcraft.api.core.Orientations;
@ -19,64 +17,89 @@ import buildcraft.api.liquids.ILiquidTank;
import buildcraft.api.liquids.ITankContainer;
import buildcraft.api.liquids.LiquidStack;
import buildcraft.api.liquids.LiquidTank;
import buildcraft.core.DefaultProps;
import buildcraft.core.TileBuildCraft;
import buildcraft.core.network.TileNetworkData;
import buildcraft.core.network.PacketPayload;
import buildcraft.core.network.PacketUpdate;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.TileEntity;
public class TileTank extends TileBuildCraft implements ITankContainer {
public @TileNetworkData
int stored = 0;
public @TileNetworkData
int liquidId = 0;
public class TileTank extends TileBuildCraft implements ITankContainer
{
public final ILiquidTank tank = new LiquidTank(BuildCraftAPI.BUCKET_VOLUME * 16);
public boolean hasUpdate = false;
public SafeTimeTracker tracker = new SafeTimeTracker();
/* UPDATING */
@Override
public void updateEntity() {
if (APIProxy.isServerSide() && hasUpdate && tracker.markTimeIfDelay(worldObj, 2 * BuildCraftCore.updateFactor)) {
public void updateEntity()
{
if(APIProxy.isServerSide() && hasUpdate && tracker.markTimeIfDelay(worldObj, 2 * BuildCraftCore.updateFactor)) {
sendNetworkUpdate();
hasUpdate = false;
}
if(APIProxy.isRemote())
if(APIProxy.isRemote()) {
return;
}
// Have liquid flow down into tanks below if any.
if(stored > 0)
if(tank.getLiquid() != null) {
moveLiquidBelow();
}
}
/* NETWORK */
@Override
public PacketPayload getPacketPayload()
{
PacketPayload payload = new PacketPayload(3, 0, 0);
if(tank.getLiquid() != null) {
payload.intPayload[0] = tank.getLiquid().itemID;
payload.intPayload[1] = tank.getLiquid().itemMeta;
payload.intPayload[2] = tank.getLiquid().amount;
} else {
payload.intPayload[0] = 0;
payload.intPayload[1] = 0;
payload.intPayload[2] = 0;
}
return payload;
}
@Override
public void handleUpdatePacket(PacketUpdate packet)
{
if(packet.payload.intPayload[0] > 0) {
LiquidStack liquid = new LiquidStack(packet.payload.intPayload[0], packet.payload.intPayload[2], packet.payload.intPayload[1]);
tank.setLiquid(liquid);
} else {
tank.setLiquid(null);
}
}
/* SAVING & LOADING */
@Override
public void readFromNBT(NBTTagCompound nbttagcompound) {
super.readFromNBT(nbttagcompound);
stored = nbttagcompound.getInteger("stored");
liquidId = nbttagcompound.getInteger("liquidId");
if (liquidId == 0) {
stored = 0;
}
public void readFromNBT(NBTTagCompound data)
{
super.readFromNBT(data);
LiquidStack liquid = new LiquidStack(0, 0, 0);
liquid.readFromNBT(data.getCompoundTag("tank"));
tank.setLiquid(liquid);
}
@Override
public void writeToNBT(NBTTagCompound nbttagcompound) {
super.writeToNBT(nbttagcompound);
nbttagcompound.setInteger("stored", stored);
nbttagcompound.setInteger("liquidId", liquidId);
public void writeToNBT(NBTTagCompound data)
{
super.writeToNBT(data);
data.setTag("tank", tank.getLiquid().writeToNBT(new NBTTagCompound()));
}
/* HELPER FUNCTIONS */
/**
* @return Last tank block below this one or this one if it is the last.
*/
public TileTank getBottomTank() {
public TileTank getBottomTank()
{
TileTank lastTank = this;
@ -84,182 +107,102 @@ public class TileTank extends TileBuildCraft implements ITankContainer {
TileTank below = getTankBelow(lastTank);
if(below != null) {
lastTank = below;
} else
} else {
break;
}
}
return lastTank;
}
public TileTank getTankBelow(TileTank tile) {
TileEntity below = worldObj.getBlockTileEntity(tile.xCoord, tile.yCoord - 1, tile.zCoord);
if(below instanceof TileTank)
return(TileTank)below;
else
return null;
public TileTank getTopTank()
{
TileTank lastTank = this;
while(true) {
TileTank above = getTankAbove(lastTank);
if(above != null) {
lastTank = above;
} else {
break;
}
}
public TileTank getTankAbove(TileTank tile) {
TileEntity above = worldObj.getBlockTileEntity(tile.xCoord, tile.yCoord + 1, tile.zCoord);
if(above instanceof TileTank)
return(TileTank)above;
else
return null;
return lastTank;
}
public void moveLiquidBelow() {
public static TileTank getTankBelow(TileTank tile)
{
TileEntity below = tile.worldObj.getBlockTileEntity(tile.xCoord, tile.yCoord - 1, tile.zCoord);
if(below instanceof TileTank) {
return (TileTank)below;
} else {
return null;
}
}
public static TileTank getTankAbove(TileTank tile)
{
TileEntity above = tile.worldObj.getBlockTileEntity(tile.xCoord, tile.yCoord + 1, tile.zCoord);
if(above instanceof TileTank) {
return (TileTank)above;
} else {
return null;
}
}
public void moveLiquidBelow()
{
TileTank below = getTankBelow(this);
if(below == null)
return;
if(below.stored >= below.getTankCapacity())
return;
if(below.liquidId > 0
&& below.liquidId != this.liquidId)
if(below == null) {
return;
}
int toMove = Math.min(stored, 100);
int moved = Math.min(toMove, below.getTankCapacity() - below.stored);
stored -= moved;
below.liquidId = liquidId;
below.stored += moved;
int used = below.tank.fill(tank.getLiquid(), true);
tank.drain(used, true);
}
/* ITANKCONTAINER */
@Override
public int fill(Orientations from, LiquidStack resource, boolean doFill) {
return getBottomTank().actualFill(from, resource.amount, resource.itemID, doFill);
public int fill(Orientations from, LiquidStack resource, boolean doFill)
{
return fill(0, resource, doFill);
}
@Override
public int fill(int tankIndex, LiquidStack resource, boolean doFill) {
return getBottomTank().actualFill(Orientations.YPos, resource.amount, resource.itemID, doFill);
}
@Override
public LiquidStack drain(Orientations from, int maxEmpty, boolean doDrain) {
int drained = getBottomTank().actualEmtpy(maxEmpty, doDrain);
return new LiquidStack(liquidId, drained);
}
@Override
public LiquidStack drain(int tankIndex, int maxEmpty, boolean doDrain) {
int drained = getBottomTank().actualEmtpy(maxEmpty, doDrain);
return new LiquidStack(liquidId, drained);
}
@Override
public ILiquidTank[] getTanks() {
int resultLiquidId = 0;
int resultLiquidQty = 0;
int resultCapacity = 0;
if (stored != 0) {
resultLiquidId = liquidId;
}
resultLiquidQty += stored;
resultCapacity += getTankCapacity();
for (int ySearch = yCoord - 1; ySearch >= 0; --ySearch) {
if (worldObj.getBlockId(xCoord, ySearch, zCoord) != BuildCraftFactory.tankBlock.blockID) {
break;
}
TileTank tank = (TileTank) worldObj.getBlockTileEntity(xCoord, ySearch, zCoord);
if (tank.stored != 0) {
resultLiquidId = tank.liquidId;
}
resultLiquidQty += tank.stored;
resultCapacity += tank.getTankCapacity();
}
for (int ySearch = yCoord + 1; ySearch < 128; ++ySearch) {
if (worldObj.getBlockId(xCoord, ySearch, zCoord) != BuildCraftFactory.tankBlock.blockID) {
break;
}
TileTank tank = (TileTank) worldObj.getBlockTileEntity(xCoord, ySearch, zCoord);
if (tank.stored != 0) {
resultLiquidId = tank.liquidId;
}
resultLiquidQty += tank.stored;
resultCapacity += tank.getTankCapacity();
}
return new ILiquidTank[] { new LiquidTank(resultLiquidId, resultLiquidQty, resultCapacity) };
}
private int actualFill(Orientations from, int quantity, int id, boolean doFill) {
if (stored != 0 && id != liquidId)
public int fill(int tankIndex, LiquidStack resource, boolean doFill)
{
if(tankIndex != 0 || resource == null)
return 0;
liquidId = id;
int used = 0;
TileTank above = getTankAbove(this);
if (stored + quantity <= getTankCapacity()) {
if (doFill) {
stored += quantity;
hasUpdate = true;
resource = resource.copy();
int totalUsed = 0;
TileTank tankToFill = getBottomTank();
while(tankToFill != null && resource.amount > 0){
int used = tankToFill.tank.fill(resource, doFill);
resource.amount -= used;
totalUsed += used;
tankToFill = getTankAbove(tankToFill);
}
return totalUsed;
}
used = quantity;
} else if (stored <= getTankCapacity()) {
used = getTankCapacity() - stored;
if (doFill) {
stored = getTankCapacity();
hasUpdate = true;
}
@Override
public LiquidStack drain(Orientations from, int maxEmpty, boolean doDrain)
{
return drain(0, maxEmpty, doDrain);
}
if (used < quantity && above != null)
used = used + above.actualFill(from, quantity - used, id, doFill);
return used;
@Override
public LiquidStack drain(int tankIndex, int maxEmpty, boolean doDrain)
{
return getBottomTank().tank.drain(maxEmpty, doDrain);
}
public int getTankCapacity() {
return BuildCraftAPI.BUCKET_VOLUME * 16;
@Override
public ILiquidTank[] getTanks()
{
return new ILiquidTank[]{tank};
}
public LiquidStack getLiquid() {
return new LiquidStack(liquidId, stored, 0);
}
private int actualEmtpy(int quantityMax, boolean doEmpty) {
if (stored >= quantityMax) {
if (doEmpty) {
stored -= quantityMax;
hasUpdate = true;
}
return quantityMax;
} else {
int result = stored;
if (doEmpty) {
stored = 0;
hasUpdate = true;
}
TileTank below = getTankBelow(this);
if (below != null)
result += below.actualEmtpy(quantityMax - result, doEmpty);
return result;
}
}
}

View file

@ -26,7 +26,6 @@ import buildcraft.core.DefaultProps;
import buildcraft.core.IMachine;
import buildcraft.core.Utils;
import buildcraft.transport.network.PacketLiquidUpdate;
import buildcraft.transport.network.PacketPowerUpdate;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.TileEntity;
@ -48,6 +47,9 @@ public class PipeTransportLiquids extends PipeTransport implements ITankContaine
@Override
public int fill(LiquidStack resource, boolean doFill) {
if(resource == null)
return 0;
int maxToFill = Math.min(resource.amount, flowRate - incomming[currentTime]);
if (maxToFill <= 0) return 0;

View file

@ -103,9 +103,12 @@ public class PipeLiquidsWood extends Pipe implements IPowerReceptor {
LiquidStack extracted = container.drain(pos.orientation.reverse(), liquidToExtract > flowRate ? flowRate : liquidToExtract, false);
int inserted = ((PipeTransportLiquids) transport).fill(pos.orientation, extracted, true);
int inserted = 0;
if(extracted != null) {
inserted = ((PipeTransportLiquids) transport).fill(pos.orientation, extracted, true);
container.drain(pos.orientation.reverse(), inserted, true);
}
liquidToExtract -= inserted;
}