@name tr_test_game2
@inputs 
@outputs 
@persist [CurTime DeltaTime] Players:table TempDelay TempTime Lines:table
@trigger none

if (first()) {
    
    #--------------------------------------------------
    #-- Delta time function
    
    function dt( Interval ) {
        interval(Interval)
        
        DeltaTime = curtime() - CurTime
        CurTime   = curtime()    
    }

    CurTime = curtime()


    #--------------------------------------------------
    #-- Minimum distance from point to line 
    
    function number linePointDistance( LineA:vector2, LineB:vector2, Point:vector2 ) {
        local Length2 = LineA:distance2(LineB)
        
        # Case: LineA == LineB
        if (Length2 == 0) { return Point:distance(LineA) }

        local Dot = (Point - LineA):dot(LineB - LineA) / Length2

        # Case: Beyond LineA
        if (Dot < 0) { return Point:distance(LineA) }

        # Case: Beyond LineB
        if (Dot > 1) { return Point:distance(LineB) }

        # Case: On Segment
        return Point:distance(LineA + Dot*(LineB - LineA))
    }
    

    #--------------------------------------------------
    #-- Create new player table
    
    function table addPlayer( Player:entity ) {
        local SteamID = Player:steamID()
        local Hash = hash(SteamID)
        
        Players[SteamID, table] = table(
            "pEnt"  = Player,
            "pHash" = Hash,
            "pPos"  = entity():pos() + randvec(-50,50):setZ(0),
            "pDir"  = vec(1, 0, 0),
            "pYaw"  = 0,
            "pVel"  = 50,
            
            "pLineA" = vec2(),
            "pLineB" = vec2(),
            "pLines" = table(),
            "plineN" = 0,
            
            "debug"  = Hash + 1,
            
            "tempdel" = random(0.5, 1),
            "temptim" = curtime()
        )   
        
        holoCreate(Hash)
        holoColor(Hash, hsv2rgb(360/Players:count(), 1, 1))
        
        Players[SteamID, table]["color", vector] = hsv2rgb(360/Players:count(), 1, 1)
        
        return Players[SteamID, table]
    }
    
    
    #--------------------------------------------------
    #-- Set player direction
    
    function table:setPlayerDir( AddDir ) {
        This["pYaw", number] = This["pYaw", number] + sign(AddDir)*90
        This["pDir", vector] = vec(1, 0, 0):rotate(0, This["pYaw", number], 0)
        
        #- set new line on direction change
        This["pLineA", vector2] = vec2(This["pPos", vector])
        This["pLineB", vector2] = vec2(This["pPos", vector])
        
        #- debug
        This["debug", number] = This["debug", number] + 1
        holoCreate(This["debug", number], This["pPos", vector], vec(1/3))
        holoColor(This["debug", number], This["color", vector])
        holoAlpha(This["debug", number], 100)
        
        This["tempdel", number] = random(1, 2)
        This["temptim", number] = curtime()
        #TempDelay = random(0.5, 1)
        #TempTime = curtime()
    }

    
    #--------------------------------------------------
    #-- Push currrent player line
    
    function table:pushPlayerLine() {
        Lines:unshiftArray( array(This["pLineA", vector2], This["pLineB", vector2]) )
        #This["pLines", table]:unshiftArray(array(This["pLineA", vector2], This["pLineB", vector2]))
        #This["pLineN", number] = This["pLines", table]:count()
    }


    #--------------------------------------------------
    #-- Update player table
    function table:updatePlayer() {
        if (!This["pHalt", number]) {
            This["pPos", vector] = This["pPos", vector] + This["pDir", vector]*This["pVel", number]*DeltaTime

            if (CurTime - This["temptim", number] > This["tempdel", number]) {
                This:setPlayerDir( random(-100, 100) + 1 )
                This:pushPlayerLine()
                
                This["wait", number] = This["pVel", number]
            }
            
            #This["wait", number] = max(This["wait", number] - This["pVel", number]*5*DeltaTime, 0)

            This["pLineB", vector2] = vec2(This["pPos", vector])
            
            
            holoPos(This["pHash", number], This["pPos", vector])
        }
    }
    
    
    function number lDir( PointA:vector2, PointB:vector2, PointC:vector2 ) {
        local A = (PointB[1] - PointA[1])*(PointC[2] - PointA[2])
        local B = (PointC[1] - PointA[1])*(PointB[2] - PointA[2])
        return sign(A - B)
    }
    
    function number lineSegmentIntersection( [LineAP1 LineAP2]:vector2, [LineBP1 LineBP2]:vector2 ) {
        
        holoCreate(1, entity():pos() + vec(LineAP1 + LineAP2)/2, vec((LineAP1 - LineAP2):length(), 5, 5)/12)
        holoColor(1, vec(0, 255, 0))
        
        return lDir(LineAP1, LineAP2, LineBP1) != lDir(LineAP1, LineAP2, LineBP2) & lDir(LineBP1, LineBP2, LineAP1) != lDir(LineBP1, LineBP2, LineAP2)
    }    
    
    
    lineSegmentIntersection( vec2(), vec2(100,0), vec2(0,100), vec2(-100, 100) )
    
    
    
    #--------------------------------------------------
    #-- Test
    
    addPlayer( owner() ):setPlayerDir( 0 )
    #addPlayer( findPlayerByName("div") ):setPlayerDir( 0 )
}

dt(90)


for (I = 1, Lines:count()) {
    local LineA = Lines[I, array][1, vector2]    
    local LineB = Lines[I, array][2, vector2]  
    
    foreach (K, Player:table = Players) {
        if (!Player["wait", number]) {
            local Dist = linePointDistance(LineA, LineB, vec2(Player["pPos", vector]))
            if (Dist < Player["pVel", number]) {
                print("wtf")
                Player["pHalt", number] = 1
                break
            }
        } else {
            Player["wait", number] = 0
        }
    }
}

foreach (K, Player:table = Players) {
    Player:updatePlayer()    
}

