@name Mech
@inputs Pod:wirelink 
@persist [R1 R2]:vector 
@persist Hip:entity TPOSV:array 
@persist Index Height Width Offset Walk Yaw L1 L2 L3 Y Y2 Total 
@persist Mode Open State 
@model models/hunter/blocks/cube05x05x025.mdl

local Seat = Pod["Entity",entity]
local Driver = Seat:driver()
local Active = Driver:isPlayer()
local W = Driver:keyForward()
local A = Driver:keyLeft()
local S = Driver:keyBack()
local D = Driver:keyRight()
local Shift = Driver:keySprint()
local Space = Driver:keyJump() 
local M1 = Driver:keyAttack1()
local M2 = Driver:keyAttack2() 
local R = Driver:keyReload()

if (first() | dupefinished()) {
    Height = 55 ## Height of torso above the feet
    Width  = 25  ## Width between hipjoints and hip prop
    Offset = 0   ## Distance of hipjoint up and down

    Hip = entity()
    Pos = Hip:pos()
    
    Hip:setMass(50000)
    
    L1 = 35
    L2 = 25
    L3 = 35
    Total = L1 + L2 + L3
    Y = 1
    Y2 = -0.5
    
    R1 = rangerOffset(30,Hip:toWorld(vec(Width*Y2,-Width*Y,20)),vec(0,0,-1)):position() 
    R2 = rangerOffset(30,Hip:toWorld(vec(Width*Y2,Width*Y,20)),vec(0,0,-1)):position()
    
    Yaw = Hip:angles():yaw()
    
    timer("checkfeet",10)
    
    rangerFilter(Hip)
    rangerPersist(1)
    
    holoCreate(1,Hip:toWorld(vec(0,-Width,-Offset)))
    holoParent(1,Hip)
    
    holoCreate(2,holoEntity(1):toWorld( vec(L1,0,0)))
    holoParent(2,1)
    
    holoCreate(3,holoEntity(2):toWorld(vec(0,0,-L2)))
    holoParent(3,2)
    
    holoCreate(4,holoEntity(3):toWorld(vec(0,0,L3)))
    holoParent(4,3)
    
    holoCreate(5,Hip:toWorld(vec(0,Width,-Offset)))
    holoParent(5,Hip)
    
    holoCreate(6,holoEntity(5):toWorld( vec(L1,0,0)))
    holoParent(6,5)
    
    holoCreate(7,holoEntity(6):toWorld(vec(0,0,-L2)))
    holoParent(7,6)
    
    holoCreate(8,holoEntity(7):toWorld(vec(0,0,L3)))
    holoParent(8,7)
    
    for (A0 = 1,8) {holoAlpha(A0,0)}
    
    holoCreate(10)
    holoModel(10,"hq_cylinder")
    holoPos(10,holoEntity(1):toWorld(vec(L1*0.6,0,0)))
    holoAng(10,holoEntity(1):toWorld(ang(270,0,180)))
    holoScale(10,vec(0.7,0.7,3))
    holoColor(10,vec(230,210,160))
    holoParent(10,1)
    
    holoCreate(11)
    holoModel(11,"hq_cylinder")
    holoPos(11,holoEntity(2):toWorld(vec(0,0,-L2*0.5)))
    holoAng(11,holoEntity(2):toWorld(ang(0,0,0)))
    holoScale(11,vec(0.7,0.7,2))
    holoColor(11,vec(230,210,160))
    holoParent(11,2)
    
    holoCreate(12)
    holoModel(12,"hq_cylinder")
    holoPos(12,holoEntity(3):toWorld(vec(0,0,L3*0.5)))
    holoAng(12,holoEntity(3):toWorld(ang(0,0,0)))
    holoScale(12,vec(0.7,0.7,2))
    holoColor(12,vec(230,210,160))
    holoParent(12,3)
    
    holoCreate(13)
    holoModel(13,"hq_cylinder")
    holoPos(13,holoEntity(5):toWorld(vec(L1*0.6,0,0)))
    holoAng(13,holoEntity(5):toWorld(ang(270,0,180)))
    holoScale(13,vec(0.7,0.7,3))
    holoColor(13,vec(230,210,160))
    holoParent(13,5)
    
    holoCreate(14)
    holoModel(14,"hq_cylinder")
    holoPos(14,holoEntity(6):toWorld(vec(0,0,-L2*0.5)))
    holoAng(14,holoEntity(2):toWorld(ang(0,0,0)))
    holoScale(14,vec(0.7,0.7,2))
    holoColor(14,vec(230,210,160))
    holoParent(14,6)
    
    holoCreate(15)
    holoModel(15,"hq_cylinder")
    holoPos(15,holoEntity(7):toWorld(vec(0,0,L3*0.5)))
    holoAng(15,holoEntity(7):toWorld(ang(0,0,0)))
    holoScale(15,vec(0.7,0.7,2))
    holoColor(15,vec(230,210,160))
    holoParent(15,7)
    
    for (A0 = 1,15) {holoAlpha(A0,0)}
    
    #Right Leg
    holoCreate(16)
    holoModel(16,"models/gibs/scanner_gib01.mdl")
    holoPos(16,holoEntity(10):toWorld(vec(1.0,0,-6)))
    holoAng(16,holoEntity(10):toWorld(ang(90,0,0)))
    holoScale(16,vec(1.3,1.3,1.3))
    holoParent(16,10)
    
    holoCreate(17)
    holoModel(17,"models/gibs/scanner_gib01.mdl")
    holoPos(17,holoEntity(10):toWorld(vec(1.0,0,0)))
    holoAng(17,holoEntity(10):toWorld(ang(-90,180,0)))
    holoScale(17,vec(1.3,1.3,1.3))
    holoParent(17,10)
    
    holoCreate(18)
    holoModel(18,"models/gibs/scanner_gib01.mdl")
    holoPos(18,holoEntity(11):toWorld(vec(1.0,0,0)))
    holoAng(18,holoEntity(11):toWorld(ang(-90,180,0)))
    holoScale(18,vec(1.3,1.3,1.3))
    holoParent(18,11)
    
    holoCreate(19)
    holoModel(19,"models/gibs/scanner_gib01.mdl")
    holoPos(19,holoEntity(12):toWorld(vec(1.0,0,0)))
    holoAng(19,holoEntity(12):toWorld(ang(90,180,0)))
    holoScale(19,vec(1.3,1.0,1.3))
    holoParent(19,12)
    
    holoCreate(20)
    holoModel(20,"models/props_combine/combine_barricade_bracket01b.mdl")
    holoPos(20,holoEntity(4):toWorld(vec(5,0,8)))
    holoAng(20,holoEntity(4):toWorld(ang(0,0,90)))
    holoScale(20,vec(1,1,1))
    holoParent(20,4)
    
    #Left Leg
    holoCreate(21)
    holoModel(21,"models/gibs/scanner_gib01.mdl")
    holoPos(21,holoEntity(13):toWorld(vec(1.0,0,-6)))
    holoAng(21,holoEntity(13):toWorld(ang(90,0,0)))
    holoScale(21,vec(1.3,1.3,1.3))
    holoParent(21,13)
    
    holoCreate(22)
    holoModel(22,"models/gibs/scanner_gib01.mdl")
    holoPos(22,holoEntity(13):toWorld(vec(1.0,0,0)))
    holoAng(22,holoEntity(13):toWorld(ang(-90,180,0)))
    holoScale(22,vec(1.3,1.3,1.3))
    holoParent(22,13)
    
    holoCreate(23)
    holoModel(23,"models/gibs/scanner_gib01.mdl")
    holoPos(23,holoEntity(14):toWorld(vec(1.0,0,0)))
    holoAng(23,holoEntity(14):toWorld(ang(-90,180,0)))
    holoScale(23,vec(1.3,1.3,1.3))
    holoParent(23,14)
    
    holoCreate(24)
    holoModel(24,"models/gibs/scanner_gib01.mdl")
    holoPos(24,holoEntity(15):toWorld(vec(1.0,0,0)))
    holoAng(24,holoEntity(15):toWorld(ang(90,180,0)))
    holoScale(24,vec(1.3,1.0,1.3))
    holoParent(24,15)
    
    holoCreate(25)
    holoModel(25,"models/props_combine/combine_barricade_bracket01a.mdl")
    holoPos(25,holoEntity(8):toWorld(vec(5,0,8)))
    holoAng(25,holoEntity(8):toWorld(ang(180,180,90)))
    holoScale(25,vec(1,1,1))
    holoParent(25,8)
    
    #Jetpack
    holoCreate(26)
    holoModel(26,"models/props_combine/combine_emitter01.mdl")
    holoPos(26,Hip:toWorld(vec(-8,10,10)))
    holoAng(26,Hip:toWorld(ang(-90,0,0)))
    holoScale(26,vec(1,1,1.5))
    holoParent(26,Hip)
    
    holoCreate(27)
    holoModel(27,"models/props_combine/combine_emitter01.mdl")
    holoPos(27,Hip:toWorld(vec(-8,-10,10)))
    holoAng(27,Hip:toWorld(ang(-90,0,0)))
    holoScale(27,vec(1,1,1.5))
    holoParent(27,Hip)
    
    holoCreate(28)
    holoModel(28,"models/props_combine/breenlight.mdl")
    holoPos(28,Hip:toWorld(vec(-18,0,10)))
    holoAng(28,Hip:toWorld(ang(0,180,0)))
    holoScale(28,vec(2,3,2))
    holoParent(28,Hip)
    
    #Body
    holoCreate(29)
    holoModel(29,"models/props_combine/combine_barricade_med01a.mdl")
    holoPos(29,Hip:toWorld(vec(17,0,10)))
    holoAng(29,Hip:toWorld(ang(90,180,0)))
    holoScale(29,vec(0.5,0.5,0.5))
    holoParent(29,Hip)
    
    holoCreate(30)
    holoModel(30,"models/props_combine/combine_barricade_bracket01a.mdl")
    holoPos(30,Hip:toWorld(vec(0,-15,10)))
    holoAng(30,Hip:toWorld(ang(-90,0,0)))
    holoScale(30,vec(0.7,0.6,0.6))
    holoParent(30,Hip)
    
    holoCreate(31)
    holoModel(31,"models/props_combine/combine_barricade_bracket01b.mdl")
    holoPos(31,Hip:toWorld(vec(0,15,10)))
    holoAng(31,Hip:toWorld(ang(-90,0,0)))
    holoScale(31,vec(0.7,0.6,0.6))
    holoParent(31,Hip)
    
    holoCreate(32)
    holoModel(32,"hq_cylinder")
    holoMaterial(32,"models/props_combine/metal_combinebridge001")
    holoPos(32,Hip:toWorld(vec(-9,0,42)))
    holoAng(32,Hip:toWorld(ang(-36,0,90)))
    holoScale(32,vec(0.4,0.4,2.6))
    holoParent(32,Hip)
    
    holoCreate(33)
    holoModel(33,"models/props_combine/combine_barricade_med01b.mdl")
    holoPos(33,Hip:toWorld(vec(8,0,0)))
    holoAng(33,Hip:toWorld(ang(-35,0,0)))
    holoScale(33,vec(0.5,0.5,0.8))
    holoColor(33,vec(0),180)
    holoParent(33,32)
    
    holoClipEnabled(33,1,1)
    holoClip(33,1,vec(0,0,47),vec(0,0,-1),0)
    
    holoClipEnabled(33,2,1)
    holoClip(33,2,vec(9,0,0),vec(1,0,0),0)
    
    holoCreate(34)
    holoMaterial(34,"models/props_combine/metal_combinebridge001")
    holoPos(34,Hip:toWorld(vec(-11,0,38)))
    holoAng(34,Hip:toWorld(ang(90,0,0)))
    holoScale(34,vec(0.9,2.6,0.1))
    holoParent(34,Hip)
    
    holoCreate(35)
    holoMaterial(35,"models/props_combine/metal_combinebridge001")
    holoPos(35,Hip:toWorld(vec(-7.5,-0.4,45.9)))
    holoAng(35,Hip:toWorld(ang(-36,0,0)))
    holoScale(35,vec(0.7,2.6,0.1))
    holoParent(35,32)
    
    holoCreate(100)
    holoPos(100,Hip:toWorld(vec(-35,-10,-5)))
    holoAng(100,Hip:toWorld(ang(0,0,0)))
    holoScale(100,vec(0.1,0.1,0.1))
    holoParent(100,Hip)
    
    holoCreate(101)
    holoPos(101,Hip:toWorld(vec(-35,10,-5)))
    holoAng(101,Hip:toWorld(ang(0,0,0)))
    holoScale(101,vec(0.1,0.1,0.1))
    holoParent(101,Hip)
}

if (changed(Active) & Active) {if(State == 0) {State = 1} else {State = 0}}

if (changed(!Active) & !Active) {if(State == 0) {State = 1} else {State = 0}}

if(State == 1) {
    if(Open > -45) {
        Open -= 1
        holoAng(32,Hip:toWorld(ang(-36+Open,0,90)))
    }
} else {
    if(Open < 0) {
        Open += 1
        holoAng(32,Hip:toWorld(ang(-36+Open,0,90)))
    }
}

function number cos(A,B,C) { 
    return acos((C^2 + B^2 - A^2)/(2*B*C))
}
     
function holoanim(H,K,A,F,Ta:vector,N,D1,D2,D3) {
    if (Mode == 0) {
        Dis = vec2(TPOSV[N,vector]):distance(vec2(Ta))
        Ofz = clamp(vec2(Ta):distance(vec2(TPOSV[N,vector]))/5,0,100)
        Ang = ((Ta + vec(0,0,Ofz)) - TPOSV[N,vector]):toAngle() 
        TPOSV[N,vector] = (TPOSV[N,vector] + vec(clamp(Dis,0,30),0,0):rotate(Ang))
    }
    
    if (Mode == 1) {TPOSV[N,vector] = Ta}
    
    Bea = -bearing(holoEntity(H):pos(),Hip:angles(),TPOSV[N,vector])
    Ang = Hip:toLocalAxis(TPOSV[N,vector] - holoEntity(H):pos()):toAngle():setRoll(Bea)
    Off = Total - abs(min(holoEntity(H):pos():distance(TPOSV[N,vector]),Total))
    Qua = quat(Ang) * qRotation(vec(0,-Off + 10,0))
    holoAng(H,Hip:toWorld(slerp(quat(H),Qua,1):toAngle()))
    
    Distance = min(holoEntity(K):pos():distance(TPOSV[N,vector]),(D2 + D3))
    Axis = holoEntity(H):toLocalAxis(holoEntity(K):pos() - TPOSV[N,vector])
    Atan = atan(-Axis:z(), Axis:x()) + cos(D3,D2,Distance) + 90
    
    holoAng(K,holoEntity(H):toWorld(ang(Atan,0,0)))
    holoAng(A,holoEntity(K):toWorld(ang(cos(Distance,D2,D3),0,0)))
    holoAng(F,Hip:angles())
}

function applytorque(TaAn:angle,Ta:entity) { 
    Ve = Ta:toLocal(rotationVector(quat(TaAn)/quat(Ta)) + Ta:pos())
    Ta:applyTorque((150 * Ve - 25 * Ta:angVelVector()) * Ta:inertia())
}
    
interval(30)

if (changed(R) & R) {if(Mode == 0) {Mode = 1} else {Mode = 0}}

if (Mode == 0) {
    Swag = clamp(vec2(Hip:pos()):distance(vec2((TPOSV[1,vector] + TPOSV[2,vector])/2))/(5+Shift*5), 0, 20)
    TZ = (R1:z() + R2:z())/2 + Swag
    Up = vec(0,0,TZ + Height + Offset - Hip:pos():z())
    Ac = Hip:forward() * (W-S)*(200) + Hip:right() * (D-A) * 12*Space
    Pa = -Hip:vel()*0.1
    Hip:applyForce((Up * 5 + Ac + Pa) * Hip:mass() - Hip:vel() * Hip:mass())
}
if (Mode == 1) {
    RZ = rangerOffset(500,Hip:pos(),vec(0,0,-1)):distance()
    
    if (RZ < Height*1.2) {Up = vec(0,0,Height*1.2-RZ) * 3.7 - vec(0,0,Hip:vel():z())}
    Ac = vec(0,0,1)*(Space-Shift)*200 + Hip:forward()*(W-S)*(400+Shift*10)
    Pa = vec(0,0,1) - Hip:vel()
    Hip:applyForce((Ac + Pa + Up/20) * Hip:mass())
}

if (changed(Active) & Active) {
    Hip:soundPlay(0,0,"ambient/machines/hydraulic_1.wav")
    Hip:soundPlay(5,0,"ambient/turbine5.wav")
    soundPitch(5,10)
}

if (changed(Mode == 1) & Mode == 1) {
    Hip:soundPlay(1,0,"ambient/atmosphere/noise2.wav")
    Hip:soundPlay(2,0,"ambient/atmosphere/mountain_wind_lp_01.wav")
    holoEntity(100):setTrails(75,75,0.2,"trails/laser",vec(150,150,255),255)
    holoEntity(101):setTrails(75,75,0.2,"trails/laser",vec(150,150,255),255)
}

if (changed(Mode == 0) & Mode == 0) {
    soundStop(0)
    soundStop(1)
    soundStop(2)
    holoEntity(100):removeTrails()
    holoEntity(101):removeTrails()
}

if (clk("checkfeet")) { 
    timer("checkfeet",412 - clamp(Hip:vel():length() / 2,0,390))
    Walk = !Walk
}

VelX = clamp(abs(Hip:velL():x())*(W-S)/2,-50,50)
VelY = clamp(abs(Hip:velL():y())*(A-D)*Space,-6,6)
AngV = clamp(Hip:angVel():yaw()/2,-6,6)

if (Mode == 0) {
    if (changed(Walk == 1) & Walk == 1) {
        if ((W|S|A|D)) {Hip:soundPlay(3,0.3,"npc/dog/dog_footstep" + randint(1,4) + ".wav")}
        
        TPOSV[2,vector] = holoEntity(8):pos() 
        R2 = rangerOffset(1000,Hip:toWorld(vec(VelX + Width * Y2,VelY + Width * Y + (AngV * (A-D)),100)),vec(0,0,-1)):position()
    }
    
    if (changed(Walk == 0) & Walk == 0) {
        if ((W|S|A|D)) {Hip:soundPlay(4,0.3,"npc/dog/dog_footstep" + randint(1,4) + ".wav")}
        
        TPOSV[1,vector] = holoEntity(4):pos()
        R1 = rangerOffset(1000,Hip:toWorld(vec(VelX + Width * Y2,VelY - Width * Y - (AngV * (A-D)),100)),vec(0,0,-1)):position()
    }
}

if (Mode == 1) {
    R1 = Hip:toWorld(vec(-25-VelX/7,-Width*Y,0))-vec(0,0,50)
    R2 = Hip:toWorld(vec(-25-VelX/7,Width*Y,0))-vec(0,0,50)
}

if (Active) { 
    if(Mode == 0){if((W|S|A|D) & !Space){Yaw = (Yaw + (A-D)*2)%360}}
    
    if (Mode == 1) {Yaw = (Yaw + (A-D)*3)%360}
}

if (!Active) {
    soundStop(5)
    Yaw = Hip:angles():yaw()
}
    
if (Mode == 0) {A1 = ang(Swag/2,Yaw,-5*(A-D))}

if (Mode == 1) {A1 = ang(VelX/25,Yaw,-AngV/1.5)}
    
applytorque(A1,Hip) 

holoanim(1,2,3,4,R1,1,L1,L2,L3)
holoanim(5,6,7,8,R2,2,L1,L2,L3)
