New gear rotation calculation algorithm

This commit is contained in:
Calclavia 2014-01-20 22:28:02 +08:00
parent fea61d5241
commit bc81e18874
16 changed files with 227 additions and 482 deletions

View file

@ -3,14 +3,14 @@ package resonantinduction.api;
import java.util.List;
import net.minecraft.entity.Entity;
import resonantinduction.mechanical.network.IMechanicalConnector;
import resonantinduction.mechanical.network.IMechanical;
/**
* An interface applied to the tile entity of a conveyor belt
*
* @Author DarkGuardsman
*/
public interface IBelt extends IMechanicalConnector
public interface IBelt extends IMechanical
{
/**
* Used to get a list of entities the belt exerts an effect upon.

View file

@ -45,11 +45,11 @@ public class RenderBattery extends TileEntitySpecialRenderer
GL11.glRotatef(90 * i, 0, 1, 0);
ForgeDirection dir = ForgeDirection.getOrientation(i);
FMLClientHandler.instance().getClient().renderEngine.bindTexture(TEXTURE_LEVELS);
MODEL.renderPart("Battery");
if (t.worldObj != null)
{
FMLClientHandler.instance().getClient().renderEngine.bindTexture(TEXTURE_LEVELS);
MODEL.renderPart("Battery");
// Render top and bottom
//if (!(new Vector3(t).translate(dir).getTileEntity(t.worldObj) instanceof TileBattery))
{
@ -81,6 +81,10 @@ public class RenderBattery extends TileEntitySpecialRenderer
if (new Vector3(t).translate(ForgeDirection.UP).getTileEntity(t.worldObj) instanceof TileBattery)
MODEL.renderPart("VertConnector");
}else
{
FMLClientHandler.instance().getClient().renderEngine.bindTexture(TEXTURE_CAP);
MODEL.renderAll();
}
glPopMatrix();

View file

@ -6,6 +6,8 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import resonantinduction.mechanical.network.IMechanical;
import resonantinduction.mechanical.network.IMechanicalNetwork;
import resonantinduction.mechanical.network.MechanicalNetwork;
import universalelectricity.api.energy.EnergyStorageHandler;
import universalelectricity.api.vector.Vector3;
import calclavia.lib.prefab.tile.IRotatable;
@ -18,6 +20,8 @@ import calclavia.lib.prefab.tile.TileElectrical;
*/
public class TileGenerator extends TileElectrical implements IMechanical, IRotatable
{
private IMechanicalNetwork network;
/** Generator turns KE -> EE. Inverted one will turn EE -> KE. */
public boolean isInversed = false;
@ -41,6 +45,7 @@ public class TileGenerator extends TileElectrical implements IMechanical, IRotat
{
if (!isInversed)
{
energy.receiveEnergy(getNetwork().getPower(), true);
produce();
}
else
@ -53,7 +58,7 @@ public class TileGenerator extends TileElectrical implements IMechanical, IRotat
public void produceMechanical(ForgeDirection outputDir)
{
Vector3 outputVector = new Vector3(this).modifyPositionFromSide(outputDir);
Vector3 outputVector = new Vector3(this).translate(outputDir);
TileEntity mechanical = outputVector.getTileEntity(worldObj);
if (mechanical instanceof IMechanical)
@ -64,7 +69,7 @@ public class TileGenerator extends TileElectrical implements IMechanical, IRotat
{
float angularVelocity = extract / torqueRatio;
long torque = (long) (extract / angularVelocity);
energy.extractEnergy(((IMechanical) mechanical).onReceiveEnergy(outputDir.getOpposite(), torque, angularVelocity, true), true);
energy.extractEnergy(((IMechanical) mechanical).getNetwork().onReceiveEnergy(((IMechanical) mechanical), torque, angularVelocity), true);
}
}
}
@ -94,7 +99,6 @@ public class TileGenerator extends TileElectrical implements IMechanical, IRotat
public void setDirection(ForgeDirection dir)
{
this.worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, dir.ordinal(), 3);
}
private boolean isFunctioning()
@ -102,16 +106,6 @@ public class TileGenerator extends TileElectrical implements IMechanical, IRotat
return true;
}
@Override
public long onReceiveEnergy(ForgeDirection from, long torque, float angularVelocity, boolean doReceive)
{
if (!this.isInversed)
{
return energy.receiveEnergy((long) (torque * angularVelocity), doReceive);
}
return 0;
}
@Override
public void readFromNBT(NBTTagCompound nbt)
{
@ -140,4 +134,47 @@ public class TileGenerator extends TileElectrical implements IMechanical, IRotat
}
@Override
public Object[] getConnections()
{
Object[] connections = new Object[6];
connections[getDirection().ordinal()] = new Vector3(this).translate(getDirection()).getTileEntity(worldObj);
return connections;
}
@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 boolean sendNetworkPacket(long torque, float angularVelocity)
{
return false;
}
@Override
public float getResistance()
{
return 0;
}
@Override
public boolean isRotationInversed()
{
return false;
}
}

View file

@ -18,7 +18,6 @@ public class MultipartMechanical implements IPartFactory
MultiPartRegistry.registerParts(this, PART_TYPES);
MultipartGenerator.registerPassThroughInterface("resonantinduction.api.fluid.IFluidPipe");
MultipartGenerator.registerTrait("resonantinduction.mechanical.network.IMechanical", "resonantinduction.mechanical.trait.TraitMechanical");
MultipartGenerator.registerTrait("resonantinduction.mechanical.network.IMechanicalConnector", "resonantinduction.mechanical.trait.TraitMechanicalConnector");
}
@Override

View file

@ -15,7 +15,6 @@ import resonantinduction.api.IBelt;
import resonantinduction.core.ResonantInduction;
import resonantinduction.mechanical.Mechanical;
import resonantinduction.mechanical.network.IMechanical;
import resonantinduction.mechanical.network.IMechanicalConnector;
import resonantinduction.mechanical.network.TileMechanical;
import universalelectricity.api.vector.Vector3;
import calclavia.lib.network.IPacketReceiverWithID;
@ -30,7 +29,7 @@ import cpw.mods.fml.common.network.PacketDispatcher;
*
* @author DarkGuardsman
*/
public class TileConveyorBelt extends TileMechanical implements IMechanicalConnector, IBelt, IRotatable, IPacketReceiverWithID
public class TileConveyorBelt extends TileMechanical implements IBelt, IRotatable, IPacketReceiverWithID
{
public enum SlantType
{

View file

@ -4,7 +4,7 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.MovingObjectPosition;
import resonantinduction.mechanical.Mechanical;
import resonantinduction.mechanical.network.IMechanicalConnector;
import resonantinduction.mechanical.network.IMechanical;
import resonantinduction.mechanical.network.PartMechanical;
import codechicken.lib.vec.Vector3;
import cpw.mods.fml.relauncher.Side;
@ -16,7 +16,7 @@ import cpw.mods.fml.relauncher.SideOnly;
* @author Calclavia
*
*/
public class PartGear extends PartMechanical implements IMechanicalConnector
public class PartGear extends PartMechanical implements IMechanical
{
private int manualCrankTime = 0;
@ -27,7 +27,7 @@ public class PartGear extends PartMechanical implements IMechanicalConnector
{
if (manualCrankTime > 0)
{
onReceiveEnergy(null, 20, 0.2f, true);
manualCrankTime--;
}
}
@ -38,15 +38,16 @@ public class PartGear extends PartMechanical implements IMechanicalConnector
@Override
public float getResistance()
{
return 0.1f;
return 0.5f;
}
@Override
public boolean activate(EntityPlayer player, MovingObjectPosition hit, ItemStack item)
{
// System.out.println(world().isRemote + ": " + getNetwork());
System.out.println(world().isRemote + ": " + getNetwork());
if (player.isSneaking())
{
getNetwork().onReceiveEnergy(this, 20, 0.3f);
this.manualCrankTime = 20;
}
@ -65,10 +66,16 @@ public class PartGear extends PartMechanical implements IMechanicalConnector
{
if (pass == 0)
{
RenderGear.INSTANCE.renderDynamic(this, pos.x, pos.y, pos.z);
RenderGear.INSTANCE.renderDynamic(this, pos.x, pos.y, pos.z, frame);
}
}
@Override
public boolean isRotationInversed()
{
return true;
}
@Override
public String getType()
{

View file

@ -29,7 +29,7 @@ public class RenderGear
GL11.glPopMatrix();
}
public void renderDynamic(PartGear part, double x, double y, double z)
public void renderDynamic(PartGear part, double x, double y, double z, float frame)
{
GL11.glPushMatrix();
// Center the model first.
@ -63,7 +63,7 @@ public class RenderGear
break;
}
GL11.glRotatef((float) Math.toDegrees(part.angle), 0, 1, 0);
GL11.glRotatef((float) Math.toDegrees(part.isClockwise() ? part.getNetwork().getRotation() : -part.getNetwork().getRotation()), 0, 1, 0);
FMLClientHandler.instance().getClient().renderEngine.bindTexture(TEXTURE);
MODEL.renderAll();

View file

@ -1,20 +1,23 @@
package resonantinduction.mechanical.network;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.api.net.IConnectable;
import universalelectricity.api.net.IConnector;
public interface IMechanical extends IConnectable
public interface IMechanical extends IConnector<IMechanicalNetwork>
{
/**
* Adds energy to a block. Returns the quantity of energy that was accepted. This should always
* return 0 if the block cannot be externally charged.
* Uses this connector to send a packet to the client for the network.
*
* @param from Orientation the energy is sent in from.
* @param receive Maximum amount of energy (joules) to be sent into the block.
* @param doReceive If false, the charge will only be simulated.
* @return Amount of energy that was accepted by the block.
* @return True if the packet was successfully sent.
*/
public long onReceiveEnergy(ForgeDirection from, long torque, float angularVelocity, boolean doReceive);
public boolean sendNetworkPacket(long torque, float angularVelocity);
/**
* The percentage of resistance caused by this connector.
*
* @return A small value, most likely less than one.
*/
public float getResistance();
/**
* @return Is the mechanical machine going clockwise currently?
@ -22,4 +25,11 @@ public interface IMechanical extends IConnectable
public boolean isClockwise();
public void setClockwise(boolean isClockwise);
/**
* *
*
* @return Return true if the mechanical block should have its rotation set inveresed.
*/
public boolean isRotationInversed();
}

View file

@ -1,25 +0,0 @@
package resonantinduction.mechanical.network;
import universalelectricity.api.net.IConnector;
/**
* Applied to connectors in a mechanical network
*
* @author Calclavia
*/
public interface IMechanicalConnector extends IMechanical, IConnector<IMechanicalNetwork>
{
/**
* Uses this connector to send a packet to the client for the network.
*
* @return True if the packet was successfully sent.
*/
public boolean sendNetworkPacket(long torque, float angularVelocity);
/**
* The percentage of resistance caused by this connector.
*
* @return A small value, most likely less than one.
*/
public float getResistance();
}

View file

@ -1,13 +1,13 @@
package resonantinduction.mechanical.network;
import universalelectricity.api.net.INodeNetwork;
import universalelectricity.api.net.INetwork;
/**
* Mechanical network in interface form for interaction or extension
*
* @author DarkGuardsman
*/
public interface IMechanicalNetwork extends INodeNetwork<IMechanicalNetwork, IMechanicalConnector, IMechanical>
public interface IMechanicalNetwork extends INetwork<IMechanicalNetwork, IMechanical>
{
/**
* Gets the power of the network.
@ -32,11 +32,7 @@ public interface IMechanicalNetwork extends INodeNetwork<IMechanicalNetwork, IMe
public float getPrevAngularVelocity();
/** Called to rebuild the network */
@Override
public void reconstruct();
public long onReceiveEnergy(long torque, float angularVelocity);
public long onReceiveEnergy(IMechanical source, long torque, float angularVelocity);
/**
* @return The current rotation value of the network.

View file

@ -4,11 +4,13 @@ import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Set;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.api.net.IUpdate;
import universalelectricity.core.net.Network;
import universalelectricity.core.net.NetworkTickHandler;
import universalelectricity.core.net.NodeNetwork;
/**
* A mechanical network for translate speed and force using mechanical rotations.
@ -26,7 +28,7 @@ import universalelectricity.core.net.NodeNetwork;
*
* @author Calclavia
*/
public class MechanicalNetwork extends NodeNetwork<IMechanicalNetwork, IMechanicalConnector, IMechanical> implements IMechanicalNetwork, IUpdate
public class MechanicalNetwork extends Network<IMechanicalNetwork, IMechanical> implements IMechanicalNetwork, IUpdate
{
private long prevTorque = 0;
private float prevAngularVelocity = 0;
@ -35,7 +37,7 @@ public class MechanicalNetwork extends NodeNetwork<IMechanicalNetwork, IMechanic
private float angularVelocity = 0;
/** The cached resistance caused by all connectors */
private float connectorResistance = 0;
private float load = 0;
/** The current rotation of the network */
private float rotation = 0;
@ -45,8 +47,11 @@ public class MechanicalNetwork extends NodeNetwork<IMechanicalNetwork, IMechanic
/** The direction in which a conductor is placed relative to a specific conductor. */
protected final HashMap<Object, EnumSet<ForgeDirection>> handlerDirectionMap = new LinkedHashMap<Object, EnumSet<ForgeDirection>>();
private Set<IMechanical> prevGenerators = new LinkedHashSet<IMechanical>();
private Set<IMechanical> generators = new LinkedHashSet<IMechanical>();
@Override
public void addConnector(IMechanicalConnector connector)
public void addConnector(IMechanical connector)
{
this.markPacketUpdate = true;
super.addConnector(connector);
@ -58,26 +63,29 @@ public class MechanicalNetwork extends NodeNetwork<IMechanicalNetwork, IMechanic
@Override
public void update()
{
/**
* Calculation rotations of all generators.
*/
prevGenerators = generators;
Set<IMechanical> closedSet = new LinkedHashSet<IMechanical>();
for (IMechanical generatorNode : generators)
{
PathfinderRotationManager rotationPathfinder = new PathfinderRotationManager(generatorNode, closedSet);
rotationPathfinder.findNodes(generatorNode);
closedSet.addAll(rotationPathfinder.closedSet);
}
generators.clear();
/**
* Calculate load
*/
if (getPower() > 0)
if (load > 0)
{
float division = connectorResistance;
for (IMechanical node : this.getNodes())
{
for (ForgeDirection dir : handlerDirectionMap.get(node))
{
division += node.onReceiveEnergy(dir, torque, angularVelocity, false) / torque;
}
}
if (division > 0)
{
torque /= division / 2;
angularVelocity /= division / 2;
}
torque /= load / 2;
angularVelocity /= load / 2;
}
/**
@ -88,7 +96,7 @@ public class MechanicalNetwork extends NodeNetwork<IMechanicalNetwork, IMechanic
/**
* Send network update packet for connectors.
*/
for (IMechanicalConnector connector : this.getConnectors())
for (IMechanical connector : this.getConnectors())
{
if (connector.sendNetworkPacket(torque, angularVelocity))
{
@ -97,24 +105,22 @@ public class MechanicalNetwork extends NodeNetwork<IMechanicalNetwork, IMechanic
}
}
/**
* Distribute energy to handlers
*/
if (getPower() > 0)
{
for (IMechanical node : this.getNodes())
{
for (ForgeDirection dir : handlerDirectionMap.get(node))
{
node.onReceiveEnergy(dir, torque, angularVelocity, true);
}
}
}
prevTorque = torque;
prevAngularVelocity = angularVelocity;
torque = 0;
angularVelocity = 0;
torque *= 0.5;
angularVelocity *= 0.5;
}
@Override
public boolean canUpdate()
{
return true;
}
@Override
public boolean continueUpdate()
{
return canUpdate();
}
/**
@ -122,10 +128,11 @@ public class MechanicalNetwork extends NodeNetwork<IMechanicalNetwork, IMechanic
* Note: Server side only.
*/
@Override
public long onReceiveEnergy(long torque, float angularVelocity)
public long onReceiveEnergy(IMechanical source, long torque, float angularVelocity)
{
this.torque += torque;
this.angularVelocity += angularVelocity;
this.generators.add(source);
NetworkTickHandler.addNetwork(this);
return (long) (torque * angularVelocity);
}
@ -169,67 +176,28 @@ public class MechanicalNetwork extends NodeNetwork<IMechanicalNetwork, IMechanic
this.angularVelocity = angularVelocity;
}
@Override
public boolean canUpdate()
{
return true;
}
@Override
public boolean continueUpdate()
{
return true;
}
@Override
public void reconstruct()
{
// Reset
prevTorque = torque = 0;
prevAngularVelocity = angularVelocity = 0;
connectorResistance = 0;
load = 0;
if (this.getConnectors().size() > 0)
{
// Reset all values related to wires
this.getNodes().clear();
// Iterate threw list of wires
Iterator<IMechanicalConnector> it = this.getConnectors().iterator();
while (it.hasNext())
{
IMechanicalConnector connector = it.next();
if (connector != null)
{
reconstructConnector(connector);
}
else
{
it.remove();
}
}
}
super.reconstruct();
}
/** Segmented out call so overriding can be done when conductors are reconstructed. */
protected void reconstructConnector(IMechanicalConnector connector)
@Override
protected void reconstructConnector(IMechanical connector)
{
connector.setNetwork(this);
for (int i = 0; i < connector.getConnections().length; i++)
{
reconstructHandler(connector.getConnections()[i], ForgeDirection.getOrientation(i).getOpposite());
}
connectorResistance += connector.getResistance();
load += connector.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 != null && !(obj instanceof IMechanical))
{
if (obj instanceof IMechanical)
{
@ -238,7 +206,7 @@ public class MechanicalNetwork extends NodeNetwork<IMechanicalNetwork, IMechanic
{
set = EnumSet.noneOf(ForgeDirection.class);
}
this.getNodes().add((IMechanical) obj);
this.getConnectors().add((IMechanical) obj);
set.add(side);
this.handlerDirectionMap.put(obj, set);
}
@ -252,7 +220,7 @@ public class MechanicalNetwork extends NodeNetwork<IMechanicalNetwork, IMechanic
if (deltaTime > 1)
{
rotation = (float) (((angularVelocity) * (deltaTime / 1000f) + rotation) % Math.PI);
rotation = (float) (((angularVelocity) * (deltaTime / 1000f) + rotation) % (2 * Math.PI));
lastRotateTime = System.currentTimeMillis();
}
@ -268,6 +236,6 @@ public class MechanicalNetwork extends NodeNetwork<IMechanicalNetwork, IMechanic
@Override
public String toString()
{
return this.getClass().getSimpleName() + "[" + this.hashCode() + ", Handlers: " + getNodes().size() + ", Connectors: " + getConnectors().size() + ", Power:" + getPower() + "]";
return this.getClass().getSimpleName() + "[" + this.hashCode() + ", Handlers: " + getConnectors().size() + ", Connectors: " + getConnectors().size() + ", Power:" + getPower() + "]";
}
}

View file

@ -28,7 +28,7 @@ import codechicken.multipart.TileMultipart;
* @author Calclavia
*
*/
public abstract class PartMechanical extends JCuboidPart implements JNormalOcclusion, TFacePart, IMechanicalConnector
public abstract class PartMechanical extends JCuboidPart implements JNormalOcclusion, TFacePart, IMechanical
{
public static Cuboid6[][] oBoxes = new Cuboid6[6][2];
@ -60,22 +60,15 @@ public abstract class PartMechanical extends JCuboidPart implements JNormalOcclu
/** The current angle the gear is on. In radians per second. */
public float angle = 0;
/** When true, it will start marking nearby gears for update */
public boolean markRotationUpdate = true;
public void preparePlacement(int side, int itemDamage)
{
this.placementSide = ForgeDirection.getOrientation((byte) (side ^ 1));
}
// TODO: We don't need to tick.
@Override
public void update()
{
if (markRotationUpdate)
{
updateRotations();
}
if (this.world().isRemote)
{
/**
@ -89,61 +82,6 @@ public abstract class PartMechanical extends JCuboidPart implements JNormalOcclu
angle -= getNetwork().getAngularVelocity() / 20f;
}
}
}
/**
* Updates rotations of all nearby gears.
*/
public void updateRotations()
{
/** 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);
TileEntity tile = vec.getTileEntity(world());
if (tile instanceof TileMultipart)
{
TMultiPart neighbor = ((TileMultipart) tile).partMap(this.placementSide.getOpposite().ordinal());
if (neighbor instanceof PartMechanical)
{
equateRotation((PartMechanical) neighbor, false);
}
}
/** Look for gears outside this block space, the relative UP, DOWN, LEFT, RIGHT */
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 (checkTile instanceof TileMultipart)
{
TMultiPart neighbor = ((TileMultipart) checkTile).partMap(this.placementSide.ordinal());
if (neighbor != this && neighbor instanceof PartMechanical)
{
equateRotation((PartMechanical) neighbor, false);
}
}
}
/** Look for gears that are internal and adjacent to this gear. (The 2 sides) */
for (int i = 0; i < 6; i++)
{
ForgeDirection checkDir = ForgeDirection.getOrientation(i);
TMultiPart neighbor = tile().partMap(this.placementSide.getRotation(checkDir).ordinal());
if (neighbor != this && neighbor instanceof PartMechanical)
{
equateRotation((PartMechanical) neighbor, false);
}
}
markRotationUpdate = false;
}
@Override
@ -185,7 +123,7 @@ public abstract class PartMechanical extends JCuboidPart implements JNormalOcclu
public void refresh()
{
/** 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);
universalelectricity.api.vector.Vector3 vec = new universalelectricity.api.vector.Vector3(tile()).translate(placementSide);
TileEntity tile = vec.getTileEntity(world());
@ -193,18 +131,18 @@ public abstract class PartMechanical extends JCuboidPart implements JNormalOcclu
{
TMultiPart neighbor = ((TileMultipart) tile).partMap(this.placementSide.getOpposite().ordinal());
if (neighbor instanceof IMechanicalConnector)
if (neighbor instanceof IMechanical)
{
connections[this.placementSide.getOpposite().ordinal()] = neighbor;
getNetwork().merge(((IMechanicalConnector) neighbor).getNetwork());
getNetwork().merge(((IMechanical) neighbor).getNetwork());
}
}
else if (tile instanceof IMechanical)
{
connections[this.placementSide.getOpposite().ordinal()] = tile;
if (tile instanceof IMechanicalConnector)
if (tile instanceof IMechanical)
{
getNetwork().merge(((IMechanicalConnector) tile).getNetwork());
getNetwork().merge(((IMechanical) tile).getNetwork());
}
}
@ -212,18 +150,17 @@ public abstract class PartMechanical extends JCuboidPart implements JNormalOcclu
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);
universalelectricity.api.vector.Vector3 checkVec = new universalelectricity.api.vector.Vector3(tile()).translate(checkDir);
TileEntity checkTile = checkVec.getTileEntity(world());
if (checkTile instanceof TileMultipart)
{
TMultiPart neighbor = ((TileMultipart) checkTile).partMap(this.placementSide.ordinal());
if (neighbor != this && neighbor instanceof PartMechanical)
if (neighbor != this && neighbor instanceof IMechanical)
{
connections[checkDir.ordinal()] = neighbor;
getNetwork().merge(((PartMechanical) neighbor).getNetwork());
getNetwork().merge(((IMechanical) neighbor).getNetwork());
}
}
}
@ -234,10 +171,10 @@ public abstract class PartMechanical extends JCuboidPart implements JNormalOcclu
ForgeDirection checkDir = ForgeDirection.getOrientation(i);
TMultiPart neighbor = tile().partMap(this.placementSide.getRotation(checkDir).ordinal());
if (neighbor != this && neighbor instanceof PartMechanical)
if (neighbor != this && neighbor instanceof IMechanical)
{
connections[checkDir.ordinal()] = neighbor;
getNetwork().merge(((PartMechanical) neighbor).getNetwork());
getNetwork().merge(((IMechanical) neighbor).getNetwork());
}
}
@ -255,35 +192,6 @@ public abstract class PartMechanical extends JCuboidPart implements JNormalOcclu
return connections;
}
public void equateRotation(PartMechanical neighbor, boolean isPositive)
{
if (!neighbor.markRotationUpdate)
{
if (isPositive)
{
neighbor.setClockwise(isClockwise);
}
else
{
neighbor.setClockwise(!isClockwise);
}
neighbor.markRotationUpdate = true;
}
}
@Override
public long onReceiveEnergy(ForgeDirection from, long torque, float angularVelocity, boolean doReceive)
{
if (!world().isRemote && doReceive)
{
getNetwork().onReceiveEnergy(torque, angularVelocity);
markRotationUpdate = true;
}
return (long) (torque * angularVelocity);
}
@Override
public void preRemove()
{
@ -295,7 +203,7 @@ public abstract class PartMechanical extends JCuboidPart implements JNormalOcclu
@Override
public boolean sendNetworkPacket(long torque, float angularVelocity)
{
if (tile() != null)
if (!world().isRemote && tile() != null)
{
tile().getWriteStream(this).writeByte(0).writeLong(torque).writeFloat(angularVelocity).writeBoolean(isClockwise);
}
@ -317,7 +225,6 @@ public abstract class PartMechanical extends JCuboidPart implements JNormalOcclu
{
getNetwork().setPower(packet.readLong(), packet.readFloat());
isClockwise = packet.readBoolean();
markRotationUpdate = true;
}
else if (packetID == 1)
{
@ -348,7 +255,7 @@ public abstract class PartMechanical extends JCuboidPart implements JNormalOcclu
@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;
return new universalelectricity.api.vector.Vector3(this.x() + direction.offsetX, this.y() + direction.offsetY, this.z() + direction.offsetZ).getTileEntity(this.world()) instanceof IMechanical;
}
@Override

View file

@ -8,6 +8,7 @@ import java.util.List;
import java.util.Set;
import universalelectricity.api.net.IConnector;
import universalelectricity.core.net.ConnectionPathfinder;
/**
* Sets proper rotations on all connected units in the mechanical network.
@ -18,92 +19,40 @@ import universalelectricity.api.net.IConnector;
* @author Calclavia
*
*/
public class PathfinderRotationManager
public class PathfinderRotationManager extends ConnectionPathfinder<IMechanical>
{
/** A list of nodes that the pathfinder already went through. */
public final Set<IConnector> closedSet = new LinkedHashSet<IConnector>();
private boolean currentIsClockwise = true;
private Set<IMechanical> prevClosedSet;
/** The resulted path found by the pathfinder. Could be null if no path was found. */
public final Set<IConnector> results = new LinkedHashSet<IConnector>();
private final IConnector targetConnector;
private final List<IConnector> ignoreConnector;
public PathfinderRotationManager(IConnector targetConnector, IConnector... ignoreConnector)
public PathfinderRotationManager(IMechanical first, Set<IMechanical> prevClosedSet)
{
this.targetConnector = targetConnector;
if (ignoreConnector != null)
{
this.ignoreConnector = Arrays.asList(ignoreConnector);
}
else
{
this.ignoreConnector = new ArrayList<IConnector>();
}
super(first);
this.currentIsClockwise = first.isClockwise();
this.prevClosedSet = prevClosedSet;
}
/**
* A recursive function to find all connectors.
*
* @return True on success finding, false on failure.
*/
public boolean findNodes(IConnector currentNode)
public boolean findNodes(IMechanical currentNode)
{
this.closedSet.add(currentNode);
if (this.onSearch(currentNode))
{
return false;
}
currentNode.setClockwise(currentIsClockwise);
currentIsClockwise = !currentNode.isClockwise();
for (IConnector node : this.getConnectedNodes(currentNode))
for (IMechanical node : this.getConnectedNodes(currentNode))
{
if (!this.closedSet.contains(node))
{
if (this.findNodes(node))
if (prevClosedSet.contains(node) && node.isClockwise() != currentNode.isClockwise())
{
return true;
// We have conflicting gears. Network is now equal.
currentNode.getNetwork().setPower(0, 0);
}
findNodes(node);
currentIsClockwise = node.isRotationInversed() ? !currentNode.isClockwise() : currentNode.isClockwise();
}
}
return false;
}
public Set<IConnector> getConnectedNodes(IConnector currentNode)
{
Set<IConnector> connectedNodes = new HashSet<IConnector>();
if (currentNode != null)
{
for (int i = 0; i < currentNode.getConnections().length; i++)
{
Object obj = currentNode.getConnections()[i];
if (obj instanceof IConnector && !this.ignoreConnector.contains(obj))
{
connectedNodes.add((IConnector) obj);
}
}
}
return connectedNodes;
}
public boolean onSearch(IConnector node)
{
if (node == this.targetConnector)
{
this.results.add(node);
return true;
}
return false;
}
public void reset()
{
this.results.clear();
this.closedSet.clear();
}
}

View file

@ -3,7 +3,7 @@ package resonantinduction.mechanical.network;
import net.minecraftforge.common.ForgeDirection;
import calclavia.lib.prefab.tile.TileAdvanced;
public class TileMechanical extends TileAdvanced implements IMechanicalConnector
public class TileMechanical extends TileAdvanced implements IMechanical
{
/** The mechanical connections this connector has made */
protected Object[] connections = new Object[6];
@ -12,12 +12,6 @@ public class TileMechanical extends TileAdvanced implements IMechanicalConnector
private boolean isClockwise = false;
@Override
public long onReceiveEnergy(ForgeDirection from, long torque, float angularVelocity, boolean doReceive)
{
return this.getNetwork().onReceiveEnergy(torque, angularVelocity);
}
@Override
public boolean canConnect(ForgeDirection direction)
{
@ -70,4 +64,10 @@ public class TileMechanical extends TileAdvanced implements IMechanicalConnector
{
this.isClockwise = isClockwise;
}
@Override
public boolean isRotationInversed()
{
return false;
}
}

View file

@ -5,6 +5,7 @@ import java.util.Set;
import net.minecraftforge.common.ForgeDirection;
import resonantinduction.mechanical.network.IMechanical;
import resonantinduction.mechanical.network.IMechanicalNetwork;
import codechicken.multipart.TMultiPart;
import codechicken.multipart.TileMultipart;
@ -66,22 +67,6 @@ public class TraitMechanical extends TileMultipart implements IMechanical
return false;
}
@Override
public long onReceiveEnergy(ForgeDirection from, long torque, float angularVelocity, boolean doReceive)
{
TMultiPart part = this.partMap(from.ordinal());
if (part != null)
{
if (this.mechanicalInterfaces.contains(part))
{
return ((IMechanical) part).onReceiveEnergy(from, torque, angularVelocity, doReceive);
}
}
return 0;
}
@Override
public boolean isClockwise()
{
@ -93,4 +78,40 @@ public class TraitMechanical extends TileMultipart implements IMechanical
{
}
@Override
public Object[] getConnections()
{
return null;
}
@Override
public IMechanicalNetwork getNetwork()
{
return null;
}
@Override
public void setNetwork(IMechanicalNetwork network)
{
}
@Override
public boolean sendNetworkPacket(long torque, float angularVelocity)
{
return false;
}
@Override
public float getResistance()
{
return 0;
}
@Override
public boolean isRotationInversed()
{
return false;
}
}

View file

@ -1,127 +0,0 @@
package resonantinduction.mechanical.trait;
import java.util.HashSet;
import java.util.Set;
import net.minecraftforge.common.ForgeDirection;
import resonantinduction.mechanical.network.IMechanicalConnector;
import resonantinduction.mechanical.network.IMechanicalNetwork;
import codechicken.multipart.TMultiPart;
import codechicken.multipart.TileMultipart;
public class TraitMechanicalConnector extends TileMultipart implements IMechanicalConnector
{
public Set<IMechanicalConnector> mechanicalConnectorInterfaces = new HashSet<IMechanicalConnector>();
@Override
public void copyFrom(TileMultipart that)
{
super.copyFrom(that);
if (that instanceof TraitMechanicalConnector)
{
this.mechanicalConnectorInterfaces = ((TraitMechanicalConnector) that).mechanicalConnectorInterfaces;
}
}
@Override
public void bindPart(TMultiPart part)
{
super.bindPart(part);
if (part instanceof IMechanicalConnector)
{
this.mechanicalConnectorInterfaces.add((IMechanicalConnector) part);
}
}
@Override
public void partRemoved(TMultiPart part, int p)
{
super.partRemoved(part, p);
if (part instanceof IMechanicalConnector)
{
this.mechanicalConnectorInterfaces.remove(part);
}
}
@Override
public void clearParts()
{
super.clearParts();
this.mechanicalConnectorInterfaces.clear();
}
@Override
public boolean canConnect(ForgeDirection direction)
{
for (IMechanicalConnector connector : this.mechanicalConnectorInterfaces)
{
if (connector.canConnect(direction.getOpposite()))
{
return true;
}
}
return false;
}
@Override
public long onReceiveEnergy(ForgeDirection from, long torque, float angularVelocity, boolean doReceive)
{
TMultiPart part = this.partMap(from.ordinal());
if (part != null)
{
if (this.mechanicalConnectorInterfaces.contains(part))
{
return ((IMechanicalConnector) part).onReceiveEnergy(from, torque, angularVelocity, doReceive);
}
}
return 0;
}
@Override
public Object[] getConnections()
{
return null;
}
@Override
public IMechanicalNetwork getNetwork()
{
return null;
}
@Override
public void setNetwork(IMechanicalNetwork network)
{
}
@Override
public boolean sendNetworkPacket(long torque, float angularVelocity)
{
return false;
}
@Override
public float getResistance()
{
return 0;
}
@Override
public boolean isClockwise()
{
return false;
}
@Override
public void setClockwise(boolean isClockwise)
{
}
}