@name Gait Thingo
@persist [Base]:entity
@persist RangerLength Height OnGround
@persist Proceed Cycle [F_Step F_Prog F_Final F_Old F_Ranger]:array
@persist [Hover]:vector

#@model models/maxofs2d/cube_tool.mdl

function do(I)
{
    # Check for distance against arbitrary threshold
    local Threshold = 10
    if(F_Ranger[I, ranger]:pos():distance(F_Final[I, vector]) > Threshold)
    {
        F_Step[I, number] = 1
        F_Prog[I, number] = 0
    }
}

function number within(N, Min, Max)
{
    return N > Min & N <= Max
}

if(first())
{
    Base = entity():isWeldedTo()
    Base:setMass(500)
    
    RangerLength = 100
    Height = 50
    
    local RX = 80
    local RY = 50
    
    holoCreate(5, Base:toWorld(vec(RX, RY, 0)))
    holoParent(5, Base)
    
    holoCreate(6, Base:toWorld(vec(RX, -RY, 0)))
    holoParent(6, Base)
    
    holoCreate(7, Base:toWorld(vec(-RX, RY, 0)))
    holoParent(7, Base)
    
    holoCreate(8, Base:toWorld(vec(-RX, -RY, 0)))
    holoParent(8, Base)
    
    for(I = 1, 4)
    {
        # holoModel(I + 4, "models/sprops/misc/alphanum/alphanum_" + I + ".mdl")
        holoAlpha(I + 4, 0)
        
        holoCreate(I)
        
        F_Final[I, vector] = F_Old[I, vector] = rangerOffset(RangerLength, holoEntity(I + 4):pos(), -Base:up()):pos()
    }
    
    # rest assured: this code shouldn't be hard to browse.
    # all the stuff is seperated and put into these timers.
    timer("cycle", 50)
    timer("step", 50)
    timer("chassis", 25)
    
    Proceed = 1
}

if(clk("cycle"))
{
    timer("cycle", 50)
    
    # Make sure this number gets divided very largely
    local Speed = Base:vel():length() / 1500
    
    if(Proceed)
    {
        Cycle += max(Speed, 0.1)
        if(Cycle > 1)
        {
            Cycle = Cycle % 1
            if(Speed <= 0)
            {
                Proceed = 0
            }
        }
        
        
        if(within(Cycle, 0, 0.25) & !F_Step[3, number])
        {
            do(3)
        }
        
        if(within(Cycle, 0.25, 0.5) & !F_Step[1, number])
        {
            do(1)
        }
        
        if(within(Cycle, 0.5, 0.75) & !F_Step[4, number])
        {
            do(4)
        }
        
        if(within(Cycle, 0.75, 1) & !F_Step[2, number])
        {
            do(2)
        }
    }
    else
    {
        Proceed = Speed > 0
    }
}

if(clk("step"))
{
    timer("step", 50)
    
    for(I = 1, 4)
    {
        # holoColor(I + 4, F_Step[I, number] ? vec(0, 255, 0) : vec(255, 0, 0))
        
        if(F_Step[I, number])
        {
            local Lead = Base:vel() / 5
            local RD = rangerOffset(RangerLength, holoEntity(I + 4):pos() + Lead, -Base:up())
            local Mid = (RD:pos() + F_Old[I, vector]) / 2 + Base:toWorldAxis(vec(0, 0, RangerLength / 2))
            local Final = bezier(F_Old[I, vector], Mid, RD:pos(), F_Prog[I, number])
            
            F_Final[I, vector] = Final
            
            F_Prog[I, number] = F_Prog[I, number] + 0.2
            
            if(F_Prog[I, number] > 1)
            {
                F_Step[I, number] = 0
                F_Old[I, vector] = Final
                F_Final[I, vector] = RD:pos()
            }
            
            OnGround = RD:hit() & abs(Base:angles():pitch()) < 70 & abs(Base:angles():roll()) < 70
            
            F_Ranger[I, ranger] = RD
        }
        
        holoPos(I, mix(F_Final[I, vector], holoEntity(I):pos(), 0.8))
    }
}

if(clk("chassis"))
{
    #print(4, toString(OnGround))#OnGround = RD:hit() & abs(Base:angles():pitch()) < 70 & abs(Base:angles():roll()) < 70
    
    Hover = (holoEntity(1):pos() + holoEntity(2):pos() + holoEntity(3):pos() + holoEntity(4):pos()) / 4 + vec(0, 0, Height) - Base:pos() - Base:vel() * 0.5
    if(OnGround)
    {
        Base:applyForce(Hover * Base:mass())
    }
    
    timer("chassis", 20)
}