Started working on active tile networks
This commit is contained in:
parent
01333fe4b0
commit
e57ea196a2
6 changed files with 298 additions and 154 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ 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
|
||||
*
|
||||
|
@ -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()
|
||||
{
|
||||
|
|
156
src/dark/core/prefab/tilenetwork/NetworkHandler.java
Normal file
156
src/dark/core/prefab/tilenetwork/NetworkHandler.java
Normal file
|
@ -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<String, Class<?>> nameToClassMap = new HashMap<String, Class<?>>();
|
||||
private static HashMap<Class<?>, String> classToNameMap = new HashMap<Class<?>, String>();
|
||||
|
||||
private byte count = 0;
|
||||
|
||||
private Set<ITileNetwork> 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<TickType> 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<TickType> type, Object... tickData)
|
||||
{
|
||||
Iterator<ITileNetwork> it = networks.iterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
ITileNetwork network = it.next();
|
||||
if (network.isInvalid())
|
||||
{
|
||||
network.invalidate();
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<TickType> ticks()
|
||||
{
|
||||
return EnumSet.of(TickType.SERVER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel()
|
||||
{
|
||||
return "[CoreMachine]TileNetworkHandler";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextTickSpacing()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
}
|
|
@ -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 */
|
||||
}
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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<INetworkPart> networkMember = new HashSet<INetworkPart>();
|
||||
protected final Set<INetworkPart> networkMembers = new HashSet<INetworkPart>();
|
||||
|
||||
public NetworkTileEntities()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public NetworkTileEntities(INetworkPart... parts)
|
||||
{
|
||||
this.networkMember.addAll(Arrays.asList(parts));
|
||||
}
|
||||
|
||||
/** Should be called after a network is created from a split or merge */
|
||||
public void init()
|
||||
if (parts != null)
|
||||
{
|
||||
cleanUpMembers();
|
||||
}
|
||||
|
||||
/** 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)
|
||||
for (INetworkPart part : parts)
|
||||
{
|
||||
if (tileEntity == null || this.isPartOfNetwork(tileEntity))
|
||||
if (this.isValidMember(part))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (tileEntity instanceof INetworkPart && member)
|
||||
{
|
||||
return this.addNetworkPart((INetworkPart) tileEntity);
|
||||
}
|
||||
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);
|
||||
networkMembers.add(part);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return "TileNetwork";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<INetworkPart> getMembers()
|
||||
{
|
||||
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 (ent instanceof INetworkPart && this.isValidMember((INetworkPart) ent) && member)
|
||||
{
|
||||
((INetworkPart) ent).setTileNetwork(this);
|
||||
if (this.networkMembers.contains((INetworkPart) ent))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return this.networkMembers.add((INetworkPart) ent);
|
||||
}
|
||||
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<INetworkPart> it = this.networkMember.iterator();
|
||||
Iterator<INetworkPart> 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<INetworkPart> 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()))
|
||||
{
|
||||
|
@ -155,100 +161,90 @@ public abstract class NetworkTileEntities
|
|||
* 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<TileEntity> connections = splitPoint.getNetworkConnections();
|
||||
|
||||
for (int i = 0; i < connectedBlocks.length; i++)
|
||||
for (final TileEntity connectionStart : connections)
|
||||
{
|
||||
TileEntity connectedBlockA = connectedBlocks[i];
|
||||
if (connectionStart instanceof INetworkPart)
|
||||
{
|
||||
for (final TileEntity connectionEnd : connections)
|
||||
{
|
||||
if (connectionStart != connectionEnd && connectionEnd instanceof INetworkPart)
|
||||
{
|
||||
Pathfinder finder = new NetworkPathFinder(connectionEnd.worldObj, (INetworkPart) connectionEnd, splitPoint);
|
||||
finder.init(new Vector3(connectionStart));
|
||||
|
||||
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 NetworkPathFinder(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
|
||||
if (finder.results.size() <= 0)
|
||||
{
|
||||
this.save();
|
||||
/* NO LONGER CONNECTED ELSE WHERE SO SPLIT AND REFRESH */
|
||||
NetworkTileEntities newNetwork = this.newInstance();
|
||||
int parts = 0;
|
||||
ITileNetwork newNetwork = NetworkHandler.createNewNetwork(NetworkHandler.getID(this.getClass()));
|
||||
if (newNetwork != null)
|
||||
{
|
||||
for (Vector3 node : finder.closedSet)
|
||||
{
|
||||
TileEntity entity = node.getTileEntity(world);
|
||||
TileEntity entity = node.getTileEntity(connectionEnd.worldObj);
|
||||
if (entity instanceof INetworkPart)
|
||||
{
|
||||
if (node != splitPoint)
|
||||
{
|
||||
newNetwork.getNetworkMemebers().add((INetworkPart) entity);
|
||||
parts++;
|
||||
}
|
||||
}
|
||||
}
|
||||
newNetwork.init();
|
||||
}
|
||||
newNetwork.getMembers().add((INetworkPart) entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
newNetwork.onCreated();
|
||||
}
|
||||
this.cleanUpMembers();
|
||||
this.load();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@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
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue