@name A-Chair
@inputs Chair:entity
@persist Path:array CurNode Pos:vector FinTarget:vector Going
@persist CurHolo LastLine:vector Iteration MaxHolo 

@persist [FirstNode LastNode]:string Calculating 
@persist SearchI SearchDist LastPos:vector
@persist LastDist
@persist NodeArray:array Target:entity

@persist CalcN TargetP:entity

@trigger PathClk Chair
#include "lib/path/astar"
#include "e2shared/graph_gm_construct"

runOnChat(1)


if (first()) {
    MaxHolo=30
    setGraph(GMGraph)
    foreach(I,V:table=GMGraph) {NodeArray:pushString(I)}
    print("Total nodes: ",NodeArray:count())
    
    for(I=1,MaxHolo) {
        holoCreate(I)
        holoAlpha(I,0)
    }
    function startup() {
        if (FirstNode & LastNode) {
            Chair:printColorDriver(vec(255,255,0),"[sChair] ",vec(0,255,0),"Prepare for departure.")
            rangerHitEntities(0)
            local Ray_Fin=rangerOffset(LastPos,LastPos-vec(0,0,50)):position()
            rangerHitEntities(1)
            FinTarget=Ray_Fin
            Chair:soundPlay(1,0,"misc/talk.wav")
            for(I=1, MaxHolo) {
                holoAlpha(I,0)
            }
            CurHolo=0
            Iteration=0
            Going=1
            
            path(FirstNode,LastNode,50)
        }
    }
}

if (~Chair & Chair) {
    entity():propNotSolid(1) 
    entity():setAlpha(0)
    
    #lightCreate(1)
    #lightPos(1,Chair:pos())
    #lightParent(1,Chair)
    #lightColor(1,vec(64))
}

if (chatClk(Chair:driver())) {
    local Msg=Chair:driver():lastSaid():explode(" ")
    if (Msg[1,string]=="goto" & !Going & !Calculating) {
        Target=findPlayerByName(Msg[2,string])
        Chair:printColorDriver(vec(255,255,0),"[sChair] ",vec(255),"Pathing to player ",vec(0,255,0),Target:name(),vec(255),".")
        FirstNode=""
        local FirstPos=Chair:pos()
        local FirstDist=9e9999
        
        LastNode=""
        LastPos=Target:pos()+Target:aabbSize()*vec(0,0,0.5)
        LastDist=9e9999
        
        foreach(I,V:table=GMGraph) {
            local Dist=V["Pos",vector]:distance(FirstPos)
            if (Dist<FirstDist) {
                FirstDist=Dist
                FirstNode=I
            }
        }
        
        Chair:printColorDriver(vec(255,255,0),"[sChair] ",vec(255),"Start node: ",vec(0,255,0),FirstNode,vec(255),".")
        Chair:printColorDriver(vec(255,255,0),"[sChair] ",vec(0,255,0),"Calculating final node...")

        SearchI=0
        SearchDist=9e99
        Calculating=1
        
        timer("FindLastNode",1)
    }
}

if (clk("FindLastNode")) {
    SearchI++
    local Node=NodeArray[SearchI,string]
    local Ray=rangerOffset(GMGraph[Node,table]["Pos",vector]+vec(0,0,1),LastPos)
    if (Ray:entity()==Target) {
        local Dist=Ray:distance()
        if (Dist<LastDist) {
            LastNode=Node
            LastDist=Dist
        }
    }
    if (SearchI<NodeArray:count()) {
        timer("FindLastNode",5)
    } else {
        if (LastNode) {
            Chair:printColorDriver(vec(255,255,0),"[sChair] ",vec(255),"End node: ",vec(0,255,0),LastNode,vec(255),".")
            Calculating=0
            startup()
        } else {
            Chair:printColorDriver(vec(255,255,0),"[sChair] ",vec(255,0,0),"No final node found.")
            Calculating=0
        }
    }
}

if (clk("PathClk")) {
    print("pathclk")
    Chair:propNotSolid(1)
    local Interval=1/PathClk["Path",array]:count()
    local Max=vec(0,255,0)
    local Min=vec(255,0,0)
    print(PathClk["Error",string])
    
    holoCreate(300)
    holoCreate(301)
    holoModel(300,"models/hunter/plates/plate.mdl")
    holoModel(301,"models/hunter/plates/plate.mdl")
    holoAng(301,ang(0,90,0))
    holoParent(301,300)
    holoScale(300,vec(10,2,0))
    holoScale(301,vec(10,2,0))
    holoColor(300,vec(255,0,0))
    holoColor(301,vec(255,0,0))
    holoMaterial(300,"debug/debugdrawflat")
    holoMaterial(301,"debug/debugdrawflat")
    holoAlpha(300,128)
    holoAlpha(301,128)
    
    holoPos(300,FinTarget)
    
    Path=PathClk["Path",array]
    CurNode=1
    Pos=Chair:pos()
    LastLine=Pos
    
    Chair:soundPlay(0,0,"music/bump_in_the_night.wav")
    Chair:soundPlay(1,0,"vehicles/junker/jnk_throttle_off_slow_loop2.wav")
    
    timer("gotostart",10)
}
local Shifting=Chair:driver():keySprint()
local Shift=Shifting ? 5 : 1
local MoveSpeed=15*Shift
soundPitch(0,Shifting ? 200 : 100)

if (clk("gotostart")) {
    Iteration+=0.1
    local TargetPos=GMGraph[Path[1,string],table]["Pos",vector]
    Ang=(TargetPos-Pos):toAngle()*ang(0,1,1)
    local RayForward=rangerOffset(5,Pos,(Ang+ang(45,0,0)):forward())
    Ang+=(TargetPos-RayForward:pos()):toAngle()*ang(1,0,0)
    Pos=Pos+Ang:forward()*MoveSpeed
    Pos=rangerOffset(5,Pos,vec(0,0,-1)):pos()
    
    Chair:setPos(Pos)
    Chair:setAng(Ang*ang(0,1,1)-ang(0,90,0))
    
    #print(_HUD_PRINTCENTER,toString(Pos)+"\n"+toString(PrePos))
    if (Pos:distance(TargetPos)<MoveSpeed*2) {
        timer("run",100)
    } else {timer("gotostart",100)}
}

if (clk("run")) {
    local TargetPos=GMGraph[Path[CurNode+1,string],table]["Pos",vector]
    Ang=(TargetPos-Pos):toAngle()*ang(0,1,1)
    local RayForward=rangerOffset(5,Pos,(Ang+ang(45,0,0)):forward())
    Ang+=(TargetPos-RayForward:pos()):toAngle()*ang(1,0,0)
    Pos=Pos+Ang:forward()*MoveSpeed
    Pos=rangerOffset(5,Pos,vec(0,0,-1)):pos()
    #print(_HUD_PRINTCENTER,toString(Pos)+"\n"+toString(PrePos))
    if (Pos:distance(TargetPos)<MoveSpeed*2) {
        CurNode++
    }
    holoAng(300,ang(0,curtime()*5,0))
    Iteration+=0.1
    
    Chair:setPos(Pos)
    Chair:setAng(Ang*ang(0,1,1)-ang(0,90,0))
    if (CurNode<Path:count()) {
        timer("run",100)
    } else {
        timer("Finish",1)
    }
}

if (clk("Finish")) {
    Iteration+=0.1
    local TargetPos=FinTarget
    Ang=(TargetPos-Pos):toAngle()*ang(0,1,1)
    local RayForward=rangerOffset(5,Pos,(Ang+ang(45,0,0)):forward())
    Ang+=(TargetPos-RayForward:pos()):toAngle()*ang(1,0,0)
    Pos=Pos+Ang:forward()*MoveSpeed
    Pos=rangerOffset(5,Pos,vec(0,0,-1)):pos()
    
    Chair:setPos(Pos)
    Chair:setAng(Ang*ang(0,1,1)-ang(0,90,0))
    
    if (Pos:distance(TargetPos)<=MoveSpeed*2) {
        soundStop(0)
        soundStop(1)
        Chair:soundPlay(2,0,"buttons/button3.wav")
        Chair:propNotSolid(0)
        holoColor(300,vec(0,255,0))
        holoColor(301,vec(0,255,0))
        Going=0
        Chair:printColorDriver(vec(255,255,0),"[sChair] ",vec(0,255,0),"Reached destination.")
    } else {
        timer("Finish",100)
    }
}

if (Going & Pos:distance(LastLine)>30) {
    CurHolo=(CurHolo+1)%MaxHolo
    local HoloID=CurHolo
    holoDisableShading(HoloID,1)
    holoMaterial(HoloID,"debug/debugdrawflat")
    holoColor(HoloID,vec(172,0,0))
    holoModel(HoloID,"models/hunter/plates/plate.mdl")
    
    local StartPos=LastLine+vec(0,0,5)
    local EndPos=Chair:pos()+vec(0,0,5)
    local Scale=(StartPos-EndPos):length()/3
    holoScale(HoloID,vec(Scale,2,0))
    holoPos(HoloID,(StartPos+EndPos)/2)
    holoAng(HoloID,(StartPos-EndPos):toAngle())
    holoAlpha(HoloID,128)
    
    LastLine=Pos
}
