@name Cronoid pathfinder shortcut developer
@outputs A:array F:string
@persist O:entity A2:array
@persist C En Las LEn LC Min TC [Tel T]:array

if(first()){
    O=owner()
    holoCreate(1)
    holoModel(1,"hqicosphere2")
    holoAlpha(1,170)
    
    runOnTick(1)
    runOnChat(1)
    
    F="cpath-"+map()+".txt"
    if(!fileLoaded(F)){
        fileLoad(F)
    }
    runOnFile(1)
    hint("==Cronoid Pathfinder Shortcut Dev.==",7)
    hint("All positioning commands require the gravgun.",6)
    hint("Use E to position to your aim point.",6)
    hint("Use mouse1 and mouse2 to draw and push the vector.",6)
    hint("Type /reg to record the vector to the shortcut data.",6)
    hint("Type /store to save the current shortcut data to the file.",6)
    hint("Type /clear to erase the current shortcut data.",6)
    hint("Type /restore to re-upload the shortcut data from archive.",6)
}
if(fileClk(F) & fileRead(F)){
    A=glonDecode(fileRead(F))
    A2=A:clone()
    print("Data uploaded, "+A:count()+" vectors extant")
}
elseif(!LC){
    findByClass("func_useableladder")
    L=findToArray()
    
    while(L:count()){
        E=L[1,entity]
        Z=E:boxSize():z()/2
        B=E:toWorld(E:boxCenter())
        V=B-vec(0,0,Z)+vec(0,0,16)
        V2=B+vec(0,0,Z)-vec(0,0,16)
        
        A:pushVector(V)
        A:pushVector(V2)
        
        L:remove(1)
    }
    hint("Map ladders collected, "+A:count()+" vectors assessed.",2)
    if(!L:count()){
        LC=1
    }
}
elseif(Tel:count() & LC & !TC){
    Las=Min
    LEn=En
    
    #Nearest teleporter detection
    B=owner():shootPos()
    for(N=1,Tel:count()){
        AP=Tel[N,entity]:toWorld(Tel[N,entity]:boxCenter())
        
        D=AP:distance(B)
        
        En=(D<En|N==1 ? D : En)
        Min=($En ? N : Min)
    }
    
    #Teleport detection
    Dis=Tel[Min,entity]:pos():distance(Tel[Las,entity]:pos())
    if(Min!=Las & Dis>500 & T:count()!=Tel:count()){
        if(!(T[Las,number] + T[Min,number])){
            T[Min,number]=Las
            T[Las,number]=Min
            C+=2
            
            G=Tel:count()-C+2
            hint(G+" unmapped teleports remaining.",2)
        }
    }
    
    #Teleporter vector pairing recording
    if(T:count()==Tel:count()){
        TT=table()
        for(N=1,Tel:count()){
            V1=round(Tel[N,entity]:pos())
            V2=round(Tel[T[N,number],entity]:pos())
            
            if(!(TT[V1:toString(),number]+TT[V2:toString(),number])){
                A:pushVector(V1)
                A:pushVector(V2)
                
                TT[V1:toString(),number]=1
                TT[V2:toString(),number]=1
            }
        }
        Tel=array()
        TC=1
        hint("All available teleports have been mapped.",4)
    }
}
if(LC & !TC & !Tel:count() & findCanQuery()){
    P=findByClass("trigger_teleport")
    Tel=findToArray()
    hint("Now assessing map teleporters.",2)
    hint(P+" teleporters detected.",2)
}

if(O:weapon():type()=="weapon_physcannon"){
    if(O:keyUse()){
        V=O:aimPos()
    }
    elseif(O:keyAttack1()){
        V=holoEntity(1):pos()
        V+=(V-O:shootPos()):normalized()
    }
    elseif(O:keyAttack2()){
        V=holoEntity(1):pos()
        V-=(V-O:shootPos()):normalized()
    }
    if(V){holoPos(1,V)}
}

Mes=O:lastSaid():lower()
Com=Mes=="/clear"|Mes=="/reg"|Mes=="/restore"|Mes=="/store"
Com=Com & chatClk(O)

hideChat(Com)
if(Com){
    if(Mes=="/reg"){
        V=round(holoEntity(1):pos())
        
        A:pushVector(V)
        S="Vector "+V:toString()+" (#"+A:count()+") has been added"
        
        M=mod(A:count(),2)
        if(!M){
            S+=", new pairing complete."
        }
        else{
            S+="."
        }
        print(S)
    }
    elseif(Mes=="/restore"){
        A=A2:clone()
        
        print("Data restored from archive copy.")
    }
    elseif(Mes=="/clear"){
        A=array()
        
        print("Data erased, restore to re-upload or store to destroy.")
    }
    else{
        fileWrite(F,glonEncode(A))
        
        print("Data has been saved to "+F+".")
        A2=A:clone()
    }
}