added construction pump

working on rewriting this from scratch based off of a demo pump i've
been working of out of project. The demo pump was limited though it
functioned very well.

This new pump will be designed to drain lakes, and even oceans if the
area can stay loaded. As well it works like the redpower one and will
drain water threw a drain rather than an actual block pump. The pump
will request the drain to find it liquid and fill the pump(Not how it
works in real life but best way to simulate it).
This commit is contained in:
Rseifert 2013-04-04 00:27:46 -04:00
parent c99bdb1e4e
commit 4ef06dc48a
4 changed files with 524 additions and 0 deletions

View file

@ -0,0 +1,60 @@
package fluidmech.common.pump;
import fluidmech.common.FluidMech;
import hydraulic.helpers.FluidHelper;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.liquids.LiquidStack;
import universalelectricity.core.path.IPathCallBack;
import universalelectricity.core.path.Pathfinder;
import universalelectricity.core.vector.Vector3;
/**
* Check if a conductor connects with another.
*
* @author Calclavia
*
*/
public class PathfinderCheckerLiquid extends Pathfinder
{
public PathfinderCheckerLiquid(final World world, final int maxResources, final LiquidStack resource, final Vector3... ignoreList)
{
super(new IPathCallBack()
{
@Override
public Set<Vector3> getConnectedNodes(Pathfinder finder, Vector3 currentNode)
{
Set<Vector3> neighbors = new HashSet<Vector3>();
for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS)
{
Vector3 pos = currentNode.clone().modifyPositionFromSide(direction);
if (FluidHelper.isStillLiquid(world,pos) && FluidHelper.getLiquidFromBlockId(pos.getBlockID(world)).equals(resource))
{
neighbors.add(pos);
}
}
return neighbors;
}
@Override
public boolean onSearch(Pathfinder finder, Vector3 node)
{
if (finder.closedSet.size() >= maxResources)
{
return true;
}
return false;
}
});
}
}

View file

@ -0,0 +1,101 @@
package fluidmech.common.pump;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.liquids.ILiquidTank;
import net.minecraftforge.liquids.ITankContainer;
import net.minecraftforge.liquids.LiquidContainerRegistry;
import net.minecraftforge.liquids.LiquidStack;
import net.minecraftforge.liquids.LiquidTank;
import universalelectricity.core.electricity.ElectricityPack;
import universalelectricity.core.vector.Vector3;
import universalelectricity.core.vector.VectorHelper;
import universalelectricity.prefab.tile.TileEntityElectricityRunnable;
public class TileEntityConstructionPump extends TileEntityElectricityRunnable implements ITankContainer
{
/* ENERGY PER TICK TO TRY TO PUMP */
public static final double WATTS_PER_TICK = 100;
/* LIQUID FLOW CONNECTION SIDES */
private ForgeDirection outputSide = ForgeDirection.UNKNOWN;
private ForgeDirection inputSide = ForgeDirection.UNKNOWN;
/* Fake Internal Tank */
private LiquidTank fakeTank = new LiquidTank(LiquidContainerRegistry.BUCKET_VOLUME);
@Override
public void updateEntity()
{
}
@Override
public ElectricityPack getRequest()
{
return new ElectricityPack(WATTS_PER_TICK / this.getVoltage(), this.getVoltage());
}
@Override
public boolean canConnect(ForgeDirection direction)
{
return direction != outputSide && direction != inputSide;
}
@Override
public int fill(ForgeDirection from, LiquidStack resource, boolean doFill)
{
if (from != inputSide)
{
return 0;
}
return this.fill(0, resource, doFill);
}
@Override
public int fill(int tankIndex, LiquidStack resource, boolean doFill)
{
if (tankIndex != 0 || resource == null)
{
return 0;
}
TileEntity entity = VectorHelper.getTileEntityFromSide(this.worldObj, new Vector3(this), outputSide);
if (entity instanceof ITankContainer)
{
return ((ITankContainer) entity).fill(outputSide.getOpposite(), resource, doFill);
}
return 0;
}
@Override
public LiquidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
{
// TODO maybe have it make a request for liquid if something tries to drain it
return null;
}
@Override
public LiquidStack drain(int tankIndex, int maxDrain, boolean doDrain)
{
return null;
}
@Override
public ILiquidTank[] getTanks(ForgeDirection direction)
{
if (direction == this.inputSide)
{
return new ILiquidTank[] { fakeTank };
}
return null;
}
@Override
public ILiquidTank getTank(ForgeDirection direction, LiquidStack type)
{
if (direction == this.inputSide)
{
return fakeTank;
}
return null;
}
}

View file

@ -0,0 +1,154 @@
package fluidmech.common.pump;
import hydraulic.helpers.FluidHelper;
import hydraulic.prefab.tile.TileEntityFluidDevice;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.liquids.ITankContainer;
import net.minecraftforge.liquids.LiquidStack;
import universalelectricity.core.vector.Vector3;
import universalelectricity.core.vector.VectorHelper;
public class TileEntityDrain extends TileEntityFluidDevice
{
private ForgeDirection face = ForgeDirection.UNKNOWN;
private boolean drainSources = true;
/* LIST OF PUMPS AND THERE REQUESTS FOR THIS DRAIN */
private HashMap<TileEntityConstructionPump, LiquidStack> requestMap = new HashMap<TileEntityConstructionPump, LiquidStack>();
private List<Vector3> targetSources = new ArrayList<Vector3>();
@Override
public String getMeterReading(EntityPlayer user, ForgeDirection side)
{
return (drainSources ? "Draining" : "");
}
@Override
public void updateEntity()
{
if (!this.worldObj.isRemote && this.ticks % 10 == 0)
{
/* MAIN LOGIC PATH FOR DRAINING BODIES OF LIQUID */
if (this.drainSources)
{
TileEntity entity = VectorHelper.getTileEntityFromSide(worldObj, new Vector3(this), this.face.getOpposite());
if (entity instanceof ITankContainer)
{
if (this.requestMap.size() > 0)
{
this.getNextFluidBlock();
int blocksDrained = 0;
for (Vector3 loc : targetSources)
{
if (blocksDrained >= 5 && FluidHelper.isStillLiquid(this.worldObj, loc))
{
LiquidStack stack = FluidHelper.getLiquidFromBlockId(loc.getBlockID(this.worldObj));
if (stack != null)
{
for (Entry<TileEntityConstructionPump, LiquidStack> pump : requestMap.entrySet())
{
if (pump.getValue().isLiquidEqual(stack))
{
if (((ITankContainer) entity).fill(0, stack, false) >= stack.amount)
{
((ITankContainer) entity).fill(0, stack, true);
loc.setBlock(this.worldObj, 0);
blocksDrained++;
}
}
}
}
}
}
}
}
}// END OF DRAIN
else
{
// TODO time to have fun finding a place for this block to exist
}
}
}
/**
* uses the LiquidStack to fill the area bellow the drain
*
* @param stack - liquidStack
* @return amount of liquid consumed
*/
public int fillArea(LiquidStack stack)
{
return 0;
}
@Override
public boolean canPipeConnect(TileEntity entity, ForgeDirection dir)
{
return dir == face.getOpposite();
}
/**
* Requests that this drain give the pump this liquid. The pump will have to decide if it can
* accept, request, and maintain this demand
*
* @param pump - requesting pump
* @param stack - liquid this pump wants for this request
*/
public void requestLiquid(TileEntityConstructionPump pump, LiquidStack stack)
{
this.requestMap.put(pump, stack);
}
/**
* Request that this drain no longer supply the pump with a volume. By default a request will be
* removed from the request map after being filled. However, this can be used too stop a request
* short if the pump becomes full before the request is filled
*
* @param pump - requesting pump
*/
public void stopRequesting(TileEntityConstructionPump pump)
{
if (this.requestMap.containsKey(pump))
{
this.requestMap.remove(pump);
}
}
/**
* Finds at least 10 more liquid possible targets for the pump to pump
*/
public void getNextFluidBlock()
{
int blockID = Block.waterStill.blockID;
int y = this.yCoord + 1;
while (blockID == Block.waterStill.blockID)
{
blockID = worldObj.getBlockId(xCoord, y, zCoord);
if (blockID == Block.waterStill.blockID)
{
y++;
}
}
PathfinderCheckerLiquid pathFinder = new PathfinderCheckerLiquid(worldObj, 10, null, (Vector3[]) this.targetSources.toArray());
pathFinder.init(new Vector3(xCoord, y, zCoord));
for (Vector3 loc : pathFinder.closedSet)
{
if (!this.targetSources.contains(loc))
{
this.targetSources.add(loc);
}
}
}
}

View file

@ -0,0 +1,209 @@
package fluidmech.common.pump;
import hydraulic.api.ColorCode;
import hydraulic.api.IColorCoded;
import hydraulic.api.IPipeConnection;
import hydraulic.api.IReadOut;
import hydraulic.helpers.FluidHelper;
import hydraulic.helpers.MetaGroup;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.liquids.ITankContainer;
import net.minecraftforge.liquids.LiquidContainerRegistry;
import net.minecraftforge.liquids.LiquidStack;
import universalelectricity.core.electricity.ElectricityPack;
import universalelectricity.core.vector.Vector3;
import universalelectricity.core.vector.VectorHelper;
import universalelectricity.prefab.network.IPacketReceiver;
import universalelectricity.prefab.tile.TileEntityElectricityRunnable;
import com.google.common.io.ByteArrayDataInput;
public class TileEntityStarterPump extends TileEntityElectricityRunnable implements IPacketReceiver, IReadOut, IPipeConnection
{
public final double WATTS_PER_TICK = (400 / 20);
private double percentPumped = 0.0;
public int pos = 0;
public ColorCode color = ColorCode.BLUE;
ForgeDirection wireConnection = ForgeDirection.EAST;
ForgeDirection pipeConnection = ForgeDirection.EAST;
/**
* gets the side connection for the wire and pipe
*/
public void getConnections()
{
int notchMeta = MetaGroup.getFacingMeta(worldObj.getBlockMetadata(xCoord, yCoord, zCoord));
wireConnection = ForgeDirection.getOrientation(notchMeta);
pipeConnection = VectorHelper.getOrientationFromSide(wireConnection, ForgeDirection.WEST);
if (notchMeta == 2 || notchMeta == 3)
{
pipeConnection = pipeConnection.getOpposite();
}
}
@Override
public void initiate()
{
this.getConnections();
}
@Override
public void updateEntity()
{
super.updateEntity();
this.getConnections();
if (!this.worldObj.isRemote && !this.isDisabled())
{
if (this.canPump(xCoord, yCoord - 1, zCoord) && this.wattsReceived >= this.WATTS_PER_TICK)
{
wattsReceived -= this.WATTS_PER_TICK;
if (percentPumped < 10)
{
percentPumped++;
}
else if (percentPumped >= 10 && this.drainBlock(new Vector3(xCoord, yCoord - 1, zCoord)))
{
percentPumped = 0;
}
/* DO ANIMATION CHANGE */
this.pos++;
if (pos >= 8)
{
pos = 0;
}
}
if (this.ticks % 10 == 0)
{
// Packet packet = PacketManager.getPacket(FluidMech.CHANNEL, this, color.ordinal(),
// this.wattsReceived);
// PacketManager.sendPacketToClients(packet, worldObj, new Vector3(this), 60);
}
}
}
@Override
public void handlePacketData(INetworkManager network, int packetType, Packet250CustomPayload packet, EntityPlayer player, ByteArrayDataInput data)
{
try
{
this.color = ColorCode.get(data.readInt());
this.wattsReceived = data.readDouble();
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* gets the fluidConductor or storageTank to ouput its pumped liquids too if there is not one it
* will not function
*/
public ITankContainer getFillTarget()
{
TileEntity ent = worldObj.getBlockTileEntity(xCoord + pipeConnection.offsetX, yCoord + pipeConnection.offsetY, zCoord + pipeConnection.offsetZ);
if (ent instanceof ITankContainer)
{
return (ITankContainer) ent;
}
return null;
}
/**
* gets the search range the pump used to find valid block to pump
*/
public int getPumpRange()
{
int meta = worldObj.getBlockMetadata(xCoord, yCoord, zCoord);
switch (MetaGroup.getGrouping(meta))
{
case 2:
return 20;
case 3:
return 50;
}
return 1;
}
@Override
public ElectricityPack getRequest()
{
double amps = (this.WATTS_PER_TICK / this.getVoltage());
return new ElectricityPack(amps, this.getVoltage());
}
/**
* checks to see if this pump can pump the selected target block
*
* @param x y z - location of the block, use the tileEntities world
* @return true if it can pump
*/
boolean canPump(int x, int y, int z)
{
return getFillTarget() != null && FluidHelper.getLiquidId(worldObj.getBlockId(x, y, z)) != -1 && worldObj.getBlockMetadata(x, y, z) == 0 ;
}
/**
* drains the block(removes) at the location given
*
* @param loc - vector 3 location
* @return true if the block was drained
*/
boolean drainBlock(Vector3 loc)
{
int blockID = worldObj.getBlockId(loc.intX(), loc.intY(), loc.intZ());
LiquidStack stack = FluidHelper.getLiquidFromBlockId(blockID);
if (color.isValidLiquid(stack) && getFillTarget() != null)
{
stack.amount = LiquidContainerRegistry.BUCKET_VOLUME;
int fillAmmount = getFillTarget().fill(pipeConnection.getOpposite(), stack, true);
if (fillAmmount > 0)
{
worldObj.setBlockMetadataWithNotify(xCoord, yCoord - 1, zCoord, 0, 0);
return true;
}
}
return false;
}
@Override
public String getMeterReading(EntityPlayer user, ForgeDirection side)
{
return String.format("%.2f/%.2f %f Done", this.wattsReceived,this.WATTS_PER_TICK,this.percentPumped);
}
@Override
public boolean canConnect(ForgeDirection direction)
{
return direction == wireConnection;
}
@Override
public boolean canPipeConnect(TileEntity entity, ForgeDirection dir)
{
if (dir == this.pipeConnection.getOpposite())
{
return entity != null && entity instanceof IColorCoded && (((IColorCoded) entity).getColor() == ColorCode.NONE || ((IColorCoded) entity).getColor() == this.color);
}
return false;
}
}