fixed generic fluid pumping

This commit is contained in:
SpaceToad 2014-02-14 08:53:53 +01:00
parent ebbc8d2146
commit b3dac23866
2 changed files with 86 additions and 61 deletions

View file

@ -137,14 +137,7 @@ public class BlockUtil {
} }
public static Fluid getFluid(Block block) { public static Fluid getFluid(Block block) {
if (block instanceof IFluidBlock) { return FluidRegistry.lookupFluidForBlock (block);
return ((IFluidBlock) block).getFluid();
} else if (block == Blocks.water || block == Blocks.flowing_water) {
return FluidRegistry.WATER;
} else if (block == Blocks.lava || block == Blocks.flowing_lava) {
return FluidRegistry.LAVA;
}
return null;
} }
public static FluidStack drainBlock(World world, int x, int y, int z, boolean doDrain) { public static FluidStack drainBlock(World world, int x, int y, int z, boolean doDrain) {
@ -152,27 +145,24 @@ public class BlockUtil {
} }
public static FluidStack drainBlock(Block block, World world, int x, int y, int z, boolean doDrain) { public static FluidStack drainBlock(Block block, World world, int x, int y, int z, boolean doDrain) {
if (block instanceof IFluidBlock) { Fluid fluid = FluidRegistry.lookupFluidForBlock(block);
IFluidBlock fluidBlock = (IFluidBlock) block;
if (fluidBlock.canDrain(world, x, y, z)) if (fluid != null) {
return fluidBlock.drain(world, x, y, z, doDrain);
} else if (block == Blocks.water || block == Blocks.flowing_water) {
int meta = world.getBlockMetadata(x, y, z); int meta = world.getBlockMetadata(x, y, z);
if (meta != 0)
if (meta != 0) {
return null; return null;
if (doDrain)
world.setBlockToAir(x, y, z);
return new FluidStack(FluidRegistry.WATER, FluidContainerRegistry.BUCKET_VOLUME);
} else if (block == Blocks.lava || block == Blocks.lava) {
int meta = world.getBlockMetadata(x, y, z);
if (meta != 0)
return null;
if (doDrain)
world.setBlockToAir(x, y, z);
return new FluidStack(FluidRegistry.LAVA, FluidContainerRegistry.BUCKET_VOLUME);
} }
if (doDrain) {
world.setBlockToAir(x, y, z);
}
return new FluidStack(fluid, FluidContainerRegistry.BUCKET_VOLUME);
} else {
return null; return null;
} }
}
/** /**
* Create an explosion which only affects a single block. * Create an explosion which only affects a single block.

View file

@ -55,7 +55,7 @@ import net.minecraftforge.fluids.IFluidHandler;
public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor, IFluidHandler { public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor, IFluidHandler {
public static int REBUID_DELAY = 512; public static final int REBUID_DELAY = 512;
public static int MAX_LIQUID = FluidContainerRegistry.BUCKET_VOLUME * 16; public static int MAX_LIQUID = FluidContainerRegistry.BUCKET_VOLUME * 16;
EntityBlock tube; EntityBlock tube;
private TreeMap<Integer, Deque<BlockIndex>> pumpLayerQueues = new TreeMap<Integer, Deque<BlockIndex>>(); private TreeMap<Integer, Deque<BlockIndex>> pumpLayerQueues = new TreeMap<Integer, Deque<BlockIndex>>();
@ -64,7 +64,7 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
int aimY = 0; int aimY = 0;
private PowerHandler powerHandler; private PowerHandler powerHandler;
private TileBuffer[] tileBuffer = null; private TileBuffer[] tileBuffer = null;
private SafeTimeTracker timer = new SafeTimeTracker(); private SafeTimeTracker timer = new SafeTimeTracker(REBUID_DELAY);
private int tick = Utils.RANDOM.nextInt(); private int tick = Utils.RANDOM.nextInt();
private int numFluidBlocksFound = 0; private int numFluidBlocksFound = 0;
private boolean powered = false; private boolean powered = false;
@ -86,19 +86,23 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
if (powered) { if (powered) {
pumpLayerQueues.clear(); pumpLayerQueues.clear();
destroyTube(); destroyTube();
} else } else {
createTube(); createTube();
}
if (worldObj.isRemote) if (worldObj.isRemote) {
return; return;
}
pushToConsumers(); pushToConsumers();
if(powered) if (powered) {
return; return;
}
if(tube == null) if (tube == null) {
return; return;
}
if (tube.posY - aimY > 0.01) { if (tube.posY - aimY > 0.01) {
tubeY = tube.posY - 0.01; tubeY = tube.posY - 0.01;
@ -108,17 +112,17 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
} }
tick++; tick++;
if (tick % 16 != 0)
if (tick % 16 != 0) {
return; return;
}
BlockIndex index = getNextIndexToPump(false); BlockIndex index = getNextIndexToPump(false);
FluidStack fluidToPump = index != null ? BlockUtil.drainBlock(worldObj, index.x, index.y, index.z, false) : null; FluidStack fluidToPump = index != null ? BlockUtil.drainBlock(worldObj, index.x, index.y, index.z, false) : null;
if (fluidToPump != null) { if (fluidToPump != null) {
if (isFluidAllowed(fluidToPump.getFluid()) && tank.fill(fluidToPump, false) == fluidToPump.amount) { if (isFluidAllowed(fluidToPump.getFluid()) && tank.fill(fluidToPump, false) == fluidToPump.amount) {
if (powerHandler.useEnergy(10, 10, true) == 10) { if (powerHandler.useEnergy(10, 10, true) == 10) {
if (fluidToPump.getFluid() != FluidRegistry.WATER || BuildCraftCore.consumeWaterSources || numFluidBlocksFound < 9) { if (fluidToPump.getFluid() != FluidRegistry.WATER || BuildCraftCore.consumeWaterSources || numFluidBlocksFound < 9) {
index = getNextIndexToPump(true); index = getNextIndexToPump(true);
BlockUtil.drainBlock(worldObj, index.x, index.y, index.z, true); BlockUtil.drainBlock(worldObj, index.x, index.y, index.z, true);
@ -130,7 +134,6 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
} else { } else {
if (tick % 128 == 0) { if (tick % 128 == 0) {
// TODO: improve that decision // TODO: improve that decision
rebuildQueue(); rebuildQueue();
if (getNextIndexToPump(false) == null) { if (getNextIndexToPump(false) == null) {
@ -149,27 +152,35 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
public void onNeighborBlockChange(Block block) { public void onNeighborBlockChange(Block block) {
boolean p = worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord); boolean p = worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord);
if (powered != p) { if (powered != p) {
powered = p; powered = p;
if(!worldObj.isRemote)
if(!worldObj.isRemote) {
sendNetworkUpdate(); sendNetworkUpdate();
} }
} }
}
private boolean isBlocked(int x, int y, int z) { private boolean isBlocked(int x, int y, int z) {
Material mat = worldObj.getBlock(x, y, z).getMaterial(); Material mat = worldObj.getBlock(x, y, z).getMaterial();
return mat.blocksMovement(); return mat.blocksMovement();
} }
private void pushToConsumers() { private void pushToConsumers() {
if (tileBuffer == null) if (tileBuffer == null) {
tileBuffer = TileBuffer.makeBuffer(worldObj, xCoord, yCoord, zCoord, false); tileBuffer = TileBuffer.makeBuffer(worldObj, xCoord, yCoord, zCoord, false);
}
FluidUtils.pushFluidToConsumers(tank, 400, tileBuffer); FluidUtils.pushFluidToConsumers(tank, 400, tileBuffer);
} }
private TileEntity getTile(ForgeDirection side) { private TileEntity getTile(ForgeDirection side) {
if (tileBuffer == null) if (tileBuffer == null) {
tileBuffer = TileBuffer.makeBuffer(worldObj, xCoord, yCoord, zCoord, false); tileBuffer = TileBuffer.makeBuffer(worldObj, xCoord, yCoord, zCoord, false);
}
return tileBuffer[side.ordinal()].getTile(); return tileBuffer[side.ordinal()].getTile();
} }
@ -193,10 +204,11 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
worldObj.spawnEntityInWorld(tube); worldObj.spawnEntityInWorld(tube);
if (!worldObj.isRemote) if (!worldObj.isRemote) {
sendNetworkUpdate(); sendNetworkUpdate();
} }
} }
}
private void destroyTube() { private void destroyTube() {
if (tube != null) { if (tube != null) {
@ -209,33 +221,39 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
private BlockIndex getNextIndexToPump(boolean remove) { private BlockIndex getNextIndexToPump(boolean remove) {
if (pumpLayerQueues.isEmpty()) { if (pumpLayerQueues.isEmpty()) {
if (timer.markTimeIfDelay(worldObj, REBUID_DELAY)) { if (timer.markTimeIfDelay(worldObj)) {
rebuildQueue(); rebuildQueue();
} }
return null; return null;
} }
Deque<BlockIndex> topLayer = pumpLayerQueues.lastEntry().getValue(); Deque<BlockIndex> topLayer = pumpLayerQueues.lastEntry().getValue();
if (topLayer != null) { if (topLayer != null) {
if (topLayer.isEmpty()) if (topLayer.isEmpty()) {
pumpLayerQueues.pollLastEntry(); pumpLayerQueues.pollLastEntry();
}
if (remove) { if (remove) {
BlockIndex index = topLayer.pollLast(); BlockIndex index = topLayer.pollLast();
return index; return index;
} } else {
return topLayer.peekLast(); return topLayer.peekLast();
} }
} else {
return null; return null;
} }
}
private Deque<BlockIndex> getLayerQueue(int layer) { private Deque<BlockIndex> getLayerQueue(int layer) {
Deque<BlockIndex> pumpQueue = pumpLayerQueues.get(layer); Deque<BlockIndex> pumpQueue = pumpLayerQueues.get(layer);
if (pumpQueue == null) { if (pumpQueue == null) {
pumpQueue = new LinkedList<BlockIndex>(); pumpQueue = new LinkedList<BlockIndex>();
pumpLayerQueues.put(layer, pumpQueue); pumpLayerQueues.put(layer, pumpQueue);
} }
return pumpQueue; return pumpQueue;
} }
@ -246,11 +264,14 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
int y = aimY; int y = aimY;
int z = zCoord; int z = zCoord;
Fluid pumpingFluid = BlockUtil.getFluid(worldObj.getBlock(x, y, z)); Fluid pumpingFluid = BlockUtil.getFluid(worldObj.getBlock(x, y, z));
if (pumpingFluid == null)
return;
if (pumpingFluid != tank.getAcceptedFluid() && tank.getAcceptedFluid() != null) if (pumpingFluid == null) {
return; return;
}
if (pumpingFluid != tank.getAcceptedFluid() && tank.getAcceptedFluid() != null) {
return;
}
Set<BlockIndex> visitedBlocks = new HashSet<BlockIndex>(); Set<BlockIndex> visitedBlocks = new HashSet<BlockIndex>();
Deque<BlockIndex> fluidsFound = new LinkedList<BlockIndex>(); Deque<BlockIndex> fluidsFound = new LinkedList<BlockIndex>();
@ -270,8 +291,11 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
queueForPumping(index.x, index.y, index.z + 1, visitedBlocks, fluidsFound, pumpingFluid); queueForPumping(index.x, index.y, index.z + 1, visitedBlocks, fluidsFound, pumpingFluid);
queueForPumping(index.x, index.y, index.z - 1, visitedBlocks, fluidsFound, pumpingFluid); queueForPumping(index.x, index.y, index.z - 1, visitedBlocks, fluidsFound, pumpingFluid);
if (pumpingFluid == FluidRegistry.WATER && !BuildCraftCore.consumeWaterSources && numFluidBlocksFound >= 9) if (pumpingFluid == FluidRegistry.WATER
&& !BuildCraftCore.consumeWaterSources
&& numFluidBlocksFound >= 9) {
return; return;
}
// if (System.nanoTime() > timeoutTime) // if (System.nanoTime() > timeoutTime)
// return; // return;
@ -282,13 +306,16 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
public void queueForPumping(int x, int y, int z, Set<BlockIndex> visitedBlocks, Deque<BlockIndex> fluidsFound, Fluid pumpingFluid) { public void queueForPumping(int x, int y, int z, Set<BlockIndex> visitedBlocks, Deque<BlockIndex> fluidsFound, Fluid pumpingFluid) {
BlockIndex index = new BlockIndex(x, y, z); BlockIndex index = new BlockIndex(x, y, z);
if (visitedBlocks.add(index)) { if (visitedBlocks.add(index)) {
if ((x - xCoord) * (x - xCoord) + (z - zCoord) * (z - zCoord) > 64 * 64) if ((x - xCoord) * (x - xCoord) + (z - zCoord) * (z - zCoord) > 64 * 64) {
return; return;
}
Block block = worldObj.getBlock(x, y, z); Block block = worldObj.getBlock(x, y, z);
if (BlockUtil.getFluid(block) == pumpingFluid) { if (BlockUtil.getFluid(block) == pumpingFluid) {
fluidsFound.add(index); fluidsFound.add(index);
} }
if (canDrainBlock(block, x, y, z, pumpingFluid)) { if (canDrainBlock(block, x, y, z, pumpingFluid)) {
getLayerQueue(y).add(index); getLayerQueue(y).add(index);
numFluidBlocksFound++; numFluidBlocksFound++;
@ -298,25 +325,31 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
private boolean isPumpableFluid(int x, int y, int z) { private boolean isPumpableFluid(int x, int y, int z) {
Fluid fluid = BlockUtil.getFluid(worldObj.getBlock(x, y, z)); Fluid fluid = BlockUtil.getFluid(worldObj.getBlock(x, y, z));
if (fluid == null)
if (fluid == null) {
return false; return false;
if (!isFluidAllowed(fluid)) } else if (!isFluidAllowed(fluid)) {
return false; return false;
if (tank.getAcceptedFluid() != null && tank.getAcceptedFluid() != fluid) } else if (tank.getAcceptedFluid() != null && tank.getAcceptedFluid() != fluid) {
return false; return false;
} else {
return true; return true;
} }
}
private boolean canDrainBlock(Block block, int x, int y, int z, Fluid fluid) { private boolean canDrainBlock(Block block, int x, int y, int z, Fluid fluid) {
if (!isFluidAllowed(fluid)) if (!isFluidAllowed(fluid)) {
return false; return false;
}
FluidStack fluidStack = BlockUtil.drainBlock(block, worldObj, x, y, z, false); FluidStack fluidStack = BlockUtil.drainBlock(block, worldObj, x, y, z, false);
if (fluidStack == null || fluidStack.amount <= 0)
return false;
if (fluidStack == null || fluidStack.amount <= 0) {
return false;
} else {
return fluidStack.getFluid() == fluid; return fluidStack.getFluid() == fluid;
} }
}
private boolean isFluidAllowed(Fluid fluid) { private boolean isFluidAllowed(Fluid fluid) {
return BuildCraftFactory.pumpDimensionList.isFluidAllowed(fluid, worldObj.provider.dimensionId); return BuildCraftFactory.pumpDimensionList.isFluidAllowed(fluid, worldObj.provider.dimensionId);
@ -361,10 +394,10 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
if (next != null) { if (next != null) {
return isPumpableFluid(next.x, next.y, next.z); return isPumpableFluid(next.x, next.y, next.z);
} } else {
return false; return false;
} }
}
@Override @Override
public PowerReceiver getPowerReceiver(ForgeDirection side) { public PowerReceiver getPowerReceiver(ForgeDirection side) {
@ -463,12 +496,14 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
@Override @Override
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) { public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) {
if (resource == null) if (resource == null) {
return null; return null;
if (!resource.isFluidEqual(tank.getFluid())) } else if (!resource.isFluidEqual(tank.getFluid())) {
return null; return null;
} else {
return drain(from, resource.amount, doDrain); return drain(from, resource.amount, doDrain);
} }
}
@Override @Override
public boolean canFill(ForgeDirection from, Fluid fluid) { public boolean canFill(ForgeDirection from, Fluid fluid) {