@name EngineMaker V3 ~Lethal Solaris~
@inputs Base:entity EntM:wirelink
@outputs Pistons:array
@outputs MakeP MakeH MakeR CRot Z Z2 PCount Ang:angle X
@persist [E O Crank]:entity 
@persist Command:array
@persist Stroke PMass PModel:string PCount PLength PistGap Vec:vector
@persist CModel:string CLength CWidth TotPLength PistD CRot
@persist X Y YZ Z Z2 MakeH MakeP Reset ARRY AR PreCount HD Type:string
@persist Pist:entity

#Commands are listed as order your supposed to type them

#Commands
# 1.  .cmodel Shape Diam Length ( EX .cmodel 6 42 ) Sets what crank model you want to use
# 2.  .pmodel Shape Diam Length ( EX .pmodel 6 3 ) Sets what piston model you want to use
# 3.  .pcount Number ( EX .pcount 4 ) Sets amount of pistons
# 4.  .stroke Length ( EX .stroke 16 ) Sets the length of the stroke
# 5.  .pmass mass ( EX .pmass 2 ) Sets the weight of the pistons
# 6.  .spawn ( EX .spawn ) Spawns the pistons and crank
# 7.  .rope ( EX .rope ) Ropes Crank and piston

# .reset ( EX .reset ) Removes all pistons and the crank,and resets the e2

interval( 800 )

if( first() | dupefinished() )
{
    
    runOnChat( 1 )
    
    E = entity()
    
    O = owner()
    
    Stroke = 15
    PMass = 2
    
    for( I = 100, 104 )
    {
        
        holoCreate( I, E:pos() ) holoAlpha( I, 0 )
        holoScale( I, vec( 0.10, 0.10 ,0.10 ) ) holoParent( I, E ) 
        
    }

    holoCreate( 2, E:pos() ) holoAlpha( 2, 0 )
    holoScale( 2, vec( 1, 1 ,1 ) ) holoParent( 2, E )
    
    holoCreate( 3, E:pos() ) holoAlpha( 3, 0 )
    holoScale( 3, vec( 1, 1 ,1 ) ) holoParent( 3, E )
    
    holoAng( 2, E:toWorld( ang( 0, 0, 90 ) ) )
    holoAng( 3, E:toWorld( ang( 0, 0, 0 ) ) ) holoPos( 3, E:toWorld( vec( 0, 0, Stroke ) ) )
    
    MakeH = 0
    MakeR = 0
    Y = 0
    Z = 0
    Z2 = 0
 
}
   

if( chatClk( O ) )
{
    
    Command = O:lastSaid():lower():explode(" ")
    
    if( Command[ 1, string ] == ".stroke" )
    {
        
        hideChat( 1 )  
        Stroke = Command[ 2, string ]:toNumber()
        MakeH = 2
        
    }
    elseif( Command[ 1, string ] == ".pmass" )
    {
        
        hideChat( 1 )   
        PMass = Command[ 2, string ]:toNumber()
        
    }
    elseif( Command[ 1, string ] == ".pmodel" )
    {

        hideChat( 1 )
        
        local S0 = Command[ 2, string ]
        local S1 = ""
        local S2 = Command[ 2, string ]
        local S3 = Command[ 3, string ] 

        if( S2 == "1_5" ){ S1 = "1" 
        if( S2 == "3" ){ S1 = "2" }
        }elseif( S2 == "6" ){ S1 = "3" 
        }elseif( S2 == "9" ){ S1 = "4" 
        }elseif( S2 == "12" ){ S1 = "5" }
    
            
        PModel = "models/sprops/cylinders/size_"+S1+"/cylinder_"+S2+"x"+S3+".mdl"
        #elseif( S0 == "cube" ){ PModel = "models/sprops/cuboids/height"+S1+"/size_1/cube_"+S2+"x"+S3+"x"+S2+".mdl" }
        
        "models/sprops/cuboids/height06/size_1/cube_6x6x6.mdl"
        "models/sprops/cuboids/height12/size_1/cube_12x12x12.mdl"
        "models/sprops/cuboids/height24/size_2/cube_36x18x24.mdl"
        
        PLength = S2:toNumber() - 0.5
        
        PCount = 1
        
        holoModel( 3, PModel )  holoAlpha( 3, 100 )
        MakeH = 1
        
          
        
    }
    elseif( Command[ 1, string ] == ".cmodel" )
    {
        

        hideChat( 1 )
        
        local S0 = Command[ 2, string ]
        local S1 = ""
        local S2 = Command[ 3, string ]
        local S3 = Command[ 4, string ] 

        if( S0 == "cylinder" )
        {
            if( S2 == "1_5" ){ S1 = "1" 
            if( S2 == "3" ){ S1 = "2" }
            }elseif( S2 == "6" ){ S1 = "3" 
            }elseif( S2 == "9" ){ S1 = "4" 
            }elseif( S2 == "12" ){ S1 = "5" }
        }
        elseif( S0 == "cube" )
        {
            if( S2 == "6" ){ S1 = "06" 
            if( S2 == "12" ){ S1 = "12" }
            }elseif( S2 == "24" ){ S1 = "24" 
            }elseif( S2 == "48" ){ S1 = "48" }
        }
            
        if( S0 == "cylinder" ){ CModel = "models/sprops/cylinders/size_"+S1+"/cylinder_"+S2+"x"+S3+".mdl" Type = S0 }
        elseif( S0 == "cube" ){ CModel = "models/sprops/cuboids/height"+S1+"/size_1/cube_"+S2+"x"+S3+"x"+S2+".mdl" Type = S0 }
        
        CLength = S3:toNumber() - 0.5
        CWidth = S2:toNumber() - 0.5
        
        holoModel( 2, CModel ) holoAlpha( 2, 100 )
          
        
    }
    elseif( Command[ 1, string ] == ".pcount" )
    {
        
        hideChat( 1 )
        PCount = Command[ 2, string ]:toNumber()
        TotPLength = CLength / ( PLength * PCount )
        PistD = PLength - ( PLength * TotPLength )
        CRot = 360 / ( PCount / 2 )
        Z2 = PCount + 1
        MakeH = 1
        
    }
    elseif( Command[ 1, string ] == ".spawn" )
    {
        
        hideChat( 1 )
        MakeP = 1
        
    }
    elseif( Command[ 1, string ] == ".rope" )
    {
        
        hideChat( 1 )
        MakeR = 1 
        
    }
    elseif( Command[ 1, string ] == ".reset" )
    {
        
        hideChat( 1 )
        Reset = 1
        
    }
 
}
if( MakeH == 1 )
{
    
    for( I = 1, 6 + PreCount ){ holoDelete( I + 2 ) HD = HD + 1 }
    if( HD >= PreCount + 6 ){ MakeH = 2 }
    
    
}
elseif( MakeH == 2 )
{
    
    for( I = 1, PCount )
    {
        
        PistGap = ( CLength - PistD ) / ( PLength * PCount )
        Vec = vec( 0, PistGap * ( I - 1 ) * PLength, Stroke + CWidth )
        
        holoCreate( I + 2, E:toWorld( Vec - vec( 0, PLength / -2 + CLength / 2, 0 ) ) ) holoModel( I + 2, PModel )
        holoColor( I + 2, hsv2rgb( 255 / PCount * ( PCount + 2 ), 1, 1 ) ) holoAlpha( I + 2, 100 ) holoParent( I + 2, E )
        
        X = I
        
    }
    if( X >= PCount )
    {
        
        PreCount = PCount
        MakeH = 0
        
    }
        
}

if( MakeP == 1 )
{

    timer( "PSpawn", 350 )
        
    if( clk( "PSpawn" ) )
    {
            
        Y = Y + 1
        #print( Y )
        
        Pist = propSpawn( PModel, holoEntity( Y + 2 ):pos(), holoEntity( Y + 2 ):angles(), 1 )
        Pist:setMass( PMass )
        
        holoDelete( Y + 2 )
        
        Pistons[ Y, entity ] = Pist
            
    }

    if( Y >= PCount )
    {
        
        Y = 0
        MakeP = 0
        
        Crank = propSpawn( CModel, holoEntity( 2 ):pos(), holoEntity( 2 ):angles(), 1 )
        Pistons[ PCount + 1, entity ] = Crank
        holoDelete( 2 )
        print( "Done" )
        
    }
    
}

Tester = ( ( PCount / 2 ) )
if( MakeR == 1 & Z != ( ( PCount / 2 ) + 1 ) )
{
    
    if( YZ != 1 )
    {
        
        Base:propFreeze( 1 )
        Base:setPos( Pistons[ PCount + 1, entity ]:toWorld( vec( 0, -2, 0 ) ) )
        Base:setAng( Pistons[ PCount + 1, entity ]:toWorld( ang( 90, 90, 0 ) ) )
        YZ = 1
        
    }
    
    timer( "Rope", 1050 )
    
    Ang = Pistons[ PCount + 1, entity ]:angles()
    
    if( clk( "Rope" ) )
    {
        
        #print( "Done" )
    
        Z = clamp( Z + 1, 1, ( PCount / 2 ) + 1 )
        Z2 = clamp( Z2 - 1, PCount / 2, PCount + 1 )
        
        if( Type == "cylinder" ){ Pistons[ PCount + 1, entity ]:setAng( ang( -90 + ( Z * CRot ), 0, 90 ) ) }
        elseif( Type == "cube" ){ Pistons[ PCount + 1, entity ]:setAng( ang( 0, -90, 0  + ( Z * CRot ) ) ) }
        
    }
        
    if( changed( Pistons[ PCount + 1, entity ]:angles() ) )
    {
    
    holoPos( 100, Pistons[ Z, entity ]:toWorld( vec( 0, 0, -Stroke - 3 ) ) )
    holoPos( 101, Pistons[ Z2, entity ]:toWorld( vec( 0, 0, -Stroke - 3 ) ) )
    
    holoPos( 102, Pistons[ Z, entity ]:toWorld( vec( 0, 0, -3 ) ) )
    holoPos( 103, Pistons[ Z2, entity ]:toWorld( vec( 0, 0, -3 ) ) )
    
    Pistons[PCount + 1, entity]:ropeTo( Z + 100, Pistons[ Z, entity ] , 0, 0, Pistons[ PCount + 1, entity ]:toLocal( holoEntity( 100 ):pos() ), vec(), Stroke, 0, 0, 1, "", 1 )
    Pistons[PCount + 1, entity]:ropeTo( Z + 200, Pistons[ Z2, entity ] , 0, 0, Pistons[ PCount + 1, entity ]:toLocal( holoEntity( 101 ):pos() ), vec(), Stroke, 0, 0, 1, "", 1 )
    
    Base:sliderTo( Z + 300, Pistons[ Z, entity ], 0, 0, Base:toLocal( Pistons[ Z, entity ]:toWorld(vec( 0, 0, 3 ) ) ), Pistons[ Z, entity ]:toLocal( holoEntity( 102 ):pos() ), 0.5, "" )
    Base:sliderTo( Z2 + 400, Pistons[ Z2, entity ], 0, 0, Base:toLocal( Pistons[ Z2, entity ]:toWorld(vec( 0, 0, 3 ) ) ), Pistons[ Z2, entity ]:toLocal( holoEntity( 103 ):pos() ), 0.5, "" )
    
    
    }

    if( Z == ( PCount / 2 ) + 1 )
    {
        
        MakeR = 0
        Crank:removeConstraints( "Slider" )
        print( "Done, Dont Forget to axis center your crank to your base!" )
        ARRY = 1
        
    }

}

if( MakeR == 1 &  Z == ( PCount / 2 ) + 1 )
{
    
    MakeR = 0 
    
}

if( ARRY == 1 )
{
    
    timer( "ARRY", 500 )
    
    if( clk( "ARRY" ) & AR <= Pistons:count() - 1 )
    {
        
        AR = AR + 1
        
        EntM[ "Add Entity", number ] = 1
        EntM[ "Entity", entity ] = Pistons[ AR, entity ]
        
    }
    #if( AR  Pistons:count() - 1 ){ ARRY = 0 }
    
}

if( Reset )
{
    
    for( I = 1, Pistons:count() )
    {
        
        Pistons[ I ,entity ]:propDelete()
        if( I >= Pistons:count() ){ reset() }
        
    }

}
               
        
