package resonantinduction.mechanical.fluid.pump; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Set; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.ForgeDirection; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidContainerRegistry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTank; import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidHandler; import resonantinduction.mechanical.fluid.prefab.TileEntityFluidDevice; import resonantinduction.old.api.fluid.IDrain; import universalelectricity.api.vector.Vector3; import calclavia.lib.utility.FluidHelper; import com.builtbroken.common.Pair; public class TileEntityDrain extends TileEntityFluidDevice implements IFluidHandler, IDrain { /* MAX BLOCKS DRAINED PER 1/2 SECOND */ public static int MAX_WORLD_EDITS_PER_PROCESS = 50; private int currentWorldEdits = 0; /* LIST OF PUMPS AND THERE REQUESTS FOR THIS DRAIN */ private HashMap> requestMap = new HashMap>(); private List updateQue = new ArrayList(); private LiquidPathFinder pathDrain; private LiquidPathFinder pathFill; public boolean canDrain() { return this.getBlockMetadata() < 6; } public LiquidPathFinder getFillFinder() { if (pathFill == null) { pathFill = new LiquidPathFinder(this.worldObj, 100, 100); } return pathFill; } @Override public Set getFillList() { return this.getFillFinder().refresh().results; } public LiquidPathFinder getLiquidFinder() { if (pathDrain == null) { pathDrain = new LiquidPathFinder(this.worldObj, 1000, 100); } return pathDrain; } @Override public Set getFluidList() { return this.getLiquidFinder().refresh().results; } @Override public void updateEntity() { super.updateEntity(); /* MAIN LOGIC PATH FOR DRAINING BODIES OF LIQUID */ if (!this.worldObj.isRemote && this.ticks % 20 == 0 && !this.worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord)) { this.currentWorldEdits = 0; /* ONLY FIND NEW SOURCES IF OUR CURRENT LIST RUNS DRY */ if (this.getLiquidFinder().results.size() < TileEntityDrain.MAX_WORLD_EDITS_PER_PROCESS + 10) { this.getLiquidFinder().refresh().start(new Vector3(this).modifyPositionFromSide(this.getDirection()), TileEntityDrain.MAX_WORLD_EDITS_PER_PROCESS, false); } if (this.getFillFinder().results.size() < TileEntityDrain.MAX_WORLD_EDITS_PER_PROCESS + 10) { this.getFillFinder().refresh().start(new Vector3(this).modifyPositionFromSide(this.getDirection()), TileEntityDrain.MAX_WORLD_EDITS_PER_PROCESS, true); } } } public int fillArea(FluidStack resource, boolean doFill) { int fillVolume = 0; if (this.currentWorldEdits < MAX_WORLD_EDITS_PER_PROCESS) { /* ID LIQUID BLOCK AND SET VARS FOR BLOCK PLACEMENT */ if (resource == null || resource.amount < FluidContainerRegistry.BUCKET_VOLUME) { return 0; } fillVolume = resource.amount; // System.out.println("Drain>>FillArea>>Targets>> " + getFillFinder().results.size()); List fluids = new ArrayList(); List blocks = new ArrayList(); List filled = new ArrayList(); /* Sort results out into two groups and clear the rest out of the result list */ Iterator it = this.getFillFinder().refresh().results.iterator(); while (it.hasNext()) { Vector3 vec = it.next(); if (FluidHelper.isFillableFluid(worldObj, vec) && !fluids.contains(vec) && !blocks.contains(vec)) { fluids.add(vec); } else if (FluidHelper.isFillableBlock(worldObj, vec) && !blocks.contains(vec) && !fluids.contains(vec)) { blocks.add(vec); } else { it.remove(); } } /* Fill non-full fluids first */ for (Vector3 loc : fluids) { if (fillVolume <= 0) { break; } if (FluidHelper.isFillableFluid(worldObj, loc)) { fillVolume -= FluidHelper.fillBlock(worldObj, loc, FluidHelper.getStack(resource, fillVolume), doFill); // System.out.println("Drain>>FillArea>>Filling>>" + (doFill ? "" : "Sim>>") + // ">>Fluid>" + loc.toString()); if (doFill) { filled.add(loc); this.currentWorldEdits++; if (!this.updateQue.contains(loc)) { this.updateQue.add(loc); } } } } /* Fill air or replaceable blocks after non-full fluids */ for (Vector3 loc : blocks) { if (fillVolume <= 0) { break; } if (FluidHelper.isFillableBlock(worldObj, loc)) { fillVolume -= FluidHelper.fillBlock(worldObj, loc, FluidHelper.getStack(resource, fillVolume), doFill); System.out.println("Drain>>FillArea>>Filling>>" + (doFill ? "" : "Sim>>") + ">>Block>" + loc.toString()); if (doFill) { filled.add(loc); this.currentWorldEdits++; if (!this.updateQue.contains(loc)) { this.updateQue.add(loc); } } } } this.getLiquidFinder().results.removeAll(filled); // System.out.println("Drain>>FillArea>>Filling>>Filled>>" + (doFill ? "" : "Sim>>") + // (resource.amount - fillVolume) + "mb"); return Math.max(resource.amount - fillVolume, 0); } return 0; } @Override public boolean canTileConnect(Connection type, ForgeDirection dir) { return dir != this.getDirection(); } @Override public ForgeDirection getDirection() { int meta = 0; if (worldObj != null) { meta = worldObj.getBlockMetadata(xCoord, yCoord, zCoord) % 6; } return ForgeDirection.getOrientation(meta); } @Override public void setDirection(ForgeDirection direction) { if (direction != null && direction != this.getDirection()) { this.worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, direction.ordinal(), 3); } } @Override public boolean canFill(ForgeDirection from, Fluid fluid) { return this.getDirection() != from && !this.canDrain(); } @Override public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { if (resource == null || this.canDrain()) { return 0; } return this.fillArea(resource, doFill); } @Override public boolean canDrain(ForgeDirection from, Fluid fluid) { return false; } @Override public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) { // TODO Auto-generated method stub return null; } @Override public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { return null; } @Override public FluidTankInfo[] getTankInfo(ForgeDirection from) { return new FluidTankInfo[] { new FluidTank(this.getLiquidFinder().results.size() * FluidContainerRegistry.BUCKET_VOLUME).getInfo() }; } @Override public boolean canDrain(ForgeDirection direction) { return direction == this.getDirection() && !this.worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord) && this.canDrain(); } @Override public boolean canFill(ForgeDirection direction) { return direction == this.getDirection() && !this.worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord) && !this.canDrain(); } @Override public void onUse(Vector3 vec) { this.currentWorldEdits++; } @Override public String getMeterReading(EntityPlayer user, ForgeDirection side, EnumTools tool) { if (tool != null && tool == EnumTools.PIPE_GUAGE) { return " F:" + this.getFillList().size() + " D:" + this.getFluidList().size(); } return super.getMeterReading(user, side, tool); } }