diff --git a/common/mekanism/api/GasNetwork.java b/common/mekanism/api/GasNetwork.java index df7eff03c..a5aa6d87e 100644 --- a/common/mekanism/api/GasNetwork.java +++ b/common/mekanism/api/GasNetwork.java @@ -19,16 +19,35 @@ import net.minecraftforge.event.ForgeSubscribe; import net.minecraftforge.event.world.ChunkEvent; import cpw.mods.fml.common.FMLCommonHandler; -public class GasNetwork +public class GasNetwork implements ITransmitterNetwork { - public Set tubes = new HashSet(); + public HashSet tubes = new HashSet(); public Set possibleAcceptors = new HashSet(); public Map acceptorDirections = new HashMap(); + private int ticksSinceCreate = 0; + private boolean fixed = false; + public GasNetwork(IPressurizedTube... varPipes) { tubes.addAll(Arrays.asList(varPipes)); + register(); + } + + public GasNetwork(Set networks) + { + for(GasNetwork net : networks) + { + if(net != null) + { + addAllTubes(net.tubes); + net.deregister(); + } + } + + refresh(); + register(); } public int emit(int gasToSend, EnumGas transferType, TileEntity emitter) @@ -92,7 +111,8 @@ public class GasNetwork public void refresh() { - Iterator it = tubes.iterator(); + Set iterTubes = (Set) tubes.clone(); + Iterator it = iterTubes.iterator(); possibleAcceptors.clear(); acceptorDirections.clear(); @@ -101,13 +121,10 @@ public class GasNetwork { IPressurizedTube conductor = (IPressurizedTube)it.next(); - if(conductor == null) - { - it.remove(); - } - else if(((TileEntity)conductor).isInvalid()) + if(conductor == null || ((TileEntity)conductor).isInvalid()) { it.remove(); + tubes.remove(conductor); } else { conductor.setNetwork(this); @@ -133,20 +150,27 @@ public class GasNetwork { if(network != null && network != this) { - GasNetwork newNetwork = new GasNetwork(); - newNetwork.tubes.addAll(tubes); - newNetwork.tubes.addAll(network.tubes); + Set networks = new HashSet(); + networks.add(this); + networks.add(network); + GasNetwork newNetwork = new GasNetwork(networks); newNetwork.refresh(); } } + public void addAllTubes(Set newTubes) + { + tubes.addAll(newTubes); + } + public void split(IPressurizedTube splitPoint) { if(splitPoint instanceof TileEntity) { - tubes.remove(splitPoint); + removeTube(splitPoint); TileEntity[] connectedBlocks = new TileEntity[6]; + boolean[] dealtWith = {false, false, false, false, false, false}; for(ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) { @@ -162,68 +186,109 @@ public class GasNetwork { TileEntity connectedBlockA = connectedBlocks[countOne]; - if(connectedBlockA instanceof IPressurizedTube) + if(connectedBlockA instanceof IPressurizedTube && !dealtWith[countOne]) { - for(int countTwo = 0; countTwo < connectedBlocks.length; countTwo++) + NetworkFinder finder = new NetworkFinder(((TileEntity)splitPoint).worldObj, Object3D.get(connectedBlockA), Object3D.get((TileEntity)splitPoint)); + List partNetwork = finder.exploreNetwork(); + + for(int countTwo = countOne + 1; countTwo < connectedBlocks.length; countTwo++) { TileEntity connectedBlockB = connectedBlocks[countTwo]; - if(connectedBlockA != connectedBlockB && connectedBlockB instanceof IPressurizedTube) + if(connectedBlockB instanceof IPressurizedTube && !dealtWith[countTwo]) { - NetworkFinder finder = new NetworkFinder(((TileEntity)splitPoint).worldObj, Object3D.get(connectedBlockB), Object3D.get((TileEntity)splitPoint)); - - if(finder.foundTarget(Object3D.get(connectedBlockA))) + if(partNetwork.contains(Object3D.get(connectedBlockB))) { - for(Object3D node : finder.iterated) - { - TileEntity nodeTile = node.getTileEntity(((TileEntity)splitPoint).worldObj); - - if(nodeTile instanceof IPressurizedTube) - { - if(nodeTile != splitPoint) - { - ((IPressurizedTube)nodeTile).setNetwork(this); - } - } - } - } - else { - GasNetwork newNetwork = new GasNetwork(); - - for(Object3D node : finder.iterated) - { - TileEntity nodeTile = node.getTileEntity(((TileEntity)splitPoint).worldObj); - - if(nodeTile instanceof IPressurizedTube) - { - if(nodeTile != splitPoint) - { - newNetwork.tubes.add((IPressurizedTube)nodeTile); - } - } - } - - newNetwork.refresh(); + dealtWith[countTwo] = true; } } } + + GasNetwork newNetwork = new GasNetwork(); + + for(Object3D node : finder.iterated) + { + TileEntity nodeTile = node.getTileEntity(((TileEntity)splitPoint).worldObj); + + if(nodeTile instanceof IPressurizedTube) + { + if(nodeTile != splitPoint) + { + newNetwork.tubes.add((IPressurizedTube)nodeTile); + } + } + } + + newNetwork.refresh(); } } + + deregister(); } } + public void fixMessedUpNetwork(IPressurizedTube tube) + { + if(tube instanceof TileEntity) + { + NetworkFinder finder = new NetworkFinder(((TileEntity)tube).getWorldObj(), Object3D.get((TileEntity)tube), null); + List partNetwork = finder.exploreNetwork(); + Set newTubes = new HashSet(); + + for(Object3D node : partNetwork) + { + TileEntity nodeTile = node.getTileEntity(((TileEntity)tube).worldObj); + + if(nodeTile instanceof IPressurizedTube) + { + ((IPressurizedTube) nodeTile).removeFromNetwork(); + newTubes.add((IPressurizedTube)nodeTile); + } + } + + GasNetwork newNetwork = new GasNetwork(newTubes.toArray(new IPressurizedTube[0])); + newNetwork.refresh(); + newNetwork.fixed = true; + deregister(); + } + } + + public void removeTube(IPressurizedTube tube) + { + tubes.remove(tube); + if(tubes.size() == 0) + { + deregister(); + } + } + + public void register() + { + IPressurizedTube aTube = tubes.iterator().next(); + if(aTube instanceof TileEntity && !((TileEntity)aTube).worldObj.isRemote) + { + TransmitterNetworkRegistry.getInstance().registerNetwork(this); + } + } + + public void deregister() + { + tubes.clear(); + TransmitterNetworkRegistry.getInstance().removeNetwork(this); + } + public static class NetworkFinder { public World worldObj; - public Object3D toFind; + public Object3D start; public List iterated = new ArrayList(); public List toIgnore = new ArrayList(); - public NetworkFinder(World world, Object3D target, Object3D... ignore) + public NetworkFinder(World world, Object3D location, Object3D... ignore) { worldObj = world; - toFind = target; + start = location; if(ignore != null) { @@ -231,13 +296,11 @@ public class GasNetwork } } - public void loopThrough(Object3D location) + public void loopAll(Object3D location) { - iterated.add(location); - - if(iterated.contains(toFind)) + if(location.getTileEntity(worldObj) instanceof IPressurizedTube) { - return; + iterated.add(location); } for(ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) @@ -246,25 +309,21 @@ public class GasNetwork if(!iterated.contains(obj) && !toIgnore.contains(obj)) { - TileEntity tileEntity = location.getTileEntity(worldObj); - TileEntity sideTile = obj.getTileEntity(worldObj); + TileEntity tileEntity = obj.getTileEntity(worldObj); - if(sideTile instanceof IPressurizedTube && ((IPressurizedTube)sideTile).canTransferGas()) + if(tileEntity instanceof IPressurizedTube) { - if(((IPressurizedTube)sideTile).canTransferGasToTube(tileEntity) && ((IPressurizedTube)tileEntity).canTransferGasToTube(sideTile)) - { - loopThrough(obj); - } + loopAll(obj); } } } } - public boolean foundTarget(Object3D start) + public List exploreNetwork() { - loopThrough(start); + loopAll(start); - return iterated.contains(toFind); + return iterated; } } @@ -309,4 +368,24 @@ public class GasNetwork { return "[GasNetwork] " + tubes.size() + " pipes, " + possibleAcceptors.size() + " acceptors."; } + + public void tick() + { + //Fix weird behaviour periodically. + if(!fixed) + { + ++ticksSinceCreate; + if(ticksSinceCreate > 1200) + { + ticksSinceCreate = 0; + fixMessedUpNetwork(tubes.iterator().next()); + } + } + } + + @Override + public int getSize() + { + return tubes.size(); + } } diff --git a/common/mekanism/api/IPressurizedTube.java b/common/mekanism/api/IPressurizedTube.java index 0786df7c9..550c8d157 100644 --- a/common/mekanism/api/IPressurizedTube.java +++ b/common/mekanism/api/IPressurizedTube.java @@ -24,11 +24,20 @@ public interface IPressurizedTube public void onTransfer(EnumGas type); /** - * Gets the GasNetwork currently in use by this cable segment. + * Gets the GasNetwork currently in use by this tube segment. * @return GasNetwork this cable is using */ public GasNetwork getNetwork(); + /** + * Gets the GasNetwork currently in use by this tube segment. + * @param createIfNull - If true, the tube will try and connect to an + * adjacent network, merging several if necessary, or creating a new one + * if none is available + * @return GasNetwork this cable is using + */ + public GasNetwork getNetwork(boolean createIfNull); + /** * Sets this cable segment's GasNetwork to a new value. * @param network - GasNetwork to set to @@ -36,7 +45,18 @@ public interface IPressurizedTube public void setNetwork(GasNetwork network); /** - * Refreshes the cable's GasNetwork. + * Refreshes the tube's GasNetwork. */ public void refreshNetwork(); + + /** + * Remove a tube from its network. + */ + public void removeFromNetwork(); + + /** + * Call this if you're worried a tube's network is messed up and you want + * it to try and fix itself. + */ + public void fixNetwork(); } diff --git a/common/mekanism/api/ITransmitterNetwork.java b/common/mekanism/api/ITransmitterNetwork.java new file mode 100644 index 000000000..6ee159eaf --- /dev/null +++ b/common/mekanism/api/ITransmitterNetwork.java @@ -0,0 +1,8 @@ +package mekanism.api; + +public interface ITransmitterNetwork +{ + public void tick(); + + public int getSize(); +} diff --git a/common/mekanism/common/EnergyNetworkRegistry.java b/common/mekanism/api/TransmitterNetworkRegistry.java similarity index 58% rename from common/mekanism/common/EnergyNetworkRegistry.java rename to common/mekanism/api/TransmitterNetworkRegistry.java index 5f88967dc..e31068c7c 100644 --- a/common/mekanism/common/EnergyNetworkRegistry.java +++ b/common/mekanism/api/TransmitterNetworkRegistry.java @@ -1,4 +1,4 @@ -package mekanism.common; +package mekanism.api; import java.util.EnumSet; import java.util.HashSet; @@ -9,28 +9,28 @@ import cpw.mods.fml.common.TickType; import cpw.mods.fml.common.registry.TickRegistry; import cpw.mods.fml.relauncher.Side; -public class EnergyNetworkRegistry implements ITickHandler +public class TransmitterNetworkRegistry implements ITickHandler { - private static EnergyNetworkRegistry INSTANCE = new EnergyNetworkRegistry(); + private static TransmitterNetworkRegistry INSTANCE = new TransmitterNetworkRegistry(); - private HashSet networks = new HashSet(); + private HashSet networks = new HashSet(); - public EnergyNetworkRegistry() + public TransmitterNetworkRegistry() { TickRegistry.registerTickHandler(this, Side.SERVER); } - public static EnergyNetworkRegistry getInstance() + public static TransmitterNetworkRegistry getInstance() { return INSTANCE; } - - public void registerNetwork(EnergyNetwork network) + + public void registerNetwork(ITransmitterNetwork network) { networks.add(network); } - public void removeNetwork(EnergyNetwork network) + public void removeNetwork(ITransmitterNetwork network) { if(networks.contains(network)) { @@ -40,14 +40,13 @@ public class EnergyNetworkRegistry implements ITickHandler public void pruneEmptyNetworks() { - for(EnergyNetwork e : networks) + for(ITransmitterNetwork e : networks) { - if(e.cables.size() == 0) + if(e.getSize() == 0) { removeNetwork(e); } } - } @Override @@ -55,12 +54,12 @@ public class EnergyNetworkRegistry implements ITickHandler { return; } - + @Override public void tickEnd(EnumSet type, Object... tickData) { - Set iterNetworks = (Set) networks.clone(); - for(EnergyNetwork net : iterNetworks) + Set iterNetworks = (Set) networks.clone(); + for(ITransmitterNetwork net : iterNetworks) { if(networks.contains(net)) { @@ -84,6 +83,6 @@ public class EnergyNetworkRegistry implements ITickHandler @Override public String toString() { - return networks.toString(); + return "Network Registry:\n" + networks; } } diff --git a/common/mekanism/client/EnergyClientUpdate.java b/common/mekanism/client/EnergyClientUpdate.java new file mode 100644 index 000000000..a2d69111b --- /dev/null +++ b/common/mekanism/client/EnergyClientUpdate.java @@ -0,0 +1,40 @@ +package mekanism.client; + +import java.util.ArrayList; +import java.util.List; + +import mekanism.api.Object3D; +import mekanism.common.EnergyNetwork.NetworkFinder; +import mekanism.common.IUniversalCable; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +public class EnergyClientUpdate +{ + public NetworkFinder finder; + + public World worldObj; + + public double energyScale; + + public EnergyClientUpdate(TileEntity head, double power) + { + worldObj = head.worldObj; + energyScale = power; + finder = new NetworkFinder(head.worldObj, Object3D.get(head)); + } + + public void clientUpdate() + { + List found = finder.exploreNetwork(); + + for(Object3D object : found) + { + TileEntity tileEntity = object.getTileEntity(worldObj); + if(tileEntity instanceof IUniversalCable) + { + ((IUniversalCable)tileEntity).setEnergyScale(energyScale); + } + } + } +} diff --git a/common/mekanism/common/EnergyNetwork.java b/common/mekanism/common/EnergyNetwork.java index 3e110cbff..22ec14412 100644 --- a/common/mekanism/common/EnergyNetwork.java +++ b/common/mekanism/common/EnergyNetwork.java @@ -12,11 +12,17 @@ import java.util.List; import java.util.Map; import java.util.Set; +import cpw.mods.fml.common.FMLCommonHandler; + import mekanism.api.IStrictEnergyAcceptor; +import mekanism.api.ITransmitterNetwork; import mekanism.api.Object3D; +import mekanism.api.TransmitterNetworkRegistry; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import net.minecraftforge.common.ForgeDirection; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.Event; import net.minecraftforge.event.ForgeSubscribe; import net.minecraftforge.event.world.ChunkEvent; import buildcraft.api.power.IPowerReceptor; @@ -25,22 +31,24 @@ import buildcraft.api.power.PowerHandler.Type; import universalelectricity.core.block.IElectrical; import universalelectricity.core.electricity.ElectricityPack; -public class EnergyNetwork +public class EnergyNetwork implements ITransmitterNetwork { public HashSet cables = new HashSet(); public Set possibleAcceptors = new HashSet(); public Map acceptorDirections = new HashMap(); + private double lastPowerScale = 0; private double joulesTransmitted = 0; private double joulesLastTick = 0; private int ticksSinceCreate = 0; + private int ticksSinceSecond = 0; private boolean fixed = false; public EnergyNetwork(IUniversalCable... varCables) { cables.addAll(Arrays.asList(varCables)); - EnergyNetworkRegistry.getInstance().registerNetwork(this); + register(); } public EnergyNetwork(Set networks) @@ -55,7 +63,7 @@ public class EnergyNetwork } refresh(); - EnergyNetworkRegistry.getInstance().registerNetwork(this); + register(); } public double getEnergyNeeded(ArrayList ignored) @@ -231,13 +239,21 @@ public class EnergyNetwork } } } + + double currentPowerScale = getPowerScale(); + if(FMLCommonHandler.instance().getEffectiveSide().isServer()) + { + lastPowerScale = currentPowerScale; + + MinecraftForge.EVENT_BUS.post(new EnergyTransferEvent(this, currentPowerScale)); + } } public void merge(EnergyNetwork network) { if(network != null && network != this) { - Set networks = new HashSet(); + Set networks = new HashSet(); networks.add(this); networks.add(network); EnergyNetwork newNetwork = new EnergyNetwork(networks); @@ -291,8 +307,7 @@ public class EnergyNetwork } } - EnergyNetwork newNetwork = new EnergyNetwork(); - + Set newNetCables= new HashSet(); for(Object3D node : finder.iterated) { TileEntity nodeTile = node.getTileEntity(((TileEntity)splitPoint).worldObj); @@ -301,11 +316,12 @@ public class EnergyNetwork { if(nodeTile != splitPoint) { - newNetwork.cables.add((IUniversalCable)nodeTile); + newNetCables.add((IUniversalCable)nodeTile); } } } + EnergyNetwork newNetwork = new EnergyNetwork(newNetCables.toArray(new IUniversalCable[0])); newNetwork.refresh(); } } @@ -350,10 +366,19 @@ public class EnergyNetwork } } + public void register() + { + IUniversalCable aCable = cables.iterator().next(); + if(aCable instanceof TileEntity && !((TileEntity)aCable).worldObj.isRemote) + { + TransmitterNetworkRegistry.getInstance().registerNetwork(this); + } + } + public void deregister() { cables.clear(); - EnergyNetworkRegistry.getInstance().removeNetwork(this); + TransmitterNetworkRegistry.getInstance().removeNetwork(this); } public static class NetworkFinder @@ -406,6 +431,19 @@ public class EnergyNetwork } } + public static class EnergyTransferEvent extends Event + { + public final EnergyNetwork energyNetwork; + + public final double power; + + public EnergyTransferEvent(EnergyNetwork network, double currentPower) + { + energyNetwork = network; + power = currentPower; + } + } + public static class NetworkLoader { @ForgeSubscribe @@ -435,7 +473,6 @@ public class EnergyNetwork return "[EnergyNetwork] " + cables.size() + " cables, " + possibleAcceptors.size() + " acceptors."; } - public void tick() { clearJoulesTransmitted(); @@ -447,9 +484,22 @@ public class EnergyNetwork if(ticksSinceCreate > 1200) { ticksSinceCreate = 0; - fixMessedUpNetwork(cables.toArray(new IUniversalCable[0])[0]); + fixMessedUpNetwork(cables.iterator().next()); } } + + double currentPowerScale = getPowerScale(); + if(currentPowerScale != lastPowerScale && FMLCommonHandler.instance().getEffectiveSide().isServer()) + { + lastPowerScale = currentPowerScale; + + MinecraftForge.EVENT_BUS.post(new EnergyTransferEvent(this, currentPowerScale)); + } + } + + public double getPowerScale() + { + return joulesLastTick == 0 ? 0 : Math.min(Math.ceil(Math.log10(getPower())*2)/10, 1); } public void clearJoulesTransmitted() @@ -462,4 +512,10 @@ public class EnergyNetwork { return joulesLastTick * 20; } + + @Override + public int getSize() + { + return cables.size(); + } } diff --git a/common/mekanism/common/FluidNetwork.java b/common/mekanism/common/FluidNetwork.java index a91770964..983e8945d 100644 --- a/common/mekanism/common/FluidNetwork.java +++ b/common/mekanism/common/FluidNetwork.java @@ -10,7 +10,9 @@ import java.util.List; import java.util.Map; import java.util.Set; +import mekanism.api.ITransmitterNetwork; import mekanism.api.Object3D; +import mekanism.api.TransmitterNetworkRegistry; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import net.minecraftforge.common.ForgeDirection; @@ -22,16 +24,36 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.IFluidHandler; import cpw.mods.fml.common.FMLCommonHandler; -public class FluidNetwork +public class FluidNetwork implements ITransmitterNetwork { - public Set pipes = new HashSet(); + public HashSet pipes = new HashSet(); public Set possibleAcceptors = new HashSet(); public Map acceptorDirections = new HashMap(); + private int ticksSinceCreate = 0; + private int ticksSinceSecond = 0; + private boolean fixed = false; + public FluidNetwork(IMechanicalPipe... varPipes) { pipes.addAll(Arrays.asList(varPipes)); + register(); + } + + public FluidNetwork(Set networks) + { + for(FluidNetwork net : networks) + { + if(net != null) + { + addAllPipes(net.pipes); + net.deregister(); + } + } + + refresh(); + register(); } public int emit(FluidStack fluidToSend, boolean doTransfer, TileEntity emitter) @@ -93,7 +115,8 @@ public class FluidNetwork public void refresh() { - Iterator it = pipes.iterator(); + Set iterPipes = (Set) pipes.clone(); + Iterator it = iterPipes.iterator(); possibleAcceptors.clear(); acceptorDirections.clear(); @@ -102,20 +125,17 @@ public class FluidNetwork { IMechanicalPipe conductor = (IMechanicalPipe)it.next(); - if(conductor == null) - { - it.remove(); - } - else if(((TileEntity)conductor).isInvalid()) + if(conductor == null || ((TileEntity)conductor).isInvalid()) { it.remove(); + pipes.remove(conductor); } else { conductor.setNetwork(this); } } - for(IMechanicalPipe pipe : pipes) + for(IMechanicalPipe pipe : iterPipes) { IFluidHandler[] acceptors = PipeUtils.getConnectedAcceptors((TileEntity)pipe); @@ -134,20 +154,27 @@ public class FluidNetwork { if(network != null && network != this) { - FluidNetwork newNetwork = new FluidNetwork(); - newNetwork.pipes.addAll(pipes); - newNetwork.pipes.addAll(network.pipes); + Set networks = new HashSet(); + networks.add(this); + networks.add(network); + FluidNetwork newNetwork = new FluidNetwork(networks); newNetwork.refresh(); } } + + public void addAllPipes(Set newPipes) + { + pipes.addAll(newPipes); + } public void split(IMechanicalPipe splitPoint) { if(splitPoint instanceof TileEntity) { - pipes.remove(splitPoint); + removePipe(splitPoint); TileEntity[] connectedBlocks = new TileEntity[6]; + boolean[] dealtWith = {false, false, false, false, false, false}; for(ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) { @@ -163,56 +190,97 @@ public class FluidNetwork { TileEntity connectedBlockA = connectedBlocks[countOne]; - if(connectedBlockA instanceof IMechanicalPipe) + if(connectedBlockA instanceof IMechanicalPipe && !dealtWith[countOne]) { - for(int countTwo = 0; countTwo < connectedBlocks.length; countTwo++) + NetworkFinder finder = new NetworkFinder(((TileEntity)splitPoint).worldObj, Object3D.get(connectedBlockA), Object3D.get((TileEntity)splitPoint)); + List partNetwork = finder.exploreNetwork(); + + for(int countTwo = countOne + 1; countTwo < connectedBlocks.length; countTwo++) { TileEntity connectedBlockB = connectedBlocks[countTwo]; - - if(connectedBlockA != connectedBlockB && connectedBlockB instanceof IMechanicalPipe) + + if(connectedBlockB instanceof IMechanicalPipe && !dealtWith[countTwo]) { - NetworkFinder finder = new NetworkFinder(((TileEntity)splitPoint).worldObj, Object3D.get(connectedBlockB), Object3D.get((TileEntity)splitPoint)); - - if(finder.foundTarget(Object3D.get(connectedBlockA))) + if(partNetwork.contains(Object3D.get(connectedBlockB))) { - for(Object3D node : finder.iterated) - { - TileEntity nodeTile = node.getTileEntity(((TileEntity)splitPoint).worldObj); - - if(nodeTile instanceof IMechanicalPipe) - { - if(nodeTile != splitPoint) - { - ((IMechanicalPipe)nodeTile).setNetwork(this); - } - } - } - } - else { - FluidNetwork newNetwork = new FluidNetwork(); - - for(Object3D node : finder.iterated) - { - TileEntity nodeTile = node.getTileEntity(((TileEntity)splitPoint).worldObj); - - if(nodeTile instanceof IMechanicalPipe) - { - if(nodeTile != splitPoint) - { - newNetwork.pipes.add((IMechanicalPipe)nodeTile); - } - } - } - - newNetwork.refresh(); + dealtWith[countTwo] = true; } } } + + Set newNetPipes= new HashSet(); + for(Object3D node : finder.iterated) + { + TileEntity nodeTile = node.getTileEntity(((TileEntity)splitPoint).worldObj); + + if(nodeTile instanceof IMechanicalPipe) + { + if(nodeTile != splitPoint) + { + newNetPipes.add((IMechanicalPipe)nodeTile); + } + } + } + + FluidNetwork newNetwork = new FluidNetwork(newNetPipes.toArray(new IMechanicalPipe[0])); + newNetwork.refresh(); } } + + deregister(); } } + public void fixMessedUpNetwork(IMechanicalPipe pipe) + { + if(pipe instanceof TileEntity) + { + NetworkFinder finder = new NetworkFinder(((TileEntity)pipe).getWorldObj(), Object3D.get((TileEntity)pipe), null); + List partNetwork = finder.exploreNetwork(); + Set newPipes = new HashSet(); + + for(Object3D node : partNetwork) + { + TileEntity nodeTile = node.getTileEntity(((TileEntity)pipe).worldObj); + + if(nodeTile instanceof IMechanicalPipe) + { + ((IMechanicalPipe) nodeTile).removeFromNetwork(); + newPipes.add((IMechanicalPipe)nodeTile); + } + } + + FluidNetwork newNetwork = new FluidNetwork(newPipes.toArray(new IMechanicalPipe[0])); + newNetwork.refresh(); + newNetwork.fixed = true; + deregister(); + } + } + + public void removePipe(IMechanicalPipe pipe) + { + pipes.remove(pipe); + if(pipes.size() == 0) + { + deregister(); + } + } + + public void register() + { + IMechanicalPipe aPipe = pipes.iterator().next(); + if(aPipe instanceof TileEntity && !((TileEntity)aPipe).worldObj.isRemote) + { + TransmitterNetworkRegistry.getInstance().registerNetwork(this); + } + } + + public void deregister() + { + pipes.clear(); + TransmitterNetworkRegistry.getInstance().removeNetwork(this); + } + public static class NetworkFinder { public World worldObj; @@ -221,24 +289,22 @@ public class FluidNetwork public List iterated = new ArrayList(); public List toIgnore = new ArrayList(); - public NetworkFinder(World world, Object3D target, Object3D... ignore) + public NetworkFinder(World world, Object3D location, Object3D... ignore) { worldObj = world; - start = target; + start = location; if(ignore != null) { toIgnore = Arrays.asList(ignore); } } - - public void loopThrough(Object3D location) + + public void loopAll(Object3D location) { - iterated.add(location); - - if(iterated.contains(start)) + if(location.getTileEntity(worldObj) instanceof IMechanicalPipe) { - return; + iterated.add(location); } for(ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) @@ -251,17 +317,17 @@ public class FluidNetwork if(tileEntity instanceof IMechanicalPipe) { - loopThrough(obj); + loopAll(obj); } } } } - - public boolean foundTarget(Object3D start) + + public List exploreNetwork() { - loopThrough(start); + loopAll(start); - return iterated.contains(start); + return iterated; } } @@ -301,9 +367,29 @@ public class FluidNetwork } } + public void tick() + { + //Fix weird behaviour periodically. + if(!fixed) + { + ++ticksSinceCreate; + if(ticksSinceCreate > 1200) + { + ticksSinceCreate = 0; + fixMessedUpNetwork(pipes.iterator().next()); + } + } + } + @Override public String toString() { return "[FluidNetwork] " + pipes.size() + " pipes, " + possibleAcceptors.size() + " acceptors."; } + + @Override + public int getSize() + { + return pipes.size(); + } } diff --git a/common/mekanism/common/IMechanicalPipe.java b/common/mekanism/common/IMechanicalPipe.java index cc8ce3f88..f586cda99 100644 --- a/common/mekanism/common/IMechanicalPipe.java +++ b/common/mekanism/common/IMechanicalPipe.java @@ -16,19 +16,39 @@ public interface IMechanicalPipe public void onTransfer(FluidStack fluidStack); /** - * Gets the FluidNetwork currently in use by this cable segment. - * @return FluidNetwork this cable is using + * Gets the FluidNetwork currently in use by this pipe segment. + * @return FluidNetwork this pipe is using */ public FluidNetwork getNetwork(); /** - * Sets this cable segment's FluidNetwork to a new value. + * Gets the FluidNetwork currently in use by this pipe segment. + * @param createIfNull - If true, the pipe will try and connect to an + * adjacent network, merging several if necessary, or creating a new one + * if none is available + * @return FluidNetwork this pipe is using + */ + public FluidNetwork getNetwork(boolean createIfNull); + + /** + * Sets this pipe segment's FluidNetwork to a new value. * @param network - FluidNetwork to set to */ public void setNetwork(FluidNetwork network); /** - * Refreshes the cable's FluidNetwork. + * Refreshes the pipe's FluidNetwork. */ public void refreshNetwork(); + + /** + * Remove a pipe from its network. + */ + public void removeFromNetwork(); + + /** + * Call this if you're worried a pipe's network is messed up and you want + * it to try and fix itself. + */ + public void fixNetwork(); } diff --git a/common/mekanism/common/IUniversalCable.java b/common/mekanism/common/IUniversalCable.java index 9315abcea..0ce05a9bb 100644 --- a/common/mekanism/common/IUniversalCable.java +++ b/common/mekanism/common/IUniversalCable.java @@ -45,4 +45,6 @@ public interface IUniversalCable */ public void fixNetwork(); + public void setEnergyScale(double energyScale); + } diff --git a/common/mekanism/common/ItemEnergyMeter.java b/common/mekanism/common/ItemEnergyMeter.java index ebdb1426d..98090d861 100644 --- a/common/mekanism/common/ItemEnergyMeter.java +++ b/common/mekanism/common/ItemEnergyMeter.java @@ -6,6 +6,7 @@ import universalelectricity.core.electricity.ElectricityDisplay; import universalelectricity.core.electricity.ElectricityDisplay.ElectricUnit; import mekanism.api.EnumColor; +import mekanism.api.TransmitterNetworkRegistry; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; @@ -39,14 +40,14 @@ public class ItemEnergyMeter extends ItemEnergized player.sendChatToPlayer(ChatMessageComponent.func_111066_d(EnumColor.GREY + "------------- " + EnumColor.DARK_BLUE + "[Mekanism]" + EnumColor.GREY + " -------------")); player.sendChatToPlayer(ChatMessageComponent.func_111066_d(EnumColor.GREY + " *Cables: " + EnumColor.DARK_GREY + cable.getNetwork().cables.size())); player.sendChatToPlayer(ChatMessageComponent.func_111066_d(EnumColor.GREY + " *Acceptors: " + EnumColor.DARK_GREY + cable.getNetwork().possibleAcceptors.size())); - player.sendChatToPlayer(ChatMessageComponent.func_111066_d(EnumColor.GREY + " *Needed energy: " + EnumColor.DARK_GREY + ElectricityDisplay.getDisplay((float)cable.getNetwork().getEnergyNeeded(new ArrayList()), ElectricUnit.JOULES))); - player.sendChatToPlayer(ChatMessageComponent.func_111066_d(EnumColor.GREY + " *Power: " + EnumColor.DARK_GREY + ElectricityDisplay.getDisplay((float)cable.getNetwork().getPower(), ElectricUnit.WATT))); + player.sendChatToPlayer(ChatMessageComponent.func_111066_d(EnumColor.GREY + " *Needed energy: " + EnumColor.DARK_GREY + ElectricityDisplay.getDisplay((float)(cable.getNetwork().getEnergyNeeded(new ArrayList())*Mekanism.TO_UE), ElectricUnit.JOULES))); + player.sendChatToPlayer(ChatMessageComponent.func_111066_d(EnumColor.GREY + " *Power: " + EnumColor.DARK_GREY + ElectricityDisplay.getDisplay((float)(cable.getNetwork().getPower()*Mekanism.TO_UE), ElectricUnit.WATT))); player.sendChatToPlayer(ChatMessageComponent.func_111066_d(EnumColor.GREY + "------------- " + EnumColor.DARK_BLUE + "[=======]" + EnumColor.GREY + " -------------")); } } if(player.isSneaking() && Mekanism.debug){ player.sendChatToPlayer(ChatMessageComponent.func_111066_d(EnumColor.GREY + "---------- " + EnumColor.DARK_BLUE + "[Mekanism Debug]" + EnumColor.GREY + " ----------")); - player.sendChatToPlayer(ChatMessageComponent.func_111066_d(EnumColor.GREY + " *Networks: " + EnumColor.DARK_GREY + EnergyNetworkRegistry.getInstance().toString())); + player.sendChatToPlayer(ChatMessageComponent.func_111066_d(EnumColor.GREY + " *Networks: " + EnumColor.DARK_GREY + TransmitterNetworkRegistry.getInstance().toString())); player.sendChatToPlayer(ChatMessageComponent.func_111066_d(EnumColor.GREY + "------------- " + EnumColor.DARK_BLUE + "[=======]" + EnumColor.GREY + " -------------")); } } diff --git a/common/mekanism/common/Mekanism.java b/common/mekanism/common/Mekanism.java index ad17a99af..3e1fcbf76 100644 --- a/common/mekanism/common/Mekanism.java +++ b/common/mekanism/common/Mekanism.java @@ -17,6 +17,7 @@ import mekanism.api.InfuseType; import mekanism.api.InfusionInput; import mekanism.api.Object3D; import mekanism.client.SoundHandler; +import mekanism.common.EnergyNetwork.EnergyTransferEvent; import mekanism.common.FluidNetwork.FluidTransferEvent; import mekanism.common.IFactory.RecipeType; import mekanism.common.MekanismUtils.ResourceType; @@ -1215,6 +1216,14 @@ public class Mekanism logger.info("[Mekanism] Mod loaded."); } + @ForgeSubscribe + public void onEnergyTransferred(EnergyTransferEvent event) + { + try { + PacketHandler.sendPacket(Transmission.ALL_CLIENTS, new PacketTransmitterTransferUpdate().setParams(TransmitterTransferType.ENERGY, event.energyNetwork.cables.iterator().next(), event.power)); + } catch(Exception e) {} + } + @ForgeSubscribe public void onGasTransferred(GasTransferEvent event) { diff --git a/common/mekanism/common/TileEntityMechanicalPipe.java b/common/mekanism/common/TileEntityMechanicalPipe.java index 8629786e1..1b60802d5 100644 --- a/common/mekanism/common/TileEntityMechanicalPipe.java +++ b/common/mekanism/common/TileEntityMechanicalPipe.java @@ -2,8 +2,10 @@ package mekanism.common; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import mekanism.api.Object3D; +import mekanism.api.TransmitterNetworkRegistry; import mekanism.common.PacketHandler.Transmission; import mekanism.common.network.PacketDataRequest; import net.minecraft.nbt.NBTTagCompound; @@ -64,6 +66,44 @@ public class TileEntityMechanicalPipe extends TileEntity implements IMechanicalP return fluidNetwork; } + @Override + public FluidNetwork getNetwork(boolean createIfNull) + { + if(fluidNetwork == null && createIfNull) + { + TileEntity[] adjacentCables = CableUtils.getConnectedCables(this); + HashSet connectedNets = new HashSet(); + for(TileEntity pipe : adjacentCables) + { + if(pipe instanceof IMechanicalPipe && ((IMechanicalPipe)pipe).getNetwork(false) != null) + { + connectedNets.add(((IMechanicalPipe)pipe).getNetwork()); + } + } + if(connectedNets.size() == 0 || worldObj.isRemote) + { + fluidNetwork = new FluidNetwork(this); + } + else if(connectedNets.size() == 1) + { + fluidNetwork = connectedNets.iterator().next(); + fluidNetwork.pipes.add(this); + } + else { + fluidNetwork = new FluidNetwork(connectedNets); + fluidNetwork.pipes.add(this); + } + } + + return fluidNetwork; + } + + @Override + public void fixNetwork() + { + getNetwork().fixMessedUpNetwork(this); + } + @Override public void invalidate() { @@ -78,9 +118,22 @@ public class TileEntityMechanicalPipe extends TileEntity implements IMechanicalP @Override public void setNetwork(FluidNetwork network) { - fluidNetwork = network; + if(network != fluidNetwork) + { + removeFromNetwork(); + fluidNetwork = network; + } } + @Override + public void removeFromNetwork() + { + if(fluidNetwork != null) + { + fluidNetwork.removePipe(this); + } + } + @Override public void refreshNetwork() { @@ -100,6 +153,13 @@ public class TileEntityMechanicalPipe extends TileEntity implements IMechanicalP } } + @Override + public void onChunkUnload() + { + invalidate(); + TransmitterNetworkRegistry.getInstance().pruneEmptyNetworks(); + } + @Override public void updateEntity() { diff --git a/common/mekanism/common/TileEntityPressurizedTube.java b/common/mekanism/common/TileEntityPressurizedTube.java index bba9dfe11..42daed88a 100644 --- a/common/mekanism/common/TileEntityPressurizedTube.java +++ b/common/mekanism/common/TileEntityPressurizedTube.java @@ -1,5 +1,7 @@ package mekanism.common; +import java.util.HashSet; + import mekanism.api.EnumGas; import mekanism.api.GasNetwork; import mekanism.api.IPressurizedTube; @@ -40,14 +42,47 @@ public class TileEntityPressurizedTube extends TileEntity implements IPressurize @Override public GasNetwork getNetwork() { - if(gasNetwork == null) + return getNetwork(true); + } + + @Override + public GasNetwork getNetwork(boolean createIfNull) + { + if(gasNetwork == null && createIfNull) { - gasNetwork = new GasNetwork(this); + TileEntity[] adjacentPipes = PipeUtils.getConnectedPipes(this); + HashSet connectedNets = new HashSet(); + for(TileEntity cable : adjacentPipes) + { + if(cable instanceof IPressurizedTube && ((IPressurizedTube)cable).getNetwork(false) != null) + { + connectedNets.add(((IPressurizedTube)cable).getNetwork()); + } + } + if(connectedNets.size() == 0 || worldObj.isRemote) + { + gasNetwork = new GasNetwork(this); + } + else if(connectedNets.size() == 1) + { + gasNetwork = (GasNetwork)connectedNets.iterator().next(); + gasNetwork.tubes.add(this); + } + else { + gasNetwork = new GasNetwork(connectedNets); + gasNetwork.tubes.add(this); + } } return gasNetwork; } - + + @Override + public void fixNetwork() + { + getNetwork().fixMessedUpNetwork(this); + } + @Override public void invalidate() { @@ -62,7 +97,20 @@ public class TileEntityPressurizedTube extends TileEntity implements IPressurize @Override public void setNetwork(GasNetwork network) { - gasNetwork = network; + if(network != gasNetwork) + { + removeFromNetwork(); + gasNetwork = network; + } + } + + @Override + public void removeFromNetwork() + { + if(gasNetwork != null) + { + gasNetwork.removeTube(this); + } } @Override diff --git a/common/mekanism/common/TileEntityUniversalCable.java b/common/mekanism/common/TileEntityUniversalCable.java index 1bc109120..e678219ef 100644 --- a/common/mekanism/common/TileEntityUniversalCable.java +++ b/common/mekanism/common/TileEntityUniversalCable.java @@ -1,9 +1,13 @@ package mekanism.common; -import java.util.ArrayList; import java.util.HashSet; import mekanism.api.Object3D; +import mekanism.api.TransmitterNetworkRegistry; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.INetworkManager; +import net.minecraft.network.packet.Packet; +import net.minecraft.network.packet.Packet132TileEntityData; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraft.world.World; @@ -22,6 +26,8 @@ public class TileEntityUniversalCable extends TileEntity implements IUniversalCa /** The energy network currently in use by this cable segment. */ public EnergyNetwork energyNetwork; + public double energyScale; + public TileEntityUniversalCable() { powerHandler = new PowerHandler(this, PowerHandler.Type.STORAGE); @@ -40,12 +46,6 @@ public class TileEntityUniversalCable extends TileEntity implements IUniversalCa return getNetwork(true); } - public float getEnergyScale() - { - //TODO: Let the client know how much power's being transferred - return 1.F; - } - @Override public EnergyNetwork getNetwork(boolean createIfNull) { @@ -60,13 +60,13 @@ public class TileEntityUniversalCable extends TileEntity implements IUniversalCa connectedNets.add(((IUniversalCable)cable).getNetwork()); } } - if(connectedNets.size() == 0) + if(connectedNets.size() == 0 || worldObj.isRemote) { energyNetwork = new EnergyNetwork(this); } else if(connectedNets.size() == 1) { - energyNetwork = (EnergyNetwork)connectedNets.toArray()[0]; + energyNetwork = connectedNets.iterator().next(); energyNetwork.cables.add(this); } else { @@ -159,6 +159,31 @@ public class TileEntityUniversalCable extends TileEntity implements IUniversalCa public void onChunkUnload() { invalidate(); - EnergyNetworkRegistry.getInstance().pruneEmptyNetworks(); + TransmitterNetworkRegistry.getInstance().pruneEmptyNetworks(); + } + + @Override + public void setEnergyScale(double scale) + { + energyScale = scale; + } + + @Override + public Packet getDescriptionPacket() + { + energyScale = getNetwork().getPowerScale(); + NBTTagCompound nbtTag = new NBTTagCompound(); + nbtTag.setDouble("energyScale", energyScale); + return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 1, nbtTag); + } + + public void onDataPacket(INetworkManager net, Packet132TileEntityData packet) + { + setEnergyScale(packet.customParam1.getDouble("energyScale")); + } + + public float getEnergyScale() + { + return (float)energyScale; } } \ No newline at end of file diff --git a/common/mekanism/common/network/PacketTransmitterTransferUpdate.java b/common/mekanism/common/network/PacketTransmitterTransferUpdate.java index 6f94f7746..560cf8228 100644 --- a/common/mekanism/common/network/PacketTransmitterTransferUpdate.java +++ b/common/mekanism/common/network/PacketTransmitterTransferUpdate.java @@ -3,6 +3,7 @@ package mekanism.common.network; import java.io.DataOutputStream; import mekanism.api.EnumGas; +import mekanism.client.EnergyClientUpdate; import mekanism.client.GasClientUpdate; import mekanism.client.FluidClientUpdate; import net.minecraft.entity.player.EntityPlayer; @@ -18,6 +19,8 @@ public class PacketTransmitterTransferUpdate implements IMekanismPacket public TileEntity tileEntity; + public double power; + public String gasName; public FluidStack fluidStack; @@ -36,6 +39,9 @@ public class PacketTransmitterTransferUpdate implements IMekanismPacket switch(activeType) { + case ENERGY: + power = (double)data[2]; + break; case GAS: gasName = ((EnumGas)data[2]).name; break; @@ -56,7 +62,18 @@ public class PacketTransmitterTransferUpdate implements IMekanismPacket int y = dataStream.readInt(); int z = dataStream.readInt(); - if(transmitterType == 0) + if(transmitterType == 0) + { + double powerLevel = dataStream.readDouble(); + + TileEntity tileEntity = world.getBlockTileEntity(x, y, z); + + if(tileEntity != null) + { + new EnergyClientUpdate(tileEntity, powerLevel).clientUpdate(); + } + } + else if(transmitterType == 1) { EnumGas type = EnumGas.getFromName(dataStream.readUTF()); @@ -67,7 +84,7 @@ public class PacketTransmitterTransferUpdate implements IMekanismPacket new GasClientUpdate(tileEntity, type).clientUpdate(); } } - else if(transmitterType == 1) + else if(transmitterType == 2) { TileEntity tileEntity = world.getBlockTileEntity(x, y, z); FluidStack fluidStack = new FluidStack(dataStream.readInt(), dataStream.readInt()); @@ -90,6 +107,9 @@ public class PacketTransmitterTransferUpdate implements IMekanismPacket switch(activeType) { + case ENERGY: + dataStream.writeDouble(power); + break; case GAS: dataStream.writeUTF(gasName); break; @@ -102,6 +122,7 @@ public class PacketTransmitterTransferUpdate implements IMekanismPacket public static enum TransmitterTransferType { + ENERGY, GAS, FLUID }