Finished basic mechanical grid

This commit is contained in:
Calclavia 2014-03-04 21:40:03 +08:00
parent ff152d1009
commit 503c3a9904
16 changed files with 358 additions and 419 deletions

View file

@ -6,7 +6,6 @@ import net.minecraft.item.ItemStack;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.oredict.OreDictionary;
import net.minecraftforge.oredict.ShapedOreRecipe;
import resonantinduction.api.mechanical.IMechanical;
import resonantinduction.core.Reference;
import resonantinduction.core.ResonantInduction;
import resonantinduction.core.Settings;
@ -15,7 +14,6 @@ import resonantinduction.mechanical.belt.BlockConveyorBelt;
import resonantinduction.mechanical.belt.TileConveyorBelt;
import resonantinduction.mechanical.energy.gear.ItemGear;
import resonantinduction.mechanical.energy.gear.ItemGearShaft;
import resonantinduction.mechanical.energy.network.PacketNetwork;
import resonantinduction.mechanical.energy.turbine.BlockWaterTurbine;
import resonantinduction.mechanical.energy.turbine.BlockWindTurbine;
import resonantinduction.mechanical.energy.turbine.SchematicWaterTurbine;
@ -27,10 +25,8 @@ import resonantinduction.mechanical.fluid.transport.BlockPump;
import resonantinduction.mechanical.fluid.transport.TilePump;
import resonantinduction.mechanical.logistic.belt.BlockDetector;
import resonantinduction.mechanical.logistic.belt.BlockManipulator;
import resonantinduction.mechanical.logistic.belt.BlockRejector;
import resonantinduction.mechanical.logistic.belt.TileDetector;
import resonantinduction.mechanical.logistic.belt.TileManipulator;
import resonantinduction.mechanical.logistic.belt.TileRejector;
import resonantinduction.mechanical.logistic.belt.TileSorter;
import resonantinduction.mechanical.process.crusher.BlockMechanicalPiston;
import resonantinduction.mechanical.process.crusher.TileMechanicalPiston;
@ -103,8 +99,6 @@ public class Mechanical
public static Block blockPurifier;
public static Block blockMechanicalPiston;
public static final PacketNetwork PACKET_NETWORK = new PacketNetwork(IMechanical.class, Reference.CHANNEL);
@EventHandler
public void preInit(FMLPreInitializationEvent evt)
{

View file

@ -16,7 +16,11 @@ import resonantinduction.api.mechanical.IMechanical;
import resonantinduction.core.Reference;
import resonantinduction.core.ResonantInduction;
import resonantinduction.mechanical.Mechanical;
import resonantinduction.mechanical.energy.network.IMechanicalNodeProvider;
import resonantinduction.mechanical.energy.network.MechanicalNode;
import resonantinduction.mechanical.energy.network.TileMechanical;
import resonantinduction.mechanical.energy.network.TileMechanical.PacketMechanicalNode;
import resonantinduction.mechanical.process.crusher.TileMechanicalPiston;
import universalelectricity.api.vector.Vector3;
import calclavia.lib.prefab.tile.IRotatable;
@ -36,6 +40,84 @@ public class TileConveyorBelt extends TileMechanical implements IBelt, IRotatabl
NONE, UP, DOWN, TOP
}
public TileConveyorBelt()
{
mechanicalNode = new PacketMechanicalNode(this)
{
@Override
public void recache()
{
synchronized (connections)
{
connections.clear();
boolean didRefresh = false;
for (int i = 2; i < 6; i++)
{
ForgeDirection dir = ForgeDirection.getOrientation(i);
Vector3 pos = new Vector3(TileConveyorBelt.this).translate(dir);
TileEntity tile = pos.getTileEntity(TileConveyorBelt.this.worldObj);
if (dir == TileConveyorBelt.this.getDirection() || dir == TileConveyorBelt.this.getDirection().getOpposite())
{
if (dir == TileConveyorBelt.this.getDirection())
{
if (TileConveyorBelt.this.slantType == SlantType.DOWN)
{
pos.translate(new Vector3(0, -1, 0));
}
else if (TileConveyorBelt.this.slantType == SlantType.UP)
{
pos.translate(new Vector3(0, 1, 0));
}
}
else if (dir == TileConveyorBelt.this.getDirection().getOpposite())
{
if (TileConveyorBelt.this.slantType == SlantType.DOWN)
{
pos.translate(new Vector3(0, 1, 0));
}
else if (TileConveyorBelt.this.slantType == SlantType.UP)
{
pos.translate(new Vector3(0, -1, 0));
}
}
tile = pos.getTileEntity(worldObj);
if (tile instanceof TileConveyorBelt)
{
connections.put(((TileConveyorBelt) tile).getNode(dir.getOpposite()), dir);
didRefresh = true;
}
}
else if (tile instanceof IMechanicalNodeProvider)
{
MechanicalNode mechanical = ((IMechanicalNodeProvider) tile).getNode(dir.getOpposite());
if (mechanical != null)
{
connections.put(mechanical, dir);
}
}
}
if (!worldObj.isRemote)
{
markRefresh = true;
}
}
}
@Override
public boolean canConnect(ForgeDirection from, Object source)
{
return from != getDirection() || from != getDirection().getOpposite();
}
}.setLoad(0.5f);
}
/**
* Static constants.
*/
@ -63,6 +145,7 @@ public class TileConveyorBelt extends TileMechanical implements IBelt, IRotatabl
/* PROCESSES IGNORE LIST AND REMOVES UNNEED ENTRIES */
Iterator<Entity> it = this.ignoreList.iterator();
while (it.hasNext())
{
if (!this.getAffectedEntities().contains(it.next()))
@ -75,11 +158,10 @@ public class TileConveyorBelt extends TileMechanical implements IBelt, IRotatabl
{
if (this.ticks % 10 == 0 && this.worldObj.isRemote && this.worldObj.getBlockId(this.xCoord - 1, this.yCoord, this.zCoord) != Mechanical.blockConveyorBelt.blockID && this.worldObj.getBlockId(xCoord, yCoord, zCoord - 1) != Mechanical.blockConveyorBelt.blockID)
{
worldObj.playSound(this.xCoord, this.yCoord, this.zCoord, Reference.PREFIX + "conveyor", 0.5f, 0.5f + 0.15f * getMoveVelocity(), true);
worldObj.playSound(this.xCoord, this.yCoord, this.zCoord, Reference.PREFIX + "conveyor", 0.5f, 0.5f + 0.15f * (float) getMoveVelocity(), true);
}
angle = getNetwork().getRotation(getMoveVelocity());
double beltPercentage = angle / (2 * Math.PI);
double beltPercentage = mechanicalNode.angle / (2 * Math.PI);
// Sync the animation. Slant belts are slower.
if (this.getSlant() == SlantType.NONE || this.getSlant() == SlantType.TOP)
@ -132,7 +214,7 @@ public class TileConveyorBelt extends TileMechanical implements IBelt, IRotatabl
if (id == PACKET_SLANT)
this.slantType = SlantType.values()[data.readInt()];
else if (id == PACKET_REFRESH)
getNetwork().reconstruct();
mechanicalNode.reconstruct();
}
public SlantType getSlant()
@ -148,7 +230,7 @@ public class TileConveyorBelt extends TileMechanical implements IBelt, IRotatabl
}
this.slantType = slantType;
getNetwork().reconstruct();
mechanicalNode.reconstruct();
this.worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
@ -200,88 +282,8 @@ public class TileConveyorBelt extends TileMechanical implements IBelt, IRotatabl
}
}
@Override
public boolean canConnect(ForgeDirection from, Object source)
public double getMoveVelocity()
{
return from != getDirection() || from != getDirection().getOpposite();
}
@Override
public Object[] getConnections()
{
Object[] connections = new Object[6];
boolean didRefresh = false;
for (int i = 2; i < 6; i++)
{
ForgeDirection dir = ForgeDirection.getOrientation(i);
Vector3 pos = new Vector3(this).translate(dir);
TileEntity tile = pos.getTileEntity(this.worldObj);
if (dir == this.getDirection() || dir == this.getDirection().getOpposite())
{
if (dir == this.getDirection())
{
if (this.slantType == SlantType.DOWN)
{
pos.translate(new Vector3(0, -1, 0));
}
else if (this.slantType == SlantType.UP)
{
pos.translate(new Vector3(0, 1, 0));
}
}
else if (dir == this.getDirection().getOpposite())
{
if (this.slantType == SlantType.DOWN)
{
pos.translate(new Vector3(0, 1, 0));
}
else if (this.slantType == SlantType.UP)
{
pos.translate(new Vector3(0, -1, 0));
}
}
tile = pos.getTileEntity(this.worldObj);
if (tile instanceof IBelt)
{
connections[dir.ordinal()] = tile;
didRefresh = true;
}
}
else if (tile instanceof IMechanical)
{
IMechanical mechanical = ((IMechanical) tile).getInstance(dir.getOpposite());
if (mechanical != null)
{
connections[dir.ordinal()] = mechanical;
}
}
}
if (didRefresh)
{
if (!worldObj.isRemote)
{
markRefresh = true;
}
}
return connections;
}
@Override
public void invalidate()
{
getNetwork().split(this);
super.invalidate();
}
public float getMoveVelocity()
{
return Math.abs(angularVelocity);
return Math.abs(mechanicalNode.getAngularVelocity());
}
}

View file

@ -1,8 +1,8 @@
package resonantinduction.mechanical.energy.network;
import resonantinduction.core.grid.INode;
import resonantinduction.core.grid.Node;
public abstract class EnergyNode implements INode
public abstract class EnergyNode extends Node
{
public abstract double getEnergy();
}

View file

@ -1,14 +1,6 @@
package resonantinduction.mechanical.energy.network;
import java.lang.ref.WeakReference;
import java.util.Iterator;
import resonantinduction.core.grid.Grid;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.api.net.IUpdate;
import universalelectricity.api.vector.Vector3;
import universalelectricity.core.net.NetworkTickHandler;
import resonantinduction.core.grid.NodeGrid;
/**
* A mechanical network for translate speed and force using mechanical rotations.
@ -26,119 +18,11 @@ import universalelectricity.core.net.NetworkTickHandler;
*
* @author Calclavia
*/
public class MechanicalNetwork extends Grid<MechanicalNode>
public class MechanicalNetwork extends NodeGrid<MechanicalNode>
{
public MechanicalNetwork()
public MechanicalNetwork(MechanicalNode node)
{
super(MechanicalNode.class);
}
@Override
public void add(MechanicalNode node)
{
super.add(node);
NetworkTickHandler.addNetwork(this);
}
@Override
public void reconstruct()
{
connectionCache.clear();
super.reconstruct();
}
@Override
protected void reconstructConnector(IMechanical node)
{
node.setNetwork(this);
/**
* Cache connections.
*/
Object[] conn = node.getConnections();
if (conn == null && node instanceof TileEntity)
{
/**
* Default connection implementation
*/
conn = new Object[6];
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS)
{
TileEntity tile = new Vector3((TileEntity) node).translate(dir).getTileEntity(((TileEntity) node).worldObj);
if (tile instanceof IMechanical)
{
IMechanical mech = ((IMechanical) tile).getInstance(dir.getOpposite());
if (mech != null && node.canConnect(dir, mech) && mech.canConnect(dir.getOpposite(), node))
{
conn[dir.ordinal()] = mech;
}
}
}
}
WeakReference[] connections = new WeakReference[conn.length];
for (int i = 0; i < connections.length; i++)
{
if (conn[i] != null)
{
if (conn[i] instanceof IMechanical)
{
IMechanical connected = ((IMechanical) conn[i]);
if (connected.getNetwork() != this)
{
connected.getNetwork().getConnectors().clear();
connected.setNetwork(this);
addConnector(connected);
reconstructConnector(connected);
}
}
connections[i] = new WeakReference(conn[i]);
}
}
connectionCache.put(node, connections);
}
@Override
public Object[] getConnectionsFor(IMechanical connector)
{
Object[] conn = new Object[6];
WeakReference[] connections = connectionCache.get(connector);
if (connections != null)
{
for (int i = 0; i < connections.length; i++)
if (connections[i] != null)
conn[i] = connections[i].get();
}
return conn;
}
@Override
public float getRotation(float velocity)
{
long deltaTime = System.currentTimeMillis() - lastRotateTime;
if (deltaTime > 1)
{
rotation = (float) (((velocity) * (deltaTime / 1000d) + rotation) % (2 * Math.PI));
lastRotateTime = System.currentTimeMillis();
}
return rotation;
}
@Override
public IMechanicalNetwork newInstance()
{
return new MechanicalNetwork();
add(node);
}
}

View file

@ -5,6 +5,8 @@ import java.util.Iterator;
import java.util.Map.Entry;
import java.util.WeakHashMap;
import resonantinduction.core.grid.IGrid;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
@ -15,30 +17,45 @@ public class MechanicalNode extends EnergyNode
{
protected final AbstractMap<MechanicalNode, ForgeDirection> connections = new WeakHashMap<MechanicalNode, ForgeDirection>();
protected final Object parent;
protected final IMechanicalNodeProvider parent;
public double torque = 0;
public double angularVelocity = 0;
public float acceleration = 0.1f;
public double prevAngularVelocity, angularVelocity = 0;
public float acceleration = 2f;
/**
* The current rotation of the mechanical node.
*/
public double angle = 0;
public MechanicalNode(Object parent)
protected double load = 1;
public MechanicalNode(IMechanicalNodeProvider parent)
{
this.parent = parent;
}
@Override
public void update()
public MechanicalNode setLoad(double load)
{
this.load = load;
return this;
}
@Override
public void update(float deltaTime)
{
float acceleration = this.acceleration * deltaTime;
double load = getLoad() * deltaTime;
prevAngularVelocity = angularVelocity;
onUpdate();
/**
* Loss energy
*/
torque -= torque * torque * getLoad();
angularVelocity -= angularVelocity * angularVelocity * getLoad();
torque -= torque * torque * load;
angularVelocity -= angularVelocity * angularVelocity * load;
angle += angularVelocity / 20;
@ -81,6 +98,11 @@ public class MechanicalNode extends EnergyNode
}
}
protected void onUpdate()
{
}
/**
* Called when one revolution is made.
*/
@ -115,9 +137,12 @@ public class MechanicalNode extends EnergyNode
return true;
}
/**
* The energy percentage loss due to resistance in seconds.
*/
public double getLoad()
{
return 0.01;
return load;
}
/**
@ -172,4 +197,26 @@ public class MechanicalNode extends EnergyNode
{
return torque * angularVelocity;
}
@Override
public IGrid newGrid()
{
return new MechanicalNetwork(this);
}
@Override
public void load(NBTTagCompound nbt)
{
super.load(nbt);
torque = nbt.getDouble("torque");
angularVelocity = nbt.getDouble("angularVelocity");
}
@Override
public void save(NBTTagCompound nbt)
{
super.save(nbt);
nbt.setDouble("torque", torque);
nbt.setDouble("angularVelocity", angularVelocity);
}
}

View file

@ -3,8 +3,6 @@ package resonantinduction.mechanical.energy.network;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.ForgeDirection;
import resonantinduction.api.mechanical.IMechanical;
import resonantinduction.api.mechanical.IMechanicalNetwork;
import resonantinduction.core.ResonantInduction;
import resonantinduction.mechanical.Mechanical;
import universalelectricity.api.vector.Vector3;
@ -18,21 +16,35 @@ public abstract class TileMechanical extends TileAdvanced implements IMechanical
{
protected static final int PACKET_VELOCITY = Mechanical.contentRegistry.getNextPacketID();
private IMechanicalNetwork network;
protected float angularVelocity;
protected long torque;
public float angle = 0;
protected MechanicalNode mechanicalNode = new PacketMechanicalNode(this).setLoad(0.5f);;
protected class PacketMechanicalNode extends MechanicalNode
{
public PacketMechanicalNode(IMechanicalNodeProvider parent)
{
super(parent);
}
@Override
protected void onUpdate()
{
if (Math.abs(prevAngularVelocity - angularVelocity) > 0.01f)
{
prevAngularVelocity = angularVelocity;
markPacketUpdate = true;
}
}
};
/**
* For sending client update packets
*/
private float prevAngularVelocity;
private boolean markPacketUpdate;
@Override
public void initiate()
{
getNetwork().reconstruct();
mechanicalNode.reconstruct();
}
@Override
@ -40,26 +52,6 @@ public abstract class TileMechanical extends TileAdvanced implements IMechanical
{
super.updateEntity();
angle += angularVelocity / 20;
if (angle % (Math.PI * 2) != angle)
{
revolve(angle <= Math.PI * 2 || angle >= Math.PI * 2);
angle = (float) (angle % (Math.PI * 2));
}
if (!worldObj.isRemote)
{
torque *= getLoad();
angularVelocity *= getLoad();
}
if (Math.abs(prevAngularVelocity - angularVelocity) > 0.01f)
{
prevAngularVelocity = angularVelocity;
markPacketUpdate = true;
}
if (markPacketUpdate && ticks % 10 == 0)
{
sendRotationPacket();
@ -67,19 +59,15 @@ public abstract class TileMechanical extends TileAdvanced implements IMechanical
}
}
protected void revolve(boolean isAmplitude)
@Override
public MechanicalNode getNode(ForgeDirection dir)
{
}
public long getPower()
{
return (long) (torque * angularVelocity);
return mechanicalNode;
}
private void sendRotationPacket()
{
PacketHandler.sendPacketToClients(ResonantInduction.PACKET_TILE.getPacket(this, PACKET_VELOCITY, angularVelocity), worldObj, new Vector3(this), 20);
PacketHandler.sendPacketToClients(ResonantInduction.PACKET_TILE.getPacket(this, PACKET_VELOCITY, mechanicalNode.angularVelocity), worldObj, new Vector3(this), 20);
}
@Override
@ -91,105 +79,20 @@ public abstract class TileMechanical extends TileAdvanced implements IMechanical
public void onReceivePacket(int id, ByteArrayDataInput data, EntityPlayer player, Object... extra)
{
if (id == PACKET_VELOCITY)
angularVelocity = data.readFloat();
}
@Override
public void invalidate()
{
getNetwork().split(this);
super.invalidate();
}
protected float getLoad()
{
return 0.95f;
}
@Override
public Object[] getConnections()
{
return null;
}
@Override
public IMechanicalNetwork getNetwork()
{
if (this.network == null)
{
this.network = new MechanicalNetwork();
this.network.addConnector(this);
}
return this.network;
}
@Override
public void setNetwork(IMechanicalNetwork network)
{
this.network = network;
}
@Override
public float getAngularVelocity()
{
return angularVelocity;
}
@Override
public void setAngularVelocity(float velocity)
{
this.angularVelocity = velocity;
}
@Override
public long getTorque()
{
return torque;
}
@Override
public void setTorque(long torque)
{
this.torque = torque;
}
@Override
public float getRatio(ForgeDirection dir, Object source)
{
return 0.5f;
}
@Override
public IMechanical getInstance(ForgeDirection from)
{
return this;
}
@Override
public Vector3 position()
{
return new Vector3(this);
}
@Override
public boolean inverseRotation(ForgeDirection dir, IMechanical with)
{
return true;
mechanicalNode.angularVelocity = data.readFloat();
}
@Override
public void readFromNBT(NBTTagCompound nbt)
{
super.readFromNBT(nbt);
torque = nbt.getLong("torque");
angularVelocity = nbt.getFloat("angularVelocity");
mechanicalNode.load(nbt);
}
@Override
public void writeToNBT(NBTTagCompound nbt)
{
super.writeToNBT(nbt);
nbt.setLong("torque", torque);
nbt.setFloat("angularVelocity", angularVelocity);
mechanicalNode.save(nbt);
}
}

View file

@ -36,7 +36,7 @@ public class RenderPump extends TileEntitySpecialRenderer
List<String> notRendered = new ArrayList<String>();
GL11.glPushMatrix();
GL11.glRotated(Math.toDegrees(tile.angle), 0, 0, 1);
GL11.glRotated(Math.toDegrees((float) tile.getNode(null).angle), 0, 0, 1);
for (int i = 1; i <= 12; i++)
{

View file

@ -33,12 +33,12 @@ public class RenderMechanicalPiston extends TileEntitySpecialRenderer
RenderUtility.bind(TEXTURE);
// Angle in radians of the rotor.
float angle = tile.angle;
float angle = (float) tile.getNode(null).angle;
float radius = 0.5f;
// Length of piston arm
float length = 1f;
double beta = Math.asin((radius * Math.sin(angle)) / (length/2));
double beta = Math.asin((radius * Math.sin(angle)) / (length / 2));
/**
* Render Piston Rod
@ -49,7 +49,7 @@ public class RenderMechanicalPiston extends TileEntitySpecialRenderer
GL11.glTranslated(0, pistonTranslateY, pistonTranslateX);
GL11.glRotated(-Math.toDegrees(beta), 1, 0, 0);
//MODEL.renderOnly("PistonShaft", "PistonFace", "PistonFace2");
// MODEL.renderOnly("PistonShaft", "PistonFace", "PistonFace2");
GL11.glPopMatrix();
/**

View file

@ -15,6 +15,32 @@ import cpw.mods.fml.relauncher.ReflectionHelper;
public class TileMechanicalPiston extends TileMechanical
{
public TileMechanicalPiston()
{
mechanicalNode = new PacketMechanicalNode(this)
{
@Override
protected void revolve()
{
if (!worldObj.isRemote)
{
Vector3 movePosition = new Vector3(TileMechanicalPiston.this).translate(getDirection());
Vector3 moveNewPosition = movePosition.clone().translate(getDirection());
if (canMove(movePosition, moveNewPosition))
move(movePosition, moveNewPosition);
}
}
@Override
public boolean canConnect(ForgeDirection from, Object source)
{
return from != getDirection();
}
}.setLoad(0.5f);
}
@Override
public void updateEntity()
{
@ -24,20 +50,7 @@ public class TileMechanicalPiston extends TileMechanical
Vector3 moveNewPosition = movePosition.clone().translate(getDirection());
if (!canMove(movePosition, moveNewPosition))
angle = 0;
}
@Override
protected void revolve(boolean isAmplitude)
{
if (!worldObj.isRemote && isAmplitude)
{
Vector3 movePosition = new Vector3(this).translate(getDirection());
Vector3 moveNewPosition = movePosition.clone().translate(getDirection());
if (canMove(movePosition, moveNewPosition))
move(movePosition, moveNewPosition);
}
mechanicalNode.angle = 0;
}
public boolean canMove(Vector3 from, Vector3 to)
@ -161,10 +174,4 @@ public class TileMechanicalPiston extends TileMechanical
}
}
}
@Override
public boolean canConnect(ForgeDirection from, Object source)
{
return from != getDirection();
}
}

View file

@ -40,7 +40,7 @@ public class RenderMixer extends TileEntitySpecialRenderer implements ISimpleIte
RenderUtility.bind(TEXTURE);
MODEL.renderOnly("centerTop", "centerBase");
glPushMatrix();
glRotatef((float) Math.toDegrees(tile.angle), 0, 1, 0);
glRotatef((float) Math.toDegrees((float) tile.getNode(null).angle), 0, 1, 0);
MODEL.renderAllExcept("centerTop", "centerBase");
glPopMatrix();
glPopMatrix();

View file

@ -9,6 +9,7 @@ import net.minecraft.entity.Entity;
*
* @Author DarkGuardsman
*/
@Deprecated
public interface IBelt
{
/**

View file

@ -16,13 +16,12 @@ import universalelectricity.core.net.ConnectionPathfinder;
*
* @param <N> - The node type.
*/
public abstract class Grid<N extends INode> implements IGrid<N>, IUpdate
public abstract class Grid<N> implements IGrid<N>
{
/**
* A set of connectors (e.g conductors).
*/
private final Set<N> nodes = Collections.newSetFromMap(new WeakHashMap<N, Boolean>());
protected final Set<N> nodes = Collections.newSetFromMap(new WeakHashMap<N, Boolean>());
private final Class<? extends N> nodeType;
public Grid(Class<? extends N> type)
@ -30,8 +29,6 @@ public abstract class Grid<N extends INode> implements IGrid<N>, IUpdate
nodeType = type;
}
public abstract N newInstance();
@Override
public void add(N node)
{
@ -56,52 +53,28 @@ public abstract class Grid<N extends INode> implements IGrid<N>, IUpdate
return nodes;
}
/**
* An grid update called only server side.
*/
@Override
public void update()
{
synchronized (nodes)
{
for (INode node : nodes)
{
node.update();
}
}
}
@Override
public boolean canUpdate()
{
return nodes.size() > 0;
}
@Override
public boolean continueUpdate()
{
return canUpdate();
}
/**
* A simple reconstruct class to rebuild the grid.
*/
@Override
public void reconstruct()
{
Iterator<N> it = new HashSet<N>(getNodes()).iterator();
while (it.hasNext())
synchronized (nodes)
{
N node = it.next();
Iterator<N> it = nodes.iterator();
if (isValidNode(node))
while (it.hasNext())
{
reconstructNode(node);
}
else
{
it.remove();
N node = it.next();
if (isValidNode(node))
{
reconstructNode(node);
}
else
{
it.remove();
}
}
}
}

View file

@ -2,7 +2,7 @@ package resonantinduction.core.grid;
import java.util.Set;
public interface IGrid<N extends INode>
public interface IGrid<N>
{
public void add(N node);

View file

@ -2,12 +2,28 @@ package resonantinduction.core.grid;
import java.util.AbstractMap;
public interface INode
import net.minecraftforge.common.ForgeDirection;
public interface INode<G extends IGrid>
{
public void update();
/**
* Updates the node. This may be called on a different thread.
*
* @param deltaTime - The time in seconds that has passed between the successive updates.
*/
void update(float deltaTime);
/**
* @return A map consisting of the connected object and a ForgeDirection.
*/
public AbstractMap getConnections();
AbstractMap<?, ForgeDirection> getConnections();
G getGrid();
void setGrid(G grid);
/**
* Called whenever the node changes to update its cached connections and network.
*/
void reconstruct();
}

View file

@ -0,0 +1,47 @@
package resonantinduction.core.grid;
import net.minecraft.nbt.NBTTagCompound;
public abstract class Node<G extends IGrid> implements INode<G>
{
public G grid = null;
@Override
public final G getGrid()
{
if (grid == null)
grid = newGrid();
return grid;
}
protected abstract G newGrid();
@Override
public final void setGrid(G grid)
{
this.grid = grid;
}
@Override
public void reconstruct()
{
recache();
getGrid().reconstruct();
}
public void recache()
{
}
public void load(NBTTagCompound nbt)
{
}
public void save(NBTTagCompound nbt)
{
}
}

View file

@ -0,0 +1,65 @@
package resonantinduction.core.grid;
import java.util.AbstractMap;
import net.minecraftforge.common.ForgeDirection;
import resonantinduction.mechanical.energy.network.MechanicalNode;
import universalelectricity.api.net.IUpdate;
public class NodeGrid<N extends INode> extends Grid<N> implements IUpdate
{
public NodeGrid(Class<? extends N> type)
{
super(type);
}
/**
* An grid update called only server side.
*/
@Override
public void update()
{
synchronized (nodes)
{
for (INode node : nodes)
{
node.update(1 / 20f);
}
}
}
@Override
public boolean canUpdate()
{
return nodes.size() > 0;
}
@Override
public boolean continueUpdate()
{
return canUpdate();
}
@Override
protected void reconstructNode(N node)
{
node.setGrid(this);
AbstractMap<Object, ForgeDirection> connections = node.getConnections();
for (Object connection : connections.keySet())
{
if (isValidNode(connection) && connection instanceof INode)
{
INode connectedNode = (INode) connection;
if (connectedNode.getGrid() != this)
{
connectedNode.getGrid().getNodes().clear();
connectedNode.setGrid(this);
reconstructNode((N) connectedNode);
}
}
}
}
}