diff --git a/src/minecraft/dark/library/helpers/DebugToPlayer.java b/src/minecraft/dark/library/helpers/DebugToPlayer.java deleted file mode 100644 index e6d63069..00000000 --- a/src/minecraft/dark/library/helpers/DebugToPlayer.java +++ /dev/null @@ -1,52 +0,0 @@ -package dark.library.helpers; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.World; - -public class DebugToPlayer -{ - /** - * Sends a message to the closest player - * - * @param range - range - * @param msg - display message under 200 chars - */ - public static void SendToClosest(World world, int x, int y, int z, int range, String msg) - { - EntityPlayer player = world.getClosestPlayer(x, y, z, range); - if (player != null) - { - msg = trimForDisplay(msg); - player.sendChatToPlayer("Debug: " + msg); - } - } - - /** - * Sends a debug message to the player using the tileEntity as the center - * - * @param r - range - * @param msg - display message under 200 chars - */ - public static void SendToClosest(TileEntity ent, int r, String msg) - { - if (ent != null) - { - DebugToPlayer.SendToClosest(ent.worldObj, ent.xCoord, ent.yCoord, ent.zCoord, r, msg); - } - } - - /** - * cleans up the display text and adds the [Debug] prefix too the text - * - * @param msg - display string under 200 chars - * @return - */ - public static String trimForDisplay(String msg) - { - // TODO trim the length to under 255 to prevent crashing - msg = msg.trim(); - msg = "[Debug] " + msg; - return msg; - } -} diff --git a/src/minecraft/dark/library/helpers/PlayerMsgHelper.java b/src/minecraft/dark/library/helpers/PlayerMsgHelper.java new file mode 100644 index 00000000..f23b153f --- /dev/null +++ b/src/minecraft/dark/library/helpers/PlayerMsgHelper.java @@ -0,0 +1,47 @@ +package dark.library.helpers; + +import java.util.Iterator; +import java.util.List; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.World; +import universalelectricity.core.vector.Vector3; + +public class PlayerMsgHelper +{ + public static void msgAllPlayersInRange(World world, Vector3 loc, double range, String sender, String... msgs) + { + if (world != null && loc != null && msgs != null) + { + String sendMsg = sender + ">>>"; + for (int i = 0; i < msgs.length; i++) + { + sendMsg += msgs[i] + ">>>"; + } + sendMsg = sendMsg.substring(0, sendMsg.length() > 255 ? 255 : sendMsg.length()); + List list = getPlayersInRange(world, loc, range, false); + + for (EntityPlayer player : list) + { + player.sendChatToPlayer(sendMsg); + } + } + } + + public static List getPlayersInRange(World world, Vector3 loc, double range, boolean canSee) + { + AxisAlignedBB bound = AxisAlignedBB.getBoundingBox(loc.x - range, loc.y - range, loc.z - range, loc.x + range, loc.y + range, loc.z + range); + List list = world.getEntitiesWithinAABB(EntityPlayer.class, bound); + Iterator it = list.iterator(); + while (it.hasNext() && canSee) + { + EntityPlayer player = it.next(); + if (world.rayTraceBlocks(loc.toVec3(), new Vector3(player).add(new Vector3(0, player.getEyeHeight(), 0)).toVec3()) != null) + { + it.remove(); + } + } + return list; + } +} diff --git a/src/minecraft/dark/library/math/LinearAlg.java b/src/minecraft/dark/library/math/LinearAlg.java new file mode 100644 index 00000000..f4dbec5f --- /dev/null +++ b/src/minecraft/dark/library/math/LinearAlg.java @@ -0,0 +1,6 @@ +package dark.library.math; + +public class LinearAlg +{ + +} diff --git a/src/minecraft/dark/library/math/OrbitHelper.java b/src/minecraft/dark/library/math/OrbitHelper.java new file mode 100644 index 00000000..cb0cb2ea --- /dev/null +++ b/src/minecraft/dark/library/math/OrbitHelper.java @@ -0,0 +1,42 @@ +package dark.library.math; + +import universalelectricity.core.vector.Vector3; + +public class OrbitHelper +{ + /** + * Get the offset of the center of the circle and object will be if move around the edge of the + * circle so far + * + * @param radus distance of the circle + * @param pos in the circle + * @return change from center of the circle + */ + public Vector3 getRadianPos(float radus, int pos, float spacing) + { + return null; + } + + /** + * Gets the spacing in order to to have x number of the same width object orbit a point + * + * @param radus of the circle + * @param width of the object including spacing + * @param number of objects + * @return spacing in radians of the circle + */ + public float getObjectSpacing(double radus, double width, double number) + { + return 0; + } + + public Vector3 getCirclePos(int objects, double width, double radius) + { + if (radius < (width + (width / 2)) * objects) + { + radius = (width + width / 2) * objects; + } + float spacing = this.getObjectSpacing(radius, width, objects); + return null; + } +} diff --git a/src/minecraft/dark/library/terminal/TileEntityTerminal.java b/src/minecraft/dark/library/terminal/TileEntityTerminal.java index a2466d82..42b4c78f 100644 --- a/src/minecraft/dark/library/terminal/TileEntityTerminal.java +++ b/src/minecraft/dark/library/terminal/TileEntityTerminal.java @@ -186,7 +186,7 @@ public abstract class TileEntityTerminal extends TileEntityRunnableMachine imple } catch (Exception e) { - FMLLog.severe("ICBM: Failed to receive packet for terminal."); + FMLLog.severe("DarkLib>>>TerminalInstance>>>PacketReadError>>>ForTile>>>"+this.toString()); e.printStackTrace(); } } diff --git a/src/minecraft/hydraulic/api/FluidRestrictionHandler.java b/src/minecraft/hydraulic/api/FluidRestrictionHandler.java index 7b1b73ec..fd1217c5 100644 --- a/src/minecraft/hydraulic/api/FluidRestrictionHandler.java +++ b/src/minecraft/hydraulic/api/FluidRestrictionHandler.java @@ -22,7 +22,7 @@ public class FluidRestrictionHandler @ForgeSubscribe public void onLiquidRegistered(LiquidRegisterEvent event) { - if (event.Name != null) + if (event != null && event.Name != null) { if (event.Name.equalsIgnoreCase("Fuel") && !restrictedStacks.containsKey(ColorCode.YELLOW)) { @@ -46,14 +46,16 @@ public class FluidRestrictionHandler { return restrictedStacks.containsKey(ColorCode.get(meta)); } + public static boolean hasRestrictedStack(LiquidStack stack) { - if(stack == null) + if (stack == null) { return false; - } + } return restrictedStacks.inverse().containsKey(stack); } + /** * gets the liquid stack that is restricted to this color * diff --git a/src/minecraft/hydraulic/api/INetworkFluidPart.java b/src/minecraft/hydraulic/api/INetworkFluidPart.java new file mode 100644 index 00000000..6862a62e --- /dev/null +++ b/src/minecraft/hydraulic/api/INetworkFluidPart.java @@ -0,0 +1,18 @@ +package hydraulic.api; + +import net.minecraftforge.liquids.ITankContainer; +import net.minecraftforge.liquids.LiquidStack; +import net.minecraftforge.liquids.LiquidTank; + +public interface INetworkFluidPart extends IColorCoded, ITankContainer, INetworkPart +{ + /** + * Gets the part's main tank for shared storage + */ + public LiquidTank getTank(); + + /** + * Sets the content of the part's main tank + */ + public void setTankContent(LiquidStack stack); +} diff --git a/src/minecraft/hydraulic/api/INetworkPart.java b/src/minecraft/hydraulic/api/INetworkPart.java new file mode 100644 index 00000000..3da143c6 --- /dev/null +++ b/src/minecraft/hydraulic/api/INetworkPart.java @@ -0,0 +1,27 @@ +package hydraulic.api; + +import hydraulic.network.TileNetwork; +import net.minecraft.tileentity.TileEntity; + +public interface INetworkPart extends ITileConnector +{ + /** + * Array of connections this tile has to other tiles + */ + public TileEntity[] getNetworkConnections(); + + /** + * Update the connection this tile has to other tiles + */ + public void updateNetworkConnections(); + + /** + * Gets the networkPart's primary network + */ + public TileNetwork getTileNetwork(); + + /** + * Sets the networkPart's primary network + */ + public void setTileNetwork(TileNetwork fluidNetwok); +} diff --git a/src/minecraft/hydraulic/fluidnetwork/IFluidNetworkPart.java b/src/minecraft/hydraulic/api/INetworkPipe.java similarity index 50% rename from src/minecraft/hydraulic/fluidnetwork/IFluidNetworkPart.java rename to src/minecraft/hydraulic/api/INetworkPipe.java index d6622440..e1d5c44a 100644 --- a/src/minecraft/hydraulic/fluidnetwork/IFluidNetworkPart.java +++ b/src/minecraft/hydraulic/api/INetworkPipe.java @@ -1,10 +1,6 @@ -package hydraulic.fluidnetwork; +package hydraulic.api; -import hydraulic.api.IColorCoded; -import hydraulic.api.IPipeConnection; import net.minecraftforge.common.ForgeDirection; -import net.minecraftforge.liquids.ILiquidTank; -import net.minecraftforge.liquids.ITankContainer; import net.minecraftforge.liquids.LiquidStack; /** @@ -12,34 +8,30 @@ import net.minecraftforge.liquids.LiquidStack; * that doesn't change the over all network pressure. So pipes, gauges, tubes, buffers, decor * blocks. */ -public interface IFluidNetworkPart extends IPipeConnection, IColorCoded, ITankContainer, INetworkPath +public interface INetworkPipe extends INetworkFluidPart { /** - * gets the devices pressure from a given side for input + * Gets the parts max pressure limit it can handle + * + * Note this is not recommended max limit by rather actual breaking point of the part */ public double getMaxPressure(ForgeDirection side); /** - * The max amount of liquid that can flow per request + * Max flow rate of liquid flow this part from the side for the liquid type that his part will + * allow + * + * @return limit in bucket parts(1/1000 of a bucket) */ - public int getMaxFlowRate(LiquidStack stack, ForgeDirection side); + public int getMaxFlowRate(LiquidStack stack, ForgeDirection side); /** - * Called when the pressure on the machine reachs max + * Called when the pressure on the machine goes beyond max limits. Suggest doing random chance + * of damage or break too simulate real chances of pipe going beyond designed limits * * @param damageAllowed - can this tileEntity cause grief damage * @return true if the device over pressured and destroyed itself */ public boolean onOverPressure(Boolean damageAllowed); - /** - * size of the pipes liquid storage ability - */ - public int getTankSize(); - - public ILiquidTank getTank(); - - public void setTankContent(LiquidStack stack); - - } diff --git a/src/minecraft/hydraulic/api/IPipeConnection.java b/src/minecraft/hydraulic/api/IPipeConnection.java deleted file mode 100644 index 9f98c072..00000000 --- a/src/minecraft/hydraulic/api/IPipeConnection.java +++ /dev/null @@ -1,18 +0,0 @@ -package hydraulic.api; - -import net.minecraft.tileentity.TileEntity; -import net.minecraftforge.common.ForgeDirection; - -public interface IPipeConnection -{ - /** - * This method should only be used by pipe like objects to find if they can connect to this - * object - * - * @param entity - the pipe connecting to this object as a TileEntity instance - * @param dir - side connecting too - * - * @return true if it can connect - */ - public boolean canPipeConnect(TileEntity entity, ForgeDirection dir); -} diff --git a/src/minecraft/hydraulic/api/IPsiReciever.java b/src/minecraft/hydraulic/api/IPsiReciever.java index 4ffd99b6..de9c8b29 100644 --- a/src/minecraft/hydraulic/api/IPsiReciever.java +++ b/src/minecraft/hydraulic/api/IPsiReciever.java @@ -6,7 +6,7 @@ package hydraulic.api; * net.minecraftforge.liquids too make your machine work with other fluid mods that don't use * pressure */ -public interface IPsiReciever extends IPipeConnection +public interface IPsiReciever extends ITileConnector { /** * the load that this machine is handling, working, or moving diff --git a/src/minecraft/hydraulic/api/ITileConnector.java b/src/minecraft/hydraulic/api/ITileConnector.java new file mode 100644 index 00000000..eed0bee7 --- /dev/null +++ b/src/minecraft/hydraulic/api/ITileConnector.java @@ -0,0 +1,12 @@ +package hydraulic.api; + +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.ForgeDirection; + +public interface ITileConnector +{ + /** + * Can this tile connect on the given side + */ + public boolean canTileConnect(TileEntity entity, ForgeDirection dir); +} diff --git a/src/minecraft/hydraulic/fluidnetwork/HydraulicNetwork.java b/src/minecraft/hydraulic/fluidnetwork/HydraulicNetwork.java deleted file mode 100644 index 73e78a07..00000000 --- a/src/minecraft/hydraulic/fluidnetwork/HydraulicNetwork.java +++ /dev/null @@ -1,700 +0,0 @@ -package hydraulic.fluidnetwork; - -import hydraulic.api.ColorCode; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.World; -import net.minecraftforge.common.ForgeDirection; -import net.minecraftforge.liquids.ILiquidTank; -import net.minecraftforge.liquids.ITankContainer; -import net.minecraftforge.liquids.LiquidContainerRegistry; -import net.minecraftforge.liquids.LiquidDictionary; -import net.minecraftforge.liquids.LiquidStack; -import net.minecraftforge.liquids.LiquidTank; -import universalelectricity.core.path.Pathfinder; -import universalelectricity.core.vector.Vector3; -import cpw.mods.fml.common.FMLLog; -import dark.library.helpers.ConnectionHelper; - -/** - * Side note: the network should act like this when done {@link http - * ://www.e4training.com/hydraulic_calculators/B1.htm} as well as stay compatible with the forge - * Liquids - * - * @author Rseifert - * - */ -public class HydraulicNetwork -{ - /* BLOCK THAT ACT AS FLUID CONVEYORS ** */ - public final List fluidParts = new ArrayList(); - /* MACHINES THAT USE THE FORGE LIQUID API TO RECEIVE LIQUID ** */ - public final List fluidTanks = new ArrayList(); - /* MACHINES THAT USE THE PRESSURE SYSTEM TO DO WORK ** */ - private final HashMap pressureProducers = new HashMap(); - private final HashMap pressureLoads = new HashMap(); - - public ColorCode color = ColorCode.NONE; - /* PRESSURE OF THE NETWORK AS A TOTAL. ZERO AS IN NO PRODUCTION */ - public double pressureProduced = 0; - /* PRESSURE OF THE NETWORK'S LOAD AS A TOTAL. ZERO AS IN NO LOAD */ - public double pressureLoad = 0; - /* IS IT PROCESSING AN ADD LIQUID EVENT */ - private boolean processingRequest = false; - /* COMBINED TEMP STORAGE FOR ALL PIPES IN THE NETWORK */ - private LiquidTank combinedStorage = new LiquidTank(LiquidContainerRegistry.BUCKET_VOLUME); - - public HydraulicNetwork(ColorCode color, IFluidNetworkPart... parts) - { - this.fluidParts.addAll(Arrays.asList(parts)); - this.color = color; - } - - /** - * sets this tileEntity to produce a pressure and flow rate in the network - */ - public void startProducingPressure(TileEntity tileEntity, FluidPressurePack fluidPack) - { - if (tileEntity != null && fluidPack.liquidStack != null) - { - if ((this.combinedStorage.getLiquid() == null || fluidPack.liquidStack.isLiquidEqual(this.combinedStorage.getLiquid())) && fluidPack.liquidStack.amount > 0) - { - this.pressureProducers.put(tileEntity, fluidPack); - } - } - } - - /** - * sets this tileEntity to produce a pressure and flow rate in the network - */ - public void startProducingPressure(TileEntity tileEntity, LiquidStack stack, double pressure) - { - this.startProducingPressure(tileEntity, new FluidPressurePack(stack, pressure)); - } - - /** - * is this tile entity producing a pressure - */ - public boolean isProducingPressure(TileEntity tileEntity) - { - return this.pressureProducers.containsKey(tileEntity); - } - - /** - * Sets this tile entity to stop producing pressure and flow in this network - */ - public void removeSource(TileEntity tileEntity) - { - this.pressureProducers.remove(tileEntity); - } - - /** - * Sets this tile entity to act as a load on the system - */ - public void addLoad(TileEntity tileEntity, FluidPressurePack fluidPack) - { - if (tileEntity != null && fluidPack.liquidStack != null && fluidPack.liquidStack.amount > 0) - { - this.pressureLoads.put(tileEntity, fluidPack); - } - } - - /** - * Sets this tile entity to act as a load on the system - */ - public void addLoad(TileEntity tileEntity, LiquidStack stack, double pressure) - { - this.addLoad(tileEntity, new FluidPressurePack(stack, pressure)); - } - - /** - * is this tileEntity a load in the network - */ - public boolean isLoad(TileEntity tileEntity) - { - return this.pressureLoads.containsKey(tileEntity); - } - - /** - * removes this tileEntity from being a load on the network - */ - public void removeLoad(TileEntity tileEntity) - { - this.pressureLoads.remove(tileEntity); - } - - /** - * Removes a tileEntity from any of the valid lists - */ - public void removeEntity(TileEntity ent) - { - if (fluidTanks.contains(ent)) - { - fluidTanks.remove(ent); - } - this.removeLoad(ent); - this.removeSource(ent); - } - - /** - * Adds a tileEntity to the list if its valid - */ - public void addEntity(ITankContainer ent) - { - if (ent == null) - { - return; - } - else if (ent instanceof IFluidNetworkPart) - { - this.addNetworkPart((IFluidNetworkPart) ent); - } - else if (!fluidTanks.contains(ent)) - { - fluidTanks.add(ent); - } - } - - public void addNetworkPart(IFluidNetworkPart newConductor) - { - this.cleanConductors(); - - if (newConductor.getColor() == this.color && !fluidParts.contains(newConductor)) - { - fluidParts.add(newConductor); - newConductor.setNetwork(this); - } - } - - /** - * Checks too see if the tileEntity is part of or connected too the network - */ - public boolean isConnected(TileEntity tileEntity) - { - if (this.fluidParts.contains(tileEntity)) - { - return true; - } - else if (this.fluidTanks.contains(tileEntity)) - { - return true; - } - else - { - return false; - } - } - - /** - * @param ignoreTiles The TileEntities to ignore during this calculation. Null will make it not - * ignore any. - * @return The electricity produced in this electricity network - */ - public double getPressureProduced(TileEntity... ignoreTiles) - { - // TODO pressure is not added as a sum but rather as a collective sum of the largest - // pressures. IF the pressure is to small it will be ignored and stop producing pressure. - int totalPressure = 0; - - Iterator it = this.pressureProducers.entrySet().iterator(); - - loop: - while (it.hasNext()) - { - Map.Entry pairs = (Map.Entry) it.next(); - - if (pairs != null) - { - TileEntity tileEntity = (TileEntity) pairs.getKey(); - - if (tileEntity == null) - { - it.remove(); - continue; - } - - if (tileEntity.isInvalid()) - { - it.remove(); - continue; - } - - if (tileEntity.worldObj.getBlockTileEntity(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord) != tileEntity) - { - it.remove(); - continue; - } - - if (ignoreTiles != null) - { - for (TileEntity ignoreTile : ignoreTiles) - { - if (tileEntity == ignoreTile) - { - continue loop; - } - } - } - - FluidPressurePack pack = (FluidPressurePack) pairs.getValue(); - - if (pairs.getKey() != null && pairs.getValue() != null && pack != null) - { - totalPressure += pack.pressure; - } - } - } - - return totalPressure; - } - - /** - * Adds FLuid to this network from one of the connected Pipes - * - * @param source - Were this liquid came from - * @param stack - LiquidStack to be sent - * @param doFill - actually fill the tank or just check numbers - * @return the amount of liquid consumed from the init stack - */ - public int addFluidToNetwork(TileEntity source, LiquidStack stack, boolean doFill) - { - return this.addFluidToNetwork(source, stack, doFill, false); - } - - /** - * Adds FLuid to this network from one of the connected Pipes - * - * @param source - Were this liquid came from - * @param stack - LiquidStack to be sent - * @param doFill - actually fill the tank or just check numbers - * @param allowStore - allows the network to store this liquid in the pipes - * @return the amount of liquid consumed from the init stack - */ - public int addFluidToNetwork(TileEntity source, LiquidStack stack, boolean doFill, boolean allowStore) - { - int used = 0; - LiquidStack prevCombined = this.combinedStorage.getLiquid(); - if (!this.processingRequest && stack != null && color.isValidLiquid(stack)) - { - if (this.combinedStorage.getLiquid() != null && !stack.isLiquidEqual(this.combinedStorage.getLiquid())) - { - // TODO cause mixing - } - if (stack.amount > this.getMaxFlow(stack)) - { - stack = new LiquidStack(stack.itemID, this.getMaxFlow(stack), stack.itemMeta); - } - - /* Main fill target to try to fill with the stack */ - ITankContainer primaryFill = null; - int volume = Integer.MAX_VALUE; - ForgeDirection fillDir = ForgeDirection.UNKNOWN; - - /* Secondary fill target if the main target is not found */ - ITankContainer secondayFill = null; - int mostFill = 0; - ForgeDirection otherFillDir = ForgeDirection.UNKNOWN; - - boolean found = false; - - /* FIND THE FILL TARGET FROM THE LIST OF FLUID RECIEVERS */ - for (ITankContainer tankContainer : fluidTanks) - { - if (tankContainer instanceof TileEntity && tankContainer != source && !(tankContainer instanceof IFluidNetworkPart)) - { - TileEntity[] connectedTiles = ConnectionHelper.getSurroundingTileEntities((TileEntity) tankContainer); - - for (int i = 0; i < 6; i++) - { - if (connectedTiles[i] instanceof IFluidNetworkPart && ((IFluidNetworkPart) connectedTiles[i]).getNetwork() == this) - { - ForgeDirection dir = ForgeDirection.getOrientation(i).getOpposite(); - ILiquidTank targetTank = tankContainer.getTank(dir, stack); - int fill = tankContainer.fill(dir, stack, false); - - /* USE GET TANK FROM SIDE METHOD FIRST */ - if (targetTank != null) - { - LiquidStack stackStored = targetTank.getLiquid(); - if (stackStored == null) - { - primaryFill = tankContainer; - found = true; - fillDir = dir; - break; - } - else if (stackStored.amount < targetTank.getCapacity() && stackStored.amount < volume) - { - primaryFill = tankContainer; - volume = stackStored.amount; - } - }/* USE FILL METHOD IF GET TANK == NULL */ - else if (fill > 0 && fill > mostFill) - { - secondayFill = tankContainer; - mostFill = fill; - otherFillDir = dir; - } - } - } - } - if (found) - { - break; - } - }// End of tank finder - boolean filledMain = false; - if (primaryFill != null) - { - used = primaryFill.fill(fillDir, stack, doFill); - //System.out.println("Primary Target " + used + doFill); - } - else if (secondayFill != null) - { - used = secondayFill.fill(fillDir, stack, doFill); - //System.out.println("Seconday Target " + used + doFill); - } - else if (allowStore && (this.combinedStorage.getLiquid() == null || this.combinedStorage.getLiquid().amount < this.combinedStorage.getCapacity())) - { - used = this.combinedStorage.fill(stack, doFill); - //System.out.println("Network Target filled for " + used + doFill); - filledMain = true; - } - /* IF THE COMBINED STORAGE OF THE PIPES HAS LIQUID MOVE IT FIRST */ - if (!filledMain && used > 0 && this.combinedStorage.getLiquid() != null && this.combinedStorage.getLiquid().amount > 0) - { - - LiquidStack drainStack = new LiquidStack(0, 0, 0); - if (this.combinedStorage.getLiquid().amount >= used) - { - drainStack = this.combinedStorage.drain(used, doFill); - used = 0; - } - else - { - int pUsed = used; - used = Math.min(used, Math.max(used - this.combinedStorage.getLiquid().amount, 0)); - drainStack = this.combinedStorage.drain(pUsed - used, doFill); - } - //System.out.println("Pulling " + (drainStack != null ? drainStack.amount : 0) + " from combined leaving " + (this.combinedStorage.getLiquid() != null ? this.combinedStorage.getLiquid().amount : 0)); - - } - if (prevCombined != null && this.combinedStorage.getLiquid() != null && prevCombined.amount != this.combinedStorage.getLiquid().amount) - { - this.moveAndSumVolume(false); - } - } - this.processingRequest = false; - return used; - } - - /** - * gets the flow rate of the network by getting the pipe with the lowest flow rate. - * - * @return units of liquid per tick, default 20B/s - */ - public int getMaxFlow(LiquidStack stack) - { - int flow = 1000; - for (IFluidNetworkPart conductor : this.fluidParts) - { - // TODO change the direction to actual look for connected only directions and pipes - // along - // the path to the target - int cFlow = conductor.getMaxFlowRate(stack, ForgeDirection.UNKNOWN); - if (cFlow < flow) - { - flow = cFlow; - } - } - return flow; - } - - public void cleanConductors() - { - for (int i = 0; i < fluidParts.size(); i++) - { - if (fluidParts.get(i) == null) - { - fluidParts.remove(i); - } - else if (((TileEntity) fluidParts.get(i)).isInvalid()) - { - fluidParts.remove(i); - } - } - } - - public void setNetwork() - { - this.cleanConductors(); - - for (IFluidNetworkPart conductor : this.fluidParts) - { - conductor.setNetwork(this); - } - } - - public void onPresureChange() - { - this.cleanConductors(); - - for (int i = 0; i < fluidParts.size(); i++) - { - // TODO change to actual check connected sides only && get true value from settings file - IFluidNetworkPart part = fluidParts.get(i); - if (part.getMaxPressure(ForgeDirection.UNKNOWN) < this.pressureProduced && part.onOverPressure(true)) - { - this.fluidParts.remove(part); - this.cleanConductors(); - } - - } - } - - public void cleanUpConductors() - { - Iterator it = this.fluidParts.iterator(); - int capacity = 0; - - while (it.hasNext()) - { - IFluidNetworkPart conductor = (IFluidNetworkPart) it.next(); - - if (conductor == null) - { - it.remove(); - } - else if (((TileEntity) conductor).isInvalid()) - { - it.remove(); - } - else if (conductor.getColor() != this.color) - { - it.remove(); - } - else - { - conductor.setNetwork(this); - capacity += LiquidContainerRegistry.BUCKET_VOLUME; - } - } - this.combinedStorage.setCapacity(capacity); - } - - /** - * This function is called to refresh all conductors in this network - */ - public void refreshConductors() - { - this.cleanUpConductors(); - - try - { - Iterator it = this.fluidParts.iterator(); - - while (it.hasNext()) - { - IFluidNetworkPart conductor = it.next(); - conductor.updateAdjacentConnections(); - } - } - catch (Exception e) - { - FMLLog.severe("Universal Electricity: Failed to refresh conductor."); - e.printStackTrace(); - } - } - - public List getFluidNetworkParts() - { - return this.fluidParts; - } - - public void mergeNetworks(HydraulicNetwork network) - { - if (network != null && network != this && network.color == this.color) - { - if (this.combinedStorage.getLiquid() != null && network.combinedStorage.getLiquid() != null && !this.combinedStorage.getLiquid().isLiquidEqual(network.combinedStorage.getLiquid())) - { - this.causingMixing(this.combinedStorage.getLiquid(), network.combinedStorage.getLiquid()); - } - else - { - this.moveAndSumVolume(false); - network.moveAndSumVolume(false); - LiquidStack stack = new LiquidStack(0, 0, 0); - if (this.combinedStorage.getLiquid() != null && network.combinedStorage.getLiquid() != null && this.combinedStorage.getLiquid().isLiquidEqual(network.combinedStorage.getLiquid())) - { - stack = this.combinedStorage.getLiquid(); - stack.amount += network.combinedStorage.getLiquid().amount; - } - else if (this.combinedStorage.getLiquid() == null && network.combinedStorage.getLiquid() != null) - { - stack = network.combinedStorage.getLiquid(); - } - else if (this.combinedStorage.getLiquid() != null && network.combinedStorage.getLiquid() == null) - { - stack = this.combinedStorage.getLiquid(); - } - HydraulicNetwork newNetwork = new HydraulicNetwork(this.color); - - newNetwork.getFluidNetworkParts().addAll(this.getFluidNetworkParts()); - newNetwork.getFluidNetworkParts().addAll(network.getFluidNetworkParts()); - - newNetwork.cleanUpConductors(); - newNetwork.moveAndSumVolume(true); - } - } - } - - public void causingMixing(LiquidStack stack, LiquidStack stack2) - { - // TODO cause mixing of liquids based on types and volume. Also apply damage to pipes/parts - // as needed - } - - public void splitNetwork(World world, IFluidNetworkPart splitPoint) - { - if (splitPoint instanceof TileEntity) - { - this.getFluidNetworkParts().remove(splitPoint); - this.moveAndSumVolume(false); - /** - * Loop through the connected blocks and attempt to see if there are connections between - * the two points elsewhere. - */ - TileEntity[] connectedBlocks = splitPoint.getAdjacentConnections(); - - for (int i = 0; i < connectedBlocks.length; i++) - { - TileEntity connectedBlockA = connectedBlocks[i]; - - if (connectedBlockA instanceof IFluidNetworkPart) - { - for (int pipeCount = 0; pipeCount < connectedBlocks.length; pipeCount++) - { - final TileEntity connectedBlockB = connectedBlocks[pipeCount]; - - if (connectedBlockA != connectedBlockB && connectedBlockB instanceof IFluidNetworkPart) - { - Pathfinder finder = new PathfinderCheckerPipes(world, (IFluidNetworkPart) connectedBlockB, splitPoint); - finder.init(new Vector3(connectedBlockA)); - - if (finder.results.size() > 0) - { - /* STILL CONNECTED SOMEWHERE ELSE */ - for (Vector3 node : finder.closedSet) - { - TileEntity entity = node.getTileEntity(world); - if (entity instanceof IFluidNetworkPart) - { - if (node != splitPoint) - { - ((IFluidNetworkPart) entity).setNetwork(this); - } - } - } - } - else - { - /* NO LONGER CONNECTED ELSE WHERE SO SPLIT AND REFRESH */ - HydraulicNetwork newNetwork = new HydraulicNetwork(this.color); - int parts = 0; - for (Vector3 node : finder.closedSet) - { - TileEntity entity = node.getTileEntity(world); - if (entity instanceof IFluidNetworkPart) - { - if (node != splitPoint) - { - newNetwork.getFluidNetworkParts().add((IFluidNetworkPart) entity); - parts++; - } - } - } - - newNetwork.cleanUpConductors(); - newNetwork.moveAndSumVolume(true); - } - } - } - } - } - } - } - - /** - * Moves the volume stored in the network to the parts or sums up the volume from the parts and - * loads it to the network. Assumes that all liquidStacks stored are equal - * - * @param load - loads the volume from the parts before leveling out the volumes - */ - public void moveAndSumVolume(boolean load) - { - int volume = 0; - int itemID = 0; - int itemMeta = 0; - if (load) - { - for (IFluidNetworkPart part : this.fluidParts) - { - - if (part.getTank() != null && part.getTank().getLiquid() != null) - { - if (itemID == 0) - { - itemID = part.getTank().getLiquid().itemID; - itemMeta = part.getTank().getLiquid().itemMeta; - } - volume += part.getTank().getLiquid().amount; - } - } - this.combinedStorage.setLiquid(new LiquidStack(itemID, volume, itemMeta)); - } - - if (this.combinedStorage.getLiquid() != null && this.fluidParts.size() > 0) - { - volume = this.combinedStorage.getLiquid().amount / this.fluidParts.size(); - itemID = this.combinedStorage.getLiquid().itemID; - itemMeta = this.combinedStorage.getLiquid().itemMeta; - - for (IFluidNetworkPart part : this.fluidParts) - { - part.setTankContent(null); - part.setTankContent(new LiquidStack(itemID, volume, itemMeta)); - } - } - } - - @Override - public String toString() - { - return "HydraulicNetwork[" + this.hashCode() + "|parts:" + this.fluidParts.size() + "]"; - } - - public String getStorageFluid() - { - if (!combinedStorage.containsValidLiquid()) - { - return "Zero"; - } - return String.format("%d/%d %S Stored", combinedStorage.getLiquid().amount / LiquidContainerRegistry.BUCKET_VOLUME, combinedStorage.getCapacity() / LiquidContainerRegistry.BUCKET_VOLUME, LiquidDictionary.findLiquidName(this.combinedStorage.getLiquid())); - } - - public ILiquidTank getTank() - { - if (this.combinedStorage == null) - { - this.combinedStorage = new LiquidTank(0); - } - return this.combinedStorage; - } -} diff --git a/src/minecraft/hydraulic/fluidnetwork/INetworkPath.java b/src/minecraft/hydraulic/fluidnetwork/INetworkPath.java deleted file mode 100644 index d63730c9..00000000 --- a/src/minecraft/hydraulic/fluidnetwork/INetworkPath.java +++ /dev/null @@ -1,31 +0,0 @@ -package hydraulic.fluidnetwork; - -import net.minecraft.tileentity.TileEntity; - -public interface INetworkPath -{ - - /** - * Gets a list of all the connected TileEntities that this conductor is connected to. The - * array's length should be always the 6 adjacent wires. - * - * @return - */ - public TileEntity[] getAdjacentConnections(); - - /** - * Instantly refreshes all connected blocks around the conductor, recalculating the connected - * blocks. - */ - public void updateAdjacentConnections(); - - /** - * The Fluid network that this machine is part of - */ - public HydraulicNetwork getNetwork(); - - /** - * sets the machines network - */ - public void setNetwork(HydraulicNetwork network); -} diff --git a/src/minecraft/hydraulic/helpers/FillDrainHelper.java b/src/minecraft/hydraulic/helpers/TankHelper.java similarity index 93% rename from src/minecraft/hydraulic/helpers/FillDrainHelper.java rename to src/minecraft/hydraulic/helpers/TankHelper.java index 2c8c1936..5a569f18 100644 --- a/src/minecraft/hydraulic/helpers/FillDrainHelper.java +++ b/src/minecraft/hydraulic/helpers/TankHelper.java @@ -13,7 +13,7 @@ import universalelectricity.core.vector.VectorHelper; * * @author DarkGuardsman */ -public class FillDrainHelper +public class TankHelper { /** * Fills all ITankContainers around the point @@ -29,7 +29,7 @@ public class FillDrainHelper int fill = 0; for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) { - fill += FillDrainHelper.fillDirection(world, center, stack, direction); + fill += TankHelper.fillDirection(world, center, stack, direction); } return fill; } diff --git a/src/minecraft/hydraulic/network/ContainerNetwork.java b/src/minecraft/hydraulic/network/ContainerNetwork.java new file mode 100644 index 00000000..9d85497b --- /dev/null +++ b/src/minecraft/hydraulic/network/ContainerNetwork.java @@ -0,0 +1,15 @@ +package hydraulic.network; + + +/** + * Side note: the network should act like this when done {@link http + * ://www.e4training.com/hydraulic_calculators/B1.htm} as well as stay compatible with the forge + * Liquids + * + * @author Rseifert + * + */ +public class ContainerNetwork +{ + +} diff --git a/src/minecraft/hydraulic/network/FluidNetwork.java b/src/minecraft/hydraulic/network/FluidNetwork.java new file mode 100644 index 00000000..2c1d8b2d --- /dev/null +++ b/src/minecraft/hydraulic/network/FluidNetwork.java @@ -0,0 +1,295 @@ +package hydraulic.network; + +import hydraulic.api.ColorCode; +import hydraulic.api.INetworkFluidPart; +import hydraulic.api.INetworkPart; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraftforge.liquids.ILiquidTank; +import net.minecraftforge.liquids.ITankContainer; +import net.minecraftforge.liquids.LiquidContainerRegistry; +import net.minecraftforge.liquids.LiquidDictionary; +import net.minecraftforge.liquids.LiquidStack; +import net.minecraftforge.liquids.LiquidTank; +import universalelectricity.core.path.Pathfinder; +import universalelectricity.core.vector.Vector3; +import cpw.mods.fml.common.FMLLog; + +public class FluidNetwork extends TileNetwork +{ + /* MACHINES THAT USE THE FORGE LIQUID API TO RECEIVE LIQUID ** */ + public final List fluidTanks = new ArrayList(); + + /* COMBINED TEMP STORAGE FOR ALL PIPES IN THE NETWORK */ + public LiquidTank combinedStorage = new LiquidTank(LiquidContainerRegistry.BUCKET_VOLUME); + + public ColorCode color = ColorCode.NONE; + + public FluidNetwork(ColorCode color, INetworkPart... parts) + { + super(parts); + this.color = color; + } + + /** + * Moves the volume stored in the network to the parts or sums up the volume from the parts and + * loads it to the network. Assumes that all liquidStacks stored are equal + * + * @param sumParts - loads the volume from the parts before leveling out the volumes + */ + public void balanceColletiveTank(boolean sumParts) + { + int volume = 0, itemID = 0, itemMeta = 0; + + if (sumParts) + { + for (INetworkPart par : this.networkMember) + { + if (par instanceof INetworkFluidPart) + { + INetworkFluidPart part = ((INetworkFluidPart) par); + if (part.getTank() != null && part.getTank().getLiquid() != null) + { + if (itemID == 0) + { + itemID = part.getTank().getLiquid().itemID; + itemMeta = part.getTank().getLiquid().itemMeta; + } + volume += part.getTank().getLiquid().amount; + } + } + } + this.combinedStorage.setLiquid(new LiquidStack(itemID, volume, itemMeta)); + } + + if (this.combinedStorage.getLiquid() != null && this.networkMember.size() > 0) + { + volume = this.combinedStorage.getLiquid().amount / this.networkMember.size(); + itemID = this.combinedStorage.getLiquid().itemID; + itemMeta = this.combinedStorage.getLiquid().itemMeta; + + for (INetworkPart par : this.networkMember) + { + if (par instanceof INetworkFluidPart) + { + INetworkFluidPart part = ((INetworkFluidPart) par); + part.setTankContent(null); + part.setTankContent(new LiquidStack(itemID, volume, itemMeta)); + } + } + } + } + + @Override + public void removeEntity(TileEntity ent) + { + super.removeEntity(ent); + this.fluidTanks.remove(ent); + } + + @Override + public boolean addEntity(TileEntity ent, boolean member) + { + if (!(super.addEntity(ent, member)) && ent instanceof ITankContainer && !fluidTanks.contains(ent)) + { + fluidTanks.add((ITankContainer) ent); + return true; + } + return false; + } + + /** + * Checks too see if the tileEntity is part of or connected too the network + */ + public boolean isConnected(TileEntity tileEntity) + { + return this.fluidTanks.contains(tileEntity); + } + + public boolean isPartOfNetwork(TileEntity ent) + { + return super.isPartOfNetwork(ent) || this.fluidTanks.contains(ent); + } + + public void causingMixing(LiquidStack stack, LiquidStack stack2) + { + // TODO cause mixing of liquids based on types and volume. Also apply damage to pipes/parts + // as needed + } + + public void splitNetwork(World world, INetworkPart splitPoint) + { + if (splitPoint instanceof TileEntity) + { + this.getNetworkMemebers().remove(splitPoint); + this.balanceColletiveTank(false); + /** + * Loop through the connected blocks and attempt to see if there are connections between + * the two points elsewhere. + */ + TileEntity[] connectedBlocks = splitPoint.getNetworkConnections(); + + for (int i = 0; i < connectedBlocks.length; i++) + { + TileEntity connectedBlockA = connectedBlocks[i]; + + if (connectedBlockA instanceof INetworkPart) + { + for (int pipeCount = 0; pipeCount < connectedBlocks.length; pipeCount++) + { + final TileEntity connectedBlockB = connectedBlocks[pipeCount]; + + if (connectedBlockA != connectedBlockB && connectedBlockB instanceof INetworkPart) + { + Pathfinder finder = new PathfinderCheckerPipes(world, (INetworkPart) connectedBlockB, splitPoint); + finder.init(new Vector3(connectedBlockA)); + + if (finder.results.size() > 0) + { + /* STILL CONNECTED SOMEWHERE ELSE */ + for (Vector3 node : finder.closedSet) + { + TileEntity entity = node.getTileEntity(world); + if (entity instanceof INetworkPart) + { + if (node != splitPoint) + { + ((INetworkPart) entity).setTileNetwork(this); + } + } + } + } + else + { + /* NO LONGER CONNECTED ELSE WHERE SO SPLIT AND REFRESH */ + PipeNetwork newNetwork = new PipeNetwork(this.color); + int parts = 0; + for (Vector3 node : finder.closedSet) + { + TileEntity entity = node.getTileEntity(world); + if (entity instanceof INetworkPart) + { + if (node != splitPoint) + { + newNetwork.getNetworkMemebers().add((INetworkPart) entity); + parts++; + } + } + } + + newNetwork.cleanUpConductors(); + newNetwork.balanceColletiveTank(true); + } + } + } + } + } + } + } + + @Override + public boolean preMergeProcessing(TileNetwork net) + { + if (net instanceof FluidNetwork && ((FluidNetwork)net).color == this.color) + { + FluidNetwork network = (FluidNetwork) net; + if (this.combinedStorage.getLiquid() != null && network.combinedStorage.getLiquid() != null && !this.combinedStorage.getLiquid().isLiquidEqual(network.combinedStorage.getLiquid())) + { + this.causingMixing(this.combinedStorage.getLiquid(), network.combinedStorage.getLiquid()); + } + else + { + this.balanceColletiveTank(false); + network.balanceColletiveTank(false); + + LiquidStack stack = new LiquidStack(0, 0, 0); + + if (this.combinedStorage.getLiquid() != null && network.combinedStorage.getLiquid() != null && this.combinedStorage.getLiquid().isLiquidEqual(network.combinedStorage.getLiquid())) + { + stack = this.combinedStorage.getLiquid(); + stack.amount += network.combinedStorage.getLiquid().amount; + } + else if (this.combinedStorage.getLiquid() == null && network.combinedStorage.getLiquid() != null) + { + stack = network.combinedStorage.getLiquid(); + } + else if (this.combinedStorage.getLiquid() != null && network.combinedStorage.getLiquid() == null) + { + stack = this.combinedStorage.getLiquid(); + } + + } + return true; + } + return false; + } + + @Override + public void postMergeProcessing(TileNetwork network) + { + FluidNetwork newNetwork = new FluidNetwork(this.color); + newNetwork.getNetworkMemebers().addAll(this.getNetworkMemebers()); + newNetwork.getNetworkMemebers().addAll(network.getNetworkMemebers()); + + newNetwork.cleanUpConductors(); + newNetwork.balanceColletiveTank(true); + } + + public void refresh() + { + this.cleanUpConductors(); + int capacity = 0; + + try + { + Iterator it = this.networkMember.iterator(); + + while (it.hasNext()) + { + INetworkPart conductor = it.next(); + conductor.updateNetworkConnections(); + capacity += LiquidContainerRegistry.BUCKET_VOLUME; + } + this.combinedStorage.setCapacity(capacity); + } + catch (Exception e) + { + FMLLog.severe("FluidNetwork>>>Refresh>>>Critical Error."); + e.printStackTrace(); + } + } + + public boolean isValidMember(INetworkPart part) + { + return super.isValidMember(part) && part instanceof INetworkFluidPart && ((INetworkFluidPart) part).getColor() == this.color; + } + + @Override + public String toString() + { + return "FluidNetwork[" + this.hashCode() + "|parts:" + this.networkMember.size() + "]"; + } + + public String getNetworkFluid() + { + if (!combinedStorage.containsValidLiquid()) + { + return "Zero"; + } + return String.format("%d/%d %S Stored", combinedStorage.getLiquid().amount / LiquidContainerRegistry.BUCKET_VOLUME, combinedStorage.getCapacity() / LiquidContainerRegistry.BUCKET_VOLUME, LiquidDictionary.findLiquidName(this.combinedStorage.getLiquid())); + } + + public ILiquidTank getNetworkTank() + { + if (this.combinedStorage == null) + { + this.combinedStorage = new LiquidTank(0); + } + return this.combinedStorage; + } +} diff --git a/src/minecraft/hydraulic/fluidnetwork/FluidPressurePack.java b/src/minecraft/hydraulic/network/FluidPressurePack.java similarity index 95% rename from src/minecraft/hydraulic/fluidnetwork/FluidPressurePack.java rename to src/minecraft/hydraulic/network/FluidPressurePack.java index 786ca010..c9a7953d 100644 --- a/src/minecraft/hydraulic/fluidnetwork/FluidPressurePack.java +++ b/src/minecraft/hydraulic/network/FluidPressurePack.java @@ -1,4 +1,4 @@ -package hydraulic.fluidnetwork; +package hydraulic.network; import net.minecraftforge.liquids.LiquidStack; diff --git a/src/minecraft/hydraulic/fluidnetwork/HydraulicNetworkHelper.java b/src/minecraft/hydraulic/network/HydraulicNetworkHelper.java similarity index 62% rename from src/minecraft/hydraulic/fluidnetwork/HydraulicNetworkHelper.java rename to src/minecraft/hydraulic/network/HydraulicNetworkHelper.java index 2cc8e590..584335ad 100644 --- a/src/minecraft/hydraulic/fluidnetwork/HydraulicNetworkHelper.java +++ b/src/minecraft/hydraulic/network/HydraulicNetworkHelper.java @@ -1,7 +1,7 @@ -package hydraulic.fluidnetwork; - +package hydraulic.network; import hydraulic.api.IDrain; +import hydraulic.api.INetworkPart; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.ForgeDirection; import net.minecraftforge.liquids.ITankContainer; @@ -12,7 +12,7 @@ public class HydraulicNetworkHelper { /** - * Invalidates a TileEntity + * Invalidates a TileEntity */ public static void invalidate(TileEntity tileEntity) { @@ -21,18 +21,18 @@ public class HydraulicNetworkHelper ForgeDirection direction = ForgeDirection.getOrientation(i); TileEntity checkTile = VectorHelper.getConnectorFromSide(tileEntity.worldObj, new Vector3(tileEntity), direction); - if (checkTile instanceof IFluidNetworkPart) + if (checkTile instanceof INetworkPart) { - HydraulicNetwork network = ((IFluidNetworkPart) checkTile).getNetwork(); + TileNetwork network = ((INetworkPart) checkTile).getTileNetwork(); - if (network != null) + if (network != null && network instanceof FluidNetwork) { network.removeEntity(tileEntity); - for(ITankContainer tank : network.fluidTanks) + for (ITankContainer tank : ((FluidNetwork) network).fluidTanks) { - if(tank instanceof IDrain) + if (tank instanceof IDrain) { - ((IDrain)tank).stopRequesting(tileEntity); + ((IDrain) tank).stopRequesting(tileEntity); } } } diff --git a/src/minecraft/hydraulic/fluidnetwork/PathfinderCheckerPipes.java b/src/minecraft/hydraulic/network/PathfinderCheckerPipes.java similarity index 71% rename from src/minecraft/hydraulic/fluidnetwork/PathfinderCheckerPipes.java rename to src/minecraft/hydraulic/network/PathfinderCheckerPipes.java index b03b0dce..93bb06e3 100644 --- a/src/minecraft/hydraulic/fluidnetwork/PathfinderCheckerPipes.java +++ b/src/minecraft/hydraulic/network/PathfinderCheckerPipes.java @@ -1,4 +1,7 @@ -package hydraulic.fluidnetwork; +package hydraulic.network; + +import hydraulic.api.INetworkPart; +import hydraulic.api.INetworkPipe; import java.util.Arrays; import java.util.HashSet; @@ -16,7 +19,7 @@ import universalelectricity.core.vector.Vector3; */ public class PathfinderCheckerPipes extends Pathfinder { - public PathfinderCheckerPipes(final World world, final IFluidNetworkPart targetConnector, final IFluidNetworkPart... ignoreConnector) + public PathfinderCheckerPipes(final World world, final INetworkPart connectedBlockB, final INetworkPart splitPoint) { super(new IPathCallBack() { @@ -31,9 +34,9 @@ public class PathfinderCheckerPipes extends Pathfinder Vector3 position = currentNode.clone().modifyPositionFromSide(direction); TileEntity connectedBlock = position.getTileEntity(world); - if (connectedBlock instanceof IFluidNetworkPart && !Arrays.asList(ignoreConnector).contains(connectedBlock)) + if (connectedBlock instanceof INetworkPipe && !Arrays.asList(splitPoint).contains(connectedBlock)) { - if (((IFluidNetworkPart) connectedBlock).canPipeConnect(connectedBlock, direction.getOpposite())) + if (((INetworkPipe) connectedBlock).canTileConnect(connectedBlock, direction.getOpposite())) { neighbors.add(position); } @@ -46,7 +49,7 @@ public class PathfinderCheckerPipes extends Pathfinder @Override public boolean onSearch(Pathfinder finder, Vector3 node) { - if (node.getTileEntity(world) == targetConnector) + if (node.getTileEntity(world) == connectedBlockB) { finder.results.add(node); return true; diff --git a/src/minecraft/hydraulic/network/PipeNetwork.java b/src/minecraft/hydraulic/network/PipeNetwork.java new file mode 100644 index 00000000..f7969cde --- /dev/null +++ b/src/minecraft/hydraulic/network/PipeNetwork.java @@ -0,0 +1,360 @@ +package hydraulic.network; + +import hydraulic.api.ColorCode; +import hydraulic.api.INetworkPart; +import hydraulic.api.INetworkPipe; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.ForgeDirection; +import net.minecraftforge.liquids.ILiquidTank; +import net.minecraftforge.liquids.ITankContainer; +import net.minecraftforge.liquids.LiquidStack; +import dark.library.helpers.ConnectionHelper; + +/** + * Side note: the network should act like this when done {@link http + * ://www.e4training.com/hydraulic_calculators/B1.htm} as well as stay compatible with the forge + * Liquids + * + * @author Rseifert + * + */ +public class PipeNetwork extends FluidNetwork +{ + + /* MACHINES THAT USE THE PRESSURE SYSTEM TO DO WORK ** */ + private final HashMap pressureProducers = new HashMap(); + private final HashMap pressureLoads = new HashMap(); + + /* PRESSURE OF THE NETWORK AS A TOTAL. ZERO AS IN NO PRESSURE */ + public double pressureProduced = 0, pressureLoad = 0; + + /* IS IT PROCESSING AN ADD LIQUID EVENT */ + private boolean processingRequest = false; + + public PipeNetwork(ColorCode color, INetworkPart... parts) + { + super(color, parts); + } + + public boolean isPartOfNetwork(TileEntity ent) + { + return super.isPartOfNetwork(ent) || this.pressureLoads.containsKey(ent) || this.pressureProducers.containsKey(ent); + } + + /** + * sets this tileEntity to produce a pressure and flow rate in the network + */ + public void startProducingPressure(TileEntity tileEntity, FluidPressurePack fluidPack) + { + if (tileEntity != null && fluidPack.liquidStack != null) + { + if ((this.combinedStorage.getLiquid() == null || fluidPack.liquidStack.isLiquidEqual(this.combinedStorage.getLiquid())) && fluidPack.liquidStack.amount > 0) + { + this.pressureProducers.put(tileEntity, fluidPack); + } + } + } + + /** + * sets this tileEntity to produce a pressure and flow rate in the network + */ + public void startProducingPressure(TileEntity tileEntity, LiquidStack stack, double pressure) + { + this.startProducingPressure(tileEntity, new FluidPressurePack(stack, pressure)); + } + + /** + * is this tile entity producing a pressure + */ + public boolean isProducingPressure(TileEntity tileEntity) + { + return this.pressureProducers.containsKey(tileEntity); + } + + /** + * Sets this tile entity to act as a load on the system + */ + public void addLoad(TileEntity tileEntity, FluidPressurePack fluidPack) + { + if (tileEntity != null && fluidPack.liquidStack != null && fluidPack.liquidStack.amount > 0) + { + this.pressureLoads.put(tileEntity, fluidPack); + } + } + + /** + * Sets this tile entity to act as a load on the system + */ + public void addLoad(TileEntity tileEntity, LiquidStack stack, double pressure) + { + this.addLoad(tileEntity, new FluidPressurePack(stack, pressure)); + } + + /** + * is this tileEntity a load in the network + */ + public boolean isLoad(TileEntity tileEntity) + { + return this.pressureLoads.containsKey(tileEntity); + } + + /** + * @param ignoreTiles The TileEntities to ignore during this calculation. Null will make it not + * ignore any. + * @return The electricity produced in this electricity network + */ + public double getPressureProduced(TileEntity... ignoreTiles) + { + // TODO pressure is not added as a sum but rather as a collective sum of the largest + // pressures. IF the pressure is to small it will be ignored and stop producing pressure. + int totalPressure = 0; + + Iterator it = this.pressureProducers.entrySet().iterator(); + + loop: + while (it.hasNext()) + { + Map.Entry pairs = (Map.Entry) it.next(); + + if (pairs != null) + { + TileEntity tileEntity = (TileEntity) pairs.getKey(); + + if (tileEntity == null) + { + it.remove(); + continue; + } + + if (tileEntity.isInvalid()) + { + it.remove(); + continue; + } + + if (tileEntity.worldObj.getBlockTileEntity(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord) != tileEntity) + { + it.remove(); + continue; + } + + if (ignoreTiles != null) + { + for (TileEntity ignoreTile : ignoreTiles) + { + if (tileEntity == ignoreTile) + { + continue loop; + } + } + } + + FluidPressurePack pack = (FluidPressurePack) pairs.getValue(); + + if (pairs.getKey() != null && pairs.getValue() != null && pack != null) + { + totalPressure += pack.pressure; + } + } + } + + return totalPressure; + } + + @Override + public void removeEntity(TileEntity ent) + { + super.removeEntity(ent); + this.pressureLoads.remove(ent); + this.pressureProducers.remove(ent); + } + + /** + * Adds FLuid to this network from one of the connected Pipes + * + * @param source - Were this liquid came from + * @param stack - LiquidStack to be sent + * @param doFill - actually fill the tank or just check numbers + * @return the amount of liquid consumed from the init stack + */ + public int addFluidToNetwork(TileEntity source, LiquidStack stack, boolean doFill) + { + return this.addFluidToNetwork(source, stack, doFill, false); + } + + /** + * Adds FLuid to this network from one of the connected Pipes + * + * @param source - Were this liquid came from + * @param stack - LiquidStack to be sent + * @param doFill - actually fill the tank or just check numbers + * @param allowStore - allows the network to store this liquid in the pipes + * @return the amount of liquid consumed from the init stack + */ + public int addFluidToNetwork(TileEntity source, LiquidStack stack, boolean doFill, boolean allowStore) + { + int used = 0; + LiquidStack prevCombined = this.combinedStorage.getLiquid(); + if (!this.processingRequest && stack != null && color.isValidLiquid(stack)) + { + if (this.combinedStorage.getLiquid() != null && !stack.isLiquidEqual(this.combinedStorage.getLiquid())) + { + // TODO cause mixing + } + if (stack.amount > this.getMaxFlow(stack)) + { + stack = new LiquidStack(stack.itemID, this.getMaxFlow(stack), stack.itemMeta); + } + + /* Main fill target to try to fill with the stack */ + ITankContainer primaryFill = null; + int volume = Integer.MAX_VALUE; + ForgeDirection fillDir = ForgeDirection.UNKNOWN; + + /* Secondary fill target if the main target is not found */ + ITankContainer secondayFill = null; + int mostFill = 0; + ForgeDirection otherFillDir = ForgeDirection.UNKNOWN; + + boolean found = false; + + /* FIND THE FILL TARGET FROM THE LIST OF FLUID RECIEVERS */ + for (ITankContainer tankContainer : fluidTanks) + { + if (tankContainer instanceof TileEntity && tankContainer != source && !(tankContainer instanceof INetworkPipe)) + { + TileEntity[] connectedTiles = ConnectionHelper.getSurroundingTileEntities((TileEntity) tankContainer); + + for (int i = 0; i < 6; i++) + { + if (connectedTiles[i] instanceof INetworkPipe && ((INetworkPipe) connectedTiles[i]).getTileNetwork() == this) + { + ForgeDirection dir = ForgeDirection.getOrientation(i).getOpposite(); + ILiquidTank targetTank = tankContainer.getTank(dir, stack); + int fill = tankContainer.fill(dir, stack, false); + + /* USE GET TANK FROM SIDE METHOD FIRST */ + if (targetTank != null) + { + LiquidStack stackStored = targetTank.getLiquid(); + if (stackStored == null) + { + primaryFill = tankContainer; + found = true; + fillDir = dir; + break; + } + else if (stackStored.amount < targetTank.getCapacity() && stackStored.amount < volume) + { + primaryFill = tankContainer; + volume = stackStored.amount; + } + }/* USE FILL METHOD IF GET TANK == NULL */ + else if (fill > 0 && fill > mostFill) + { + secondayFill = tankContainer; + mostFill = fill; + otherFillDir = dir; + } + } + } + } + if (found) + { + break; + } + }// End of tank finder + boolean filledMain = false; + if (primaryFill != null) + { + used = primaryFill.fill(fillDir, stack, doFill); + // System.out.println("Primary Target " + used + doFill); + } + else if (secondayFill != null) + { + used = secondayFill.fill(fillDir, stack, doFill); + // System.out.println("Seconday Target " + used + doFill); + } + else if (allowStore && (this.combinedStorage.getLiquid() == null || this.combinedStorage.getLiquid().amount < this.combinedStorage.getCapacity())) + { + used = this.combinedStorage.fill(stack, doFill); + // System.out.println("Network Target filled for " + used + doFill); + filledMain = true; + } + /* IF THE COMBINED STORAGE OF THE PIPES HAS LIQUID MOVE IT FIRST */ + if (!filledMain && used > 0 && this.combinedStorage.getLiquid() != null && this.combinedStorage.getLiquid().amount > 0) + { + + LiquidStack drainStack = new LiquidStack(0, 0, 0); + if (this.combinedStorage.getLiquid().amount >= used) + { + drainStack = this.combinedStorage.drain(used, doFill); + used = 0; + } + else + { + int pUsed = used; + used = Math.min(used, Math.max(used - this.combinedStorage.getLiquid().amount, 0)); + drainStack = this.combinedStorage.drain(pUsed - used, doFill); + } + // System.out.println("Pulling " + (drainStack != null ? drainStack.amount : 0) + + // " from combined leaving " + (this.combinedStorage.getLiquid() != null ? + // this.combinedStorage.getLiquid().amount : 0)); + + } + if (prevCombined != null && this.combinedStorage.getLiquid() != null && prevCombined.amount != this.combinedStorage.getLiquid().amount) + { + this.balanceColletiveTank(false); + } + } + this.processingRequest = false; + return used; + } + + /** + * gets the flow rate of the network by getting the pipe with the lowest flow rate. + * + * @return units of liquid per tick, default 20B/s + */ + public int getMaxFlow(LiquidStack stack) + { + int flow = 1000; + for (INetworkPart conductor : this.networkMember) + { + if (conductor instanceof INetworkPipe) + { + int cFlow = ((INetworkPipe) conductor).getMaxFlowRate(stack, ForgeDirection.UNKNOWN); + if (cFlow < flow) + { + flow = cFlow; + } + } + } + return flow; + } + + public void onPresureChange() + { + this.cleanUpConductors(); + + for (int i = 0; i < networkMember.size(); i++) + { + if (networkMember.get(i) instanceof INetworkPipe) + { + INetworkPipe part = (INetworkPipe) networkMember.get(i); + if (part.getMaxPressure(ForgeDirection.UNKNOWN) < this.pressureProduced && part.onOverPressure(true)) + { + this.networkMember.remove(part); + this.cleanUpConductors(); + } + } + + } + } + +} diff --git a/src/minecraft/hydraulic/network/TileNetwork.java b/src/minecraft/hydraulic/network/TileNetwork.java new file mode 100644 index 00000000..f1479252 --- /dev/null +++ b/src/minecraft/hydraulic/network/TileNetwork.java @@ -0,0 +1,254 @@ +package hydraulic.network; + +import hydraulic.api.INetworkPart; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import universalelectricity.core.path.Pathfinder; +import universalelectricity.core.vector.Vector3; + +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import cpw.mods.fml.common.FMLLog; + +public class TileNetwork +{ + /* BLOCK THAT ACT AS FLUID CONVEYORS ** */ + public final List networkMember = new ArrayList(); + + public TileNetwork(INetworkPart... parts) + { + this.networkMember.addAll(Arrays.asList(parts)); + } + + /** + * Adds a TileEntity to the network + * + * @param ent - tileEntity instance + * @param member - add to network member list + * @return + */ + public boolean addEntity(TileEntity ent, boolean member) + { + if (ent == null || this.isPartOfNetwork(ent)) + { + return false; + } + else if (ent instanceof INetworkPart && member) + { + return this.addNetworkPart((INetworkPart) ent); + } + return false; + } + + public boolean isPartOfNetwork(TileEntity ent) + { + return this.networkMember.contains(ent); + } + + /** + * Adds a new part to the network member list + */ + public boolean addNetworkPart(INetworkPart part) + { + if (!networkMember.contains(part) && this.isValidMember(part)) + { + networkMember.add(part); + part.setTileNetwork(this); + this.cleanUpConductors(); + return true; + } + return false; + } + + /** + * Removes a tileEntity from any of the valid lists + */ + public void removeEntity(TileEntity ent) + { + this.networkMember.remove(ent); + } + + /** + * Cleans the list of networkMembers and remove those that no longer belong + */ + public void cleanUpConductors() + { + Iterator it = this.networkMember.iterator(); + + while (it.hasNext()) + { + INetworkPart part = it.next(); + if (!this.isValidMember(part)) + { + it.remove(); + } + else + { + part.setTileNetwork(this); + + } + } + + } + + /** + * Is this part a valid member of the network + */ + public boolean isValidMember(INetworkPart part) + { + return part != null && part instanceof TileEntity && !((TileEntity) part).isInvalid(); + } + + /** + * Refreshes the network... mainly the network member list + */ + public void refresh() + { + this.cleanUpConductors(); + try + { + Iterator it = this.networkMember.iterator(); + + while (it.hasNext()) + { + INetworkPart conductor = it.next(); + conductor.updateNetworkConnections(); + } + } + catch (Exception e) + { + FMLLog.severe("TileNetwork>>>Refresh>>>Critical Error."); + e.printStackTrace(); + } + } + + /** + * Gets the list of network members + */ + public List getNetworkMemebers() + { + return this.networkMember; + } + + /** + * Combines two networks together into one + * + * @param network + */ + public void merge(TileNetwork network) + { + if (network != null && network != this && network.getClass().equals(this.getClass())) + { + if (this.preMergeProcessing(network)) + { + this.postMergeProcessing(network); + } + } + } + + /** + * Processing that needs too be done before the network merges + * + * @return false if the merge needs to be canceled + */ + public boolean preMergeProcessing(TileNetwork network) + { + return true; + } + + /** + * Finalizing the merge of two networks by creating the new network and importing all network + * parts + */ + public void postMergeProcessing(TileNetwork network) + { + TileNetwork newNetwork = new TileNetwork(); + newNetwork.getNetworkMemebers().addAll(this.getNetworkMemebers()); + newNetwork.getNetworkMemebers().addAll(network.getNetworkMemebers()); + + newNetwork.cleanUpConductors(); + // newNetwork.balanceColletiveTank(true); + } + + /** + * Called when a peace of the network is remove from the network. Will split the network if it + * can no longer find a valid connection too all parts + */ + public void splitNetwork(World world, INetworkPart splitPoint) + { + if (splitPoint instanceof TileEntity) + { + this.getNetworkMemebers().remove(splitPoint); + /** + * Loop through the connected blocks and attempt to see if there are connections between + * the two points elsewhere. + */ + TileEntity[] connectedBlocks = splitPoint.getNetworkConnections(); + + for (int i = 0; i < connectedBlocks.length; i++) + { + TileEntity connectedBlockA = connectedBlocks[i]; + + if (connectedBlockA instanceof INetworkPart) + { + for (int pipeCount = 0; pipeCount < connectedBlocks.length; pipeCount++) + { + final TileEntity connectedBlockB = connectedBlocks[pipeCount]; + + if (connectedBlockA != connectedBlockB && connectedBlockB instanceof INetworkPart) + { + Pathfinder finder = new PathfinderCheckerPipes(world, (INetworkPart) connectedBlockB, splitPoint); + finder.init(new Vector3(connectedBlockA)); + + if (finder.results.size() > 0) + { + /* STILL CONNECTED SOMEWHERE ELSE */ + for (Vector3 node : finder.closedSet) + { + TileEntity entity = node.getTileEntity(world); + if (entity instanceof INetworkPart) + { + if (node != splitPoint) + { + ((INetworkPart) entity).setTileNetwork(this); + } + } + } + } + else + { + /* NO LONGER CONNECTED ELSE WHERE SO SPLIT AND REFRESH */ + TileNetwork newNetwork = new TileNetwork(); + int parts = 0; + for (Vector3 node : finder.closedSet) + { + TileEntity entity = node.getTileEntity(world); + if (entity instanceof INetworkPart) + { + if (node != splitPoint) + { + newNetwork.getNetworkMemebers().add((INetworkPart) entity); + parts++; + } + } + } + + newNetwork.cleanUpConductors(); + } + } + } + } + } + } + } + + @Override + public String toString() + { + return "TileNetwork[" + this.hashCode() + "|parts:" + this.networkMember.size() + "]"; + } +} diff --git a/src/minecraft/hydraulic/prefab/tile/TileEntityFluidDevice.java b/src/minecraft/hydraulic/prefab/tile/TileEntityFluidDevice.java index a71cec02..a1a6cd9c 100644 --- a/src/minecraft/hydraulic/prefab/tile/TileEntityFluidDevice.java +++ b/src/minecraft/hydraulic/prefab/tile/TileEntityFluidDevice.java @@ -1,8 +1,8 @@ package hydraulic.prefab.tile; -import hydraulic.api.IPipeConnection; +import hydraulic.api.ITileConnector; import hydraulic.api.IReadOut; -import hydraulic.fluidnetwork.HydraulicNetworkHelper; +import hydraulic.network.HydraulicNetworkHelper; import java.util.Random; @@ -12,7 +12,7 @@ import net.minecraftforge.liquids.ITankContainer; import net.minecraftforge.liquids.LiquidStack; import universalelectricity.prefab.tile.TileEntityAdvanced; -public abstract class TileEntityFluidDevice extends TileEntityAdvanced implements IReadOut, IPipeConnection +public abstract class TileEntityFluidDevice extends TileEntityAdvanced implements IReadOut, ITileConnector { public Random random = new Random(); diff --git a/src/minecraft/hydraulic/prefab/tile/TileEntityFluidStorage.java b/src/minecraft/hydraulic/prefab/tile/TileEntityFluidStorage.java index da2d1df6..e497bdc1 100644 --- a/src/minecraft/hydraulic/prefab/tile/TileEntityFluidStorage.java +++ b/src/minecraft/hydraulic/prefab/tile/TileEntityFluidStorage.java @@ -34,9 +34,13 @@ public abstract class TileEntityFluidStorage extends TileEntityFluidDevice imple } @Override - public boolean canPipeConnect(TileEntity entity, ForgeDirection dir) + public boolean canTileConnect(TileEntity entity, ForgeDirection dir) { - return true; + if (entity instanceof ITankContainer) + { + return true; + } + return false; } @Override