resonant-induction/archive/java/resonantinduction/mechanical/fluid/pump/TileEntityDrain.java
2014-01-11 17:44:07 +08:00

288 lines
7.6 KiB
Java

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<TileEntity, Pair<FluidStack, Integer>> requestMap = new HashMap<TileEntity, Pair<FluidStack, Integer>>();
private List<Vector3> updateQue = new ArrayList<Vector3>();
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<Vector3> getFillList()
{
return this.getFillFinder().refresh().results;
}
public LiquidPathFinder getLiquidFinder()
{
if (pathDrain == null)
{
pathDrain = new LiquidPathFinder(this.worldObj, 1000, 100);
}
return pathDrain;
}
@Override
public Set<Vector3> 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<Vector3> fluids = new ArrayList<Vector3>();
List<Vector3> blocks = new ArrayList<Vector3>();
List<Vector3> filled = new ArrayList<Vector3>();
/* Sort results out into two groups and clear the rest out of the result list */
Iterator<Vector3> 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);
}
}