2014-09-27 20:37:05 +02:00
package resonantinduction.mechanical.mech.gear
import codechicken.lib.vec.Rotation
2014-10-16 14:13:57 +02:00
import codechicken.multipart. { TMultiPart , TileMultipart }
2014-09-27 20:37:05 +02:00
import net.minecraft.tileentity.TileEntity
import net.minecraftforge.common.util.ForgeDirection
2014-11-06 07:05:42 +01:00
import resonant.api.grid.INodeProvider
2014-11-21 05:17:28 +01:00
import resonant.lib.transform.vector. { VectorWorld , Vector3 }
2014-11-10 12:28:36 +01:00
import resonant.lib.wrapper.ForgeDirectionWrapper._
2014-11-19 05:12:53 +01:00
import resonantinduction.core.interfaces.TNodeMechanical
2014-11-10 12:28:36 +01:00
import resonantinduction.mechanical.mech.gearshaft. { GearShaftNode , PartGearShaft }
2014-11-13 03:22:46 +01:00
import resonantinduction.mechanical.mech.grid.NodeMechanical
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-10 14:20:42 +01:00
angleDisplacement = Math . PI / 12
2014-11-09 06:59:37 +01:00
2014-11-09 07:49:56 +01:00
protected def gear = getParent . asInstanceOf [ PartGear ]
2014-11-06 07:05:42 +01:00
2014-11-13 06:16:25 +01:00
override def getLoad : Double =
2014-11-06 07:05:42 +01:00
{
2014-11-09 05:06:09 +01:00
return gear . tier match
{
case 0 => 0.1
case 1 => 0.2
2014-11-09 07:49:56 +01:00
case 2 => 0.1
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
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
{
2014-11-13 03:22:46 +01:00
val instance : NodeMechanical = ( tileBehind . asInstanceOf [ INodeProvider ] ) . getNode ( classOf [ NodeMechanical ] , gear . placementSide . getOpposite )
2014-11-06 07:05:42 +01:00
if ( instance != null && instance != this && ! ( instance . getParent . isInstanceOf [ PartGearShaft ] ) && instance . canConnect ( this , gear . placementSide . getOpposite ) )
{
connect ( instance , gear . placementSide )
}
2014-09-27 20:37:05 +02:00
}
2014-11-06 07:05:42 +01:00
for ( i <- 0 until 6 )
2014-09-27 20:37:05 +02:00
{
2014-11-06 07:05:42 +01:00
val checkDir : ForgeDirection = ForgeDirection . getOrientation ( i )
var tile : TileEntity = gear . tile
if ( gear . getMultiBlock . isConstructed && checkDir != gear . placementSide && checkDir != gear . placementSide . getOpposite )
{
tile = new Vector3 ( gear . tile ) . add ( checkDir ) . getTileEntity ( world )
}
if ( tile . isInstanceOf [ INodeProvider ] )
{
2014-11-13 03:22:46 +01:00
val instance : NodeMechanical = ( tile . asInstanceOf [ INodeProvider ] ) . getNode ( classOf [ NodeMechanical ] , if ( checkDir == gear . placementSide . getOpposite ) ForgeDirection . UNKNOWN else checkDir ) . asInstanceOf [ NodeMechanical ]
2014-11-06 07:05:42 +01:00
if ( ! directionMap . containsValue ( checkDir ) && instance != this && checkDir != gear . placementSide && instance != null && instance . canConnect ( this , checkDir . getOpposite ) )
2014-09-27 20:37:05 +02:00
{
2014-11-06 07:05:42 +01:00
connect ( instance , checkDir )
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-13 16:04:21 +01:00
val instance = checkTile . asInstanceOf [ INodeProvider ] . getNode ( classOf [ NodeMechanical ] , gear . placementSide )
if ( instance != null && instance != this && instance . canConnect ( this , toDir . getOpposite ) && ! instance . isInstanceOf [ GearShaftNode ] )
2014-09-27 20:37:05 +02:00
{
2014-11-13 16:04:21 +01:00
connect ( instance , 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-06 07:05:42 +01:00
if ( from == gear . placementSide . getOpposite )
{
2014-11-13 16:04:21 +01:00
//This object is coming from the front of the gear
if ( otherParent . isInstanceOf [ PartGear ] || otherParent . isInstanceOf [ PartGearShaft ] )
2014-09-27 20:37:05 +02:00
{
2014-11-13 16:04:21 +01:00
if ( otherParent . isInstanceOf [ PartGearShaft ] )
2014-11-06 07:05:42 +01:00
{
2014-11-09 07:49:56 +01:00
//We are connecting to a shaft.
2014-11-13 16:04:21 +01:00
val shaft = otherParent . asInstanceOf [ PartGearShaft ]
2014-11-09 07:49:56 +01:00
//Check if the shaft is directing connected to the center of the gear (multiblock cases) and also its direction to make sure the shaft is facing the gear itself
2014-11-10 12:28:36 +01:00
return /* shaft.tile.partMap(from.getOpposite.ordinal) != gear && */ 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
}
2014-11-13 16:04:21 +01:00
else if ( otherParent . isInstanceOf [ PartGear ] )
2014-11-06 07:05:42 +01:00
{
2014-11-13 16:04:21 +01:00
if ( ( otherParent . asInstanceOf [ PartGear ] ) . tile == gear . tile && ! gear . getMultiBlock . isConstructed )
2014-09-27 20:37:05 +02:00
{
2014-11-06 07:05:42 +01:00
return true
2014-10-16 14:13:57 +02:00
}
2014-11-13 16:04:21 +01:00
if ( ( otherParent . asInstanceOf [ PartGear ] ) . placementSide != gear . placementSide )
2014-10-16 14:13:57 +02:00
{
2014-11-13 16:04:21 +01:00
val part = gear . tile . partMap ( ( otherParent . asInstanceOf [ PartGear ] ) . placementSide . ordinal )
2014-11-06 07:05:42 +01:00
if ( part . isInstanceOf [ PartGear ] )
{
val sourceGear : PartGear = part . asInstanceOf [ PartGear ]
if ( sourceGear . isCenterMultiBlock && ! sourceGear . getMultiBlock . isPrimary )
2014-09-27 20:37:05 +02:00
{
2014-11-06 07:05:42 +01:00
return true
2014-09-27 20:37:05 +02:00
}
2014-11-06 07:05:42 +01:00
}
else
{
if ( gear . getMultiBlock . isConstructed )
2014-09-27 20:37:05 +02:00
{
2014-11-13 16:04:21 +01:00
val checkPart : TMultiPart = ( otherParent . asInstanceOf [ PartGear ] ) . tile . partMap ( gear . placementSide . ordinal )
2014-11-06 07:05:42 +01:00
if ( checkPart . isInstanceOf [ PartGear ] )
{
2014-11-09 05:06:09 +01:00
val requiredDirection : ForgeDirection = ( checkPart . asInstanceOf [ PartGear ] ) . getPosition . subtract ( toVectorWorld ) . toForgeDirection
2014-11-13 16:04:21 +01:00
return ( checkPart . asInstanceOf [ PartGear ] ) . isCenterMultiBlock && ( otherParent . asInstanceOf [ PartGear ] ) . placementSide == requiredDirection
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
}
2014-09-27 20:37:05 +02:00
}
2014-11-09 05:06:09 +01:00
val sourceTile : TileEntity = toVectorWorld . add ( from . getOpposite ) . getTileEntity ( world )
2014-11-06 07:05:42 +01:00
if ( sourceTile . isInstanceOf [ INodeProvider ] )
2014-09-27 20:37:05 +02:00
{
2014-11-13 16:04:21 +01:00
val sourceInstance = sourceTile . asInstanceOf [ INodeProvider ] . getNode ( classOf [ NodeMechanical ] , from )
2014-11-06 07:05:42 +01:00
return sourceInstance == other
2014-09-27 20:37:05 +02:00
}
2014-11-06 07:05:42 +01:00
}
else if ( from == gear . placementSide )
{
2014-11-13 16:04:21 +01:00
//This object is from the back of the gear
2014-11-09 05:06:09 +01:00
val sourceTile : TileEntity = toVectorWorld . add ( from ) . getTileEntity ( world )
2014-11-06 07:05:42 +01:00
if ( sourceTile . isInstanceOf [ INodeProvider ] )
2014-09-27 20:37:05 +02:00
{
2014-11-13 03:22:46 +01:00
val sourceInstance : NodeMechanical = ( sourceTile . asInstanceOf [ INodeProvider ] ) . getNode ( classOf [ NodeMechanical ] , from . getOpposite )
2014-11-06 07:05:42 +01:00
return sourceInstance == other
}
}
else
{
2014-11-13 16:04:21 +01:00
//This object is from the sides of the gear
val otherTile = other . asInstanceOf [ NodeMechanical ] . toVectorWorld . add ( from . getOpposite ) . getTileEntity
if ( otherTile . isInstanceOf [ INodeProvider ] && otherTile . isInstanceOf [ TileMultipart ] )
2014-11-06 07:05:42 +01:00
{
2014-11-13 16:04:21 +01:00
val otherPart = otherTile . asInstanceOf [ TileMultipart ] . partMap ( gear . placementSide . ordinal )
if ( otherPart . isInstanceOf [ PartGear ] )
2014-11-06 07:05:42 +01:00
{
2014-11-13 16:04:21 +01:00
if ( gear != otherPart )
2014-09-27 20:37:05 +02:00
{
2014-11-13 16:04:21 +01:00
return otherPart . asInstanceOf [ PartGear ] . isCenterMultiBlock
2014-09-27 20:37:05 +02:00
}
else
{
2014-11-06 07:05:42 +01:00
return true
2014-09-27 20:37:05 +02:00
}
2014-11-06 07:05:42 +01:00
}
else
{
return true
}
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
2014-11-19 05:12:53 +01:00
override def inverseRotation ( other : TNodeMechanical ) : Boolean = ! other . isInstanceOf [ GearShaftNode ] || ( other . isInstanceOf [ GearShaftNode ] && parent . placementSide . offset < Vector3 . zero )
2014-11-10 12:28:36 +01:00
2014-11-21 05:17:28 +01:00
override def radius ( other : TNodeMechanical ) : Double =
2014-11-06 07:05:42 +01:00
{
2014-11-21 05:17:28 +01: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-21 05:17:28 +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 )
}
2014-09-27 20:37:05 +02:00
}