@name Mechy
@inputs Pod:wirelink Fire 
@outputs Ran Door Props:array Refire GT:array Start
@persist Length1 Length2 FootL:entity FootR:entity E:entity N Radius Wobble X X2 Foot:array Active Height Yaw Shift Space Jump OnGround Alt
@persist Rot C1 C2 Mod G1:ranger G2:ranger GL:array 
rangerPersist(1)

if (first()|dupefinished()) {
    Wobble = 20
    
    E = entity():isWeldedTo()
    E:setMass(500)
    
    FootL = holoCreate(9,E:pos(),vec(1),E:angles())
    FootR = holoCreate(10,E:pos(),vec(1),E:angles())
            
    E:setAlpha(255)
                       
    holoParent(9,E)
    holoParent(10,E)
                        
    Length1=55
    Length2=55
    
    function number cosine(A, B, C){
        return acos((A^2 + B^2 - C^2) / (2*A*B))
    }
    function ik(L1,L2,Hip:vector,End:vector,I1,I2){
        local Axis = entity():toLocalAxis(End - Hip)
        local Angle = Axis:toAngle():setRoll(-bearing(Hip, entity():angles(), End))
        local Dist = min(Axis:length(), L1 + L2)
        local Quat = quat(Angle) * qRotation(vec(0,90 + cosine(Dist, L1, L2),0))
        holoAng(I1,entity():toWorld(Quat:toAngle()))
        holoAng(I2, holoEntity(I1):toWorld(ang(cosine(L2, L1, Dist) + 180, 0, 0)))
    }
    
    holoCreate(1,E:toWorld(vec(24,12.2,-16.5)),vec(1))
    holoParent(1,E)
    
    holoCreate(2,holoEntity(1):toWorld(vec(0,0,Length1-20)))
    holoParent(2,1)
          
    holoCreate(3,E:toWorld(vec(24,-12.2,-16.5)),vec(1))
    holoParent(3,E)
    
    holoCreate(4,holoEntity(3):toWorld(vec(0,0,Length1-20)))
    holoParent(4,3)
    
    for (I = 1,4) { holoModel(I,"hq_sphere") }
    
    rangerFilter(E)
    Radius = 40
}

runOnTick(1)

ik(Length1,Length2,holoEntity(18):pos(),FootL:pos(),1,2)
ik(Length1,Length2,holoEntity(17):pos(),FootR:pos(),3,4)

Vel = E:velL():y()/8

Seat = Pod["Entity",entity]
Driver = Seat:driver()
W = Driver:keyForward()
A = Driver:keyLeft()
S = Driver:keyBack()
D = Driver:keyRight()
Alt = Driver:keyWalk()
Space = Driver:keyJump()
Mouse1 = Driver:keyAttack1()
Mouse2 = Driver:keyAttack2()
Shift = Driver:keySprint()
Active = Driver:isPlayer()

Fade = !Active

Mod = clamp(Mod,250,1000) 

if (Active==1) {
    G1=rangerOffset(50000,holoEntity(65):pos(),holoEntity(65):forward())
    G2=rangerOffset(50000,holoEntity(66):pos(),holoEntity(66):forward())
    
    if (Alt|Space) { Height = 55 }
    if (!Alt&!Space) { Height = 75 }
    if (OnGround) { Radius = 50 }
    else { Radius = 0 }
    if (Space) { Mod += 4 }
    if ($Space&!Space&OnGround) {
        Jump = Mod
        soundPlay(-3,1,"mvm/giant_pyro/giant_pyro_step_04.wav")
    }
    if (OnGround == 0) {
        Jump = 0
        Mod = 0
    }   
}

if (Active == 0) {
    Height = 55
    Door -= 1
    Radius = 1
}
    
X2 = clamp(X2,-3,3)

if (A) { Yaw=2 }
if (D) { Yaw=-2 }
if (!A&!D) { Yaw=0 }

Door = clamp(Door,-215,-90)

if ($Active&Active) {
    soundPlay(-1,5,"ambient/machines/thumper_startup1.wav")
    timer("ac",4100)
    soundPitch(-1,70)
}
if ($Active&!Active) {
    soundPlay(-1,8,"ambient/machines/thumper_shutdown1.wav")
    soundVolume(-5,0.5)
    soundPitch(-1,70)
}

rangerFilter(E)
RR = rangerOffset(E:toWorld(vec(0,-20,0)),E:toWorld(vec(cos(N-180)*Radius,-20,-105+max(sin(N-180)*Radius*1.5*(W-S),0))))

rangerFilter(E)
RL = rangerOffset(E:toWorld(vec(0,20,0)),E:toWorld(vec(cos(N)*Radius,20,-105+max(sin(N)*Radius*1.5*(W-S),0))))

holoPos(9,RL:pos()+vec(0,0,10))
holoPos(10,RR:pos()+vec(0,0,10))

if ((W|S)&OnGround==1) {
    if (X) { X2-=0.18*(Shift+1) }
    if (!X) { X2+=0.18*(Shift+1) }
    if (W) { N+=2*(Shift+1)*((S-W)*2) }
    if (S) { N+=2*(Shift+1)*((W-S)*2) }

     if ((changed(RR:hit())&RR:hit())|(changed(RL:hit())&RL:hit())) {
        Ran=int(random(1,9))
        soundStop(1)
        soundPlay(1,0.4,Foot[Ran,string])
        X=!X
        soundVolume(1,1)
    }
} else { X2=0 }
 
rangerFilter(E) 
R = rangerOffset(E:pos(),E:pos()-vec(0,0,120))

if (R:hit()) {
    OnGround=1
    Diff = Height+sin(N*2)*(Wobble*(Shift+1))-R:distance()

    E:applyForce(vec(0,0,Diff)*2*E:mass()-(E:vel())*E:mass()+E:forward()*(W-S)*200/(Alt+1)/(Space+1)*(Shift+1)*E:mass()+E:up()*Jump*E:mass())
} else { OnGround=0 }

function entity:turnTo(Tarang:angle) {
    local V = This:toLocal(rotationVector(quat(Tarang)/quat(This))+This:pos())
    This:applyTorque((1000*V - 30*This:angVelVector())*This:inertia()/3)
}

E:turnTo(E:angles():setPitch(0):setRoll(X2):setYaw(E:angles():yaw()+Yaw))

Foot[1,string]="mvm/giant_heavy/giant_heavy_step01.wav"
Foot[2,string]="mvm/giant_heavy/giant_heavy_step02.wav"
Foot[3,string]="mvm/giant_heavy/giant_heavy_step03.wav"
Foot[4,string]="mvm/giant_heavy/giant_heavy_step04.wav"
Foot[5,string]="mvm/giant_soldier/giant_soldier_step01.wav"
Foot[6,string]="mvm/giant_soldier/giant_soldier_step02.wav"
Foot[7,string]="mvm/giant_soldier/giant_soldier_step03.wav"
Foot[8,string]="mvm/giant_soldier/giant_soldier_step04.wav"

Props[1,entity]=entity():isWeldedTo()
