288 lines
7.6 KiB
Java
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);
|
|
}
|
|
|
|
}
|