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

234 lines
6.7 KiB
Java

package resonantinduction.mechanical.fluid.pump;
import java.util.Iterator;
import java.util.Set;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidHandler;
import resonantinduction.core.prefab.tile.TileEntityEnergyMachine;
import resonantinduction.core.tilenetwork.ITileConnector;
import resonantinduction.old.api.fluid.IDrain;
import universalelectricity.api.vector.Vector3;
import calclavia.lib.utility.FluidHelper;
import com.builtbroken.common.Pair;
import dark.lib.interfaces.IReadOut;
public class TileEntityStarterPump extends TileEntityEnergyMachine implements IReadOut, ITileConnector
{
private int currentWorldEdits, MAX_WORLD_EDITS_PER_PROCESS;
public long ENERGY_PER_DRAIN = 50;
private LiquidPathFinder pathLiquid;
private Vector3 lastDrainOrigin;
public int rotation = 0;
public TileEntityStarterPump()
{
this(10, 50, 5);
}
/**
* @param wattTick - cost in watts per tick to run the tile
* @param wattDrain - cost in watts to drain or fill one block
* @param maxEdits - max world edits per update (1/2 second)
*/
public TileEntityStarterPump(long wattTick, long wattDrain, int maxEdits)
{
// Power calculation for max power (worldEdits * watts per edit) + (watts per tick * one
// second)
super(wattTick, (maxEdits * wattDrain) + (wattTick * 20));
this.MAX_WORLD_EDITS_PER_PROCESS = maxEdits;
this.ENERGY_PER_DRAIN = wattDrain;
}
/** Liquid path finder used by this tile. Retrieve the path finder if using IDrain block */
public LiquidPathFinder getLiquidFinder()
{
if (pathLiquid == null)
{
pathLiquid = new LiquidPathFinder(this.worldObj, 100, 20);
}
return pathLiquid;
}
@Override
public void updateEntity()
{
super.updateEntity();
if (this.ticks % 10 == 0)
{
this.currentWorldEdits = 0;
if (this.isFunctioning())
{
this.rotation = Math.max(Math.min(this.rotation + 1, 7), 0);
if (!this.worldObj.isRemote)
{
Pair<World, Vector3> pair = this.getDrainOrigin();
if (pair != null && pair.left() != null && pair.right() != null)
{
this.drainAroundArea(pair.left(), pair.right(), 3);
}
}
}
}
}
/** Gets the origin the path finder starts on */
public Pair<World, Vector3> getDrainOrigin()
{
// TODO change this to lower by the amount of air between the pump and bottom
return new Pair<World, Vector3>(this.worldObj, new Vector3(this).modifyPositionFromSide(ForgeDirection.DOWN));
}
/**
* Drains an area starting at the given location
*
* @param world - world to drain in, most cases will be the TileEntities world
* @param loc - origin to start the path finder with. If this is an instance of IDrain this
* method will act different
*/
public void drainAroundArea(World world, Vector3 vec, int update)
{
Vector3 origin = vec.clone();
if (origin == null)
{
return;
}
/* Update last drain origin to prevent failed path finding */
if (this.lastDrainOrigin == null || !this.lastDrainOrigin.equals(origin))
{
this.lastDrainOrigin = origin.clone();
this.getLiquidFinder().reset();
}
TileEntity drain = vec.clone().getTileEntity(world);
TileEntity entity = null;
Set<Vector3> drainList = null;
if (drain instanceof IDrain)
{
if (!((IDrain) drain).canDrain(((IDrain) drain).getDirection()))
{
return;
}
origin = vec.modifyPositionFromSide(((IDrain) drain).getDirection());
entity = origin.getTileEntity(world);
if (entity instanceof IFluidHandler)
{
FluidStack draStack = ((IFluidHandler) entity).drain(ForgeDirection.UP, MAX_WORLD_EDITS_PER_PROCESS * FluidContainerRegistry.BUCKET_VOLUME, false);
if (draStack != null && FluidHelper.fillTanksAllSides(worldObj, new Vector3(this), draStack, false, ForgeDirection.DOWN) > 0)
{
((IFluidHandler) entity).drain(ForgeDirection.UP, FluidHelper.fillTanksAllSides(worldObj, new Vector3(this), draStack, true, ForgeDirection.DOWN), true);
}
return;// TODO check why return is here
}
else
{
drainList = ((IDrain) drain).getFluidList();
}
}
if (drainList == null)
{
if (this.getLiquidFinder().results.size() < MAX_WORLD_EDITS_PER_PROCESS + 10)
{
this.getLiquidFinder().setWorld(world).refresh().start(origin, MAX_WORLD_EDITS_PER_PROCESS, false);
}
drainList = this.getLiquidFinder().refresh().results;
}
if (entity == null && drainList != null && drainList.size() > 0)
{
// System.out.println("StartPump>>DrainArea>>Targets>" +
// this.getLiquidFinder().results.size());
Iterator<Vector3> fluidList = drainList.iterator();
while (fluidList.hasNext() && this.consumePower(ENERGY_PER_DRAIN, false))
{
if (this.currentWorldEdits >= MAX_WORLD_EDITS_PER_PROCESS)
{
break;
}
Vector3 drainLocation = fluidList.next();
FluidStack drainStack = FluidHelper.drainBlock(world, drainLocation, false, 3);
// System.out.println("StartPump>>DrainArea>>Draining>>NextFluidBlock>" +
// (drainStack == null ? "Null" : drainStack.amount + "mb of " +
// drainStack.getFluid().getName()));
// int fillV = FluidHelper.fillTanksAllSides(worldObj, new Vector3(this),
// drainStack, false, ForgeDirection.DOWN);
// System.out.println("StartPump>>DrainArea>>Draining>>NextFluidBlock>Filled>" +
// fillV + "mb");
if (drainStack != null && this.fill(drainStack, false) >= drainStack.amount && this.consumePower(ENERGY_PER_DRAIN, true))
{
// System.out.println("StartPump>>DrainArea>>Draining>>Fluid>" +
// drainLocation.toString());
/* REMOVE BLOCK */
FluidHelper.drainBlock(this.worldObj, drainLocation, true, update);
this.fill(drainStack, true);
this.currentWorldEdits++;
fluidList.remove();
if (drain instanceof IDrain)
{
((IDrain) drain).onUse(drainLocation);
}
}
}
}
}
public int fill(FluidStack stack, boolean doFill)
{
return FluidHelper.fillTanksAllSides(worldObj, new Vector3(this), stack, doFill, ForgeDirection.DOWN);
}
@Override
public boolean canFunction()
{
return super.canFunction() && worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord);
}
@Override
public String getMeterReading(EntityPlayer user, ForgeDirection side, EnumTools tool)
{
if (tool == EnumTools.PIPE_GUAGE)
{
return "Source Blocks: " + this.getLiquidFinder().results.size();
}
return null;
}
@Override
public boolean canConnect(ForgeDirection direction)
{
return direction != ForgeDirection.DOWN;
}
@Override
public boolean canTileConnect(Connection type, ForgeDirection direction)
{
return direction != ForgeDirection.DOWN;
}
}