@name Bobomb Load
@outputs GDCHECK AISTATUS:string AIMODE:string INIT HOSTILE
@persist [BODY HEAD PARA PLAYER TEMP]:entity [AIMODE AISTATUS]:string 
@persist [ROFFSET RDOWN BODYPOS BODYVEL TARGPOS TARGET BGROUND RED BLUE]:vector 
@persist [WHEIGHT RHEIGHT BMOVING DISTANC MVCHECK INIT ROAMT HOSTILE FPATH] BRANGER:ranger

if (first())    {
    #-Initialize
    #include "2015_october/bobomb_hsinj"

    DELAY = TABLE:count()
    interval(DELAY), print("Spawning " + DELAY + " holograms at " + min(round(1000/DELAY),DELAY) + " holograms per second.")
    runOnLast(1)

    #-Hologram Setup
    FACTOR = random(0.5,1.5)
    SHADING = 1
    STATUS = "spawning"
    MODE = "load"
    
    ENTITY = entity()
    OWNER = owner()
    
    rangerFilter(players())
    rangerPersist(1)
} elseif (MODE == "load") {
    if (STATUS == "spawning")   {
        interval(DELAY)
        if (HINDEX < TABLE:count() & holoCanCreate()) {
            HINDEX++
    
            #PAR = holoEntity(TABLE[HINDEX, array][1, number]) ?: entity(TABLE[HINDEX, array][1, number])
            PAR = TABLE[HINDEX, array][1, number] == SEED ? ENTITY : holoEntity(TABLE[HINDEX, array][1, number])

            holoCreate(HINDEX)
            holoParent(HINDEX, PAR)
            holoPos(HINDEX, PAR:toWorld(FACTOR * TABLE[HINDEX, array][3, vector]))
            holoAng(HINDEX, PAR:toWorld(TABLE[HINDEX, array][4, angle]))
            holoModel(HINDEX, TABLE[HINDEX, array][6, string])
            holoMaterial(HINDEX, TABLE[HINDEX, array][7, string])
            holoColor(HINDEX, TABLE[HINDEX, array][8, vector])
    
            if (TABLE[HINDEX, array][2, number] == 0)    { holoScale(HINDEX, FACTOR * TABLE[HINDEX, array][5, vector]) }
            if (TABLE[HINDEX, array][2, number] == 1)    { holoScaleUnits(HINDEX, FACTOR * TABLE[HINDEX, array][5, vector]) }
            if (SHADING == 1) { holoDisableShading(HINDEX, 1) }
    
            setName("HoloLoader -- Spawning " + toString((HINDEX / TABLE:count()) * 100) + "% complete.")
            if (HINDEX == TABLE:count())   { 
                STATUS = CLIP:count() ? "clipping" : "finished"
                print("Spawning of " + TABLE:count() + " holograms finished.")
            }
        }
    } elseif (STATUS == "clipping") {
        interval(DELAY)
        if (CINDEX < CLIP:count()) {
            CINDEX++
            
            CLIPHOL = CLIP[CINDEX, array][1, number]
            CLIPNUM = CLIP[CINDEX, array][2, number]
            CLIPPOS = CLIP[CINDEX, array][3, vector]
            CLIPDIR = CLIP[CINDEX, array][4, vector]
    
            holoClipEnabled(CLIPHOL, CLIPNUM, 1)
            holoClip(CLIPHOL, CLIPNUM, CLIPPOS*FACTOR, CLIPDIR, 0)
            
            if (CINDEX == CLIP:count())   { STATUS = "finished", print(CLIP:count() + " clips created.") 
            }
        }
    } elseif (STATUS == "finished")   {
        MODE = "run", print("Script is now live!")
        propSpawnEffect(0), interval(90)

        #-ENTITY SETUP
        BODY = holoEntity(1), holoUnparent(1)
        HEAD = holoEntity(2)
        PARA = holoEntity(20)

        #-VAR SETUP
        AIMODE = "init"

        WHEIGHT = 14*FACTOR
        RHEIGHT = 35*FACTOR
        RDOWN = vec(0,0,-1)
        ROFFSET = vec(0,0,WHEIGHT)
        TARGET = BODY:pos() + randvec(-200,200):setZ(0)

        RED = vec(255,0,0)
        BLUE = vec(30,30,36)
        for (I = 20, 32)    { holoAlpha(I, 0) }

    }
} elseif (MODE == "run" & clk())    {
    interval(90)

    #-SETUP
    BODYPOS = BODY:pos()
    BODYVEL = BODY:toLocal($BODYPOS*66.566669 + BODYPOS)
    BRANGER = rangerOffset(RHEIGHT, BODYPOS + ROFFSET, RDOWN)
    BGROUND = BRANGER:position()

    TARGPOS = TARGET - BODYPOS
    DISTANC = TARGPOS:setZ(0):length()
    MVCHECK = DISTANC >= 100 - HOSTILE*90 ? min(DISTANC*0.1, 5 + HOSTILE*2) : 0
    BMOVING = MVCHECK > 0 ? BMOVING + (BODYVEL[1] / 7) : 0

    #-AI
    if (AIMODE == "init" & INIT < 1) { 
        INIT += 0.05
        if (INIT == 1)  {
            AIMODE = "active"
            TARGET = BODY:pos() + randvec(-200,200):setZ(0)
            PLAYER = noentity()

            holoPos(1, ENTITY:pos() + vec(0,0,WHEIGHT))
            for (I = 1, 19)   { holoAlpha(I, 255) }
        }
    } elseif (AIMODE == "active") {
        #-BOGIES & AI SWITCHING
        if (!PLAYER & findCanQuery()) {
            findInSphere(BODYPOS, 250)
            findSortByDistance(BODYPOS)
            findClipToClass("player")

            PLAYER = find()
        }
        PDCHECK = (PLAYER:pos() - BODYPOS):setZ(0):length() <= 200
        GDCHECK = BRANGER:distance() >= RHEIGHT-(5*FACTOR)

        if (PDCHECK & !GDCHECK)           { AISTATUS = "stalk" } else { PLAYER = noentity() }
        if (!PDCHECK & !GDCHECK)          { AISTATUS = "roam", HOSTILE = 0 }
        if (changed(GDCHECK) & GDCHECK)   { 
            AISTATUS = "float"
            BODY:soundPlay(1, 0, "/foley/alyx_hug_eli.wav")
            for (I = 20, 32) { holoAlpha(I, 255) }
            FPATH = random(1,2) == 1 ? 4 : 8
        }
        if (changed(PLAYER) & PLAYER)     { HOSTILE = random(100) > 50 ? 1 : 0 }
        if (changed(PLAYER) & !PLAYER)    { HOSTILE = 0, holoColor(2, BLUE) }
        if (changed(GDCHECK) & !GDCHECK)  { 
            TARGET = BODY:pos() + randvec(-200,200):setZ(0)
            for (I = 20, 32) { holoAlpha(I, 0) }
        }

        #-FLOAT AI
        if (AISTATUS == "float")    {
            TARGET = BODYPOS + vec(sin(BMOVING/8)*500, cos(BMOVING/FPATH)*500, -350)
            holoAng(20, BODY:toWorld(ang(0,BMOVING/4,0)))
        }

        #-STALK AI
        if (AISTATUS == "stalk")    {
            TARGET = PLAYER:shootPos()

            if (HOSTILE)    {
                holoColor(2, mix(RED, BLUE, abs(sin(BMOVING))))
                if (DISTANC < 50)  {
                    holoColor(2, BLUE)
                    TEMP = propSpawn("models/props_phx/construct/wood/wood_boardx1.mdl", BODYPOS, 1), TEMP:propBreak()

                    TARGET = BODYPOS = BGROUND = ENTITY:pos()
                    AISTATUS = AIMODE = "init"
                    HOSTILE = INIT = 0

                    for (I = 1, 32)   { holoAlpha(I, 0) }
                }
            }
        }

        #ROAM AI
        if (AISTATUS == "roam")   {
            ROAMT++
            if (ROAMT > 45 & changed(ROAMT) & BODYVEL[1] < 1) {
                TARGET = BODYPOS + vec(random(-200,200), random(-200,200), random(-20,20))
                ROAMT = 0
            }
        }
 
        #-HOLOGRAMS
        holoPos(1, BODYPOS:setZ(BGROUND[3] + WHEIGHT) + BODY:forward()*MVCHECK)
        holoAng(1, slerp(quat(BODY), quat(TARGPOS:setZ(0):toAngle()), 0.5*(MVCHECK>0)):toAngle())
        holoAng(2, TARGPOS:toAngle())
    
        holoAng(12, BODY:toWorld(ang( sin(BMOVING)*20,0,0)))
        holoAng(16, BODY:toWorld(ang(-sin(BMOVING)*20,0,0)))
        holoAng(8,  HEAD:toWorld(ang(BMOVING,90,90)))
    }
}
