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 @Override
public int getRowCount() 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; return 10;
} }
@ -99,10 +99,10 @@ public class DebugFrameMechanical extends FrameNodeDebug
@Override @Override
public Object getValueAt(int row, int col) 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]; ForgeDirection dir = (ForgeDirection) getNode().getConnections(MechanicalNode.class).values().toArray()[row];
MechanicalNode node = (MechanicalNode) getNode().getConnections().keySet().toArray()[row]; MechanicalNode node = (MechanicalNode) getNode().getConnections(MechanicalNode.class).keySet().toArray()[row];
switch(col) switch(col)
{ {
case 0: return dir; case 0: return dir;

View file

@ -11,67 +11,42 @@ import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.common.util.ForgeDirection;
import resonant.lib.utility.nbt.ISaveObj; import resonant.lib.utility.nbt.ISaveObj;
import resonantinduction.core.interfaces.IMechanicalNode; 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.INode;
import universalelectricity.api.core.grid.INodeProvider; import universalelectricity.api.core.grid.INodeProvider;
import universalelectricity.core.transform.vector.IVectorWorld; import universalelectricity.core.transform.vector.IVectorWorld;
import universalelectricity.core.transform.vector.Vector3; import universalelectricity.core.transform.vector.Vector3;
import codechicken.multipart.TMultiPart; import codechicken.multipart.TMultiPart;
import universalelectricity.core.transform.vector.VectorWorld;
/** /**
* A resonantinduction.mechanical node for resonantinduction.mechanical energy. * A resonantinduction.mechanical node for resonantinduction.mechanical energy.
* *
* @author Calclavia, Darkguardsman * @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 markRotationUpdate = false;
public boolean markTorqueUpdate = 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; public double torque = 0, prevTorque;
/**
* Rotational speed
*/
public double prevAngularVelocity, angularVelocity = 0; public double prevAngularVelocity, angularVelocity = 0;
/** public double renderAngle = 0, prev_angle = 0;
* Rotational acceleration
*/
public float acceleration = 2f; 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 double load = 2;
protected byte connectionMap = Byte.parseByte("111111", 2);
private double power = 0; 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) public MechanicalNode(INodeProvider parent)
{ {
this.setParent(parent); super(parent);
} }
@Override @Override
@ -106,11 +81,6 @@ public class MechanicalNode implements IMechanicalNode, ISaveObj, IVectorWorld
{ {
ticks = 1; ticks = 1;
} }
//temp, TODO find a better way to trigger this
if (ticks % 100 == 0)
{
this.recache();
}
//----------------------------------- //-----------------------------------
// Render Update // Render Update
//----------------------------------- //-----------------------------------
@ -164,55 +134,52 @@ public class MechanicalNode implements IMechanicalNode, ISaveObj, IVectorWorld
} }
power = getEnergy() / deltaTime; power = getEnergy() / deltaTime;
Iterator<Entry<Object, ForgeDirection>> it = connections.entrySet().iterator();
//----------------------------------- while (it.hasNext())
// Connection application of force and speed {
//----------------------------------- MechanicalNode adjacentMech = null;
synchronized (getConnections()) Entry<Object, ForgeDirection> entry = it.next();
{ ForgeDirection dir = entry.getValue();
Iterator<Entry<MechanicalNode, ForgeDirection>> it = getConnections().entrySet().iterator();
while (it.hasNext()) if (entry.getKey() instanceof Mechanical) adjacentMech = (MechanicalNode) entry.getKey();
{ if (entry.getKey() instanceof INodeProvider)
Entry<MechanicalNode, ForgeDirection> entry = it.next(); {
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(); int inversion = inverseRotation ? -1 : 1;
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; double targetTorque = inversion * adjacentMech.getTorque() / ratio;
double applyTorque = targetTorque * acceleration;
double targetTorque = inversion * adjacentMech.getTorque() / ratio; if (Math.abs(torque + applyTorque) < Math.abs(targetTorque)) {
double applyTorque = targetTorque * acceleration; torque += applyTorque;
} else if (Math.abs(torque - applyTorque) > Math.abs(targetTorque)) {
torque -= applyTorque;
}
if (Math.abs(torque + applyTorque) < Math.abs(targetTorque)) double targetVelocity = inversion * adjacentMech.getAngularSpeed() * ratio;
{ double applyVelocity = targetVelocity * acceleration;
torque += applyTorque;
}
else if (Math.abs(torque - applyTorque) > Math.abs(targetTorque))
{
torque -= applyTorque;
}
double targetVelocity = inversion * adjacentMech.getAngularSpeed() * ratio; if (Math.abs(angularVelocity + applyVelocity) < Math.abs(targetVelocity)) {
double applyVelocity = targetVelocity * acceleration; angularVelocity += applyVelocity;
} else if (Math.abs(angularVelocity - applyVelocity) > Math.abs(targetVelocity)) {
angularVelocity -= applyVelocity;
}
if (Math.abs(angularVelocity + applyVelocity) < Math.abs(targetVelocity)) /** Set all current rotations */
{ // adjacentMech.angle = Math.abs(angle) * (adjacentMech.angle >= 0 ? 1 : -1);
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);
}
}
}
onUpdate(); onUpdate();
prev_angle = renderAngle; prev_angle = renderAngle;
@ -285,19 +252,6 @@ public class MechanicalNode implements IMechanicalNode, ISaveObj, IVectorWorld
return load; 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 @Override
public double getEnergy() public double getEnergy()
{ {
@ -324,115 +278,14 @@ public class MechanicalNode implements IMechanicalNode, ISaveObj, IVectorWorld
nbt.setDouble("angularVelocity", angularVelocity); nbt.setDouble("angularVelocity", angularVelocity);
} }
@Override @Override
public void reconstruct() public boolean canConnect(ForgeDirection direction, Object object)
{ {
recache(); if(canConnect(direction)) {
} if (object instanceof INodeProvider) {
return ((INodeProvider) object).getNode(MechanicalNode.class, direction.getOpposite()) instanceof MechanicalNode;
@Override }
public void deconstruct() }
{ return false;
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;
}
} }

View file

@ -19,6 +19,7 @@ import codechicken.multipart.TFacePart;
import resonant.engine.ResonantEngine; import resonant.engine.ResonantEngine;
import universalelectricity.api.core.grid.INode; import universalelectricity.api.core.grid.INode;
import universalelectricity.api.core.grid.INodeProvider; import universalelectricity.api.core.grid.INodeProvider;
import universalelectricity.core.transform.vector.VectorWorld;
/** We assume all the force acting on the gear is 90 degrees. /** 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(); 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 @Override
public String toString() 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 @Override
public void recache() public void buildConnections()
{ {
synchronized (this) connections.clear();
{
getConnections().clear();
/** Only call refresh if this is the main block of a multiblock gear or a single gear block. */ /** Only call refresh if this is the main block of a multiblock gear or a single gear block. */
if (!gear().getMultiBlock().isPrimary() || world() == null) 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)) 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. */ * (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); 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)); ForgeDirection checkDir = ForgeDirection.getOrientation(Rotation.rotateSide(gear().placementSide.ordinal(), i));
TileEntity checkTile = new universalelectricity.core.transform.vector.Vector3(gear().tile()).add(checkDir).getTileEntity(world()); 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); MechanicalNode instance = (MechanicalNode) ((INodeProvider) checkTile).getNode(MechanicalNode.class, gear().placementSide);
if (instance != null && instance != this && instance.canConnect(checkDir.getOpposite(), this) && !(instance.getParent() instanceof PartGearShaft)) 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 @Override
public universalelectricity.core.transform.vector.Vector3[] getMultiBlockVectors() 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 @Override

View file

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