Updated MechanicalNode, and gears to use new UE node prefabs

This commit is contained in:
Robert S 2014-08-16 04:01:05 -04:00
parent 91448bf592
commit fd2c71ec97
6 changed files with 80 additions and 232 deletions

View file

@ -89,9 +89,9 @@ public class DebugFrameMechanical extends FrameNodeDebug
@Override
public int getRowCount()
{
if (getNode() != null && getNode().getConnections() != null)
if (getNode() != null && getNode().getConnections(MechanicalNode.class) != null)
{
return getNode().getConnections().size();
return getNode().getConnections(MechanicalNode.class).size();
}
return 10;
}
@ -99,10 +99,10 @@ public class DebugFrameMechanical extends FrameNodeDebug
@Override
public Object getValueAt(int row, int col)
{
if (getNode() != null && getNode().getConnections() != null)
if (getNode() != null && getNode().getConnections(MechanicalNode.class) != null)
{
ForgeDirection dir = (ForgeDirection) getNode().getConnections().values().toArray()[row];
MechanicalNode node = (MechanicalNode) getNode().getConnections().keySet().toArray()[row];
ForgeDirection dir = (ForgeDirection) getNode().getConnections(MechanicalNode.class).values().toArray()[row];
MechanicalNode node = (MechanicalNode) getNode().getConnections(MechanicalNode.class).keySet().toArray()[row];
switch(col)
{
case 0: return dir;

View file

@ -11,67 +11,42 @@ import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import resonant.lib.utility.nbt.ISaveObj;
import resonantinduction.core.interfaces.IMechanicalNode;
import resonantinduction.core.prefab.node.MultipartNode;
import resonantinduction.mechanical.Mechanical;
import universalelectricity.api.core.grid.INode;
import universalelectricity.api.core.grid.INodeProvider;
import universalelectricity.core.transform.vector.IVectorWorld;
import universalelectricity.core.transform.vector.Vector3;
import codechicken.multipart.TMultiPart;
import universalelectricity.core.transform.vector.VectorWorld;
/**
* A resonantinduction.mechanical node for resonantinduction.mechanical energy.
*
* @author Calclavia, Darkguardsman
*/
public class MechanicalNode implements IMechanicalNode, ISaveObj, IVectorWorld
public class MechanicalNode extends MultipartNode implements IMechanicalNode, ISaveObj, IVectorWorld
{
/**
* Is debug enabled for the node
*/
public boolean doDebug = false;
/**
* Used to note that you should trigger a packet update for rotation
*/
public boolean markRotationUpdate = false;
public boolean markTorqueUpdate = false;
/**
* Which section of debug is enabled
*/
public int debugCue = 0, maxDebugCue = 1, minDebugCue = 0;
public static final int UPDATE_DEBUG = 0, CONNECTION_DEBUG = 1;
/**
* Rotational Force
*/
public double torque = 0, prevTorque;
/**
* Rotational speed
*/
public double prevAngularVelocity, angularVelocity = 0;
/**
* Rotational acceleration
*/
public double renderAngle = 0, prev_angle = 0;
public float acceleration = 2f;
/**
* The current rotation of the resonantinduction.mechanical node.
*/
public double renderAngle = 0, prev_angle = 0;
/**
* Limits the max distance an object can rotate in a single update
*/
protected double maxDeltaAngle = Math.toRadians(180);
protected double maxDeltaAngle = Math.toRadians(120);
protected double load = 2;
protected byte connectionMap = Byte.parseByte("111111", 2);
private double power = 0;
private INodeProvider parent;
private long ticks = 0;
private final AbstractMap<MechanicalNode, ForgeDirection> connections = new WeakHashMap<MechanicalNode, ForgeDirection>();
private long ticks = 0;
public MechanicalNode(INodeProvider parent)
{
this.setParent(parent);
super(parent);
}
@Override
@ -106,11 +81,6 @@ public class MechanicalNode implements IMechanicalNode, ISaveObj, IVectorWorld
{
ticks = 1;
}
//temp, TODO find a better way to trigger this
if (ticks % 100 == 0)
{
this.recache();
}
//-----------------------------------
// Render Update
//-----------------------------------
@ -164,55 +134,52 @@ public class MechanicalNode implements IMechanicalNode, ISaveObj, IVectorWorld
}
power = getEnergy() / deltaTime;
Iterator<Entry<Object, ForgeDirection>> it = connections.entrySet().iterator();
//-----------------------------------
// Connection application of force and speed
//-----------------------------------
synchronized (getConnections())
{
Iterator<Entry<MechanicalNode, ForgeDirection>> it = getConnections().entrySet().iterator();
while (it.hasNext())
{
MechanicalNode adjacentMech = null;
Entry<Object, ForgeDirection> entry = it.next();
ForgeDirection dir = entry.getValue();
while (it.hasNext())
{
Entry<MechanicalNode, ForgeDirection> entry = it.next();
if (entry.getKey() instanceof Mechanical) adjacentMech = (MechanicalNode) entry.getKey();
if (entry.getKey() instanceof INodeProvider)
{
INode node = ((INodeProvider) entry.getKey()).getNode(MechanicalNode.class, dir.getOpposite());
if(node instanceof MechanicalNode)
adjacentMech = (MechanicalNode) node;
}
if (adjacentMech != null)
{
/** Calculate angular velocity and torque. */
float ratio = adjacentMech.getRatio(dir.getOpposite(), this) / getRatio(dir, adjacentMech);
boolean inverseRotation = inverseRotation(dir, adjacentMech) && adjacentMech.inverseRotation(dir.getOpposite(), this);
ForgeDirection dir = entry.getValue();
MechanicalNode adjacentMech = entry.getKey();
/** Calculate angular velocity and torque. */
float ratio = adjacentMech.getRatio(dir.getOpposite(), this) / getRatio(dir, adjacentMech);
boolean inverseRotation = inverseRotation(dir, adjacentMech) && adjacentMech.inverseRotation(dir.getOpposite(), this);
int inversion = inverseRotation ? -1 : 1;
int inversion = inverseRotation ? -1 : 1;
double targetTorque = inversion * adjacentMech.getTorque() / ratio;
double applyTorque = targetTorque * acceleration;
double targetTorque = inversion * adjacentMech.getTorque() / ratio;
double applyTorque = targetTorque * acceleration;
if (Math.abs(torque + applyTorque) < Math.abs(targetTorque)) {
torque += applyTorque;
} else if (Math.abs(torque - applyTorque) > Math.abs(targetTorque)) {
torque -= applyTorque;
}
if (Math.abs(torque + applyTorque) < Math.abs(targetTorque))
{
torque += applyTorque;
}
else if (Math.abs(torque - applyTorque) > Math.abs(targetTorque))
{
torque -= applyTorque;
}
double targetVelocity = inversion * adjacentMech.getAngularSpeed() * ratio;
double applyVelocity = targetVelocity * acceleration;
double targetVelocity = inversion * adjacentMech.getAngularSpeed() * ratio;
double applyVelocity = targetVelocity * acceleration;
if (Math.abs(angularVelocity + applyVelocity) < Math.abs(targetVelocity)) {
angularVelocity += applyVelocity;
} else if (Math.abs(angularVelocity - applyVelocity) > Math.abs(targetVelocity)) {
angularVelocity -= applyVelocity;
}
if (Math.abs(angularVelocity + applyVelocity) < Math.abs(targetVelocity))
{
angularVelocity += applyVelocity;
}
else if (Math.abs(angularVelocity - applyVelocity) > Math.abs(targetVelocity))
{
angularVelocity -= applyVelocity;
}
/** Set all current rotations */
// adjacentMech.angle = Math.abs(angle) * (adjacentMech.angle >= 0 ? 1 : -1);
}
}
}
/** Set all current rotations */
// adjacentMech.angle = Math.abs(angle) * (adjacentMech.angle >= 0 ? 1 : -1);
}
}
}
onUpdate();
prev_angle = renderAngle;
@ -285,19 +252,6 @@ public class MechanicalNode implements IMechanicalNode, ISaveObj, IVectorWorld
return load;
}
/**
* Checks to see if a connection is allowed from side and from a source
*/
public boolean canConnect(ForgeDirection from, Object source)
{
if (source instanceof MechanicalNode)
{
boolean flag = (connectionMap & (1 << from.ordinal())) != 0;
return flag;
}
return false;
}
@Override
public double getEnergy()
{
@ -324,115 +278,14 @@ public class MechanicalNode implements IMechanicalNode, ISaveObj, IVectorWorld
nbt.setDouble("angularVelocity", angularVelocity);
}
@Override
public void reconstruct()
{
recache();
}
@Override
public void deconstruct()
{
for (Entry<MechanicalNode, ForgeDirection> entry : getConnections().entrySet())
{
entry.getKey().getConnections().remove(this);
entry.getKey().recache();
}
getConnections().clear();
}
public void recache()
{
synchronized (this)
{
getConnections().clear();
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS)
{
TileEntity tile = position().add(dir).getTileEntity(world());
if (tile instanceof INodeProvider)
{
INode node = ((INodeProvider) tile).getNode(MechanicalNode.class, dir.getOpposite());
if (node instanceof MechanicalNode)
{
MechanicalNode check = (MechanicalNode) node;
boolean canConnect = canConnect(dir, check);
boolean canOtherConnect = check.canConnect(dir.getOpposite(), this);
if (canConnect && canOtherConnect)
{
getConnections().put(check, dir);
}
}
}
}
}
}
/**
* Gets the node provider for this node
*/
public INodeProvider getParent()
{
return parent;
}
/**
* Sets the node provider for the node
*/
public void setParent(INodeProvider parent)
{
this.parent = parent;
}
@Override
public String toString()
{
return this.getClass().getSimpleName() + this.hashCode();
}
public AbstractMap<MechanicalNode, ForgeDirection> getConnections()
{
return connections;
}
@Override
public World world()
{
return getParent() instanceof TMultiPart ? ((TMultiPart) getParent()).world() : getParent() instanceof TileEntity ? ((TileEntity) getParent()).getWorldObj() : null;
}
public Vector3 position()
{
return new Vector3(x(), y(), z());
}
@Override
public double z()
{
if (this.getParent() instanceof TileEntity)
{
return ((TileEntity) this.getParent()).zCoord;
}
return this.getParent() instanceof TMultiPart && ((TMultiPart) this.getParent()).tile() != null ? ((TMultiPart) this.getParent()).z() : 0;
}
@Override
public double x()
{
if (this.getParent() instanceof TileEntity)
{
return ((TileEntity) this.getParent()).xCoord;
}
return this.getParent() instanceof TMultiPart && ((TMultiPart) this.getParent()).tile() != null ? ((TMultiPart) this.getParent()).x() : 0;
}
@Override
public double y()
{
if (this.getParent() instanceof TileEntity)
{
return ((TileEntity) this.getParent()).yCoord;
}
return this.getParent() instanceof TMultiPart && ((TMultiPart) this.getParent()).tile() != null ? ((TMultiPart) this.getParent()).y() : 0;
}
@Override
public boolean canConnect(ForgeDirection direction, Object object)
{
if(canConnect(direction)) {
if (object instanceof INodeProvider) {
return ((INodeProvider) object).getNode(MechanicalNode.class, direction.getOpposite()) instanceof MechanicalNode;
}
}
return false;
}
}

View file

@ -19,6 +19,7 @@ import codechicken.multipart.TFacePart;
import resonant.engine.ResonantEngine;
import universalelectricity.api.core.grid.INode;
import universalelectricity.api.core.grid.INodeProvider;
import universalelectricity.core.transform.vector.VectorWorld;
/** We assume all the force acting on the gear is 90 degrees.
*
@ -220,14 +221,14 @@ public abstract class PartMechanical extends JCuboidPart implements JNormalOcclu
return getItem();
}
public universalelectricity.core.transform.vector.Vector3 getPosition()
public VectorWorld getPosition()
{
return new universalelectricity.core.transform.vector.Vector3(x(), y(), z());
return new VectorWorld(world(), x(), y(), z());
}
@Override
public String toString()
{
return "[PartMech]" + x() + "x " + y() + "y " + z() + "z " + getSlotMask() + "s ";
return "[" + getClass().getSimpleName() +"]" + x() + "x " + y() + "y " + z() + "z " + getSlotMask() + "s ";
}
}

View file

@ -81,11 +81,9 @@ public class GearNode extends MechanicalNode
}
@Override
public void recache()
public void buildConnections()
{
synchronized (this)
{
getConnections().clear();
connections.clear();
/** Only call refresh if this is the main block of a multiblock gear or a single gear block. */
if (!gear().getMultiBlock().isPrimary() || world() == null)
@ -102,7 +100,7 @@ public class GearNode extends MechanicalNode
if (instance != null && instance != this && !(instance.getParent() instanceof PartGearShaft) && instance.canConnect(gear().placementSide.getOpposite(), this))
{
getConnections().put(instance, gear().placementSide);
addConnection(instance, gear().placementSide);
}
}
@ -125,9 +123,9 @@ public class GearNode extends MechanicalNode
* (the center), then we try to look for a gear shaft in the center. */
MechanicalNode instance = (MechanicalNode) ((INodeProvider) tile).getNode(MechanicalNode.class, checkDir == gear().placementSide.getOpposite() ? ForgeDirection.UNKNOWN : checkDir);
if (!getConnections().containsValue(checkDir) && instance != this && checkDir != gear().placementSide && instance != null && instance.canConnect(checkDir.getOpposite(), this))
if (!connections.containsValue(checkDir) && instance != this && checkDir != gear().placementSide && instance != null && instance.canConnect(checkDir.getOpposite(), this))
{
getConnections().put(instance, checkDir);
addConnection(instance, checkDir);
}
}
}
@ -145,17 +143,16 @@ public class GearNode extends MechanicalNode
ForgeDirection checkDir = ForgeDirection.getOrientation(Rotation.rotateSide(gear().placementSide.ordinal(), i));
TileEntity checkTile = new universalelectricity.core.transform.vector.Vector3(gear().tile()).add(checkDir).getTileEntity(world());
if (!getConnections().containsValue(checkDir) && checkTile instanceof INodeProvider)
if (!connections.containsValue(checkDir) && checkTile instanceof INodeProvider)
{
MechanicalNode instance = (MechanicalNode) ((INodeProvider) checkTile).getNode(MechanicalNode.class, gear().placementSide);
if (instance != null && instance != this && instance.canConnect(checkDir.getOpposite(), this) && !(instance.getParent() instanceof PartGearShaft))
{
getConnections().put(instance, checkDir);
addConnection(instance, checkDir);
}
}
}
}
}
/**

View file

@ -188,7 +188,7 @@ public class PartGear extends PartMechanical implements IMultiBlockStructure<Par
@Override
public universalelectricity.core.transform.vector.Vector3[] getMultiBlockVectors()
{
return new universalelectricity.core.transform.vector.Vector3(this.x(), this.y(), this.z()).getAround(this.world(), placementSide, 1);
return new universalelectricity.core.transform.vector.Vector3(this.x(), this.y(), this.z()).getAround(this.world(), placementSide, 1).toArray(new universalelectricity.core.transform.vector.Vector3[9]);
}
@Override

View file

@ -41,11 +41,9 @@ public class GearShaftNode extends MechanicalNode
}
@Override
public void recache()
public void buildConnections()
{
synchronized (this)
{
getConnections().clear();
connections.clear();
List<ForgeDirection> dirs = new ArrayList<ForgeDirection>();
dirs.add(shaft().placementSide);
dirs.add(shaft().placementSide.getOpposite());
@ -62,7 +60,7 @@ public class GearShaftNode extends MechanicalNode
if (instance != null && instance != this && instance.canConnect(checkDir.getOpposite(), this))
{
getConnections().put(instance, checkDir);
addConnection(instance, checkDir);
it.remove();
}
}
@ -73,7 +71,7 @@ public class GearShaftNode extends MechanicalNode
if (!dirs.isEmpty())
for (ForgeDirection checkDir : dirs)
{
if (!getConnections().containsValue(checkDir) && (checkDir == shaft().placementSide || checkDir == shaft().placementSide.getOpposite()))
if (!connections.containsValue(checkDir) && (checkDir == shaft().placementSide || checkDir == shaft().placementSide.getOpposite()))
{
TileEntity checkTile = new Vector3(shaft().tile()).add(checkDir).getTileEntity(world());
@ -84,12 +82,11 @@ public class GearShaftNode extends MechanicalNode
// Only connect to shafts outside of this block space.
if (instance != null && instance != this && instance.getParent() instanceof PartGearShaft && instance.canConnect(checkDir.getOpposite(), this))
{
getConnections().put(instance, checkDir);
addConnection(instance, checkDir);
}
}
}
}
}
}
@Override