Some more work on gears

This commit is contained in:
Calclavia 2014-01-15 19:08:11 +08:00
parent 6c19f3f394
commit e72877cc72
22 changed files with 516 additions and 454 deletions

View file

@ -68,7 +68,10 @@ jar {
} }
repositories { repositories {
maven { url 'file://var/www/maven/' } maven {
name 'Calclavia Maven'
url 'http://calclavia.com/maven'
}
ivy { ivy {
name 'CB FS' name 'CB FS'

View file

@ -1,15 +1,15 @@
package resonantinduction.electrical.generator; package resonantinduction.electrical.generator;
import net.minecraftforge.common.ForgeDirection; import net.minecraftforge.common.ForgeDirection;
import resonantinduction.mechanical.network.IMechConnector; import resonantinduction.mechanical.network.IMechanicalConnector;
import resonantinduction.mechanical.network.IMechMachine; import resonantinduction.mechanical.network.IMechanical;
import universalelectricity.api.energy.EnergyStorageHandler; import universalelectricity.api.energy.EnergyStorageHandler;
import calclavia.lib.prefab.tile.TileElectrical; import calclavia.lib.prefab.tile.TileElectrical;
/** A kinetic energy to electrical energy converter. /** A kinetic energy to electrical energy converter.
* *
* @author Calclavia */ * @author Calclavia */
public class TileGenerator extends TileElectrical implements IMechMachine public class TileGenerator extends TileElectrical implements IMechanical
{ {
//P = \tau \times 2 \pi \times \omega //P = \tau \times 2 \pi \times \omega
private long power; private long power;

View file

@ -3,9 +3,9 @@ package resonantinduction.mechanical.belt;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import resonantinduction.api.IBelt; import resonantinduction.api.IBelt;
import resonantinduction.api.IBeltNetwork; import resonantinduction.api.IBeltNetwork;
import resonantinduction.mechanical.network.IMechConnector; import resonantinduction.mechanical.network.IMechanicalConnector;
import resonantinduction.mechanical.network.IMechNetwork; import resonantinduction.mechanical.network.IMechanicalNetwork;
import resonantinduction.mechanical.network.MechNetwork; import resonantinduction.mechanical.network.MechanicalNetwork;
import universalelectricity.api.net.IConnector; import universalelectricity.api.net.IConnector;
import universalelectricity.core.net.ConnectionPathfinder; import universalelectricity.core.net.ConnectionPathfinder;
import universalelectricity.core.net.Network; import universalelectricity.core.net.Network;
@ -122,13 +122,13 @@ public class BeltNetwork extends Network<IBeltNetwork, IBelt, TileEntity> implem
{ {
/** The connections A and B are not connected anymore. Give them both a new common /** The connections A and B are not connected anymore. Give them both a new common
* network. */ * network. */
IMechNetwork newNetwork = new MechNetwork(); IMechanicalNetwork newNetwork = new MechanicalNetwork();
for (IConnector node : finder.closedSet) for (IConnector node : finder.closedSet)
{ {
if (node instanceof IMechConnector) if (node instanceof IMechanicalConnector)
{ {
newNetwork.addConnector((IMechConnector) node); newNetwork.addConnector((IMechanicalConnector) node);
} }
} }

View file

@ -290,19 +290,19 @@ public class TileFluidNetwork extends TileEntityFluidDevice implements IFluidPar
@Override @Override
public Packet getDescriptionPacket() public Packet getDescriptionPacket()
{ {
return ResonantInduction.PACKET_TILE.getPacket(PACKET_DESCRIPTION, this, this.colorID, this.renderSides, this.getInternalTank().getCapacity(), this.getInternalTank().writeToNBT(new NBTTagCompound())); return ResonantInduction.PACKET_TILE.getPacketWithID(PACKET_DESCRIPTION, this, this.colorID, this.renderSides, this.getInternalTank().getCapacity(), this.getInternalTank().writeToNBT(new NBTTagCompound()));
} }
public void sendRenderUpdate() public void sendRenderUpdate()
{ {
PacketHandler.sendPacketToClients(ResonantInduction.PACKET_TILE.getPacket(PACKET_RENDER, this, this.colorID, this.renderSides)); PacketHandler.sendPacketToClients(ResonantInduction.PACKET_TILE.getPacketWithID(PACKET_RENDER, this, this.colorID, this.renderSides));
} }
public void sendTankUpdate(int index) public void sendTankUpdate(int index)
{ {
if (this.getInternalTank() != null && index == 0) if (this.getInternalTank() != null && index == 0)
{ {
PacketHandler.sendPacketToClients(ResonantInduction.PACKET_TILE.getPacket(PACKET_TANK, this, this.getInternalTank().getCapacity(), this.getInternalTank().writeToNBT(new NBTTagCompound())), this.worldObj, new Vector3(this), 60); PacketHandler.sendPacketToClients(ResonantInduction.PACKET_TILE.getPacketWithID(PACKET_TANK, this, this.getInternalTank().getCapacity(), this.getInternalTank().writeToNBT(new NBTTagCompound())), this.worldObj, new Vector3(this), 60);
} }
} }

View file

@ -11,9 +11,9 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.MovingObjectPosition;
import net.minecraftforge.common.ForgeDirection; import net.minecraftforge.common.ForgeDirection;
import resonantinduction.mechanical.Mechanical; import resonantinduction.mechanical.Mechanical;
import resonantinduction.mechanical.network.IMechConnector; import resonantinduction.mechanical.network.IMechanicalConnector;
import resonantinduction.mechanical.network.IMechNetwork; import resonantinduction.mechanical.network.IMechanicalNetwork;
import resonantinduction.mechanical.network.MechNetwork; import resonantinduction.mechanical.network.MechanicalNetwork;
import universalelectricity.api.UniversalElectricity; import universalelectricity.api.UniversalElectricity;
import codechicken.lib.data.MCDataInput; import codechicken.lib.data.MCDataInput;
import codechicken.lib.data.MCDataOutput; import codechicken.lib.data.MCDataOutput;
@ -30,227 +30,249 @@ import codechicken.multipart.TileMultipart;
import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly; import cpw.mods.fml.relauncher.SideOnly;
public class PartGear extends JCuboidPart implements JNormalOcclusion, TFacePart, IMechConnector /**
* We assume all the force acting on the gear is 90 degrees.
*
* @author Calclavia
*
*/
public class PartGear extends JCuboidPart implements JNormalOcclusion, TFacePart, IMechanicalConnector
{ {
public static Cuboid6[][] oBoxes = new Cuboid6[6][2]; public static Cuboid6[][] oBoxes = new Cuboid6[6][2];
private IMechNetwork network; private IMechanicalNetwork network;
static static
{ {
oBoxes[0][0] = new Cuboid6(1 / 8D, 0, 0, 7 / 8D, 1 / 8D, 1); oBoxes[0][0] = new Cuboid6(1 / 8D, 0, 0, 7 / 8D, 1 / 8D, 1);
oBoxes[0][1] = new Cuboid6(0, 0, 1 / 8D, 1, 1 / 8D, 7 / 8D); oBoxes[0][1] = new Cuboid6(0, 0, 1 / 8D, 1, 1 / 8D, 7 / 8D);
for (int s = 1; s < 6; s++) for (int s = 1; s < 6; s++)
{ {
Transformation t = Rotation.sideRotations[s].at(Vector3.center); Transformation t = Rotation.sideRotations[s].at(Vector3.center);
oBoxes[s][0] = oBoxes[0][0].copy().apply(t); oBoxes[s][0] = oBoxes[0][0].copy().apply(t);
oBoxes[s][1] = oBoxes[0][1].copy().apply(t); oBoxes[s][1] = oBoxes[0][1].copy().apply(t);
} }
} }
/** Side of the block this is placed on */ /** Side of the block this is placed on */
private ForgeDirection placementSide; private ForgeDirection placementSide;
/** Positive torque means it is spinning clockwise */ /** Positive torque means it is spinning clockwise */
private long torque = 0; private long torque = 0;
public void preparePlacement(int side, int itemDamage) private long force = 0;
{
this.placementSide = ForgeDirection.getOrientation((byte) (side ^ 1));
}
@Override /** The size of the gear */
public void update() private float radius = 0.5f;
{
// TODO: Should we average the torque? /** The angular velocity, radians per second. */
/** Look for gears that are back-to-back with this gear. Equate torque. */ private float angularVelocity = 0;
universalelectricity.api.vector.Vector3 vec = new universalelectricity.api.vector.Vector3(tile()).modifyPositionFromSide(placementSide);
/** The current angle the gear is on. In radians. */
private float angle = 0;
TileEntity tile = vec.getTileEntity(world()); public void preparePlacement(int side, int itemDamage)
{
this.placementSide = ForgeDirection.getOrientation((byte) (side ^ 1));
}
if (tile instanceof TileMultipart) public long getTorque()
{ {
TMultiPart part = ((TileMultipart) tile).partMap(this.placementSide.getOpposite().ordinal()); return (long) (force * radius);
}
if (part instanceof PartGear) @Override
{ public void update()
torque = (torque + ((PartGear) part).torque) / 2; {
((PartGear) part).torque = torque; // TODO: Should we average the torque?
} /** Look for gears that are back-to-back with this gear. Equate torque. */
} universalelectricity.api.vector.Vector3 vec = new universalelectricity.api.vector.Vector3(tile()).modifyPositionFromSide(placementSide);
/** Look for gears outside this block space, the relative UP, DOWN, LEFT, RIGHT */ TileEntity tile = vec.getTileEntity(world());
for (int i = 0; i < 4; i++)
{
ForgeDirection checkDir = ForgeDirection.getOrientation(Rotation.rotateSide(this.placementSide.ordinal(), i));
universalelectricity.api.vector.Vector3 checkVec = new universalelectricity.api.vector.Vector3(tile()).modifyPositionFromSide(checkDir);
TileEntity checkTile = checkVec.getTileEntity(world()); if (tile instanceof TileMultipart)
{
TMultiPart part = ((TileMultipart) tile).partMap(this.placementSide.getOpposite().ordinal());
if (checkTile instanceof TileMultipart) if (part instanceof PartGear)
{ {
TMultiPart neighbor = ((TileMultipart) checkTile).partMap(this.placementSide.ordinal()); torque = (torque + ((PartGear) part).torque) / 2;
((PartGear) part).torque = torque;
}
}
if (neighbor instanceof PartGear) /** Look for gears outside this block space, the relative UP, DOWN, LEFT, RIGHT */
{ for (int i = 0; i < 4; i++)
torque = (torque - ((PartGear) neighbor).torque) / 2; {
((PartGear) neighbor).torque = -torque; ForgeDirection checkDir = ForgeDirection.getOrientation(Rotation.rotateSide(this.placementSide.ordinal(), i));
} universalelectricity.api.vector.Vector3 checkVec = new universalelectricity.api.vector.Vector3(tile()).modifyPositionFromSide(checkDir);
}
}
/** Look for gears that are internal and adjacent to this gear. (The 2 sides) */ TileEntity checkTile = checkVec.getTileEntity(world());
for (int i = 0; i < 6; i++)
{
// TODO: Make it work with UP-DOWN
if (i < 2)
{
TMultiPart neighbor = tile().partMap(this.placementSide.getRotation(ForgeDirection.getOrientation(i)).ordinal());
if (neighbor instanceof PartGear) if (checkTile instanceof TileMultipart)
{ {
torque = (torque - ((PartGear) neighbor).torque) / 2; TMultiPart neighbor = ((TileMultipart) checkTile).partMap(this.placementSide.ordinal());
((PartGear) neighbor).torque = -torque;
}
}
}
}
@Override if (neighbor instanceof PartGear)
public boolean activate(EntityPlayer player, MovingObjectPosition hit, ItemStack item) {
{ torque = (torque - ((PartGear) neighbor).torque) / 2;
System.out.println("Torque" + this.torque); ((PartGear) neighbor).torque = -torque;
}
}
}
if (player.isSneaking()) /** Look for gears that are internal and adjacent to this gear. (The 2 sides) */
{ for (int i = 0; i < 6; i++)
this.torque += 10; {
} // TODO: Make it work with UP-DOWN
if (i < 2)
{
TMultiPart neighbor = tile().partMap(this.placementSide.getRotation(ForgeDirection.getOrientation(i)).ordinal());
return false; if (neighbor instanceof PartGear)
} {
torque = (torque - ((PartGear) neighbor).torque) / 2;
((PartGear) neighbor).torque = -torque;
}
}
}
}
/** Packet Code. */ @Override
@Override public boolean activate(EntityPlayer player, MovingObjectPosition hit, ItemStack item)
public void readDesc(MCDataInput packet) {
{ System.out.println("Torque" + this.torque);
this.placementSide = ForgeDirection.getOrientation(packet.readByte());
}
@Override if (player.isSneaking())
public void writeDesc(MCDataOutput packet) {
{ this.torque += 10;
packet.writeByte(this.placementSide.ordinal()); }
}
@Override return false;
public int getSlotMask() }
{
return 1 << this.placementSide.ordinal();
}
@Override /** Packet Code. */
public Cuboid6 getBounds() @Override
{ public void readDesc(MCDataInput packet)
return FaceMicroClass.aBounds()[0x10 | this.placementSide.ordinal()]; {
} this.placementSide = ForgeDirection.getOrientation(packet.readByte());
}
@Override @Override
public int redstoneConductionMap() public void writeDesc(MCDataOutput packet)
{ {
return 0; packet.writeByte(this.placementSide.ordinal());
} }
@Override @Override
public boolean solid(int arg0) public int getSlotMask()
{ {
return true; return 1 << this.placementSide.ordinal();
} }
@Override @Override
public Iterable<Cuboid6> getOcclusionBoxes() public Cuboid6 getBounds()
{ {
return Arrays.asList(oBoxes[this.placementSide.ordinal()]); return FaceMicroClass.aBounds()[0x10 | this.placementSide.ordinal()];
} }
protected ItemStack getItem() @Override
{ public int redstoneConductionMap()
return new ItemStack(Mechanical.itemGear); {
} return 0;
}
@Override @Override
public Iterable<ItemStack> getDrops() public boolean solid(int arg0)
{ {
List<ItemStack> drops = new ArrayList<ItemStack>(); return true;
drops.add(getItem()); }
return drops;
}
@Override @Override
public ItemStack pickItem(MovingObjectPosition hit) public Iterable<Cuboid6> getOcclusionBoxes()
{ {
return getItem(); return Arrays.asList(oBoxes[this.placementSide.ordinal()]);
} }
@Override protected ItemStack getItem()
@SideOnly(Side.CLIENT) {
public void renderDynamic(Vector3 pos, float frame, int pass) return new ItemStack(Mechanical.itemGear);
{ }
} @Override
public Iterable<ItemStack> getDrops()
{
List<ItemStack> drops = new ArrayList<ItemStack>();
drops.add(getItem());
return drops;
}
@Override @Override
public void load(NBTTagCompound nbt) public ItemStack pickItem(MovingObjectPosition hit)
{ {
super.load(nbt); return getItem();
this.placementSide = ForgeDirection.getOrientation(nbt.getByte("side")); }
}
@Override @Override
public void save(NBTTagCompound nbt) @SideOnly(Side.CLIENT)
{ public void renderDynamic(Vector3 pos, float frame, int pass)
super.save(nbt); {
nbt.setByte("side", (byte) this.placementSide.ordinal());
}
@Override }
public String getType()
{
return "resonant_induction_gear";
}
@Override @Override
public Object[] getConnections() public void load(NBTTagCompound nbt)
{ {
return null; super.load(nbt);
} this.placementSide = ForgeDirection.getOrientation(nbt.getByte("side"));
}
@Override @Override
public IMechNetwork getNetwork() public void save(NBTTagCompound nbt)
{ {
if (this.network == null) super.save(nbt);
{ nbt.setByte("side", (byte) this.placementSide.ordinal());
this.network = new MechNetwork(); }
this.network.addConnector(this);
}
return this.network;
}
@Override @Override
public void setNetwork(IMechNetwork network) public String getType()
{ {
this.network = network; return "resonant_induction_gear";
} }
@Override @Override
public boolean canConnect(ForgeDirection direction) public Object[] getConnections()
{ {
return new universalelectricity.api.vector.Vector3(this.x() + direction.offsetX, this.y() + direction.offsetY, this.z() + direction.offsetZ).getTileEntity(this.world()) instanceof IMechConnector; return null;
} }
@Override @Override
public int getResistance() public IMechanicalNetwork getNetwork()
{ {
// TODO Auto-generated method stub if (this.network == null)
return 0; {
} this.network = new MechanicalNetwork();
this.network.addConnector(this);
}
return this.network;
}
@Override
public void setNetwork(IMechanicalNetwork network)
{
this.network = network;
}
@Override
public boolean canConnect(ForgeDirection direction)
{
return new universalelectricity.api.vector.Vector3(this.x() + direction.offsetX, this.y() + direction.offsetY, this.z() + direction.offsetZ).getTileEntity(this.world()) instanceof IMechanicalConnector;
}
@Override
public int getResistance()
{
// TODO Auto-generated method stub
return 0;
}
} }

View file

@ -1,18 +0,0 @@
package resonantinduction.mechanical.network;
import universalelectricity.api.net.INetwork;
/** Mechanical network in interface form for interaction or extension
*
* @author DarkGuardsman */
public interface IMechNetwork extends INetwork<IMechNetwork, IMechConnector, IMechMachine>
{
/** Power applied by the network at the given speed */
public int getTorque();
/** Rotation of the the network in a single update */
public int getRotationPerTick();
/** Called to rebuild the network */
public void reconstruct();
}

View file

@ -6,7 +6,7 @@ import universalelectricity.api.net.IConnectable;
/** Applied to machines that connect to a mech network /** Applied to machines that connect to a mech network
* *
* @author Darkguardsman */ * @author Darkguardsman */
public interface IMechMachine extends IConnectable public interface IMechanical extends IConnectable
{ {
/** Called by the network when its torque value changes. */ /** Called by the network when its torque value changes. */
public void onTorqueChange(ForgeDirection side, int speed); public void onTorqueChange(ForgeDirection side, int speed);

View file

@ -5,7 +5,7 @@ import universalelectricity.api.net.IConnector;
/** For the mechanical network. /** For the mechanical network.
* *
* @author Calclavia */ * @author Calclavia */
public interface IMechConnector extends IConnector<IMechNetwork> public interface IMechanicalConnector extends IConnector<IMechanicalNetwork>
{ {
public int getResistance(); public int getResistance();
} }

View file

@ -0,0 +1,30 @@
package resonantinduction.mechanical.network;
import universalelectricity.api.net.INetwork;
/**
* Mechanical network in interface form for interaction or extension
*
* @author DarkGuardsman
*/
public interface IMechanicalNetwork extends INetwork<IMechanicalNetwork, IMechanicalConnector, IMechanical>
{
/**
* Gets the power of the network.
*
* @return Power in Watts.
*/
public long getPower();
/** Torque applied by the network at the given speed */
public int getTorque();
/**
* Gets the angular velocity of the network.
* @return In radians per second.
*/
public int getAngularVelocity();
/** Called to rebuild the network */
public void reconstruct();
}

View file

@ -1,234 +0,0 @@
package resonantinduction.mechanical.network;
import java.util.HashMap;
import java.util.Iterator;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.api.net.IConnector;
import universalelectricity.core.net.ConnectionPathfinder;
import universalelectricity.core.net.Network;
import universalelectricity.core.net.NetworkTickHandler;
/** Simple network to translate speed and force using mechanical rotation
*
* @author DarkGuardsman */
public class MechNetwork extends Network<IMechNetwork, IMechConnector, IMechMachine> implements IMechNetwork
{
private int force = 0;
private int speed = 0;
private int resistance = 0;
private HashMap<IMechMachine, ForceWrapper[]> forceMap = new HashMap<IMechMachine, ForceWrapper[]>();
@Override
public void update()
{
}
@Override
public void reconstruct()
{
if (this.getConnectors().size() > 0)
{
// Reset all values related to wires
this.getNodes().clear();
this.forceMap.clear();
this.resistance = 0;
this.force = 0;
this.speed = 0;
// Iterate threw list of wires
Iterator<IMechConnector> it = this.getConnectors().iterator();
while (it.hasNext())
{
IMechConnector conductor = it.next();
if (conductor != null)
{
this.reconstructConductor(conductor);
}
else
{
it.remove();
}
}
if (this.getNodes().size() > 0)
{
NetworkTickHandler.addNetwork(this);
}
}
}
/** Segmented out call so overriding can be done when conductors are reconstructed. */
protected void reconstructConductor(IMechConnector conductor)
{
conductor.setNetwork(this);
for (int i = 0; i < conductor.getConnections().length; i++)
{
reconstructHandler(conductor.getConnections()[i], ForgeDirection.getOrientation(i).getOpposite());
}
this.resistance += conductor.getResistance();
}
/** Segmented out call so overriding can be done when machines are reconstructed. */
protected void reconstructHandler(Object obj, ForgeDirection side)
{
if (obj != null && !(obj instanceof IMechConnector))
{
if (obj instanceof IMechMachine)
{
ForceWrapper[] set = this.forceMap.get((IMechMachine)obj);
if (set == null)
{
set = new ForceWrapper[6];
}
this.getNodes().add((IMechMachine) obj);
set[side.ordinal()] = new ForceWrapper(((IMechMachine) obj).getForceSide(side.getOpposite()),((IMechMachine) obj).getForceSide(side.getOpposite()));
this.forceMap.put((IMechMachine) obj, set);
}
}
}
@Override
public boolean canUpdate()
{
return true;
}
@Override
public boolean continueUpdate()
{
return true;
}
@Override
public IMechNetwork merge(IMechNetwork network)
{
if (network.getClass().isAssignableFrom(this.getClass()) && network != this)
{
MechNetwork newNetwork = new MechNetwork();
newNetwork.getConnectors().addAll(this.getConnectors());
newNetwork.getConnectors().addAll(network.getConnectors());
network.getConnectors().clear();
network.getNodes().clear();
this.getConnectors().clear();
this.getNodes().clear();
newNetwork.reconstruct();
return newNetwork;
}
return null;
}
@Override
public void split(IMechConnector splitPoint)
{
this.removeConnector(splitPoint);
this.reconstruct();
/** Loop through the connected blocks and attempt to see if there are connections between the
* two points elsewhere. */
Object[] connectedBlocks = splitPoint.getConnections();
for (int i = 0; i < connectedBlocks.length; i++)
{
Object connectedBlockA = connectedBlocks[i];
if (connectedBlockA instanceof IMechConnector)
{
for (int ii = 0; ii < connectedBlocks.length; ii++)
{
final Object connectedBlockB = connectedBlocks[ii];
if (connectedBlockA != connectedBlockB && connectedBlockB instanceof IMechConnector)
{
ConnectionPathfinder finder = new ConnectionPathfinder((IConnector) connectedBlockB, splitPoint);
finder.findNodes((IConnector) connectedBlockA);
if (finder.results.size() <= 0)
{
try
{
/** The connections A and B are not connected anymore. Give them both
* a new common network. */
IMechNetwork newNetwork = new MechNetwork();
for (IConnector node : finder.closedSet)
{
if (node != splitPoint && node instanceof IMechConnector)
{
newNetwork.addConnector((IMechConnector) node);
}
}
newNetwork.reconstruct();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
}
}
}
@Override
public void split(IMechConnector connectorA, IMechConnector connectorB)
{
this.reconstruct();
/** Check if connectorA connects with connectorB. */
ConnectionPathfinder finder = new ConnectionPathfinder(connectorB);
finder.findNodes(connectorA);
if (finder.results.size() <= 0)
{
/** The connections A and B are not connected anymore. Give them both a new common
* network. */
IMechNetwork newNetwork = new MechNetwork();
for (IConnector node : finder.closedSet)
{
if (node instanceof IMechConnector)
{
newNetwork.addConnector((IMechConnector) node);
}
}
newNetwork.reconstruct();
}
}
@Override
public int getTorque()
{
return this.force;
}
@Override
public int getRotationPerTick()
{
return this.speed;
}
public static class ForceWrapper
{
public int force = 0;
public int speed = 0;
public ForceWrapper(int force, int speed)
{
this.force = force;
this.speed = speed;
}
}
}

View file

@ -0,0 +1,259 @@
package resonantinduction.mechanical.network;
import java.util.HashMap;
import java.util.Iterator;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.api.net.IConnector;
import universalelectricity.core.net.ConnectionPathfinder;
import universalelectricity.core.net.Network;
import universalelectricity.core.net.NetworkTickHandler;
/**
* A mechanical network for translate speed and force using mechanical rotations.
*
* Useful Formula:
*
* Power is the work per unit time.
* Power (W) = Torque (Strength of the rotation, Newton Meters) x Speed (Angular Velocity, RADIAN
* PER SECOND).
* *OR*
* Power = Torque / Time
*
* Torque = r (Radius) * F (Force) * sin0 (Direction/Angle of the force applied. 90 degrees if
* optimal.)
*
* @author DarkGuardsman
*/
public class MechanicalNetwork extends Network<IMechanicalNetwork, IMechanicalConnector, IMechanical> implements IMechanicalNetwork
{
private int force = 0;
private int speed = 0;
private int resistance = 0;
private HashMap<IMechanical, ForceWrapper[]> forceMap = new HashMap<IMechanical, ForceWrapper[]>();
@Override
public void update()
{
}
@Override
public void reconstruct()
{
if (this.getConnectors().size() > 0)
{
// Reset all values related to wires
this.getNodes().clear();
this.forceMap.clear();
this.resistance = 0;
this.force = 0;
this.speed = 0;
// Iterate threw list of wires
Iterator<IMechanicalConnector> it = this.getConnectors().iterator();
while (it.hasNext())
{
IMechanicalConnector conductor = it.next();
if (conductor != null)
{
this.reconstructConductor(conductor);
}
else
{
it.remove();
}
}
if (this.getNodes().size() > 0)
{
NetworkTickHandler.addNetwork(this);
}
}
}
/** Segmented out call so overriding can be done when conductors are reconstructed. */
protected void reconstructConductor(IMechanicalConnector conductor)
{
conductor.setNetwork(this);
for (int i = 0; i < conductor.getConnections().length; i++)
{
reconstructHandler(conductor.getConnections()[i], ForgeDirection.getOrientation(i).getOpposite());
}
this.resistance += conductor.getResistance();
}
/** Segmented out call so overriding can be done when machines are reconstructed. */
protected void reconstructHandler(Object obj, ForgeDirection side)
{
if (obj != null && !(obj instanceof IMechanicalConnector))
{
if (obj instanceof IMechanical)
{
ForceWrapper[] set = this.forceMap.get((IMechanical) obj);
if (set == null)
{
set = new ForceWrapper[6];
}
this.getNodes().add((IMechanical) obj);
set[side.ordinal()] = new ForceWrapper(((IMechanical) obj).getForceSide(side.getOpposite()), ((IMechanical) obj).getForceSide(side.getOpposite()));
this.forceMap.put((IMechanical) obj, set);
}
}
}
@Override
public boolean canUpdate()
{
return true;
}
@Override
public boolean continueUpdate()
{
return true;
}
@Override
public IMechanicalNetwork merge(IMechanicalNetwork network)
{
if (network.getClass().isAssignableFrom(this.getClass()) && network != this)
{
MechanicalNetwork newNetwork = new MechanicalNetwork();
newNetwork.getConnectors().addAll(this.getConnectors());
newNetwork.getConnectors().addAll(network.getConnectors());
network.getConnectors().clear();
network.getNodes().clear();
this.getConnectors().clear();
this.getNodes().clear();
newNetwork.reconstruct();
return newNetwork;
}
return null;
}
@Override
public void split(IMechanicalConnector splitPoint)
{
this.removeConnector(splitPoint);
this.reconstruct();
/**
* Loop through the connected blocks and attempt to see if there are connections between the
* two points elsewhere.
*/
Object[] connectedBlocks = splitPoint.getConnections();
for (int i = 0; i < connectedBlocks.length; i++)
{
Object connectedBlockA = connectedBlocks[i];
if (connectedBlockA instanceof IMechanicalConnector)
{
for (int ii = 0; ii < connectedBlocks.length; ii++)
{
final Object connectedBlockB = connectedBlocks[ii];
if (connectedBlockA != connectedBlockB && connectedBlockB instanceof IMechanicalConnector)
{
ConnectionPathfinder finder = new ConnectionPathfinder((IConnector) connectedBlockB, splitPoint);
finder.findNodes((IConnector) connectedBlockA);
if (finder.results.size() <= 0)
{
try
{
/**
* The connections A and B are not connected anymore. Give them both
* a new common network.
*/
IMechanicalNetwork newNetwork = new MechanicalNetwork();
for (IConnector node : finder.closedSet)
{
if (node != splitPoint && node instanceof IMechanicalConnector)
{
newNetwork.addConnector((IMechanicalConnector) node);
}
}
newNetwork.reconstruct();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
}
}
}
@Override
public void split(IMechanicalConnector connectorA, IMechanicalConnector connectorB)
{
this.reconstruct();
/** Check if connectorA connects with connectorB. */
ConnectionPathfinder finder = new ConnectionPathfinder(connectorB);
finder.findNodes(connectorA);
if (finder.results.size() <= 0)
{
/**
* The connections A and B are not connected anymore. Give them both a new common
* network.
*/
IMechanicalNetwork newNetwork = new MechanicalNetwork();
for (IConnector node : finder.closedSet)
{
if (node instanceof IMechanicalConnector)
{
newNetwork.addConnector((IMechanicalConnector) node);
}
}
newNetwork.reconstruct();
}
}
@Override
public int getTorque()
{
return this.force;
}
@Override
public int getAngularVelocity()
{
return this.speed;
}
public static class ForceWrapper
{
public int force = 0;
public int speed = 0;
public ForceWrapper(int force, int speed)
{
this.force = force;
this.speed = speed;
}
}
@Override
public long getPower()
{
return this.getTorque() * this.getAngularVelocity();
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB