Added clockwise set and get methods for IMechanical

This commit is contained in:
Calclavia 2014-01-19 14:20:41 +08:00
parent 1e5319c4de
commit 20dcbce5c5
16 changed files with 725 additions and 652 deletions

View file

@ -8,7 +8,7 @@ import universalelectricity.api.net.IConnector;
* that each part can only support one fluid tank internally * that each part can only support one fluid tank internally
* *
* @author DarkGuardsman */ * @author DarkGuardsman */
public interface IFluidPart extends IConnector<IFluidNetwork>, IFluidHandler public interface IFluidConnector extends IConnector<IFluidNetwork>, IFluidHandler
{ {
/** FluidTank that the network will have access to fill or drain */ /** FluidTank that the network will have access to fill or drain */
public FluidTank getInternalTank(); public FluidTank getInternalTank();

View file

@ -10,7 +10,7 @@ import universalelectricity.api.net.INetwork;
/** Interface version of the fluid network. /** Interface version of the fluid network.
* *
* @author DarkGuardsman */ * @author DarkGuardsman */
public interface IFluidNetwork extends INetwork<IFluidNetwork, IFluidPart, IFluidHandler> public interface IFluidNetwork extends INetwork<IFluidNetwork, IFluidConnector, IFluidHandler>
{ {
/** Called to build the network when something changes such as addition of a pipe */ /** Called to build the network when something changes such as addition of a pipe */
void reconstruct(); void reconstruct();
@ -22,7 +22,7 @@ public interface IFluidNetwork extends INetwork<IFluidNetwork, IFluidPart, IFlui
* @param resource - fluid stack that is being filled into the network * @param resource - fluid stack that is being filled into the network
* @param doFill - true causes the action to be taken, false simulates the action * @param doFill - true causes the action to be taken, false simulates the action
* @return amount of fluid filled into the network */ * @return amount of fluid filled into the network */
int fill(IFluidPart source, ForgeDirection from, FluidStack resource, boolean doFill); int fill(IFluidConnector source, ForgeDirection from, FluidStack resource, boolean doFill);
/** Called to remove fluid from a network, not supported by all networks /** Called to remove fluid from a network, not supported by all networks
* *
@ -31,7 +31,7 @@ public interface IFluidNetwork extends INetwork<IFluidNetwork, IFluidPart, IFlui
* @param resource - fluid stack that is being filled into the network * @param resource - fluid stack that is being filled into the network
* @param doDrain - true causes the action to be taken, false simulates the action * @param doDrain - true causes the action to be taken, false simulates the action
* @return FluidStack that contains the fluid drained from the network */ * @return FluidStack that contains the fluid drained from the network */
FluidStack drain(IFluidPart source, ForgeDirection from, FluidStack resource, boolean doDrain); FluidStack drain(IFluidConnector source, ForgeDirection from, FluidStack resource, boolean doDrain);
/** Called to remove fluid from a network, not supported by all networks /** Called to remove fluid from a network, not supported by all networks
* *
@ -40,7 +40,7 @@ public interface IFluidNetwork extends INetwork<IFluidNetwork, IFluidPart, IFlui
* @param resource - fluid stack that is being filled into the network * @param resource - fluid stack that is being filled into the network
* @param doDrain - true causes the action to be taken, false simulates the action * @param doDrain - true causes the action to be taken, false simulates the action
* @return FluidStack that contains the fluid drained from the network */ * @return FluidStack that contains the fluid drained from the network */
FluidStack drain(IFluidPart source, ForgeDirection from, int resource, boolean doDrain); FluidStack drain(IFluidConnector source, ForgeDirection from, int resource, boolean doDrain);
/** Fluid tank that represents the entire network */ /** Fluid tank that represents the entire network */
FluidTank getTank(); FluidTank getTank();

View file

@ -3,7 +3,7 @@ package resonantinduction.api.fluid;
/** Applied to tiles that are pipes and support pressure /** Applied to tiles that are pipes and support pressure
* *
* @author DarkGuardsman */ * @author DarkGuardsman */
public interface IFluidPipe extends IFluidPart, IPressureInput public interface IFluidPipe extends IFluidConnector, IPressureInput
{ {
/** Max pressure this pipe can support */ /** Max pressure this pipe can support */
int getMaxPressure(); int getMaxPressure();

View file

@ -113,4 +113,16 @@ public class TileGenerator extends TileElectrical implements IMechanical
nbt.setBoolean("isInversed", isInversed); nbt.setBoolean("isInversed", isInversed);
nbt.setFloat("torqueRatio", torqueRatio); nbt.setFloat("torqueRatio", torqueRatio);
} }
@Override
public boolean isClockwise()
{
return false;
}
@Override
public void setRotation(boolean isClockwise)
{
}
} }

View file

@ -11,313 +11,326 @@ import net.minecraftforge.fluids.FluidTank;
import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler; import net.minecraftforge.fluids.IFluidHandler;
import resonantinduction.api.fluid.IFluidNetwork; import resonantinduction.api.fluid.IFluidNetwork;
import resonantinduction.api.fluid.IFluidPart; import resonantinduction.api.fluid.IFluidConnector;
import universalelectricity.api.net.IConnector; import universalelectricity.api.net.IConnector;
import universalelectricity.core.net.ConnectionPathfinder; import universalelectricity.core.net.ConnectionPathfinder;
import universalelectricity.core.net.Network; import universalelectricity.core.net.Network;
import universalelectricity.core.net.NetworkTickHandler; import universalelectricity.core.net.NetworkTickHandler;
import calclavia.lib.utility.FluidUtility; import calclavia.lib.utility.FluidUtility;
public class FluidNetwork extends Network<IFluidNetwork, IFluidPart, IFluidHandler> implements IFluidNetwork public abstract class FluidNetwork extends Network<IFluidNetwork, IFluidConnector, IFluidHandler> implements IFluidNetwork
{ {
protected FluidTank tank = new FluidTank(0); protected FluidTank tank = new FluidTank(0);
protected final FluidTankInfo[] tankInfo = new FluidTankInfo[1]; protected final FluidTankInfo[] tankInfo = new FluidTankInfo[1];
protected boolean reloadTanks = false; protected boolean reloadTanks = false;
protected long ticks = 0; protected long ticks = 0;
public FluidNetwork() public FluidNetwork()
{ {
NetworkTickHandler.addNetwork(this); NetworkTickHandler.addNetwork(this);
MinecraftForge.EVENT_BUS.register(this); MinecraftForge.EVENT_BUS.register(this);
} }
@Override @Override
public void reconstruct() public void addConnector(IFluidConnector connector)
{ {
if (this.reloadTanks) NetworkTickHandler.addNetwork(this);
{ super.addConnector(connector);
this.reloadTanks(); }
}
this.tank = new FluidTank(0);
for (IFluidPart part : this.getConnectors())
{
part.setNetwork(this);
this.buildPart(part);
}
this.rebuildTank();
this.reloadTanks();
}
public void buildPart(IFluidPart part) @Override
{ public void reconstruct()
FluidTank tank = part.getInternalTank(); {
if (tank != null) if (this.reloadTanks)
{ {
this.tank.setCapacity(this.tank.getCapacity() + tank.getCapacity()); this.reloadTanks();
if (this.tank.getFluid() == null) }
{ this.tank = new FluidTank(0);
this.tank.setFluid(tank.getFluid()); for (IFluidConnector part : this.getConnectors())
} {
else if (this.tank.getFluid().isFluidEqual(tank.getFluid())) part.setNetwork(this);
{ this.buildPart(part);
this.tank.getFluid().amount += tank.getFluidAmount(); }
} this.rebuildHandler();
else if (this.tank.getFluid() != null) this.reloadTanks();
{ }
//TODO cause a mixing event
}
}
}
public void rebuildTank() public void buildPart(IFluidConnector part)
{ {
if (this.getTank() != null) FluidTank tank = part.getInternalTank();
{ if (tank != null)
this.tankInfo[0] = this.getTank().getInfo(); {
} this.tank.setCapacity(this.tank.getCapacity() + tank.getCapacity());
else if (this.tank.getFluid() == null)
{ {
this.tankInfo[0] = null; this.tank.setFluid(tank.getFluid());
} }
this.reloadTanks = true; else if (this.tank.getFluid().isFluidEqual(tank.getFluid()))
NetworkTickHandler.addNetwork(this); {
} this.tank.getFluid().amount += tank.getFluidAmount();
}
else if (this.tank.getFluid() != null)
{
// TODO cause a mixing event
}
}
}
@Override public void rebuildHandler()
public int fill(IFluidPart source, ForgeDirection from, FluidStack resource, boolean doFill) {
{ if (this.getTank() != null)
int prev = this.getTank().getFluidAmount(); {
int fill = this.getTank().fill(resource, doFill); this.tankInfo[0] = this.getTank().getInfo();
if (prev != this.getTank().getFluidAmount()) }
{ else
this.rebuildTank(); {
} this.tankInfo[0] = null;
return fill; }
} this.reloadTanks = true;
NetworkTickHandler.addNetwork(this);
}
@Override @Override
public FluidStack drain(IFluidPart source, ForgeDirection from, FluidStack resource, boolean doDrain) public int fill(IFluidConnector source, ForgeDirection from, FluidStack resource, boolean doFill)
{ {
if (resource != null && resource.isFluidEqual(this.getTank().getFluid())) int prev = this.getTank().getFluidAmount();
{ int fill = this.getTank().fill(resource, doFill);
FluidStack before = this.getTank().getFluid(); if (prev != this.getTank().getFluidAmount())
FluidStack drain = this.getTank().drain(resource.amount, doDrain); {
if (before != this.getTank().getFluid() || this.getTank().getFluid() == null || this.getTank().getFluid().amount != before.amount) this.rebuildHandler();
{ }
this.rebuildTank(); return fill;
} }
return drain; @Override
} public FluidStack drain(IFluidConnector source, ForgeDirection from, FluidStack resource, boolean doDrain)
return null; {
} if (resource != null && resource.isFluidEqual(this.getTank().getFluid()))
{
FluidStack before = this.getTank().getFluid();
FluidStack drain = this.getTank().drain(resource.amount, doDrain);
if (before != this.getTank().getFluid() || this.getTank().getFluid() == null || this.getTank().getFluid().amount != before.amount)
{
this.rebuildHandler();
}
@Override return drain;
public FluidStack drain(IFluidPart source, ForgeDirection from, int resource, boolean doDrain) }
{ return null;
if (this.getTank().getFluid() != null) }
{
return this.drain(source, from, FluidUtility.getStack(this.getTank().getFluid(), resource), doDrain);
}
return null;
}
@Override @Override
public boolean canUpdate() public FluidStack drain(IFluidConnector source, ForgeDirection from, int resource, boolean doDrain)
{ {
return this.reloadTanks; if (this.getTank().getFluid() != null)
} {
return this.drain(source, from, FluidUtility.getStack(this.getTank().getFluid(), resource), doDrain);
}
return null;
}
@Override @Override
public boolean continueUpdate() public boolean canUpdate()
{ {
return this.reloadTanks; return this.reloadTanks;
} }
@Override @Override
public void update() public boolean continueUpdate()
{ {
this.ticks++; return this.reloadTanks;
if (ticks >= Long.MAX_VALUE - 10) }
{
ticks = 1;
}
if (this.reloadTanks && ticks % 10 == 0)
{
this.reloadTanks();
}
}
@ForgeSubscribe @Override
public void onWorldSave(Save event) public void update()
{ {
this.reloadTanks(); this.ticks++;
} if (ticks >= Long.MAX_VALUE - 10)
{
ticks = 1;
}
if (this.reloadTanks && ticks % 10 == 0)
{
this.reloadTanks();
}
}
public void reloadTanks() @ForgeSubscribe
{ public void onWorldSave(Save event)
this.reloadTanks = false; {
FluidStack stack = this.getTank().getFluid(); this.reloadTanks();
this.fillTankSet(stack != null ? stack.copy() : null, this.getConnectors()); }
}
public void fillTankSet(FluidStack stack, Set<IFluidPart> tankList) public void reloadTanks()
{ {
int parts = tankList.size(); this.reloadTanks = false;
for (IFluidPart part : tankList) FluidStack stack = this.getTank().getFluid();
{ this.fillTankSet(stack != null ? stack.copy() : null, this.getConnectors());
part.getInternalTank().setFluid(null); }
if (stack != null)
{
int fillPer = (stack.amount / parts) + (stack.amount % parts);
stack.amount -= part.getInternalTank().fill(FluidUtility.getStack(stack, fillPer), true);
part.onFluidChanged();
if (parts > 1)
parts--;
}
}
}
@Override public void fillTankSet(FluidStack stack, Set<IFluidConnector> tankList)
public IFluidNetwork merge(IFluidNetwork network) {
{ int parts = tankList.size();
FluidNetwork newNetwork = null; for (IFluidConnector part : tankList)
if (network != null && network.getClass().isAssignableFrom(this.getClass()) && network != this) {
{ part.getInternalTank().setFluid(null);
if (stack != null)
{
int fillPer = (stack.amount / parts) + (stack.amount % parts);
stack.amount -= part.getInternalTank().fill(FluidUtility.getStack(stack, fillPer), true);
part.onFluidChanged();
if (parts > 1)
parts--;
}
}
}
try @Override
{ public IFluidNetwork merge(IFluidNetwork network)
newNetwork = this.getClass().newInstance(); {
FluidNetwork newNetwork = null;
if (network != null && network.getClass().isAssignableFrom(this.getClass()) && network != this)
{
newNetwork.getConnectors().addAll(this.getConnectors()); try
newNetwork.getConnectors().addAll(network.getConnectors()); {
newNetwork = this.getClass().newInstance();
network.getConnectors().clear(); newNetwork.getConnectors().addAll(this.getConnectors());
network.getNodes().clear(); newNetwork.getConnectors().addAll(network.getConnectors());
this.getConnectors().clear();
this.getNodes().clear();
newNetwork.reconstruct(); network.getConnectors().clear();
network.getNodes().clear();
this.getConnectors().clear();
this.getNodes().clear();
} newNetwork.reconstruct();
catch (Exception e)
{
e.printStackTrace();
}
} }
return newNetwork; catch (Exception e)
} {
e.printStackTrace();
}
@Override }
public void split(IFluidPart splitPoint) return newNetwork;
{ }
this.removeConnector(splitPoint);
this.reconstruct();
/** Loop through the connected blocks and attempt to see if there are connections between the @Override
* two points elsewhere. */ public void split(IFluidConnector splitPoint)
Object[] connectedBlocks = splitPoint.getConnections(); {
this.removeConnector(splitPoint);
this.reconstruct();
for (int i = 0; i < connectedBlocks.length; i++) /**
{ * Loop through the connected blocks and attempt to see if there are connections between the
Object connectedBlockA = connectedBlocks[i]; * two points elsewhere.
*/
Object[] connectedBlocks = splitPoint.getConnections();
if (connectedBlockA instanceof IFluidPart) for (int i = 0; i < connectedBlocks.length; i++)
{ {
for (int ii = 0; ii < connectedBlocks.length; ii++) Object connectedBlockA = connectedBlocks[i];
{
final Object connectedBlockB = connectedBlocks[ii];
if (connectedBlockA != connectedBlockB && connectedBlockB instanceof IFluidPart) if (connectedBlockA instanceof IFluidConnector)
{ {
ConnectionPathfinder finder = new ConnectionPathfinder((IFluidPart) connectedBlockB, splitPoint); for (int ii = 0; ii < connectedBlocks.length; ii++)
finder.findNodes((IFluidPart) connectedBlockA); {
final Object connectedBlockB = connectedBlocks[ii];
if (finder.results.size() <= 0) if (connectedBlockA != connectedBlockB && connectedBlockB instanceof IFluidConnector)
{ {
try ConnectionPathfinder finder = new ConnectionPathfinder((IFluidConnector) connectedBlockB, splitPoint);
{ finder.findNodes((IFluidConnector) connectedBlockA);
/** The connections A and B are not connected anymore. Give them both
* a new common network. */
IFluidNetwork newNetwork = this.getClass().newInstance();
for (IConnector node : finder.closedSet) if (finder.results.size() <= 0)
{ {
if (node != splitPoint && node instanceof IFluidPart) try
{ {
newNetwork.addConnector((IFluidPart) node); /**
} * The connections A and B are not connected anymore. Give them both
} * a new common network.
newNetwork.reconstruct(); */
} IFluidNetwork newNetwork = this.getClass().newInstance();
catch (Exception e)
{
e.printStackTrace();
}
} for (IConnector node : finder.closedSet)
} {
} if (node != splitPoint && node instanceof IFluidConnector)
} {
} newNetwork.addConnector((IFluidConnector) node);
} }
}
newNetwork.reconstruct();
}
catch (Exception e)
{
e.printStackTrace();
}
@Override }
public void split(IFluidPart connectorA, IFluidPart connectorB) }
{ }
this.reconstruct(); }
}
}
/** Check if connectorA connects with connectorB. */ @Override
ConnectionPathfinder finder = new ConnectionPathfinder(connectorB); public void split(IFluidConnector connectorA, IFluidConnector connectorB)
finder.findNodes(connectorA); {
this.reconstruct();
if (finder.results.size() <= 0) /** Check if connectorA connects with connectorB. */
{ ConnectionPathfinder finder = new ConnectionPathfinder(connectorB);
/** The connections A and B are not connected anymore. Give them both a new common finder.findNodes(connectorA);
* network. */
IFluidNetwork newNetwork;
try
{
newNetwork = this.getClass().newInstance();
for (IConnector node : finder.closedSet) if (finder.results.size() <= 0)
{ {
if (node instanceof IFluidPart) /**
{ * The connections A and B are not connected anymore. Give them both a new common
newNetwork.addConnector((IFluidPart) node); * network.
} */
} IFluidNetwork newNetwork;
try
{
newNetwork = this.getClass().newInstance();
newNetwork.reconstruct(); for (IConnector node : finder.closedSet)
} {
catch (Exception e) if (node instanceof IFluidConnector)
{ {
e.printStackTrace(); newNetwork.addConnector((IFluidConnector) node);
} }
} }
}
@Override newNetwork.reconstruct();
public FluidTank getTank() }
{ catch (Exception e)
if (this.tank == null) {
{ e.printStackTrace();
this.tank = new FluidTank(0); }
} }
return this.tank; }
}
@Override @Override
public FluidTankInfo[] getTankInfo() public FluidTank getTank()
{ {
return tankInfo; if (this.tank == null)
} {
this.tank = new FluidTank(0);
}
return this.tank;
}
@Override @Override
public String toString() public FluidTankInfo[] getTankInfo()
{ {
return super.toString() + " Vol:" + this.tank.getFluidAmount(); return tankInfo;
} }
@Override
public String toString()
{
return super.toString() + " Vol:" + this.tank.getFluidAmount();
}
} }

View file

@ -8,7 +8,7 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection; import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidHandler; import net.minecraftforge.fluids.IFluidHandler;
import resonantinduction.api.fluid.IFluidPart; import resonantinduction.api.fluid.IFluidConnector;
import resonantinduction.api.fluid.IFluidPipe; import resonantinduction.api.fluid.IFluidPipe;
import resonantinduction.mechanical.fluid.network.FluidNetwork; import resonantinduction.mechanical.fluid.network.FluidNetwork;
import universalelectricity.api.vector.Vector3; import universalelectricity.api.vector.Vector3;
@ -17,97 +17,99 @@ import calclavia.lib.utility.FluidUtility;
/** @author DarkGuardsman */ /** @author DarkGuardsman */
public class PipeNetwork extends FluidNetwork public class PipeNetwork extends FluidNetwork
{ {
public HashMap<IFluidHandler, EnumSet<ForgeDirection>> connectionMap = new HashMap<IFluidHandler, EnumSet<ForgeDirection>>(); public HashMap<IFluidHandler, EnumSet<ForgeDirection>> connectionMap = new HashMap<IFluidHandler, EnumSet<ForgeDirection>>();
@Override @Override
public void update() public void update()
{ {
System.out.println("PipeNetwork:" + this.toString()); System.out.println("PipeNetwork:" + this.toString());
System.out.println("FluidVol: " + this.getTank().getFluidAmount()); System.out.println("FluidVol: " + this.getTank().getFluidAmount());
super.update(); super.update();
//Slight delay to allow visual effect to take place before draining the pipe's internal tank
if (this.ticks % 2 == 0 && this.getTank().getFluidAmount() > 0)
{
FluidStack stack = this.getTank().getFluid().copy();
int count = this.connectionMap.size();
for (Entry<IFluidHandler, EnumSet<ForgeDirection>> entry : this.connectionMap.entrySet())
{
int sideCount = entry.getValue().size();
for (ForgeDirection dir : entry.getValue())
{
int volPer = (stack.amount / count) + (stack.amount % count);
int volPerSide = (volPer / sideCount) + (volPer % count);
int maxFill = 1000;
TileEntity entity = new Vector3((TileEntity) entry.getKey()).modifyPositionFromSide(dir).getTileEntity(((TileEntity) entry.getKey()).worldObj);
if (entity instanceof IFluidPipe)
{
maxFill = ((IFluidPipe) entity).getMaxFlowRate();
}
stack.amount -= entry.getKey().fill(dir, FluidUtility.getStack(stack, Math.min(volPerSide, maxFill)), true);
if (sideCount > 1)
--sideCount;
if (volPer <= 0)
break;
}
if (count > 1)
count--;
if (stack == null || stack.amount <= 0)
break;
}
this.getTank().setFluid(stack);
//TODO check for change before rebuilding
this.rebuildTank();
}
}
@Override // Slight delay to allow visual effect to take place before draining the pipe's internal
public boolean canUpdate() // tank
{ if (this.ticks % 2 == 0 && this.getTank().getFluidAmount() > 0)
return true; {
} FluidStack stack = this.getTank().getFluid().copy();
int count = this.connectionMap.size();
for (Entry<IFluidHandler, EnumSet<ForgeDirection>> entry : this.connectionMap.entrySet())
{
int sideCount = entry.getValue().size();
for (ForgeDirection dir : entry.getValue())
{
int volPer = (stack.amount / count) + (stack.amount % count);
int volPerSide = (volPer / sideCount) + (volPer % count);
int maxFill = 1000;
TileEntity entity = new Vector3((TileEntity) entry.getKey()).modifyPositionFromSide(dir).getTileEntity(((TileEntity) entry.getKey()).worldObj);
if (entity instanceof IFluidPipe)
{
maxFill = ((IFluidPipe) entity).getMaxFlowRate();
}
stack.amount -= entry.getKey().fill(dir, FluidUtility.getStack(stack, Math.min(volPerSide, maxFill)), true);
if (sideCount > 1)
--sideCount;
if (volPer <= 0)
break;
}
if (count > 1)
count--;
if (stack == null || stack.amount <= 0)
break;
}
this.getTank().setFluid(stack);
// TODO check for change before rebuilding
this.rebuildHandler();
}
}
@Override @Override
public boolean continueUpdate() public boolean canUpdate()
{ {
return this.getConnectors().size() > 0; return true;
} }
@Override @Override
public void reconstruct() public boolean continueUpdate()
{ {
this.connectionMap.clear(); return true;// this.getConnectors().size() > 0;
super.reconstruct(); }
}
@Override @Override
public void buildPart(IFluidPart part) public void reconstruct()
{ {
super.buildPart(part); this.connectionMap.clear();
for (int i = 0; i < 6; i++) super.reconstruct();
{ }
if (part.getConnections()[i] instanceof IFluidHandler && !(part.getConnections()[i] instanceof IFluidPipe))
{
EnumSet<ForgeDirection> set = this.connectionMap.get(part.getConnections()[i]);
if (set == null)
{
set = EnumSet.noneOf(ForgeDirection.class);
}
set.add(ForgeDirection.getOrientation(i).getOpposite());
this.connectionMap.put((IFluidHandler) part.getConnections()[i], set);
}
}
}
@Override @Override
public FluidStack drain(IFluidPart source, ForgeDirection from, FluidStack resource, boolean doDrain) public void buildPart(IFluidConnector part)
{ {
return null; super.buildPart(part);
} for (int i = 0; i < 6; i++)
{
if (part.getConnections()[i] instanceof IFluidHandler && !(part.getConnections()[i] instanceof IFluidPipe))
{
EnumSet<ForgeDirection> set = this.connectionMap.get(part.getConnections()[i]);
if (set == null)
{
set = EnumSet.noneOf(ForgeDirection.class);
}
set.add(ForgeDirection.getOrientation(i).getOpposite());
this.connectionMap.put((IFluidHandler) part.getConnections()[i], set);
}
}
}
@Override @Override
public FluidStack drain(IFluidPart source, ForgeDirection from, int resource, boolean doDrain) public FluidStack drain(IFluidConnector source, ForgeDirection from, FluidStack resource, boolean doDrain)
{ {
return null; return null;
} }
@Override
public FluidStack drain(IFluidConnector source, ForgeDirection from, int resource, boolean doDrain)
{
return null;
}
} }

View file

@ -14,7 +14,7 @@ import net.minecraftforge.fluids.FluidTank;
import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.FluidTankInfo;
import resonantinduction.api.IReadOut; import resonantinduction.api.IReadOut;
import resonantinduction.api.fluid.IFluidNetwork; import resonantinduction.api.fluid.IFluidNetwork;
import resonantinduction.api.fluid.IFluidPart; import resonantinduction.api.fluid.IFluidConnector;
import resonantinduction.core.ResonantInduction; import resonantinduction.core.ResonantInduction;
import resonantinduction.mechanical.Mechanical; import resonantinduction.mechanical.Mechanical;
import resonantinduction.mechanical.fluid.network.FluidNetwork; import resonantinduction.mechanical.fluid.network.FluidNetwork;
@ -28,331 +28,322 @@ import com.google.common.io.ByteArrayDataInput;
import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly; import cpw.mods.fml.relauncher.SideOnly;
public class TileFluidNetwork extends TileEntityFluidDevice implements IFluidPart, IPacketReceiverWithID, IReadOut /**
* A prefab class for tiles that use the fluid network.
*
* @author DarkCow
*
*/
public abstract class TileFluidNetwork<N extends FluidNetwork> extends TileEntityFluidDevice implements IFluidConnector, IPacketReceiverWithID, IReadOut
{ {
public static int refreshRate = 10; public static int refreshRate = 10;
protected FluidTank tank = new FluidTank(1 * FluidContainerRegistry.BUCKET_VOLUME); protected FluidTank tank = new FluidTank(1 * FluidContainerRegistry.BUCKET_VOLUME);
protected Object[] connectedBlocks = new Object[6]; protected Object[] connectedBlocks = new Object[6];
protected int colorID = 0; protected int colorID = 0;
/** Copy of the tank's content last time it updated */ /** Copy of the tank's content last time it updated */
protected FluidStack prevStack = null; protected FluidStack prevStack = null;
/** Network used to link all parts together */ /** Network used to link all parts together */
protected IFluidNetwork network; protected N network;
public static final int PACKET_DESCRIPTION = Mechanical.contentRegistry.getNextPacketID(); public static final int PACKET_DESCRIPTION = Mechanical.contentRegistry.getNextPacketID();
public static final int PACKET_RENDER = Mechanical.contentRegistry.getNextPacketID(); public static final int PACKET_RENDER = Mechanical.contentRegistry.getNextPacketID();
public static final int PACKET_TANK = Mechanical.contentRegistry.getNextPacketID(); public static final int PACKET_TANK = Mechanical.contentRegistry.getNextPacketID();
/** Bitmask that handles connections for the renderer **/ /** Bitmask that handles connections for the renderer **/
public byte renderSides = 0b0; public byte renderSides = 0b0;
/** Tells the tank that on next update to check if it should update the client render data */ /** Tells the tank that on next update to check if it should update the client render data */
public boolean updateFluidRender = false; public boolean updateFluidRender = false;
@Override @Override
public void initiate() public void initiate()
{ {
super.initiate(); super.initiate();
this.refresh(); this.refresh();
} }
@Override @Override
public void updateEntity() public void updateEntity()
{ {
super.updateEntity(); super.updateEntity();
if (!worldObj.isRemote) if (!worldObj.isRemote)
{ {
if (this.updateFluidRender && ticks % TileFluidNetwork.refreshRate == 0) if (this.updateFluidRender && ticks % TileFluidNetwork.refreshRate == 0)
{ {
if (!FluidUtility.matchExact(prevStack, this.getInternalTank().getFluid())) if (!FluidUtility.matchExact(prevStack, this.getInternalTank().getFluid()))
{ {
this.sendTankUpdate(); this.sendTankUpdate();
} }
this.prevStack = this.tank.getFluid(); this.prevStack = this.tank.getFluid();
this.updateFluidRender = false; this.updateFluidRender = false;
} }
} }
} }
@Override @Override
public void onFluidChanged() public void onFluidChanged()
{ {
this.updateFluidRender = true; this.updateFluidRender = true;
} }
@Override @Override
public void invalidate() public void invalidate()
{ {
this.getNetwork().split(this); this.getNetwork().split(this);
super.invalidate(); super.invalidate();
} }
@Override @Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill) public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
{ {
if (this.getNetwork() != null && resource != null) if (this.getNetwork() != null && resource != null)
{ {
return this.getNetwork().fill(this, from, resource, doFill); return this.getNetwork().fill(this, from, resource, doFill);
} }
return 0; return 0;
} }
@Override @Override
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
{ {
if (this.getNetwork() != null && resource != null) if (this.getNetwork() != null && resource != null)
{ {
return this.getNetwork().drain(this, from, resource, doDrain); return this.getNetwork().drain(this, from, resource, doDrain);
} }
return null; return null;
} }
@Override @Override
public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
{ {
if (this.getNetwork() != null) if (this.getNetwork() != null)
{ {
return this.getNetwork().drain(this, from, maxDrain, doDrain); return this.getNetwork().drain(this, from, maxDrain, doDrain);
} }
return null; return null;
} }
@Override @Override
public boolean canFill(ForgeDirection from, Fluid fluid) public boolean canFill(ForgeDirection from, Fluid fluid)
{ {
return true; return true;
} }
@Override @Override
public boolean canDrain(ForgeDirection from, Fluid fluid) public boolean canDrain(ForgeDirection from, Fluid fluid)
{ {
return true; return true;
} }
@Override @Override
public FluidTankInfo[] getTankInfo(ForgeDirection from) public FluidTankInfo[] getTankInfo(ForgeDirection from)
{ {
return this.getNetwork().getTankInfo(); return this.getNetwork().getTankInfo();
} }
@Override @Override
public Object[] getConnections() public Object[] getConnections()
{ {
return this.connectedBlocks; return this.connectedBlocks;
} }
public void refresh() public void refresh()
{ {
if (this.worldObj != null && !this.worldObj.isRemote) if (this.worldObj != null && !this.worldObj.isRemote)
{ {
byte previousConnections = renderSides; byte previousConnections = renderSides;
this.connectedBlocks = new Object[6]; this.connectedBlocks = new Object[6];
this.renderSides = 0; this.renderSides = 0;
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS)
{ {
this.validateConnectionSide(new Vector3(this).modifyPositionFromSide(dir).getTileEntity(this.worldObj), dir); this.validateConnectionSide(new Vector3(this).modifyPositionFromSide(dir).getTileEntity(this.worldObj), dir);
} }
/** Only send packet updates if visuallyConnected changed. */ /** Only send packet updates if visuallyConnected changed. */
if (previousConnections != renderSides) if (previousConnections != renderSides)
{ {
this.sendRenderUpdate(); this.sendRenderUpdate();
this.getNetwork().reconstruct(); this.getNetwork().reconstruct();
} }
} }
} }
/** Checks to make sure the connection is valid to the tileEntity /**
* * Checks to make sure the connection is valid to the tileEntity
* @param tileEntity - the tileEntity being checked *
* @param side - side the connection is too */ * @param tileEntity - the tileEntity being checked
public void validateConnectionSide(TileEntity tileEntity, ForgeDirection side) * @param side - side the connection is too
{ */
if (!this.worldObj.isRemote) public void validateConnectionSide(TileEntity tileEntity, ForgeDirection side)
{ {
if (tileEntity instanceof IFluidPart) if (!this.worldObj.isRemote)
{ {
this.getNetwork().merge(((IFluidPart) tileEntity).getNetwork()); if (tileEntity instanceof IFluidConnector)
this.setRenderSide(side, true); {
connectedBlocks[side.ordinal()] = tileEntity; this.getNetwork().merge(((IFluidConnector) tileEntity).getNetwork());
} this.setRenderSide(side, true);
} connectedBlocks[side.ordinal()] = tileEntity;
} }
}
}
public void setRenderSide(ForgeDirection direction, boolean doRender) public void setRenderSide(ForgeDirection direction, boolean doRender)
{ {
if (doRender) if (doRender)
{ {
renderSides = (byte) (renderSides | (1 << direction.ordinal())); renderSides = (byte) (renderSides | (1 << direction.ordinal()));
} }
else else
{ {
renderSides = (byte) (renderSides & ~(1 << direction.ordinal())); renderSides = (byte) (renderSides & ~(1 << direction.ordinal()));
} }
} }
public boolean canRenderSide(ForgeDirection direction) public boolean canRenderSide(ForgeDirection direction)
{ {
return (renderSides & (1 << direction.ordinal())) != 0; return (renderSides & (1 << direction.ordinal())) != 0;
} }
@Override @Override
public IFluidNetwork getNetwork() public void readFromNBT(NBTTagCompound nbt)
{ {
if (this.network != null) super.readFromNBT(nbt);
{ this.colorID = nbt.getInteger("subID");
this.network = new FluidNetwork(); if (nbt.hasKey("stored"))
this.network.addConnector(this); {
} NBTTagCompound tag = nbt.getCompoundTag("stored");
return this.network; String name = tag.getString("LiquidName");
} int amount = nbt.getInteger("Amount");
Fluid fluid = FluidRegistry.getFluid(name);
if (fluid != null)
{
FluidStack liquid = new FluidStack(fluid, amount);
this.getInternalTank().setFluid(liquid);
}
}
else
{
this.getInternalTank().readFromNBT(nbt.getCompoundTag("FluidTank"));
}
}
@Override @Override
public void setNetwork(IFluidNetwork fluidNetwork) public void writeToNBT(NBTTagCompound nbt)
{ {
this.network = fluidNetwork; super.writeToNBT(nbt);
} nbt.setInteger("subID", this.colorID);
nbt.setCompoundTag("FluidTank", this.getInternalTank().writeToNBT(new NBTTagCompound()));
}
@Override @Override
public void readFromNBT(NBTTagCompound nbt) public boolean onReceivePacket(int id, ByteArrayDataInput data, EntityPlayer player, Object... extra)
{ {
super.readFromNBT(nbt); try
this.colorID = nbt.getInteger("subID"); {
if (nbt.hasKey("stored")) if (this.worldObj.isRemote)
{ {
NBTTagCompound tag = nbt.getCompoundTag("stored"); if (id == PACKET_DESCRIPTION)
String name = tag.getString("LiquidName"); {
int amount = nbt.getInteger("Amount"); this.colorID = data.readInt();
Fluid fluid = FluidRegistry.getFluid(name); this.renderSides = data.readByte();
if (fluid != null) this.tank = new FluidTank(data.readInt());
{ this.getInternalTank().readFromNBT(PacketHandler.readNBTTagCompound(data));
FluidStack liquid = new FluidStack(fluid, amount); return true;
this.getInternalTank().setFluid(liquid); }
} else if (id == PACKET_RENDER)
} {
else this.colorID = data.readInt();
{ this.renderSides = data.readByte();
this.getInternalTank().readFromNBT(nbt.getCompoundTag("FluidTank")); return true;
} }
} else if (id == PACKET_TANK)
{
this.tank = new FluidTank(data.readInt());
this.getInternalTank().readFromNBT(PacketHandler.readNBTTagCompound(data));
return true;
}
}
}
catch (Exception e)
{
e.printStackTrace();
return true;
}
return false;
}
@Override @Override
public void writeToNBT(NBTTagCompound nbt) public Packet getDescriptionPacket()
{ {
super.writeToNBT(nbt); return ResonantInduction.PACKET_TILE.getPacketWithID(PACKET_DESCRIPTION, this, this.colorID, this.renderSides, this.getInternalTank().getCapacity(), this.getInternalTank().writeToNBT(new NBTTagCompound()));
nbt.setInteger("subID", this.colorID); }
nbt.setCompoundTag("FluidTank", this.getInternalTank().writeToNBT(new NBTTagCompound()));
}
@Override public void sendRenderUpdate()
public boolean onReceivePacket(int id, ByteArrayDataInput data, EntityPlayer player, Object... extra) {
{ PacketHandler.sendPacketToClients(ResonantInduction.PACKET_TILE.getPacketWithID(PACKET_RENDER, this, this.colorID, this.renderSides));
try }
{
if (this.worldObj.isRemote)
{
if (id == PACKET_DESCRIPTION)
{
this.colorID = data.readInt();
this.renderSides = data.readByte();
this.tank = new FluidTank(data.readInt());
this.getInternalTank().readFromNBT(PacketHandler.readNBTTagCompound(data));
return true;
}
else if (id == PACKET_RENDER)
{
this.colorID = data.readInt();
this.renderSides = data.readByte();
return true;
}
else if (id == PACKET_TANK)
{
this.tank = new FluidTank(data.readInt());
this.getInternalTank().readFromNBT(PacketHandler.readNBTTagCompound(data));
return true;
}
}
}
catch (Exception e)
{
e.printStackTrace();
return true;
}
return false;
}
@Override public void sendTankUpdate()
public Packet getDescriptionPacket() {
{ if (this.getInternalTank() != null)
return ResonantInduction.PACKET_TILE.getPacketWithID(PACKET_DESCRIPTION, this, this.colorID, this.renderSides, this.getInternalTank().getCapacity(), this.getInternalTank().writeToNBT(new NBTTagCompound())); {
} PacketHandler.sendPacketToClients(ResonantInduction.PACKET_TILE.getPacketWithID(PACKET_TANK, this, this.getInternalTank().getCapacity(), this.getInternalTank().writeToNBT(new NBTTagCompound())), this.worldObj, new Vector3(this), 60);
}
}
public void sendRenderUpdate() @Override
{ @SideOnly(Side.CLIENT)
PacketHandler.sendPacketToClients(ResonantInduction.PACKET_TILE.getPacketWithID(PACKET_RENDER, this, this.colorID, this.renderSides)); public AxisAlignedBB getRenderBoundingBox()
} {
return AxisAlignedBB.getAABBPool().getAABB(this.xCoord, this.yCoord, this.zCoord, this.xCoord + 1, this.yCoord + 1, this.zCoord + 1);
}
public void sendTankUpdate() public int getSubID()
{ {
if (this.getInternalTank() != null) return this.colorID;
{ }
PacketHandler.sendPacketToClients(ResonantInduction.PACKET_TILE.getPacketWithID(PACKET_TANK, this, this.getInternalTank().getCapacity(), this.getInternalTank().writeToNBT(new NBTTagCompound())), this.worldObj, new Vector3(this), 60);
}
}
@Override public void setSubID(int id)
@SideOnly(Side.CLIENT) {
public AxisAlignedBB getRenderBoundingBox() this.colorID = id;
{ }
return AxisAlignedBB.getAABBPool().getAABB(this.xCoord, this.yCoord, this.zCoord, this.xCoord + 1, this.yCoord + 1, this.zCoord + 1);
}
public int getSubID() public static boolean canRenderSide(byte renderSides, ForgeDirection direction)
{ {
return this.colorID; return (renderSides & (1 << direction.ordinal())) != 0;
} }
public void setSubID(int id) @Override
{ public boolean canConnect(ForgeDirection direction)
this.colorID = id; {
} return true;
}
public static boolean canRenderSide(byte renderSides, ForgeDirection direction) @Override
{ public FluidTank getInternalTank()
return (renderSides & (1 << direction.ordinal())) != 0; {
} if (this.tank == null)
{
this.tank = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME);
}
return this.tank;
}
@Override @Override
public boolean canConnect(ForgeDirection direction) public String getMeterReading(EntityPlayer user, ForgeDirection side, EnumTools tool)
{ {
return true; if (tool == EnumTools.PIPE_GUAGE)
} {
return this.getNetwork().toString();
@Override }
public FluidTank getInternalTank() return null;
{ }
if (this.tank == null)
{
this.tank = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME);
}
return this.tank;
}
@Override
public String getMeterReading(EntityPlayer user, ForgeDirection side, EnumTools tool)
{
if (tool == EnumTools.PIPE_GUAGE)
{
return this.getNetwork().toString();
}
return null;
}
} }

View file

@ -5,7 +5,7 @@ import java.util.Set;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import resonantinduction.api.fluid.IFluidPart; import resonantinduction.api.fluid.IFluidConnector;
import resonantinduction.mechanical.fluid.network.FluidNetwork; import resonantinduction.mechanical.fluid.network.FluidNetwork;
/** Network that handles connected tanks /** Network that handles connected tanks
@ -27,7 +27,7 @@ public class TankNetwork extends FluidNetwork
else if (this.getConnectors().size() > 0) else if (this.getConnectors().size() > 0)
{ {
fillStack = fillStack.copy(); fillStack = fillStack.copy();
for (IFluidPart part : this.getConnectors()) for (IFluidConnector part : this.getConnectors())
{ {
part.getInternalTank().setFluid(null); part.getInternalTank().setFluid(null);
if (part instanceof TileEntity && ((TileEntity) part).yCoord < lowestY) if (part instanceof TileEntity && ((TileEntity) part).yCoord < lowestY)
@ -43,13 +43,13 @@ public class TankNetwork extends FluidNetwork
//TODO Add path finder to prevent filling when tanks are only connected at the top //TODO Add path finder to prevent filling when tanks are only connected at the top
for (int y = lowestY; y <= highestY; y++) for (int y = lowestY; y <= highestY; y++)
{ {
Set<IFluidPart> parts = new LinkedHashSet<IFluidPart>(); Set<IFluidConnector> parts = new LinkedHashSet<IFluidConnector>();
for (IFluidPart part : this.getConnectors()) for (IFluidConnector part : this.getConnectors())
{ {
if (part instanceof IFluidPart && ((TileEntity) part).yCoord == y) if (part instanceof IFluidConnector && ((TileEntity) part).yCoord == y)
{ {
parts.add((IFluidPart) part); parts.add((IFluidConnector) part);
} }
} }
if (!parts.isEmpty()) if (!parts.isEmpty())

View file

@ -4,7 +4,7 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection; import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.fluids.FluidContainerRegistry; import net.minecraftforge.fluids.FluidContainerRegistry;
import resonantinduction.api.fluid.IFluidNetwork; import resonantinduction.api.fluid.IFluidNetwork;
import resonantinduction.api.fluid.IFluidPart; import resonantinduction.api.fluid.IFluidConnector;
import resonantinduction.mechanical.fluid.prefab.TileFluidNetwork; import resonantinduction.mechanical.fluid.prefab.TileFluidNetwork;
public class TileTank extends TileFluidNetwork public class TileTank extends TileFluidNetwork
@ -43,7 +43,7 @@ public class TileTank extends TileFluidNetwork
{ {
if (tileEntity instanceof TileTank) if (tileEntity instanceof TileTank)
{ {
this.getNetwork().merge(((IFluidPart) tileEntity).getNetwork()); this.getNetwork().merge(((IFluidConnector) tileEntity).getNetwork());
this.setRenderSide(side, true); this.setRenderSide(side, true);
connectedBlocks[side.ordinal()] = tileEntity; connectedBlocks[side.ordinal()] = tileEntity;
} }

View file

@ -479,4 +479,16 @@ public class PartGear extends JCuboidPart implements JNormalOcclusion, TFacePart
return new universalelectricity.api.vector.Vector3(this.x() + direction.offsetX, this.y() + direction.offsetY, this.z() + direction.offsetZ).getTileEntity(this.world()) instanceof IMechanicalConnector; return new universalelectricity.api.vector.Vector3(this.x() + direction.offsetX, this.y() + direction.offsetY, this.z() + direction.offsetZ).getTileEntity(this.world()) instanceof IMechanicalConnector;
} }
@Override
public boolean isClockwise()
{
return isClockwise;
}
@Override
public void setRotation(boolean isClockwise)
{
this.isClockwise = isClockwise;
}
} }

View file

@ -15,4 +15,8 @@ public interface IMechanical extends IConnectable
* @return Amount of energy that was accepted by the block. * @return Amount of energy that was accepted by the block.
*/ */
public long onReceiveEnergy(ForgeDirection from, long torque, float angularVelocity, boolean doReceive); public long onReceiveEnergy(ForgeDirection from, long torque, float angularVelocity, boolean doReceive);
public boolean isClockwise();
public void setRotation(boolean isClockwise);
} }

View file

@ -10,6 +10,8 @@ public class TileMechanical extends TileAdvanced implements IMechanicalConnector
private IMechanicalNetwork network; private IMechanicalNetwork network;
private boolean isClockwise = false;
@Override @Override
public long onReceiveEnergy(ForgeDirection from, long torque, float angularVelocity, boolean doReceive) public long onReceiveEnergy(ForgeDirection from, long torque, float angularVelocity, boolean doReceive)
{ {
@ -56,4 +58,16 @@ public class TileMechanical extends TileAdvanced implements IMechanicalConnector
{ {
return 0; return 0;
} }
@Override
public boolean isClockwise()
{
return isClockwise;
}
@Override
public void setRotation(boolean isClockwise)
{
this.isClockwise = isClockwise;
}
} }

View file

@ -25,6 +25,7 @@ public class BlockGrinderWheel extends BlockRIRotatable implements ITileEntityPr
{ {
super("grindingWheel", Settings.getNextBlockID()); super("grindingWheel", Settings.getNextBlockID());
this.setBlockBounds(0.05f, 0.05f, 0.05f, 0.95f, 0.95f, 0.95f); this.setBlockBounds(0.05f, 0.05f, 0.05f, 0.95f, 0.95f, 0.95f);
rotationMask = 0b111111;
} }
@Override @Override

View file

@ -33,7 +33,7 @@ public class RenderGrinderWheel extends TileEntitySpecialRenderer
TileGrinderWheel tile = (TileGrinderWheel) t; TileGrinderWheel tile = (TileGrinderWheel) t;
glPushMatrix(); glPushMatrix();
glTranslatef((float) x + 0.5F, (float) y + 0.5f, (float) z + 0.5F); glTranslatef((float) x + 0.5F, (float) y + 0.5f, (float) z + 0.5F);
glScalef(0.5f, 0.5f, 0.52f); glScalef(0.5f, 0.5f, 0.515f);
glRotatef((float) Math.toDegrees(tile.getNetwork().getRotation()), 0, 0, 1); glRotatef((float) Math.toDegrees(tile.getNetwork().getRotation()), 0, 0, 1);
FMLClientHandler.instance().getClient().renderEngine.bindTexture(TEXTURE); FMLClientHandler.instance().getClient().renderEngine.bindTexture(TEXTURE);
MODEL.renderAll(); MODEL.renderAll();

View file

@ -81,4 +81,16 @@ public class TraitMechanical extends TileMultipart implements IMechanical
return 0; return 0;
} }
@Override
public boolean isClockwise()
{
return false;
}
@Override
public void setRotation(boolean isClockwise)
{
}
} }

View file

@ -113,4 +113,16 @@ public class TraitMechanicalConnector extends TileMultipart implements IMechanic
{ {
return 0; return 0;
} }
@Override
public boolean isClockwise()
{
return false;
}
@Override
public void setRotation(boolean isClockwise)
{
}
} }