From e57ea196a20fa8e5c4eb47026e5ce24512f05de4 Mon Sep 17 00:00:00 2001 From: DarkGuardsman Date: Fri, 8 Nov 2013 01:29:36 -0500 Subject: [PATCH] Started working on active tile networks --- src/dark/api/parts/INetworkPart.java | 7 +- .../core/prefab/machine/TileEntityInv.java | 10 +- .../prefab/tilenetwork/NetworkHandler.java | 156 +++++++++++ .../prefab/tilenetwork/NetworkPowerWires.java | 8 - .../tilenetwork/NetworkSharedPower.java | 26 +- .../tilenetwork/NetworkTileEntities.java | 245 +++++++++--------- 6 files changed, 298 insertions(+), 154 deletions(-) create mode 100644 src/dark/core/prefab/tilenetwork/NetworkHandler.java delete mode 100644 src/dark/core/prefab/tilenetwork/NetworkPowerWires.java diff --git a/src/dark/api/parts/INetworkPart.java b/src/dark/api/parts/INetworkPart.java index 7e0073fe..e233cb01 100644 --- a/src/dark/api/parts/INetworkPart.java +++ b/src/dark/api/parts/INetworkPart.java @@ -3,7 +3,6 @@ package dark.api.parts; import java.util.List; import net.minecraft.tileentity.TileEntity; -import dark.core.prefab.tilenetwork.NetworkTileEntities; public interface INetworkPart extends ITileConnector { @@ -14,10 +13,8 @@ public interface INetworkPart extends ITileConnector public void refresh(); /** Gets the networkPart's primary network */ - public NetworkTileEntities getTileNetwork(); + public ITileNetwork getTileNetwork(); /** Sets the networkPart's primary network */ - public void setTileNetwork(NetworkTileEntities fluidNetwork); - - public boolean mergeDamage(String result); + public void setTileNetwork(ITileNetwork network); } diff --git a/src/dark/core/prefab/machine/TileEntityInv.java b/src/dark/core/prefab/machine/TileEntityInv.java index a1b0579f..c8c9db8b 100644 --- a/src/dark/core/prefab/machine/TileEntityInv.java +++ b/src/dark/core/prefab/machine/TileEntityInv.java @@ -18,9 +18,10 @@ import dark.core.interfaces.IExternalInv; import dark.core.interfaces.IInvBox; import dark.core.prefab.invgui.InvChest; import dark.core.prefab.terminal.TerminalCommandRegistry; +import dark.core.prefab.tilenetwork.NetworkTileEntities; /** Prefab for simple object who only need basic inv support and nothing more - * + * * @author Darkguardsman */ public class TileEntityInv extends TileEntityAdvanced implements IExternalInv, ISidedInventory, ISpecialAccess { @@ -35,6 +36,13 @@ public class TileEntityInv extends TileEntityAdvanced implements IExternalInv, I TerminalCommandRegistry.loadNewGroupSet(this); } + @Override + public void invalidate() + { + super.initiate(); + NetworkTileEntities.invalidate(this); + } + @Override public IInvBox getInventory() { diff --git a/src/dark/core/prefab/tilenetwork/NetworkHandler.java b/src/dark/core/prefab/tilenetwork/NetworkHandler.java new file mode 100644 index 00000000..16ed9082 --- /dev/null +++ b/src/dark/core/prefab/tilenetwork/NetworkHandler.java @@ -0,0 +1,156 @@ +package dark.core.prefab.tilenetwork; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import cpw.mods.fml.common.IScheduledTickHandler; +import cpw.mods.fml.common.TickType; +import dark.api.parts.ITileNetwork; + +/** Manages all the tile networks making sure they get world save events, and updates every so often + * + * @author DarkGuardsman */ +public class NetworkHandler implements IScheduledTickHandler +{ + private static HashMap> nameToClassMap = new HashMap>(); + private static HashMap, String> classToNameMap = new HashMap, String>(); + + private byte count = 0; + + private Set networks = new HashSet(); + + private static NetworkHandler instance; + + static + { + registerNetworkClass("base", NetworkTileEntities.class); + } + + public static NetworkHandler instance() + { + if (instance == null) + { + instance = new NetworkHandler(); + } + return instance; + } + + public void registerNetwork(ITileNetwork network) + { + if (!networks.contains(network)) + { + this.networks.add(network); + } + } + + public static void registerNetworkClass(String id, Class clazz) + { + if (!nameToClassMap.containsKey(id) && !classToNameMap.containsKey(clazz)) + { + nameToClassMap.put(id, clazz); + classToNameMap.put(clazz, id); + } + } + + public static String getID(Class clazz) + { + return classToNameMap.get(clazz); + } + + public static Class getClazz(String id) + { + return nameToClassMap.get(id); + } + + public static ITileNetwork createNewNetwork(String id) + { + Class clazz = getClazz(id); + if (clazz != null) + { + try + { + Object object = clazz.newInstance(); + if (object instanceof ITileNetwork) + { + return (ITileNetwork) object; + } + } + catch (Exception e) + { + System.out.println("[CoreMachine]TileNetworkHandler: Failed to create a new network object"); + e.printStackTrace(); + } + } + else + { + System.out.println("[CoreMachine]TileNetworkHandler: Unkown id: " + id); + } + + return null; + } + + @Override + public void tickStart(EnumSet type, Object... tickData) + { + if (count + 1 >= Byte.MAX_VALUE) + { + count = 0; + for (ITileNetwork network : networks) + { + if (!network.isInvalid()) + { + network.refreshTick(); + } + } + } + else + { + count++; + for (ITileNetwork network : networks) + { + if (!network.isInvalid()) + { + network.updateTick(); + } + } + } + + } + + @Override + public void tickEnd(EnumSet type, Object... tickData) + { + Iterator it = networks.iterator(); + while (it.hasNext()) + { + ITileNetwork network = it.next(); + if (network.isInvalid()) + { + network.invalidate(); + it.remove(); + } + } + + } + + @Override + public EnumSet ticks() + { + return EnumSet.of(TickType.SERVER); + } + + @Override + public String getLabel() + { + return "[CoreMachine]TileNetworkHandler"; + } + + @Override + public int nextTickSpacing() + { + return 20; + } +} diff --git a/src/dark/core/prefab/tilenetwork/NetworkPowerWires.java b/src/dark/core/prefab/tilenetwork/NetworkPowerWires.java deleted file mode 100644 index 6d3d2528..00000000 --- a/src/dark/core/prefab/tilenetwork/NetworkPowerWires.java +++ /dev/null @@ -1,8 +0,0 @@ -package dark.core.prefab.tilenetwork; - -public class NetworkPowerWires -{ - /* TODO write this based on the UE universal network but with extra option, more control, and more realistic handling. - * As well a side note for making switches down the road. Add a canPowerFlowThrew method to check if power can go threw a part. - * This way the network doesn't need to be split and a lever/switch can be made in one method extend wire */ -} diff --git a/src/dark/core/prefab/tilenetwork/NetworkSharedPower.java b/src/dark/core/prefab/tilenetwork/NetworkSharedPower.java index 68fe3f65..39b3c638 100644 --- a/src/dark/core/prefab/tilenetwork/NetworkSharedPower.java +++ b/src/dark/core/prefab/tilenetwork/NetworkSharedPower.java @@ -8,7 +8,7 @@ import dark.api.parts.INetworkPart; /** Used for tile networks that only need to share power or act like a group battery that doesn't * store power on world save - * + * * @author DarkGuardsman */ public class NetworkSharedPower extends NetworkTileEntities implements IElectricalStorage, IPowerLess { @@ -20,12 +20,6 @@ public class NetworkSharedPower extends NetworkTileEntities implements IElectric super(parts); } - @Override - public NetworkTileEntities newInstance() - { - return new NetworkSharedPower(); - } - @Override public boolean isValidMember(INetworkPart part) { @@ -35,7 +29,7 @@ public class NetworkSharedPower extends NetworkTileEntities implements IElectric public float dumpPower(TileEntity source, float power, boolean doFill) { float room = (this.getMaxEnergyStored() - this.getEnergyStored()); - if (!this.runPowerLess && this.networkMember.contains(source) && Math.ceil(room) > 0) + if (!this.runPowerLess && this.networkMembers.contains(source) && Math.ceil(room) > 0) { if (doFill) { @@ -48,7 +42,7 @@ public class NetworkSharedPower extends NetworkTileEntities implements IElectric public boolean drainPower(TileEntity source, float power, boolean doDrain) { - if (this.networkMember.contains(source) && (this.getEnergyStored() >= power || this.runPowerLess)) + if (this.networkMembers.contains(source) && (this.getEnergyStored() >= power || this.runPowerLess)) { if (doDrain && !this.runPowerLess) { @@ -65,7 +59,7 @@ public class NetworkSharedPower extends NetworkTileEntities implements IElectric super.cleanUpMembers(); boolean set = false; this.energyMax = 0; - for (INetworkPart part : this.networkMember) + for (INetworkPart part : this.networkMembers) { if (!set && part instanceof IPowerLess && ((IPowerLess) part).runPowerLess()) { @@ -90,7 +84,7 @@ public class NetworkSharedPower extends NetworkTileEntities implements IElectric public void setPowerLess(boolean bool) { this.runPowerLess = bool; - for (INetworkPart part : this.networkMember) + for (INetworkPart part : this.networkMembers) { if (part instanceof IPowerLess) { @@ -133,13 +127,13 @@ public class NetworkSharedPower extends NetworkTileEntities implements IElectric } @Override - public void writeDataToTiles() + public void save() { this.cleanUpMembers(); float energyRemaining = this.getEnergyStored(); - for (INetworkPart part : this.getNetworkMemebers()) + for (INetworkPart part : this.getMembers()) { - float watts = energyRemaining / this.getNetworkMemebers().size(); + float watts = energyRemaining / this.getMembers().size(); if (part instanceof INetworkEnergyPart) { ((INetworkEnergyPart) part).setEnergyStored(Math.min(watts, ((INetworkEnergyPart) part).getMaxEnergyStored())); @@ -149,11 +143,11 @@ public class NetworkSharedPower extends NetworkTileEntities implements IElectric } @Override - public void readDataFromTiles() + public void load() { this.setEnergyStored(0); this.cleanUpMembers(); - for (INetworkPart part : this.getNetworkMemebers()) + for (INetworkPart part : this.getMembers()) { if (part instanceof INetworkEnergyPart) { diff --git a/src/dark/core/prefab/tilenetwork/NetworkTileEntities.java b/src/dark/core/prefab/tilenetwork/NetworkTileEntities.java index 4de7d3d8..ef9bf9f4 100644 --- a/src/dark/core/prefab/tilenetwork/NetworkTileEntities.java +++ b/src/dark/core/prefab/tilenetwork/NetworkTileEntities.java @@ -1,88 +1,104 @@ package dark.core.prefab.tilenetwork; -import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Set; import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.World; import net.minecraftforge.common.ForgeDirection; import universalelectricity.core.path.Pathfinder; import universalelectricity.core.vector.Vector3; import universalelectricity.core.vector.VectorHelper; import dark.api.parts.INetworkPart; -import dark.core.prefab.helpers.ConnectionHelper; +import dark.api.parts.ITileNetwork; -public abstract class NetworkTileEntities +public class NetworkTileEntities implements ITileNetwork { - /* BLOCK THAT ACT AS FLUID CONVEYORS ** */ - public final Set networkMember = new HashSet(); + protected final Set networkMembers = new HashSet(); + + public NetworkTileEntities() + { + + } public NetworkTileEntities(INetworkPart... parts) { - this.networkMember.addAll(Arrays.asList(parts)); + if (parts != null) + { + for (INetworkPart part : parts) + { + if (this.isValidMember(part)) + { + part.setTileNetwork(this); + networkMembers.add(part); + } + } + } } - /** Should be called after a network is created from a split or merge */ - public void init() + @Override + public String getName() { - cleanUpMembers(); + return "TileNetwork"; } - /** Creates a new instance of this network to be used to merge or split networks while still - * maintaining each class that extends the base network class - * - * @return - new network instance using the current networks properties */ - public abstract NetworkTileEntities newInstance(); - - /** Adds a TileEntity to the network. extends this to catch non-network parts and add them to - * other tile lists - * - * @param tileEntity - tileEntity instance - * @param member - add to network member list - * @return */ - public boolean addTile(TileEntity tileEntity, boolean member) + @Override + public Set getMembers() { - if (tileEntity == null || this.isPartOfNetwork(tileEntity)) + return networkMembers; + } + + @Override + public void onCreated() + { + this.load(); + this.cleanUpMembers(); + } + + @Override + public void updateTick() + { + // TODO Auto-generated method stub + + } + + @Override + public void refreshTick() + { + // TODO Auto-generated method stub + + } + + @Override + public boolean addTile(TileEntity ent, boolean member) + { + if (ent == null || ent.isInvalid()) { return false; } - else if (tileEntity instanceof INetworkPart && member) + else if (ent instanceof INetworkPart && this.isValidMember((INetworkPart) ent) && member) { - return this.addNetworkPart((INetworkPart) tileEntity); + ((INetworkPart) ent).setTileNetwork(this); + if (this.networkMembers.contains((INetworkPart) ent)) + { + return true; + } + return this.networkMembers.add((INetworkPart) ent); } return false; } - /** 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.cleanUpMembers(); - return true; - } - return false; - } - - public boolean isPartOfNetwork(TileEntity ent) - { - return this.networkMember.contains(ent); - } - - /** removes a tile from all parts of the network */ + @Override public boolean removeTile(TileEntity ent) { - return this.networkMember.remove(ent); + return this.networkMembers.remove(ent); } /** Cleans the list of networkMembers and remove those that no longer belong */ public void cleanUpMembers() { - Iterator it = this.networkMember.iterator(); + Iterator it = this.networkMembers.iterator(); while (it.hasNext()) { @@ -105,32 +121,22 @@ public abstract class NetworkTileEntities return part != null && part instanceof TileEntity && !((TileEntity) part).isInvalid(); } - /** Gets the list of network members */ - public Set getNetworkMemebers() - { - return this.networkMember; - } - - /** Override this to write any data to the tile. Called before a merge, split, or major edit of - * the network */ - public void writeDataToTiles() + @Override + public void save() { + // TODO Auto-generated method stub } - /** Override this to read any data to the tile. Called after a merge, split, or major edit of the - * network */ - public void readDataFromTiles() + @Override + public void load() { + // TODO Auto-generated method stub } - /** Combines two networks together into one. Calls to preMerge and doMerge instead of doing the - * merge process itself - * - * @param network - * @param mergePoint */ - public void merge(NetworkTileEntities network, INetworkPart mergePoint) + @Override + public void mergeNetwork(ITileNetwork network, INetworkPart mergePoint) { if (network != null && network != this && network.getClass().equals(this.getClass())) { @@ -143,112 +149,102 @@ public abstract class NetworkTileEntities /** Processing that needs too be done before the network merges. Use this to do final network * merge calculations and to cause network merge failure - * + * * @param network the network that is to merge with this one * @param part the part at which started the network merge. Use this to cause damage if two * networks merge with real world style failures - * + * * @return false if the merge needs to be canceled. - * + * * Cases in which the network should fail to merge are were the two networks merge with error. * Or, in the case of pipes the two networks merge and the merge point was destroyed by * combination of liquids. - * + * * Ex Lava and water */ - public boolean preMergeProcessing(NetworkTileEntities network, INetworkPart part) + public boolean preMergeProcessing(ITileNetwork network, INetworkPart part) { - this.writeDataToTiles(); + this.save(); return true; } /** Merges the two networks together */ - protected void mergeDo(NetworkTileEntities network) + protected void mergeDo(ITileNetwork network) { - NetworkTileEntities newNetwork = this.newInstance(); - newNetwork.getNetworkMemebers().addAll(this.getNetworkMemebers()); - newNetwork.getNetworkMemebers().addAll(network.getNetworkMemebers()); - newNetwork.readDataFromTiles(); - newNetwork.init(); + ITileNetwork newNetwork = NetworkHandler.createNewNetwork(NetworkHandler.getID(this.getClass())); + newNetwork.getMembers().addAll(this.getMembers()); + newNetwork.getMembers().addAll(network.getMembers()); + newNetwork.onCreated(); } - /** 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) + @Override + public void splitNetwork(INetworkPart splitPoint) { + this.getMembers().remove(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 = ConnectionHelper.getSurroundingTileEntities((TileEntity) splitPoint); + List connections = splitPoint.getNetworkConnections(); - for (int i = 0; i < connectedBlocks.length; i++) + for (final TileEntity connectionStart : connections) { - TileEntity connectedBlockA = connectedBlocks[i]; - - if (connectedBlockA instanceof INetworkPart) + if (connectionStart instanceof INetworkPart) { - for (int pipeCount = 0; pipeCount < connectedBlocks.length; pipeCount++) + for (final TileEntity connectionEnd : connections) { - final TileEntity connectedBlockB = connectedBlocks[pipeCount]; - - if (connectedBlockA != connectedBlockB && connectedBlockB instanceof INetworkPart) + if (connectionStart != connectionEnd && connectionEnd instanceof INetworkPart) { - Pathfinder finder = new NetworkPathFinder(world, (INetworkPart) connectedBlockB, splitPoint); - finder.init(new Vector3(connectedBlockA)); + Pathfinder finder = new NetworkPathFinder(connectionEnd.worldObj, (INetworkPart) connectionEnd, splitPoint); + finder.init(new Vector3(connectionStart)); - 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 + if (finder.results.size() <= 0) { + this.save(); /* NO LONGER CONNECTED ELSE WHERE SO SPLIT AND REFRESH */ - NetworkTileEntities newNetwork = this.newInstance(); - int parts = 0; - for (Vector3 node : finder.closedSet) + ITileNetwork newNetwork = NetworkHandler.createNewNetwork(NetworkHandler.getID(this.getClass())); + if (newNetwork != null) { - TileEntity entity = node.getTileEntity(world); - if (entity instanceof INetworkPart) + for (Vector3 node : finder.closedSet) { - if (node != splitPoint) + TileEntity entity = node.getTileEntity(connectionEnd.worldObj); + if (entity instanceof INetworkPart) { - newNetwork.getNetworkMemebers().add((INetworkPart) entity); - parts++; + if (node != splitPoint) + { + newNetwork.getMembers().add((INetworkPart) entity); + } } } + newNetwork.onCreated(); } - newNetwork.init(); + this.cleanUpMembers(); + this.load(); } } } } } - this.cleanUpMembers(); } + } @Override public String toString() { - return "TileNetwork[" + this.hashCode() + "| Parts:" + this.networkMember.size() + "]"; + return this.getName() + "[" + this.hashCode() + "| Parts:" + this.networkMembers.size() + "]"; + } + + @Override + public boolean isInvalid() + { + return this.networkMembers.isEmpty(); + } + + @Override + public void invalidate() + { + this.networkMembers.clear(); } - /** invalidates/remove a tile from the networks that surround and connect to it - * - * @param tileEntity - tile */ public static void invalidate(TileEntity tileEntity) { for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) @@ -261,4 +257,5 @@ public abstract class NetworkTileEntities } } } + }