@name 3D Holo Moving Bot
@inputs 
@outputs Mode Distance Height Pitch Roll Ang:angle P_Spd Target:vector Yaw Pre_Yaw Bearing Grab Hold:vector
@persist [AR AR2 AL AL2 O E T Turn]:entity Idx Cid:array R:array
@trigger 
@model models/sprops/rectangles/size_3/rect_24x24x3.mdl

if( dupefinished() ){ reset() }

if( first() )
{
    runOnTick(20)
    #runOnChat(1)
    runOnLast(1)
    
    O = owner()
    E = entity()
    
    E:setAlpha( 0 )
    
    findByModel("models/sprops/geometry/sphere_12.mdl")
    T = findClosest(E:pos())
    
    function number getID( N )
    {
        Idx += N
        return Idx
    }
    function number clipIt( N:number, [V1 V2]:vector )
    {
        Cid[N,number] = Cid[N,number] + 1
        holoClipEnabled( N, Cid[N,number], 1 )
        holoClip( N, Cid[N,number], V1, V2, 0 )
        return N
    }
    #clipIt( getID(0), vec(), vec(0,0,1) )
    function number mathIt( N1, N2, N3 )
    {
        return acos( ( N1 ^ 2 + N2 ^ 2 - N3 ^ 2 ) / ( 2 * N1 * N2 ) )
    }
    
    Mat = "sprops/textures/sprops_chrome"
    
    holoCreate( getID(1), E:toWorld(vec(0,0,-24)), vec(24) / 12, E:toWorld(ang(0,0,0)), vec(255) )
    holoModel( getID(0), "hq_sphere" )
    holoMaterial( getID(0), "models/gibs/metalgibs/metal_gibs" )
    holoParent( getID(0), E )
    
    holoCreate( getID(1), E:toWorld(vec(0,0,-24)), vec() / 12, E:toWorld(ang(0,0,0)), vec(255) )
    holoModel( getID(0), "hq_tube_thin" )
    holoMaterial( getID(0), Mat )
    holoParent( getID(0), getID(0)-1 )
    Main = getID(0)
    
    holoCreate( getID(1), E:toWorld(vec(0,0,-24)), vec(25,25,1) / 12, E:toWorld(ang(0,0,0)), vec(255) )
    holoModel( getID(0), "hq_tube_thin" )
    holoMaterial( getID(0), Mat )
    holoParent( getID(0), Main )
    
    holoCreate( getID(1), E:toWorld(vec(0,0,-24)), vec(25,25,1) / 12, E:toWorld(ang(0,0,90)), vec(255) )
    holoModel( getID(0), "hq_tube_thin" )
    holoMaterial( getID(0), Mat )
    holoParent( getID(0), Main )
    clipIt( getID(0), vec(), vec(0,1,0) )
    
    holoCreate( getID(1), E:toWorld(vec(0,0,-24)), vec(25,25,1) / 12, E:toWorld(ang(0,90,90)), vec(255) )
    holoModel( getID(0), "hq_tube_thin" )
    holoMaterial( getID(0), Mat )
    holoParent( getID(0), Main )
    clipIt( getID(0), vec(), vec(0,1,0) )
    
    holoCreate( getID(1), E:toWorld(vec(0,0,-6.25)), vec(18,18,1.5) / 12, E:toWorld(ang(0,0,0)), vec(255) )
    holoModel( getID(0), "hq_cylinder" )
    holoMaterial( getID(0), Mat )
    holoParent( getID(0), Main )
    
        holoCreate( getID(1), E:toWorld(vec(0,9,-11.5)), vec(12,12,1) / 12, E:toWorld(ang(90,180,0)), vec(255) )
        holoModel( getID(0), "hq_tube" )
        holoMaterial( getID(0), Mat )
        holoParent( getID(0), Main )
        clipIt( getID(0), vec(), vec(0,1,0) )
        
        holoCreate( getID(1), E:toWorld(vec(0,-9,-11.5)), vec(12,12,1) / 12, E:toWorld(ang(90,0,0)), vec(255) )
        holoModel( getID(0), "hq_tube" )
        holoMaterial( getID(0), Mat )
        holoParent( getID(0), Main )
        clipIt( getID(0), vec(), vec(0,1,0) )
        
        holoCreate( getID(1), E:toWorld(vec(9,0,-11.5)), vec(12,12,1) / 12, E:toWorld(ang(90,90,0)), vec(255) )
        holoModel( getID(0), "hq_tube" )
        holoMaterial( getID(0), Mat )
        holoParent( getID(0), Main )
        clipIt( getID(0), vec(), vec(0,1,0) )
        
        holoCreate( getID(1), E:toWorld(vec(-9,0,-11.5)), vec(12,12,1) / 12, E:toWorld(ang(90,-90,0)), vec(255) )
        holoModel( getID(0), "hq_tube" )
        holoMaterial( getID(0), Mat )
        holoParent( getID(0), Main )
        clipIt( getID(0), vec(), vec(0,1,0) )
    
    holoCreate( getID(1), E:toWorld(vec(0,0,-1.25)), vec(30,30,12) / 12, E:toWorld(ang(180,0,0)), vec(255) )
    holoModel( getID(0), "hq_hdome_thin" )
    holoMaterial( getID(0), "models/gibs/metalgibs/metal_gibs" )
    holoParent( getID(0), Main )
    
    Turn = holoCreate( getID(1), E:toWorld(vec(0,0,9-5.25)), vec(12,12,18) / 12, E:toWorld(ang(0,0,0)), vec(255) )
    holoModel( getID(0), "hq_rcylinder_thin" )
    holoMaterial( getID(0), Mat )
    holoParent( getID(0), Main )
    
    holoCreate( getID(1), E:toWorld(vec(0,0,0)), vec(30,30,9) / 12, E:toWorld(ang(0,0,0)), vec(255) )
    holoModel( getID(0), "hq_hdome_thin" )
    holoMaterial( getID(0), "models/gibs/metalgibs/metal_gibs" )
    holoParent( getID(0), Turn )
    
    Count = 8
    Step = 360 / Count
    for( I = 1, Count )
    {
        holoCreate( getID(1), E:toWorld(vec(-10,0,-1.25/2):rotate(ang(0,Step*I,0))), vec(7) / 12, E:toWorld(ang(0,0,0)), vec() )
        holoModel( getID(0), "hq_sphere" )
        holoMaterial( getID(0), "sprops/textures/sprops_chrome2" )
        holoParent( getID(0), Turn )
    }
    
    holoCreate( getID(1), E:toWorld(vec(0,0,12)), vec(24,24,12) / 12, E:toWorld(ang(0,0,0)), vec(255) )
    holoModel( getID(0), "hq_rcylinder_thick" )
    holoMaterial( getID(0), "models/gibs/metalgibs/metal_gibs" )
    holoParent( getID(0), Turn )
    
    # RIGHT ARM
    holoCreate( getID(1), E:toWorld(vec(12,0,12)), vec(5) / 12, E:toWorld(ang(90,0,0)), vec(255) )
    holoModel( getID(0), "hq_cylinder" )
    holoMaterial( getID(0), "models/gibs/metalgibs/metal_gibs" )
    holoParent( getID(0), Turn )
    
    AR = holoCreate( getID(1), E:toWorld(vec(15,0,12)), vec(6) / 12, E:toWorld(ang(0,0,0)), vec(255) )
    holoModel( getID(0), "hq_sphere" )
    holoMaterial( getID(0), Mat )
    holoParent( getID(0), Turn )
    
    holoCreate( getID(1), AR:toWorld(vec(0,0,9)), vec(3.5,3.5,18) / 12, AR:toWorld(ang(0,0,0)), vec(255) )
    holoModel( getID(0), "hq_cylinder" )
    holoMaterial( getID(0), "models/gibs/metalgibs/metal_gibs" )
    holoParent( getID(0), AR )
    
    AR2 = holoCreate( getID(1), AR:toWorld(vec(0,0,18)), vec(4,4,4) / 12, AR:toWorld(ang(0,0,0)), vec(255) )
    holoModel( getID(0), "hq_sphere" )
    holoMaterial( getID(0), Mat )
    holoParent( getID(0), AR )
    
    holoCreate( getID(1), AR2:toWorld(vec(0,0,9)), vec(3.5,3.5,18) / 12, AR2:toWorld(ang(0,0,0)), vec(255) )
    holoModel( getID(0), "hq_cylinder" )
    holoMaterial( getID(0), "models/gibs/metalgibs/metal_gibs" )
    holoParent( getID(0), AR2 )
    
    # LEFT ARM
    holoCreate( getID(1), E:toWorld(vec(-12,0,12)), vec(5) / 12, E:toWorld(ang(-90,0,0)), vec(255) )
    holoModel( getID(0), "hq_cylinder" )
    holoMaterial( getID(0), "models/gibs/metalgibs/metal_gibs" )
    holoParent( getID(0), Turn )
    
    AL = holoCreate( getID(1), E:toWorld(vec(-15,0,12)), vec(6) / 12, E:toWorld(ang(0,0,0)), vec(255) )
    holoModel( getID(0), "hq_sphere" )
    holoMaterial( getID(0), Mat )
    holoParent( getID(0), Turn )
    
    holoCreate( getID(1), AL:toWorld(vec(0,0,9)), vec(3.5,3.5,18) / 12, AL:toWorld(ang(0,0,0)), vec(255) )
    holoModel( getID(0), "hq_cylinder" )
    holoMaterial( getID(0), "models/gibs/metalgibs/metal_gibs" )
    holoParent( getID(0), AL )
    
    AL2 = holoCreate( getID(1), AL:toWorld(vec(0,0,18)), vec(4,4,4) / 12, AL:toWorld(ang(0,0,0)), vec(255) )
    holoModel( getID(0), "hq_sphere" )
    holoMaterial( getID(0), Mat )
    holoParent( getID(0), AL )
    
    holoCreate( getID(1), AL2:toWorld(vec(0,0,9)), vec(3.5,3.5,18) / 12, AL2:toWorld(ang(0,0,0)), vec(255) )
    holoModel( getID(0), "hq_cylinder" )
    holoMaterial( getID(0), "models/gibs/metalgibs/metal_gibs" )
    holoParent( getID(0), AL2 )
    
    Height = 36
    
    Mode = 1
}

if( tickClk() )
{
    Ro = rangerOffsetHull( Height+0.1, E:pos(), vec(0,0,-1), vec(12,12,1) )
    
    if( Ro:hit() )
    {
        Distance = Turn:pos():distance(T:pos()) - 29
        
        Pos = Ro:position() + vec(0,0,Height)
        Force = ( Pos - E:pos() ) * 15 - E:vel() / 2
        E:applyForce( vec( 0, 0, Force[3] ) * E:mass() - (Mode!=3)*( Turn:right() * Distance + E:vel():setZ(0) ) )
        
        if( Mode == 1 & changed( Distance < 10 ) )
        {
            if( Distance < 10 )
            {
                timer("grab",2000)
            }
            else
            {
                stoptimer("grab")
            }
        }
    }
    
    E:applyAngForce( ( E:toLocal(ang(0,0,0)) * 50 - E:angVel() ) * E:mass() )
    
    Pitch = ( Ro:hit() ? E:velL()[1] / 10 : Pitch - Pitch / 10 )
    Roll = ( Ro:hit() ? E:velL()[2] / 10 : Roll - Roll / 10 )
    
    Ang = Ang:rotateAroundAxis(vec(0,1,0),Pitch):rotateAroundAxis(vec(1,0,0),-Roll)
    
    holoAng( 1, E:toWorld(Ang) )
    holoPos( 1, E:toWorld(vec(0,0,-Ro:distance()+12)) )
    holoAng( 2, E:angles() )
    
    if( changed(O:keyUse()) & O:keyUse() )
    {
        Target = O:aimPos()
    }
    
    if( Grab & Hold )
    {
        if( T:isPlayerHolding() )
        {
            if( Distance > 10 )
            {
                Mode = 1
                Grab = 0
                Hold = vec()
            }
            else
            {
                Hold = Turn:toLocal(T:pos())
            }
        }
        T:applyForce(((Turn:toWorld(Hold)-T:pos())*15-T:vel()/2)*T:mass())
        if( O:keyUse() )
        {
            T:applyForce((O:aimPos():setZ(T:pos()[3])-T:pos())*15)
            E:applyForce((O:aimPos():setZ(E:pos()[3])-E:pos()):normalized()*(E:pos():distance(O:aimPos())-30))
        }
    }
    
    if( Mode == 2 & changed(O:keyAttack2()) & O:keyAttack2() )
    {
        Mode = 3
        Grab = 0
        Hold = vec()
    }
}

if( clk("grab") )
{
    Grab = 1
    Hold = Turn:toLocal(T:pos())
    Mode = 2
}

interval(100)

if( clk() )
{
    holoAng( holoIndex(Turn), E:toWorld(ang(0,-E:bearing(T:pos())-90,0)) )
    
    local Bearing = bearing( AR:pos(), Turn:angles(), T:pos() )
    local Elevation = elevation( AR:pos(), Turn:angles(), T:pos() )
    local Main_Angle = Turn:toWorld(-ang(Elevation-90,Bearing,0))
    local Dist = min( 35.75, AR:pos():distance(T:pos()) )
    holoAng( holoIndex(AR), toWorldAng( vec(), ang(0,0,mathIt(18,Dist,18)), vec(), Main_Angle ) )
    holoAng( holoIndex(AR2), toWorldAng( vec(), ang(0,0,-mathIt(18,Dist,18)), vec(), Main_Angle ) )
    
    local Bearing = bearing( AL:pos(), Turn:angles(), T:pos() )
    local Elevation = elevation( AL:pos(), Turn:angles(), T:pos() )
    local Main_Angle = Turn:toWorld(-ang(Elevation-90,Bearing,0))
    local Dist = min( 35.75, AL:pos():distance(T:pos()) )
    holoAng( holoIndex(AL), toWorldAng( vec(), ang(0,0,-mathIt(18,Dist,18)), vec(), Main_Angle ) )
    holoAng( holoIndex(AL2), toWorldAng( vec(), ang(0,0,mathIt(18,Dist,18)), vec(), Main_Angle ) )
}

if( last() )
{
    holoDeleteAll()
}
