Merge pull request #1300 from mitchej123/bloody_unstable

Single block pump refactor & bugfix
This commit is contained in:
Blood-Asp 2017-11-25 19:02:00 +01:00 committed by GitHub
commit 84e95d30ab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,5 +1,7 @@
package gregtech.common.tileentities.machines.basic; package gregtech.common.tileentities.machines.basic;
import cpw.mods.fml.common.registry.GameRegistry;
import gregtech.api.enums.Textures; import gregtech.api.enums.Textures;
import gregtech.api.gui.GT_Container_BasicTank; import gregtech.api.gui.GT_Container_BasicTank;
import gregtech.api.gui.GT_GUIContainer_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.BaseTileEntity;
import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch; import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch;
import gregtech.api.objects.GT_RenderedTexture; import gregtech.api.objects.GT_RenderedTexture;
import gregtech.api.util.GT_Log;
import gregtech.api.util.GT_ModHandler; import gregtech.api.util.GT_ModHandler;
import gregtech.api.util.GT_Utility; import gregtech.api.util.GT_Utility;
import net.minecraft.block.Block; import net.minecraft.block.Block;
@ -21,25 +24,43 @@ import net.minecraft.world.ChunkPosition;
import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidBlock; 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.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.enums.GT_Values.V;
import static gregtech.api.util.GT_Utility.getFakePlayer;
public class GT_MetaTileEntity_Pump extends GT_MetaTileEntity_Hatch { 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_BLOCK = GT_Utility.getBlockFromStack(MINING_PIPE);
private static final Block MINING_PIPE_TIP_BLOCK = GT_Utility.getBlockFromStack(GT_ModHandler.getIC2Item("miningPipeTip", 0)); 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 mPumpTimer = 0;
public int mPumpCountBelow = 0; public int mPumpCountBelow = 0;
public Block mPumpedBlock1 = null; public Block mPrimaryPumpedBlock = null;
public Block mPumpedBlock2 = null; public Block mSecondaryPumpedBlock = null;
public GT_MetaTileEntity_Pump(int aID, String aName, String aNameRegional, int aTier) { 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) { 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) { 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); super.saveNBTData(aNBT);
aNBT.setString("mPumpedBlock1", this.mPumpedBlock1 == null ? "" : this.mPumpedBlock1.getUnlocalizedName()); aNBT.setString("mPumpedBlock1", this.mPrimaryPumpedBlock == null ? "" : Block.blockRegistry.getNameForObject(this.mPrimaryPumpedBlock));
aNBT.setString("mPumpedBlock2", this.mPumpedBlock2 == null ? "" : this.mPumpedBlock2.getUnlocalizedName()); aNBT.setString("mPumpedBlock2", this.mSecondaryPumpedBlock == null ? "" : Block.blockRegistry.getNameForObject(this.mSecondaryPumpedBlock));
aNBT.setBoolean("wasPumping", wasPumping);
} }
public void loadNBTData(NBTTagCompound aNBT) { public void loadNBTData(NBTTagCompound aNBT) {
super.loadNBTData(aNBT); super.loadNBTData(aNBT);
this.mPumpedBlock1 = Block.getBlockFromName(aNBT.getString("mPumpedBlock1")); this.wasPumping = aNBT.getBoolean("wasPumping");
this.mPumpedBlock2 = Block.getBlockFromName(aNBT.getString("mPumpedBlock2")); 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 @Override
@ -122,51 +154,97 @@ public class GT_MetaTileEntity_Pump extends GT_MetaTileEntity_Hatch {
} }
this.doTickProfilingInThisTick = true; this.doTickProfilingInThisTick = true;
this.mPumpCountBelow = 0; this.mPumpCountBelow = 0;
IGregTechTileEntity tTileEntity; IGregTechTileEntity tTileEntity;
for (int i = 1; (i < 21) && ((tTileEntity = getBaseMetaTileEntity().getIGregTechTileEntityAtSideAndDistance((byte) 0, i)) != null) for (int i = 1 ;
&& ((tTileEntity.getMetaTileEntity() instanceof GT_MetaTileEntity_Pump)); i++) { (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()); getBaseMetaTileEntity().setActive(tTileEntity.isActive());
this.mPumpCountBelow += 1; this.mPumpCountBelow += 1;
// The more pumps we have stacked, the faster the ones below go
((GT_MetaTileEntity_Pump) tTileEntity.getMetaTileEntity()).mPumpTimer -= 1; ((GT_MetaTileEntity_Pump) tTileEntity.getMetaTileEntity()).mPumpTimer -= 1;
} }
if (this.mPumpCountBelow <= 0) { 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()))) { && ((this.mFluid == null) || (this.mFluid.amount + 1000 <= getCapacity()))) {
boolean tMovedOneDown = false; boolean tMovedOneDown = false;
if ((this.mPumpList.isEmpty()) && (getBaseMetaTileEntity().getTimer() % 100L == 0L)) { if ((this.mPumpList.isEmpty()) && (getBaseMetaTileEntity().getTimer() % 100L == 0L)) {
tMovedOneDown = moveOneDown(); if (!this.wasPumping){
} tMovedOneDown = moveOneDown();
if ((GT_Utility.isBlockInvalid(this.mPumpedBlock1)) || (GT_Utility.isBlockInvalid(this.mPumpedBlock2))) { if (D1) {
getFluidAt(getBaseMetaTileEntity().getXCoord(), getYOfPumpHead() - 1, getBaseMetaTileEntity().getZCoord()); GT_Log.out.println("PUMP: Moved down");
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 ((GT_Utility.isBlockInvalid(this.mPumpedBlock1)) || (GT_Utility.isBlockInvalid(this.mPumpedBlock2))) {
getFluidAt(getBaseMetaTileEntity().getXCoord() + 1, getYOfPumpHead(), getBaseMetaTileEntity().getZCoord());
}
if ((GT_Utility.isBlockInvalid(this.mPumpedBlock1)) || (GT_Utility.isBlockInvalid(this.mPumpedBlock2))) {
getFluidAt(getBaseMetaTileEntity().getXCoord() - 1, getYOfPumpHead(), getBaseMetaTileEntity().getZCoord());
}
} 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)));
} }
} else if (D1) {
GT_Log.out.println("PUMP: Was pumping, didn't move down");
}
}
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);
}
// 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()) {
// 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)) { if ((!tMovedOneDown) && (this.mPumpTimer <= 0)) {
while ((!this.mPumpList.isEmpty()) while ((!this.mPumpList.isEmpty())) {
&& (!consumeFluid(((ChunkPosition) this.mPumpList.get(this.mPumpList.size() - 1)).chunkPosX, ChunkPosition pos = this.mPumpList.pollLast();
((ChunkPosition) this.mPumpList.get(this.mPumpList.size() - 1)).chunkPosY, if (consumeFluid(pos.chunkPosX, pos.chunkPosY, pos.chunkPosZ)) {
((ChunkPosition) this.mPumpList.remove(this.mPumpList.size() - 1)).chunkPosZ))) { // Keep trying until we consume something, or the list is empty
//Should this be 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()); 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() { private boolean moveOneDown() {
if ((this.mInventory[0] == null) || (this.mInventory[0].stackSize < 1) if ((this.mInventory[0] == null) || (this.mInventory[0].stackSize < 1) || (!GT_Utility.areStacksEqual(this.mInventory[0], MINING_PIPE))) {
|| (!GT_Utility.areStacksEqual(this.mInventory[0], MINING_PIPE))) { // No mining pipes
return false; return false;
} }
int yHead = getYOfPumpHead(); int yHead = getYOfPumpHead();
if (yHead <= 0) { if (yHead <= 1) {
// Let's not punch through bedrock
return false; 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; 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; return false;
} }
// And change the previous block to a pipe -- as long as it isn't the pump itself!
if (yHead != getBaseMetaTileEntity().getYCoord()) { 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); getBaseMetaTileEntity().decrStackSize(0, 1);
return true; return true;
} }
private int getYOfPumpHead() { private int getYOfPumpHead() {
int y = getBaseMetaTileEntity().getYCoord() - 1; // Let's play find the pump head!
while (getBaseMetaTileEntity().getBlock(getBaseMetaTileEntity().getXCoord(), y, getBaseMetaTileEntity().getZCoord()) == MINING_PIPE_BLOCK) {
y--; // TODO: Handle pipe|pipe|head|pipe|pipe
} int y = getBaseMetaTileEntity().getYCoord() - 1, x = getBaseMetaTileEntity().getXCoord(), z = getBaseMetaTileEntity().getZCoord();
if (y == getBaseMetaTileEntity().getYCoord() - 1) {
if (getBaseMetaTileEntity().getBlock(getBaseMetaTileEntity().getXCoord(), y, getBaseMetaTileEntity().getZCoord()) != MINING_PIPE_TIP_BLOCK) { while(y > 0) {
return y + 1; 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;
} }
} 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); 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);
}
return y + 1;
} }
return y; 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) {
doTickProfilingInThisTick = false; if(checkPumping) {
ArrayList tList1 = new ArrayList(); this.wasPumping = !this.mPumpList.isEmpty();
ArrayList tList2 = new ArrayList(); } else {
tList1.add(new ChunkPosition(aX, aY, aZ)); this.wasPumping = false;
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();
} }
for (int y = getBaseMetaTileEntity().getYCoord(); y >= aY; y--) this.mPumpList.clear();
aList.remove(new ChunkPosition(aX, y, aZ));
} }
private boolean addToFirstListIfFluidAndNotAlreadyAddedToAnyOfTheLists(int aX, int aY, int aZ, ArrayList<ChunkPosition> aList1, private void rebuildPumpQueue(int aX, int yStart, int aZ, int yEnd) {
ArrayList<ChunkPosition> aList2) { int mDist = this.getMaxPumpableDistance();
doTickProfilingInThisTick = false;
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));
}
}
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); 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); Block aBlock = getBaseMetaTileEntity().getBlock(aX, aY, aZ);
if ((this.mPumpedBlock1 == aBlock) || (this.mPumpedBlock2 == aBlock)) { if ((this.mPrimaryPumpedBlock == aBlock) || (this.mSecondaryPumpedBlock == aBlock)) {
aList1.add(tCoordinate); fluidsFound.addFirst(tCoordinate);
return true; return true;
} }
} }
return false; 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); Block aBlock = getBaseMetaTileEntity().getBlock(aX, aY, aZ);
if (GT_Utility.isBlockValid(aBlock)) { if (GT_Utility.isBlockValid(aBlock)) {
if ((aBlock == Blocks.water) || (aBlock == Blocks.flowing_water)) { if ((aBlock == Blocks.water) || (aBlock == Blocks.flowing_water)) {
this.mPumpedBlock1 = Blocks.water; this.mPrimaryPumpedBlock = Blocks.water;
this.mPumpedBlock2 = Blocks.flowing_water; this.mSecondaryPumpedBlock = Blocks.flowing_water;
return; return;
} }
if ((aBlock == Blocks.lava) || (aBlock == Blocks.flowing_lava)) { if ((aBlock == Blocks.lava) || (aBlock == Blocks.flowing_lava)) {
this.mPumpedBlock1 = Blocks.lava; this.mPrimaryPumpedBlock = Blocks.lava;
this.mPumpedBlock2 = Blocks.flowing_lava; this.mSecondaryPumpedBlock = Blocks.flowing_lava;
return; return;
} }
if ((aBlock instanceof IFluidBlock)) { if ((aBlock instanceof IFluidBlock)) {
this.mPumpedBlock1 = aBlock; this.mPrimaryPumpedBlock = aBlock;
this.mPumpedBlock2 = aBlock; this.mSecondaryPumpedBlock = aBlock;
return; return;
} }
} }
this.mPumpedBlock1 = null; this.mPrimaryPumpedBlock = null;
this.mPumpedBlock2 = null; this.mSecondaryPumpedBlock = null;
} }
private boolean consumeFluid(int aX, int aY, int aZ) { 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); 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 ((GT_Utility.isBlockValid(aBlock)) && ((this.mPrimaryPumpedBlock == aBlock) || (this.mSecondaryPumpedBlock == aBlock))) {
if ((aBlock == Blocks.water) || (aBlock == Blocks.flowing_water)) { boolean isWaterOrLava = ((this.mPrimaryPumpedBlock == Blocks.water || this.mPrimaryPumpedBlock == Blocks.lava));
if (aMeta == 0) {
if (this.mFluid == null) { if (isWaterOrLava && getBaseMetaTileEntity().getMetaID(aX, aY, aZ) != 0) {
getBaseMetaTileEntity().decreaseStoredEnergyUnits(16 * ((int) Math.pow(4, this.mTier)), true); // Water/Lava that isn't a source block - do nothing here, but set the block to air and consume energy below
this.mFluid = GT_ModHandler.getWater(1000L); if (D1) {
} else if (GT_ModHandler.isWater(this.mFluid)) { GT_Log.out.println("PUMP: Water/Lava - Not a source block");
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);
} }
} } else if (this.mFluid == null) {
if ((aBlock == Blocks.lava) || (aBlock == Blocks.flowing_lava)) { // The pump has no internal fluid
if (aMeta == 0) { if (this.mPrimaryPumpedBlock == Blocks.water)
if (this.mFluid == null) { this.mFluid = GT_ModHandler.getWater(1000L);
getBaseMetaTileEntity().decreaseStoredEnergyUnits(16 * ((int) Math.pow(4, this.mTier)), true); else if (this.mPrimaryPumpedBlock == Blocks.lava)
this.mFluid = GT_ModHandler.getLava(1000L); this.mFluid = GT_ModHandler.getLava(1000L);
} else if (GT_ModHandler.isLava(this.mFluid)) { else {
getBaseMetaTileEntity().decreaseStoredEnergyUnits(16 * ((int) Math.pow(4, this.mTier)), true); // Not water or lava; try to drain and set to air
this.mFluid.amount += 1000;
} else {
return false;
}
} else {
getBaseMetaTileEntity().decreaseStoredEnergyUnits(4 * ((int) Math.pow(4, this.mTier)), true);
}
}
if ((aBlock instanceof IFluidBlock)) {
if (this.mFluid == null) {
this.mFluid = ((IFluidBlock) aBlock).drain(getBaseMetaTileEntity().getWorld(), aX, aY, aZ, true); 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))) {
this.getBaseMetaTileEntity().getWorld().setBlockToAir(aX, aY, aZ);
this.mFluid.amount += 1000;
getBaseMetaTileEntity().decreaseStoredEnergyUnits(16 * ((int) Math.pow(4, this.mTier)), true);
} else {
return 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;
} 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); getBaseMetaTileEntity().getWorld().setBlock(aX, aY, aZ, Blocks.air, 0, 2);
return true; return true;
} }
@ -435,7 +569,7 @@ public class GT_MetaTileEntity_Pump extends GT_MetaTileEntity_Hatch {
@Override @Override
public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, byte aSide, byte aFacing, byte aColorIndex, boolean aActive, boolean aRedstone) { 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 @Override
@ -453,9 +587,9 @@ public class GT_MetaTileEntity_Pump extends GT_MetaTileEntity_Hatch {
private FakePlayer mFakePlayer = null; private FakePlayer mFakePlayer = null;
protected FakePlayer getFakePlayer(IGregTechTileEntity aBaseTile) { protected FakePlayer getFakePlayer(IGregTechTileEntity aBaseTile) {
if (mFakePlayer == null) mFakePlayer = GT_Utility.getFakePlayer(aBaseTile); if (mFakePlayer == null) mFakePlayer = GT_Utility.getFakePlayer(aBaseTile);
mFakePlayer.setWorld(aBaseTile.getWorld()); mFakePlayer.setWorld(aBaseTile.getWorld());
mFakePlayer.setPosition(aBaseTile.getXCoord(), aBaseTile.getYCoord(), aBaseTile.getZCoord()); mFakePlayer.setPosition(aBaseTile.getXCoord(), aBaseTile.getYCoord(), aBaseTile.getZCoord());
return mFakePlayer; return mFakePlayer;
} }
} }