electrodynamics/src/main/scala/edx/mechanical/mech/gear/NodeGear.scala

268 lines
9.2 KiB
Scala
Raw Normal View History

2015-01-14 12:06:03 +01:00
package edx.mechanical.mech.gear
2014-09-27 20:37:05 +02:00
import codechicken.lib.vec.Rotation
import codechicken.multipart.TileMultipart
2015-01-14 12:06:03 +01:00
import edx.core.interfaces.TNodeMechanical
import edx.mechanical.mech.gearshaft.{NodeGearShaft, PartGearShaft}
import edx.mechanical.mech.grid.NodeMechanical
2014-09-27 20:37:05 +02:00
import net.minecraft.tileentity.TileEntity
import net.minecraftforge.common.util.ForgeDirection
2015-01-26 13:17:04 +01:00
import resonantengine.api.graph.INodeProvider
2015-01-26 12:40:32 +01:00
import resonantengine.lib.transform.vector.Vector3
import resonantengine.lib.wrapper.ForgeDirectionWrapper._
2014-09-27 20:37:05 +02:00
/**
* Node for the gear
*
* @author Calclavia, Edited by: Darkguardsman
*/
2014-11-13 06:16:25 +01:00
class NodeGear(parent: PartGear) extends NodeMechanical(parent: PartGear)
2014-09-27 20:37:05 +02:00
{
2014-11-22 11:25:59 +01:00
override def angleDisplacement = if (gear.getMultiBlock.isConstructed) Math.PI / 36 else Math.PI / 12
2014-11-09 06:59:37 +01:00
override def inertia: Double =
2014-11-06 07:05:42 +01:00
{
2015-01-23 04:41:55 +01:00
gear.tier match
2014-11-09 05:06:09 +01:00
{
case 0 => 50
case 1 => 20
case 2 => 15
2015-01-23 04:41:55 +01:00
}
}
2015-01-27 09:15:44 +01:00
protected def gear = getParent.asInstanceOf[PartGear]
2015-01-23 04:41:55 +01:00
override def friction: Double =
{
gear.tier match
{
case 0 => 1
case 1 => 1.5
case 2 => 1.3
2014-11-09 05:06:09 +01:00
}
2014-11-06 07:05:42 +01:00
}
2014-11-13 14:34:16 +01:00
override def reconstruct()
2014-11-06 07:05:42 +01:00
{
2014-11-13 14:34:16 +01:00
if (!parent.getMultiBlock.isPrimary)
2014-11-09 05:06:09 +01:00
{
2014-11-13 14:34:16 +01:00
parent.getMultiBlock.getPrimary.mechanicalNode.reconstruct()
2014-11-09 05:06:09 +01:00
}
2014-11-13 14:34:16 +01:00
super.reconstruct()
2014-11-06 07:05:42 +01:00
}
2014-09-27 20:37:05 +02:00
2014-11-09 06:28:58 +01:00
override def rebuild()
2014-11-06 07:05:42 +01:00
{
if (!gear.getMultiBlock.isPrimary || world == null)
2014-09-27 20:37:05 +02:00
{
2014-11-06 07:05:42 +01:00
return
2014-09-27 20:37:05 +02:00
}
2014-11-09 06:28:58 +01:00
//Check behind
2014-11-13 16:04:21 +01:00
val tileBehind = new Vector3(gear.tile).add(gear.placementSide).getTileEntity(world)
2014-11-06 07:05:42 +01:00
if (tileBehind.isInstanceOf[INodeProvider])
2014-09-27 20:37:05 +02:00
{
val other = tileBehind.asInstanceOf[INodeProvider].getNode(classOf[NodeMechanical], gear.placementSide.getOpposite)
if (other != null && other != this && !other.getParent.isInstanceOf[PartGearShaft] && other.canConnect(this, gear.placementSide.getOpposite))
2014-11-06 07:05:42 +01:00
{
connect(other, gear.placementSide)
2014-11-06 07:05:42 +01:00
}
2014-09-27 20:37:05 +02:00
}
//Check internal
2014-11-06 07:05:42 +01:00
for (i <- 0 until 6)
2014-09-27 20:37:05 +02:00
{
2014-11-26 16:13:49 +01:00
val toDir = ForgeDirection.getOrientation(i)
2014-11-06 07:05:42 +01:00
var tile: TileEntity = gear.tile
if (gear.getMultiBlock.isConstructed && toDir != gear.placementSide && toDir != gear.placementSide.getOpposite)
2014-11-06 07:05:42 +01:00
{
tile = new Vector3(gear.tile).add(toDir).getTileEntity(world)
2014-11-06 07:05:42 +01:00
}
2014-11-06 07:05:42 +01:00
if (tile.isInstanceOf[INodeProvider])
{
2014-11-26 16:13:49 +01:00
val other = tile.asInstanceOf[INodeProvider].getNode(classOf[NodeMechanical], if (toDir == gear.placementSide.getOpposite) ForgeDirection.UNKNOWN else toDir)
if (other != this && toDir != gear.placementSide && other != null && canConnect(other, toDir) && other.canConnect(this, toDir.getOpposite))
2014-09-27 20:37:05 +02:00
{
connect(other, toDir)
2014-09-27 20:37:05 +02:00
}
2014-11-06 07:05:42 +01:00
}
}
2014-11-13 16:04:21 +01:00
//TODO: Change this to the radius of the gear
val checkDisplacement = if (gear.getMultiBlock.isPrimary && gear.getMultiBlock.isConstructed) 2 else 1
//Check the sides of the gear for any other gear connections
2014-11-06 07:05:42 +01:00
for (i <- 0 until 4)
{
2014-11-13 16:04:21 +01:00
val toDir = ForgeDirection.getOrientation(Rotation.rotateSide(gear.placementSide.ordinal, i))
val checkTile = (new Vector3(gear.tile) + (new Vector3(toDir) * checkDisplacement)).getTileEntity(world)
if (!directionMap.containsValue(toDir) && checkTile.isInstanceOf[INodeProvider])
2014-11-06 07:05:42 +01:00
{
2014-11-23 04:59:44 +01:00
val other = checkTile.asInstanceOf[INodeProvider].getNode(classOf[NodeMechanical], gear.placementSide)
2014-11-13 16:04:21 +01:00
if (other != null && other != this && canConnect(other, toDir) && other.canConnect(this, toDir.getOpposite) && !other.isInstanceOf[NodeGearShaft])
2014-09-27 20:37:05 +02:00
{
2014-11-23 04:59:44 +01:00
connect(other, toDir)
2014-09-27 20:37:05 +02:00
}
2014-11-06 07:05:42 +01:00
}
}
}
/**
* Can this gear be connected BY the source?
*
* @param from - Direction source is coming from.
* @param other - The source of the connection.
* @return True is so.
*/
2014-11-13 16:04:21 +01:00
override def canConnect[B <: NodeMechanical](other: B, from: ForgeDirection): Boolean =
2014-11-06 07:05:42 +01:00
{
if (!gear.getMultiBlock.isPrimary)
{
return false
}
2014-11-13 16:04:21 +01:00
2014-11-13 03:22:46 +01:00
if (other.isInstanceOf[NodeMechanical])
2014-11-06 07:05:42 +01:00
{
2014-11-13 16:04:21 +01:00
val otherParent = other.getParent
2014-11-26 16:13:24 +01:00
if (from == gear.placementSide)
2014-11-06 07:05:42 +01:00
{
2014-11-26 16:13:24 +01:00
//This object is coming from the back of the gear
//Check if it's a gear that's connected back-to-back
if (otherParent.isInstanceOf[PartGear])
2014-09-27 20:37:05 +02:00
{
2014-11-26 16:13:24 +01:00
val otherGearPart = otherParent.asInstanceOf[PartGear]
if (otherGearPart.placementSide == parent.placementSide.getOpposite)
2014-11-06 07:05:42 +01:00
{
2014-11-26 16:13:24 +01:00
//Check if it is the center of another gear (if it is a multiblock)
return otherGearPart.getMultiBlock.isPrimary
2014-11-06 07:05:42 +01:00
}
2014-11-26 16:13:24 +01:00
}
//It's not a gear. It might be be another tile node
2021-04-05 14:41:30 +02:00
val sourceTile = toVectorWorld.add(from).getTileEntity(world)
2014-11-26 16:13:24 +01:00
if (sourceTile.isInstanceOf[INodeProvider])
{
//Found a potential node. Check if it is actually adjacent to the gear.
val sourceInstance = sourceTile.asInstanceOf[INodeProvider].getNode(classOf[NodeMechanical], from)
return sourceInstance == other
}
}
else if (from == gear.placementSide.getOpposite)
{
//This object is from the front of the gear
//Check if it's a gear internally
if (otherParent.isInstanceOf[PartGear])
{
//Check internal gears
if (otherParent.asInstanceOf[PartGear].tile == parent.tile && !parent.getMultiBlock.isConstructed)
2014-11-06 07:05:42 +01:00
{
2014-11-26 16:13:24 +01:00
return true
// otherParent.asInstanceOf[PartGear].placementSide != parent.placementSide.getOpposite
}
if (otherParent.asInstanceOf[PartGear].placementSide != gear.placementSide)
{
val part = gear.tile.partMap(otherParent.asInstanceOf[PartGear].placementSide.ordinal)
if (part.isInstanceOf[PartGear])
{
2014-11-26 16:13:24 +01:00
val sourceGear: PartGear = part.asInstanceOf[PartGear]
if (sourceGear.isCenterMultiBlock && !sourceGear.getMultiBlock.isPrimary)
2014-11-06 07:05:42 +01:00
{
2014-11-26 16:13:24 +01:00
return true
2014-11-06 07:05:42 +01:00
}
2014-11-26 16:13:24 +01:00
}
else
{
if (gear.getMultiBlock.isConstructed)
2014-11-06 07:05:42 +01:00
{
2014-11-26 16:13:24 +01:00
val checkPart = otherParent.asInstanceOf[PartGear].tile.partMap(gear.placementSide.ordinal)
if (checkPart.isInstanceOf[PartGear])
2014-09-27 20:37:05 +02:00
{
2021-04-05 14:41:30 +02:00
val requiredDirection = checkPart.asInstanceOf[PartGear].getPosition.subtract(toVectorWorld).toForgeDirection
2014-11-26 16:13:24 +01:00
return checkPart.asInstanceOf[PartGear].isCenterMultiBlock && otherParent.asInstanceOf[PartGear].placementSide == requiredDirection
2014-09-27 20:37:05 +02:00
}
2014-11-06 07:05:42 +01:00
}
2014-09-27 20:37:05 +02:00
}
2014-11-06 07:05:42 +01:00
}
2014-09-27 20:37:05 +02:00
}
2014-11-26 16:13:24 +01:00
//Check if it's a shaft
if (otherParent.isInstanceOf[PartGearShaft])
2014-09-27 20:37:05 +02:00
{
2014-11-26 16:13:24 +01:00
//We are connecting to a shaft.
val shaft = otherParent.asInstanceOf[PartGearShaft]
/*shaft.tile.partMap(from.getOpposite.ordinal) != gear && */
2014-11-26 16:13:49 +01:00
return Math.abs(shaft.placementSide.offsetX) == Math.abs(gear.placementSide.offsetX) && Math.abs(shaft.placementSide.offsetY) == Math.abs(gear.placementSide.offsetY) && Math.abs(shaft.placementSide.offsetZ) == Math.abs(gear.placementSide.offsetZ)
2014-11-06 07:05:42 +01:00
}
}
else if (from != ForgeDirection.UNKNOWN)
2014-11-06 07:05:42 +01:00
{
2014-11-23 04:59:44 +01:00
//This object is from the sides of the gear. It can either be a gear within this block or outside
if (other.isInstanceOf[NodeGear])
2014-11-06 07:05:42 +01:00
{
2014-11-23 04:59:44 +01:00
val otherParent = other.parent.asInstanceOf[PartGear]
//Check inside this block
if (otherParent.tile == parent.tile)
{
return otherParent.placementSide != parent.placementSide && otherParent != parent.placementSide.getOpposite
}
2014-11-13 16:04:21 +01:00
2014-11-23 04:59:44 +01:00
//Check for gear outside this block placed on the same plane
2021-04-05 14:41:30 +02:00
val otherTile = other.toVectorWorld.getTileEntity
2014-11-23 04:59:44 +01:00
if (otherTile.isInstanceOf[TileMultipart])
2014-11-06 07:05:42 +01:00
{
2014-11-23 04:59:44 +01:00
if (otherTile.asInstanceOf[TileMultipart].partMap(gear.placementSide.ordinal()) == other.parent)
2014-09-27 20:37:05 +02:00
{
2014-11-23 04:59:44 +01:00
//We found another gear, but check if we are connecting to the center spaces of the gear
//If this is a multiblock, "otherTile" would be the center of that gear, not the adjacent
2021-04-05 14:41:30 +02:00
val adjacentTile = toVectorWorld.add(from).getTileEntity
2014-11-23 04:59:44 +01:00
if (adjacentTile.isInstanceOf[TileMultipart])
{
val adjacentPart = adjacentTile.asInstanceOf[TileMultipart].partMap(gear.placementSide.ordinal)
return adjacentPart.asInstanceOf[PartGear].isCenterMultiBlock
}
2014-09-27 20:37:05 +02:00
}
2014-11-06 07:05:42 +01:00
}
2014-09-27 20:37:05 +02:00
}
2014-11-06 07:05:42 +01:00
}
2014-09-27 20:37:05 +02:00
}
2014-11-06 07:05:42 +01:00
return false
}
2014-09-27 20:37:05 +02:00
override def inverseRotation(other: TNodeMechanical): Boolean =
{
if (other.isInstanceOf[NodeGearShaft])
{
return parent.placementSide.offset < Vector3.zero
}
return !other.isInstanceOf[NodeGearShaft]
}
2014-11-10 12:28:36 +01:00
2014-11-22 11:25:59 +01:00
override def radius(other: TNodeMechanical): Double =
2014-11-06 07:05:42 +01:00
{
2021-04-05 14:41:30 +02:00
val deltaPos = other.asInstanceOf[NodeMechanical].toVectorWorld - toVectorWorld
2014-11-09 06:28:58 +01:00
val caseX = gear.placementSide.offsetX != 0 && deltaPos.y == 0 && deltaPos.z == 0
val caseY = gear.placementSide.offsetY != 0 && deltaPos.x == 0 && deltaPos.z == 0
val caseZ = gear.placementSide.offsetZ != 0 && deltaPos.x == 0 && deltaPos.y == 0
2014-11-06 07:05:42 +01:00
if (caseX || caseY || caseZ)
2014-11-22 11:25:59 +01:00
return super.radius(other)
2014-11-09 06:28:58 +01:00
2014-11-21 05:17:28 +01:00
if (gear.getMultiBlock.isConstructed) 1.5 else super.radius(other)
}
2021-04-05 14:41:30 +02:00
}