aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/common
diff options
context:
space:
mode:
authorJason Mitchell <mitchej@gmail.com>2017-11-23 16:47:49 -0800
committerJason Mitchell <mitchej@gmail.com>2017-11-23 17:21:05 -0800
commit2dc5b03f14f6ddb7025c407dd3c10e7cdbec0200 (patch)
tree2037daebdf557c8636709859e3c920f9d9d51024 /src/main/java/gregtech/common
parent5fc136166e6d34caf6a6856c780d455fcfb2a53c (diff)
downloadGT5-Unofficial-2dc5b03f14f6ddb7025c407dd3c10e7cdbec0200.tar.gz
GT5-Unofficial-2dc5b03f14f6ddb7025c407dd3c10e7cdbec0200.tar.bz2
GT5-Unofficial-2dc5b03f14f6ddb7025c407dd3c10e7cdbec0200.zip
Single block pump refactor & bugfix:
1) Pump will properly save it's state and reload with chunk load/reload. It remembers that it was pumping and doesn't immediately move down. Additionally, corrected saving of fluid type so it will properly look it up when it reloads 2) Fixed getYHeadOfPump() so it doesn't punch through bedrock if you destroy the pump head. If you break a gap into an existing pipe line, it will move down through the broken spots until it finds an existing set of pipes - in which case it will continue from the bottom. If you break the pump head, it will replace the last pipe with a new Head and carry on about it's business.
Diffstat (limited to 'src/main/java/gregtech/common')
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/basic/GT_MetaTileEntity_Pump.java414
1 files changed, 274 insertions, 140 deletions
diff --git a/src/main/java/gregtech/common/tileentities/machines/basic/GT_MetaTileEntity_Pump.java b/src/main/java/gregtech/common/tileentities/machines/basic/GT_MetaTileEntity_Pump.java
index 1c02526ab9..9e6f6088d0 100644
--- a/src/main/java/gregtech/common/tileentities/machines/basic/GT_MetaTileEntity_Pump.java
+++ b/src/main/java/gregtech/common/tileentities/machines/basic/GT_MetaTileEntity_Pump.java
@@ -1,5 +1,7 @@
package gregtech.common.tileentities.machines.basic;
+import cpw.mods.fml.common.registry.GameRegistry;
+
import gregtech.api.enums.Textures;
import gregtech.api.gui.GT_Container_BasicTank;
import gregtech.api.gui.GT_GUIContainer_BasicTank;
@@ -9,6 +11,7 @@ import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.metatileentity.BaseTileEntity;
import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch;
import gregtech.api.objects.GT_RenderedTexture;
+import gregtech.api.util.GT_Log;
import gregtech.api.util.GT_ModHandler;
import gregtech.api.util.GT_Utility;
import net.minecraft.block.Block;
@@ -21,25 +24,43 @@ import net.minecraft.world.ChunkPosition;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidBlock;
+import net.minecraftforge.fluids.IFluidHandler;
-import java.util.ArrayList;
+import java.util.ArrayDeque;
import java.util.Iterator;
+import java.util.HashSet;
+import java.util.Set;
+import static gregtech.api.enums.GT_Values.D1;
import static gregtech.api.enums.GT_Values.V;
+import static gregtech.api.util.GT_Utility.getFakePlayer;
public class GT_MetaTileEntity_Pump extends GT_MetaTileEntity_Hatch {
- private static final ItemStack MINING_PIPE = GT_ModHandler.getIC2Item("miningPipe", 0);
+ private static final ItemStack MINING_PIPE = GT_ModHandler.getIC2Item("miningPipe", 0);
private static final Block MINING_PIPE_BLOCK = GT_Utility.getBlockFromStack(MINING_PIPE);
private static final Block MINING_PIPE_TIP_BLOCK = GT_Utility.getBlockFromStack(GT_ModHandler.getIC2Item("miningPipeTip", 0));
- public ArrayList<ChunkPosition> mPumpList = new ArrayList<ChunkPosition>();
+ public static int getMaxDistanceForTier(byte aTier) {
+ return (10 * ((int) Math.pow(1.6D, aTier)));
+ }
+
+ public static long getEuUsagePerTier(byte aTier) {
+ return (16 * ((long) Math.pow(4, aTier)));
+ }
+
+ public ArrayDeque<ChunkPosition> mPumpList = new ArrayDeque<ChunkPosition>();
+ public boolean wasPumping = false;
public int mPumpTimer = 0;
public int mPumpCountBelow = 0;
- public Block mPumpedBlock1 = null;
- public Block mPumpedBlock2 = null;
+ public Block mPrimaryPumpedBlock = null;
+ public Block mSecondaryPumpedBlock = null;
public GT_MetaTileEntity_Pump(int aID, String aName, String aNameRegional, int aTier) {
- super(aID, aName, aNameRegional, aTier, 3, new String[]{"The best way to empty Oceans!", "Pumping Area: " + ((10 * ((int) Math.pow(1.6, aTier))) * 2 + 1) + "x" + ((10 * ((int) Math.pow(1.6, aTier))) * 2 + 1)});
+
+ super(aID, aName, aNameRegional, aTier, 3,
+ new String[]{"The best way to empty Oceans!",
+ "Pumping Area: " + (GT_MetaTileEntity_Pump.getMaxDistanceForTier((byte)aTier) * 2 + 1) + "x" +
+ (GT_MetaTileEntity_Pump.getMaxDistanceForTier((byte)aTier) * 2 + 1)});
}
public GT_MetaTileEntity_Pump(String aName, int aTier, String aDescription, ITexture[][][] aTextures) {
@@ -56,15 +77,26 @@ public class GT_MetaTileEntity_Pump extends GT_MetaTileEntity_Hatch {
}
public void saveNBTData(NBTTagCompound aNBT) {
+ boolean wasPumping = this.wasPumping || !this.mPumpList.isEmpty();
+ if (D1) {
+ GT_Log.out.println("PUMP: NBT:Save - WasPumping - " + wasPumping + " blocks (" + this.mPrimaryPumpedBlock + ", " + this.mSecondaryPumpedBlock + ")");
+ }
super.saveNBTData(aNBT);
- aNBT.setString("mPumpedBlock1", this.mPumpedBlock1 == null ? "" : this.mPumpedBlock1.getUnlocalizedName());
- aNBT.setString("mPumpedBlock2", this.mPumpedBlock2 == null ? "" : this.mPumpedBlock2.getUnlocalizedName());
+ aNBT.setString("mPumpedBlock1", this.mPrimaryPumpedBlock == null ? "" : Block.blockRegistry.getNameForObject(this.mPrimaryPumpedBlock));
+ aNBT.setString("mPumpedBlock2", this.mSecondaryPumpedBlock == null ? "" : Block.blockRegistry.getNameForObject(this.mSecondaryPumpedBlock));
+ aNBT.setBoolean("wasPumping", wasPumping);
}
public void loadNBTData(NBTTagCompound aNBT) {
super.loadNBTData(aNBT);
- this.mPumpedBlock1 = Block.getBlockFromName(aNBT.getString("mPumpedBlock1"));
- this.mPumpedBlock2 = Block.getBlockFromName(aNBT.getString("mPumpedBlock2"));
+ this.wasPumping = aNBT.getBoolean("wasPumping");
+ this.mPrimaryPumpedBlock = Block.getBlockFromName(aNBT.getString("mPumpedBlock1"));
+ this.mSecondaryPumpedBlock = Block.getBlockFromName(aNBT.getString("mPumpedBlock2"));
+
+ if (D1) {
+ GT_Log.out.println("PUMP: NBT:Load - WasPumping - " + this.wasPumping + "(" + aNBT.getString("mPumpedBlock1") + ") " + this.mPrimaryPumpedBlock);
+ }
+
}
@Override
@@ -122,51 +154,97 @@ public class GT_MetaTileEntity_Pump extends GT_MetaTileEntity_Hatch {
}
this.doTickProfilingInThisTick = true;
this.mPumpCountBelow = 0;
+
IGregTechTileEntity tTileEntity;
- for (int i = 1; (i < 21) && ((tTileEntity = getBaseMetaTileEntity().getIGregTechTileEntityAtSideAndDistance((byte) 0, i)) != null)
- && ((tTileEntity.getMetaTileEntity() instanceof GT_MetaTileEntity_Pump)); i++) {
+ for (int i = 1 ;
+ (i < 21) && ((tTileEntity = getBaseMetaTileEntity().getIGregTechTileEntityAtSideAndDistance((byte) 0, i)) != null)
+ && ((tTileEntity.getMetaTileEntity() instanceof GT_MetaTileEntity_Pump)) ; i++)
+ {
+ // Apparently someone might stack 21 pumps on top of each other, so let's check for that
getBaseMetaTileEntity().setActive(tTileEntity.isActive());
this.mPumpCountBelow += 1;
+ // The more pumps we have stacked, the faster the ones below go
((GT_MetaTileEntity_Pump) tTileEntity.getMetaTileEntity()).mPumpTimer -= 1;
}
if (this.mPumpCountBelow <= 0) {
- if ((getBaseMetaTileEntity().isAllowedToWork()) && (getBaseMetaTileEntity().isUniversalEnergyStored(16 * ((int) Math.pow(4, this.mTier))))
+ // Only the bottom most pump does anything
+ if ((getBaseMetaTileEntity().isAllowedToWork()) && (getBaseMetaTileEntity().isUniversalEnergyStored(this.getEuUsagePerAction()))
&& ((this.mFluid == null) || (this.mFluid.amount + 1000 <= getCapacity()))) {
boolean tMovedOneDown = false;
if ((this.mPumpList.isEmpty()) && (getBaseMetaTileEntity().getTimer() % 100L == 0L)) {
- tMovedOneDown = moveOneDown();
- }
- if ((GT_Utility.isBlockInvalid(this.mPumpedBlock1)) || (GT_Utility.isBlockInvalid(this.mPumpedBlock2))) {
- getFluidAt(getBaseMetaTileEntity().getXCoord(), getYOfPumpHead() - 1, getBaseMetaTileEntity().getZCoord());
- if ((GT_Utility.isBlockInvalid(this.mPumpedBlock1)) || (GT_Utility.isBlockInvalid(this.mPumpedBlock2))) {
- getFluidAt(getBaseMetaTileEntity().getXCoord(), getYOfPumpHead(), getBaseMetaTileEntity().getZCoord() + 1);
- }
- if ((GT_Utility.isBlockInvalid(this.mPumpedBlock1)) || (GT_Utility.isBlockInvalid(this.mPumpedBlock2))) {
- getFluidAt(getBaseMetaTileEntity().getXCoord(), getYOfPumpHead(), getBaseMetaTileEntity().getZCoord() - 1);
+ if (!this.wasPumping){
+ tMovedOneDown = moveOneDown();
+ if (D1) {
+ GT_Log.out.println("PUMP: Moved down");
+ }
+ } else if (D1) {
+ GT_Log.out.println("PUMP: Was pumping, didn't move down");
}
- if ((GT_Utility.isBlockInvalid(this.mPumpedBlock1)) || (GT_Utility.isBlockInvalid(this.mPumpedBlock2))) {
- getFluidAt(getBaseMetaTileEntity().getXCoord() + 1, getYOfPumpHead(), getBaseMetaTileEntity().getZCoord());
+ }
+ int x = getBaseMetaTileEntity().getXCoord(), z = getBaseMetaTileEntity().getZCoord();
+
+ if (!this.hasValidFluid()) {
+ // We don't have a valid block, let's try to find one
+ int y = getYOfPumpHead();
+
+ if (D1 && this.mPrimaryPumpedBlock != null) {
+ GT_Log.out.println("PUMP: Had an invalid pump block. Trying to find a fluid at Y: " + y +
+ " Previous blocks 1: " + this.mPrimaryPumpedBlock + " 2: " + this.mSecondaryPumpedBlock);
}
- if ((GT_Utility.isBlockInvalid(this.mPumpedBlock1)) || (GT_Utility.isBlockInvalid(this.mPumpedBlock2))) {
- getFluidAt(getBaseMetaTileEntity().getXCoord() - 1, getYOfPumpHead(), getBaseMetaTileEntity().getZCoord());
+ // First look down
+ checkForFluidToPump(x, y - 1, z );
+
+ // Then look all around
+ checkForFluidToPump(x, y, z + 1);
+ checkForFluidToPump(x, y, z - 1);
+ checkForFluidToPump(x + 1, y, z );
+ checkForFluidToPump(x - 1, y, z );
+ this.clearQueue(false);
+
+ if(this.hasValidFluid()) {
+ // Don't move down and rebuild the queue if we now have a valid fluid
+ this.wasPumping = true;
}
+
} else if (getYOfPumpHead() < getBaseMetaTileEntity().getYCoord()) {
- if ((tMovedOneDown) || ((this.mPumpList.isEmpty()) && (getBaseMetaTileEntity().getTimer() % 200L == 100L)) || (getBaseMetaTileEntity().getTimer() % 72000L == 100L)) {
- this.mPumpList.clear();
- int y = getBaseMetaTileEntity().getYCoord() - 1;
- for (int yHead = getYOfPumpHead(); (this.mPumpList.isEmpty()) && (y >= yHead); y--) {
- scanForFluid(getBaseMetaTileEntity().getXCoord(), y, getBaseMetaTileEntity().getZCoord(), this.mPumpList, getBaseMetaTileEntity().getXCoord(), getBaseMetaTileEntity().getZCoord(), 10 * ((int) Math.pow(1.6, this.mTier)));
+ // We didn't just look for a block, and the pump head is below the pump
+ if ((tMovedOneDown) || this.wasPumping ||
+ ((this.mPumpList.isEmpty()) && (getBaseMetaTileEntity().getTimer() % 200L == 100L)) ||
+ (getBaseMetaTileEntity().getTimer() % 72000L == 100L))
+ {
+ // Rebuild the list to pump if any of the following conditions are true:
+ // 1) We just moved down
+ // 2) We were previously pumping (and possibly just reloaded)
+ // 3) We have an empty queue and enough time has passed
+ // 4) A long while has has passed
+ if (D1) {
+ GT_Log.out.println("PUMP: Rebuilding pump list - Size " +
+ this.mPumpList.size() + " WasPumping: " + this.wasPumping + " Timer " + getBaseMetaTileEntity().getTimer());
+ }
+ int yPump = getBaseMetaTileEntity().getYCoord() - 1, yHead = getYOfPumpHead();
+
+ this.rebuildPumpQueue(x, yPump, z, yHead);
+
+ if (D1) {
+ GT_Log.out.println("PUMP: Rebuilt pump list - Size " + this.mPumpList.size());
}
+
}
if ((!tMovedOneDown) && (this.mPumpTimer <= 0)) {
- while ((!this.mPumpList.isEmpty())
- && (!consumeFluid(((ChunkPosition) this.mPumpList.get(this.mPumpList.size() - 1)).chunkPosX,
- ((ChunkPosition) this.mPumpList.get(this.mPumpList.size() - 1)).chunkPosY,
- ((ChunkPosition) this.mPumpList.remove(this.mPumpList.size() - 1)).chunkPosZ))) {
- //Should this be empty?
+ while ((!this.mPumpList.isEmpty())) {
+ ChunkPosition pos = this.mPumpList.pollLast();
+ if (consumeFluid(pos.chunkPosX, pos.chunkPosY, pos.chunkPosZ)) {
+ // Keep trying until we consume something, or the list is empty
+ break;
+ }
}
- this.mPumpTimer = 160 / ((int) Math.pow(2, this.mTier));
+ this.mPumpTimer = GT_Utility.safeInt(160 / (long)Math.pow(2, this.mTier) );
+ this.mPumpTimer = mPumpTimer==0 ? 1 : mPumpTimer;
}
+ } else {
+ // We somehow have a valid fluid, but the head of the pump isn't below the pump. Perhaps someone broke some pipes
+ // -- Clear the queue and we should try to move down until we can find a valid fluid
+ this.clearQueue(false);
}
}
getBaseMetaTileEntity().setActive(!this.mPumpList.isEmpty());
@@ -174,160 +252,216 @@ public class GT_MetaTileEntity_Pump extends GT_MetaTileEntity_Hatch {
}
}
+ private int getMaxPumpableDistance() {
+ return GT_MetaTileEntity_Pump.getMaxDistanceForTier(this.mTier);
+ }
+
+ private long getEuUsagePerAction() {
+ return GT_MetaTileEntity_Pump.getEuUsagePerTier(this.mTier);
+ }
+
+ private boolean hasValidFluid() {
+ return (!GT_Utility.isBlockInvalid(this.mPrimaryPumpedBlock) && !GT_Utility.isBlockInvalid(this.mSecondaryPumpedBlock));
+ }
+
private boolean moveOneDown() {
- if ((this.mInventory[0] == null) || (this.mInventory[0].stackSize < 1)
- || (!GT_Utility.areStacksEqual(this.mInventory[0], MINING_PIPE))) {
+ if ((this.mInventory[0] == null) || (this.mInventory[0].stackSize < 1) || (!GT_Utility.areStacksEqual(this.mInventory[0], MINING_PIPE))) {
+ // No mining pipes
return false;
}
+
int yHead = getYOfPumpHead();
- if (yHead <= 0) {
+ if (yHead <= 1) {
+ // Let's not punch through bedrock
return false;
}
- if ((!consumeFluid(getBaseMetaTileEntity().getXCoord(), yHead - 1, getBaseMetaTileEntity().getZCoord())) && (!getBaseMetaTileEntity().getBlock(getBaseMetaTileEntity().getXCoord(), yHead - 1, getBaseMetaTileEntity().getZCoord()).isAir(getBaseMetaTileEntity().getWorld(), getBaseMetaTileEntity().getXCoord(), yHead - 1, getBaseMetaTileEntity().getZCoord()))) {
+
+ int x = getBaseMetaTileEntity().getXCoord(), z = getBaseMetaTileEntity().getZCoord();
+
+ if ((!consumeFluid(x, yHead - 1, z)) && (!getBaseMetaTileEntity().getBlock(x, yHead - 1, z).isAir(getBaseMetaTileEntity().getWorld(), x, yHead - 1, z))) {
+ // Either we didn't consume a fluid, or it's a non Air block
return false;
}
- if (!GT_Utility.setBlockByFakePlayer(getFakePlayer(getBaseMetaTileEntity()), getBaseMetaTileEntity().getXCoord(), yHead - 1, getBaseMetaTileEntity().getZCoord(), MINING_PIPE_TIP_BLOCK, 0, false)) {
+
+ // Try to set the block below us to a a tip
+ if (!GT_Utility.setBlockByFakePlayer(getFakePlayer(getBaseMetaTileEntity()), x, yHead - 1, z, MINING_PIPE_TIP_BLOCK, 0, false)) {
return false;
}
+ // And change the previous block to a pipe -- as long as it isn't the pump itself!
if (yHead != getBaseMetaTileEntity().getYCoord()) {
- getBaseMetaTileEntity().getWorld().setBlock(getBaseMetaTileEntity().getXCoord(), yHead, getBaseMetaTileEntity().getZCoord(), MINING_PIPE_BLOCK);
+ getBaseMetaTileEntity().getWorld().setBlock(x, yHead, z, MINING_PIPE_BLOCK);
}
getBaseMetaTileEntity().decrStackSize(0, 1);
return true;
}
private int getYOfPumpHead() {
- int y = getBaseMetaTileEntity().getYCoord() - 1;
- while (getBaseMetaTileEntity().getBlock(getBaseMetaTileEntity().getXCoord(), y, getBaseMetaTileEntity().getZCoord()) == MINING_PIPE_BLOCK) {
- y--;
+ // Let's play find the pump head!
+
+ // TODO: Handle pipe|pipe|head|pipe|pipe
+ int y = getBaseMetaTileEntity().getYCoord() - 1, x = getBaseMetaTileEntity().getXCoord(), z = getBaseMetaTileEntity().getZCoord();
+
+ while(y > 0) {
+ Block curBlock = getBaseMetaTileEntity().getBlock(x, y, z);
+ if(curBlock == MINING_PIPE_BLOCK) {
+ y--;
+ } else if (curBlock == MINING_PIPE_TIP_BLOCK) {
+ Block nextBlock = getBaseMetaTileEntity().getBlock(x, y - 1 , z);
+ if (nextBlock == MINING_PIPE_BLOCK || nextBlock == MINING_PIPE_TIP_BLOCK) {
+ // We're running into an existing set of pipes -- Turn this block into a pipe and keep going
+ this.clearQueue(true);
+ getBaseMetaTileEntity().getWorld().setBlock(x, y, z, MINING_PIPE_BLOCK);
+ }
+ y--;
+
+ } else {
+ break;
+ }
}
- if (y == getBaseMetaTileEntity().getYCoord() - 1) {
- if (getBaseMetaTileEntity().getBlock(getBaseMetaTileEntity().getXCoord(), y, getBaseMetaTileEntity().getZCoord()) != MINING_PIPE_TIP_BLOCK) {
- return y + 1;
+
+
+ if (getBaseMetaTileEntity().getBlock(x, y, z) != MINING_PIPE_TIP_BLOCK) {
+ if (y != getBaseMetaTileEntity().getYCoord() - 1 && getBaseMetaTileEntity().getBlock(x, y + 1, z) == MINING_PIPE_BLOCK) {
+ // We're below the pump at the bottom of the pipes, we haven't found a tip; make the previous pipe a tip!
+ this.clearQueue(true);
+ getBaseMetaTileEntity().getWorld().setBlock(x, y + 1, z, MINING_PIPE_TIP_BLOCK);
}
- } else if (getBaseMetaTileEntity().getBlock(getBaseMetaTileEntity().getXCoord(), y, getBaseMetaTileEntity().getZCoord()) != MINING_PIPE_TIP_BLOCK
- && this.mInventory[0] != null && this.mInventory[0].stackSize > 0 && GT_Utility.areStacksEqual(this.mInventory[0], MINING_PIPE)) {
- getBaseMetaTileEntity().getWorld().setBlock(getBaseMetaTileEntity().getXCoord(), y, getBaseMetaTileEntity().getZCoord(), MINING_PIPE_BLOCK);
- getBaseMetaTileEntity().decrStackSize(0, 1);
+
+ return y + 1;
}
return y;
}
- private void scanForFluid(int aX, int aY, int aZ, ArrayList<ChunkPosition> aList, int mX, int mZ, int mDist) {
+ private void clearQueue(boolean checkPumping) {
+ if(checkPumping) {
+ this.wasPumping = !this.mPumpList.isEmpty();
+ } else {
+ this.wasPumping = false;
+ }
+ this.mPumpList.clear();
+ }
+
+ private void rebuildPumpQueue(int aX, int yStart, int aZ, int yEnd) {
+ int mDist = this.getMaxPumpableDistance();
doTickProfilingInThisTick = false;
- ArrayList tList1 = new ArrayList();
- ArrayList tList2 = new ArrayList();
- tList1.add(new ChunkPosition(aX, aY, aZ));
- while (!tList1.isEmpty()) {
- Iterator i$ = tList1.iterator();
- do {
- if (!i$.hasNext())
- break;
- ChunkPosition tPos = (ChunkPosition) i$.next();
- if (tPos.chunkPosX < mX + mDist)
- addToFirstListIfFluidAndNotAlreadyAddedToAnyOfTheLists(tPos.chunkPosX + 1, tPos.chunkPosY, tPos.chunkPosZ, tList2, aList);
- if (tPos.chunkPosX > mX - mDist)
- addToFirstListIfFluidAndNotAlreadyAddedToAnyOfTheLists(tPos.chunkPosX - 1, tPos.chunkPosY, tPos.chunkPosZ, tList2, aList);
- if (tPos.chunkPosZ < mZ + mDist)
- addToFirstListIfFluidAndNotAlreadyAddedToAnyOfTheLists(tPos.chunkPosX, tPos.chunkPosY, tPos.chunkPosZ + 1, tList2, aList);
- if (tPos.chunkPosZ > mZ - mDist)
- addToFirstListIfFluidAndNotAlreadyAddedToAnyOfTheLists(tPos.chunkPosX, tPos.chunkPosY, tPos.chunkPosZ - 1, tList2, aList);
- addToFirstListIfFluidAndNotAlreadyAddedToAnyOfTheLists(tPos.chunkPosX, tPos.chunkPosY + 1, tPos.chunkPosZ, tList2, aList);
- ChunkPosition tCoordinate = new ChunkPosition(aX, aY + 1, aZ);
- if (tPos.chunkPosX == mX && tPos.chunkPosZ == mZ && tPos.chunkPosY < getBaseMetaTileEntity().getYCoord() && !aList.contains(tCoordinate) && !tList2.contains(tCoordinate))
- tList2.add(tCoordinate);
- } while (true);
- aList.addAll(tList2);
- tList1 = tList2;
- tList2 = new ArrayList();
+ ArrayDeque<ChunkPosition> fluidsToSearch = new ArrayDeque<ChunkPosition>();
+ ArrayDeque<ChunkPosition> fluidsFound = new ArrayDeque<ChunkPosition>();
+ Set<ChunkPosition> checked = new HashSet<ChunkPosition>();
+ this.clearQueue(false);
+
+ for (int aY = yStart ; this.mPumpList.isEmpty() && aY >= yEnd ; aY--) {
+ // Start at the top (presumably the block below the pump), and work our way down to the end (presumably the location of the pump Head)
+ // and build up a queue of fluids to pump
+ fluidsToSearch.add(new ChunkPosition(aX, aY, aZ));
+
+ while (!fluidsToSearch.isEmpty()) {
+ Iterator<ChunkPosition> i$ = fluidsToSearch.iterator();
+ while(i$.hasNext()) {
+ ChunkPosition tPos = i$.next();
+
+ // Look all around
+ if (tPos.chunkPosX < aX + mDist) queueFluid(tPos.chunkPosX + 1, tPos.chunkPosY, tPos.chunkPosZ, fluidsFound, checked);
+ if (tPos.chunkPosX > aX - mDist) queueFluid(tPos.chunkPosX - 1, tPos.chunkPosY, tPos.chunkPosZ, fluidsFound, checked);
+ if (tPos.chunkPosZ < aZ + mDist) queueFluid(tPos.chunkPosX, tPos.chunkPosY, tPos.chunkPosZ + 1, fluidsFound, checked);
+ if (tPos.chunkPosZ > aZ - mDist) queueFluid(tPos.chunkPosX, tPos.chunkPosY, tPos.chunkPosZ - 1, fluidsFound, checked);
+
+ // And then look up
+ queueFluid(tPos.chunkPosX, tPos.chunkPosY + 1, tPos.chunkPosZ, this.mPumpList, checked);
+ }
+ this.mPumpList.addAll(fluidsFound);
+ fluidsToSearch = fluidsFound;
+ fluidsFound = new ArrayDeque<ChunkPosition>();
+ }
+
+ // Make sure we don't have the pipe location in the queue
+ this.mPumpList.remove(new ChunkPosition(aX, aY, aZ));
}
- for (int y = getBaseMetaTileEntity().getYCoord(); y >= aY; y--)
- aList.remove(new ChunkPosition(aX, y, aZ));
}
- private boolean addToFirstListIfFluidAndNotAlreadyAddedToAnyOfTheLists(int aX, int aY, int aZ, ArrayList<ChunkPosition> aList1,
- ArrayList<ChunkPosition> aList2) {
+ private boolean queueFluid(int aX, int aY, int aZ, ArrayDeque<ChunkPosition> fluidsFound, Set<ChunkPosition> checked) {
+ // If we haven't already looked at this coordinate set, and it's not already in the list of fluids found, see if there is
+ // a valid fluid and add it to the fluids found
ChunkPosition tCoordinate = new ChunkPosition(aX, aY, aZ);
- if ((!aList1.contains(tCoordinate)) && (!aList2.contains(tCoordinate))) {
+ if (checked.add(tCoordinate) && !fluidsFound.contains(tCoordinate)) {
Block aBlock = getBaseMetaTileEntity().getBlock(aX, aY, aZ);
- if ((this.mPumpedBlock1 == aBlock) || (this.mPumpedBlock2 == aBlock)) {
- aList1.add(tCoordinate);
+ if ((this.mPrimaryPumpedBlock == aBlock) || (this.mSecondaryPumpedBlock == aBlock)) {
+ fluidsFound.addFirst(tCoordinate);
return true;
}
}
return false;
}
- private void getFluidAt(int aX, int aY, int aZ) {
+ private void checkForFluidToPump(int aX, int aY, int aZ) {
+ // If we don't currently have a valid fluid to pump, try pumping the fluid at the given coordinates
+ if(this.hasValidFluid())
+ return;
+
Block aBlock = getBaseMetaTileEntity().getBlock(aX, aY, aZ);
if (GT_Utility.isBlockValid(aBlock)) {
if ((aBlock == Blocks.water) || (aBlock == Blocks.flowing_water)) {
- this.mPumpedBlock1 = Blocks.water;
- this.mPumpedBlock2 = Blocks.flowing_water;
+ this.mPrimaryPumpedBlock = Blocks.water;
+ this.mSecondaryPumpedBlock = Blocks.flowing_water;
return;
}
if ((aBlock == Blocks.lava) || (aBlock == Blocks.flowing_lava)) {
- this.mPumpedBlock1 = Blocks.lava;
- this.mPumpedBlock2 = Blocks.flowing_lava;
+ this.mPrimaryPumpedBlock = Blocks.lava;
+ this.mSecondaryPumpedBlock = Blocks.flowing_lava;
return;
}
if ((aBlock instanceof IFluidBlock)) {
- this.mPumpedBlock1 = aBlock;
- this.mPumpedBlock2 = aBlock;
+ this.mPrimaryPumpedBlock = aBlock;
+ this.mSecondaryPumpedBlock = aBlock;
return;
}
}
- this.mPumpedBlock1 = null;
- this.mPumpedBlock2 = null;
+ this.mPrimaryPumpedBlock = null;
+ this.mSecondaryPumpedBlock = null;
}
private boolean consumeFluid(int aX, int aY, int aZ) {
- if (!GT_Utility.eraseBlockByFakePlayer(getFakePlayer(getBaseMetaTileEntity()), aX, aY, aZ, true)) return false;
+ // Try to consume a fluid at a location
+ // Returns true if something was consumed, otherwise false
+ if (!GT_Utility.eraseBlockByFakePlayer(getFakePlayer(getBaseMetaTileEntity()), aX, aY, aZ, true)) return false;
+
Block aBlock = getBaseMetaTileEntity().getBlock(aX, aY, aZ);
- int aMeta = getBaseMetaTileEntity().getMetaID(aX, aY, aZ);
- if ((GT_Utility.isBlockValid(aBlock)) && ((this.mPumpedBlock1 == aBlock) || (this.mPumpedBlock2 == aBlock))) {
- if ((aBlock == Blocks.water) || (aBlock == Blocks.flowing_water)) {
- if (aMeta == 0) {
- if (this.mFluid == null) {
- getBaseMetaTileEntity().decreaseStoredEnergyUnits(16 * ((int) Math.pow(4, this.mTier)), true);
- this.mFluid = GT_ModHandler.getWater(1000L);
- } else if (GT_ModHandler.isWater(this.mFluid)) {
- getBaseMetaTileEntity().decreaseStoredEnergyUnits(16 * ((int) Math.pow(4, this.mTier)), true);
- this.mFluid.amount += 1000;
- } else {
- return false;
- }
- } else {
- getBaseMetaTileEntity().decreaseStoredEnergyUnits(4 * ((int) Math.pow(4, this.mTier)), true);
- }
- }
- if ((aBlock == Blocks.lava) || (aBlock == Blocks.flowing_lava)) {
- if (aMeta == 0) {
- if (this.mFluid == null) {
- getBaseMetaTileEntity().decreaseStoredEnergyUnits(16 * ((int) Math.pow(4, this.mTier)), true);
- this.mFluid = GT_ModHandler.getLava(1000L);
- } else if (GT_ModHandler.isLava(this.mFluid)) {
- getBaseMetaTileEntity().decreaseStoredEnergyUnits(16 * ((int) Math.pow(4, this.mTier)), true);
- this.mFluid.amount += 1000;
- } else {
- return false;
- }
- } else {
- getBaseMetaTileEntity().decreaseStoredEnergyUnits(4 * ((int) Math.pow(4, this.mTier)), true);
+
+ if ((GT_Utility.isBlockValid(aBlock)) && ((this.mPrimaryPumpedBlock == aBlock) || (this.mSecondaryPumpedBlock == aBlock))) {
+ boolean isWaterOrLava = ((this.mPrimaryPumpedBlock == Blocks.water || this.mPrimaryPumpedBlock == Blocks.lava));
+
+ if (isWaterOrLava && getBaseMetaTileEntity().getMetaID(aX, aY, aZ) != 0) {
+ // Water/Lava that isn't a source block - do nothing here, but set the block to air and consume energy below
+ if (D1) {
+ GT_Log.out.println("PUMP: Water/Lava - Not a source block");
}
- }
- if ((aBlock instanceof IFluidBlock)) {
- if (this.mFluid == null) {
+ } else if (this.mFluid == null) {
+ // The pump has no internal fluid
+ if (this.mPrimaryPumpedBlock == Blocks.water)
+ this.mFluid = GT_ModHandler.getWater(1000L);
+ else if (this.mPrimaryPumpedBlock == Blocks.lava)
+ this.mFluid = GT_ModHandler.getLava(1000L);
+ else {
+ // Not water or lava; try to drain and set to air
this.mFluid = ((IFluidBlock) aBlock).drain(getBaseMetaTileEntity().getWorld(), aX, aY, aZ, true);
- getBaseMetaTileEntity().decreaseStoredEnergyUnits(this.mFluid == null ? 1000 : this.mFluid.amount, true);
- } else if (this.mFluid.isFluidEqual(((IFluidBlock) aBlock).drain(getBaseMetaTileEntity().getWorld(), aX, aY, aZ, false))) {
+ }
+ } else if (GT_ModHandler.isWater(this.mFluid) || GT_ModHandler.isLava(this.mFluid) ||
+ this.mFluid.isFluidEqual(((IFluidBlock) aBlock).drain(getBaseMetaTileEntity().getWorld(), aX, aY, aZ, false)))
+ {
+ if (!isWaterOrLava) {
+ // Only set Block to Air for non lava/water fluids
this.getBaseMetaTileEntity().getWorld().setBlockToAir(aX, aY, aZ);
- this.mFluid.amount += 1000;
- getBaseMetaTileEntity().decreaseStoredEnergyUnits(16 * ((int) Math.pow(4, this.mTier)), true);
- } else {
- return false;
}
+ this.mFluid.amount += 1000;
+
+ } else {
+ if (D1) {
+ GT_Log.out.println("PUMP: Couldn't consume " + aBlock);
+ }
+ // We didn't do anything
+ return false;
}
+
+ getBaseMetaTileEntity().decreaseStoredEnergyUnits(this.getEuUsagePerAction(), true);
getBaseMetaTileEntity().getWorld().setBlock(aX, aY, aZ, Blocks.air, 0, 2);
return true;
}
@@ -435,7 +569,7 @@ public class GT_MetaTileEntity_Pump extends GT_MetaTileEntity_Hatch {
@Override
public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, byte aSide, byte aFacing, byte aColorIndex, boolean aActive, boolean aRedstone) {
- return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[mTier][aColorIndex + 1], (aSide == 0 || aSide == 1) ? null : new GT_RenderedTexture(Textures.BlockIcons.OVERLAY_ADV_PUMP)};
+ return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[mTier][aColorIndex + 1], (aSide == 0 || aSide == 1) ? new GT_RenderedTexture(Textures.BlockIcons.OVERLAY_PIPE_OUT) : new GT_RenderedTexture(Textures.BlockIcons.OVERLAY_ADV_PUMP)};
}
@Override
@@ -453,9 +587,9 @@ public class GT_MetaTileEntity_Pump extends GT_MetaTileEntity_Hatch {
private FakePlayer mFakePlayer = null;
protected FakePlayer getFakePlayer(IGregTechTileEntity aBaseTile) {
- if (mFakePlayer == null) mFakePlayer = GT_Utility.getFakePlayer(aBaseTile);
- mFakePlayer.setWorld(aBaseTile.getWorld());
- mFakePlayer.setPosition(aBaseTile.getXCoord(), aBaseTile.getYCoord(), aBaseTile.getZCoord());
- return mFakePlayer;
+ if (mFakePlayer == null) mFakePlayer = GT_Utility.getFakePlayer(aBaseTile);
+ mFakePlayer.setWorld(aBaseTile.getWorld());
+ mFakePlayer.setPosition(aBaseTile.getXCoord(), aBaseTile.getYCoord(), aBaseTile.getZCoord());
+ return mFakePlayer;
}
}