@name Holo Base
@inputs 
@outputs [PLoc TP RTP]:vector Go Map Yin Xin Origin:vector2 [Targ Nearest]:entity  
@persist [Grid]:table [Origin Max]:vector2 [Ball Nearest]:entity Go Map
@trigger 

runOnTick(1)
#interval(20)
Sides=0 #displace markers on the corners
E=entity()
Min=100
G=150 #Grid Size controls maze size
Cubes=vec(1,1,2)*(G/10)
#Door=round(vec(G*Origin:x(),G*Origin:y(),0)+E:pos())
if(first()){Map=1} #starting map
Flag="models/Roller.mdl" #model for flag
Turret="models/Combine_turrets/Floor_turret.mdl"
FlagColor=vec(0,0,1)*255  #what color is the flag?
Mazecount=4  #how many mazes are there?

if(first()){Gun=0}
Walls=vec(1,1,1)*255 #wall color

        
#Origin=vec2(6,5) #Where is the start square?




if(last()){Ball:propDelete()}

Pl=players()
#Dist=array()
#for(C=1,Pl:count()){
#    Dist:pushNumber(Pl[C,entity]:pos():distance(Door))
#}
#Nearest=Pl[Dist:minIndex(),entity]
#DCheck=Dist[Dist:minIndex(),number]<Min #distance check
#
#if(DCheck){Labrat=Nearest Reset=0}
#
#if(!Labrat){Reset=1}

######Find a way to locate player on grid



#####TEMPOARY
if(!Nearest){
    
    findInSphere(E:pos()+(vec(Origin)*G),G)
    findIncludeClass("player")
    if(find():type()=="player"){
        Nearest=find()
        
    }
    
}
#Nearest=Pl[1,entity]



if(Nearest){
    #if(changed(Nearest)){Map=randint(1,4)}    
    PLoc=ceil(((Nearest:pos()-E:pos())-(G/2))/G) #Player Location on Grid
    PBall=ceil(((Ball:pos()-E:pos())-(G/2))/G) #Location of the ball
    Xin=inrange(PLoc:x(),1,Max:x())
    Yin=inrange(PLoc:y(),1,Max:y())
    Type=Grid[PLoc:x(),array][PLoc:y(),number]
    TypeB=Grid[PBall:x(),array][PBall:y(),number]
}
if(PLoc==vec(Origin)){Go=1}

if(PLoc:z()|!Xin|!Yin|(Type==1)){Go=0 Nearest=noentity()}
if((TypeB==1)|(!Go&inrange(PBall:x(),1,Max:x())&inrange(PBall:y(),1,Max:y()))){
    #ifdef entity:propDelete()
        Ball:propDelete()
    #endif
}

if(!Go&changed(Go)){Map=randint(1,Mazecount) print("Maze "+Map)}

######THIS IS THE MASTER LAYOUT FOR THE MAZE########
if(Map==1){
    Grid=table()
    Origin=vec2(3,2) 
    
    #0=air 1=wall cube 2=flag 3=fake flag 4=turret 5=explosion
    #                   1 2 3 4 5 6 7 8 9 A B
    Grid[1,array]=array(1,1,1,1,0,1,1,1,1,1,1)
    Grid[2,array]=array(1,0,4,1,0,1,3,0,0,0,1)
    Grid[3,array]=array(1,0,1,1,0,1,1,1,0,1,1)
    Grid[4,array]=array(1,0,0,0,0,0,0,0,0,1,0)
    Grid[5,array]=array(1,1,1,1,1,1,0,1,1,1,1)
    Grid[6,array]=array(1,0,0,0,0,0,0,1,0,2,1)
    Grid[7,array]=array(1,0,1,1,0,1,1,1,0,1,1)
    Grid[8,array]=array(1,0,3,1,5,1,0,0,0,1,1)
    Grid[9,array]=array(1,1,0,0,0,0,0,1,0,0,1)
   Grid[10,array]=array(1,0,0,1,1,1,5,1,1,3,1)
   Grid[11,array]=array(1,1,1,1,1,1,1,1,1,1,1)
} 
if(Map==2){
    Grid=table()
    Origin=vec2(5,7) 
    #0=air 1=wall cube 2=flag 3=fake flag 4=turret 5=explosion
    #                   1 2 3 4 5 6 7 8 9 A B
    Grid[1,array]=array(1,1,1,1,1,1,1,1,1,0,1)
    Grid[2,array]=array(1,0,0,0,0,1,0,0,1,0,1)
    Grid[3,array]=array(1,0,4,1,0,1,1,0,0,0,1)
    Grid[4,array]=array(1,0,0,0,0,0,0,0,0,1,0)
    Grid[5,array]=array(1,0,4,1,0,1,0,1,1,1,1)
    Grid[6,array]=array(1,0,1,0,0,0,0,1,0,3,1)
    Grid[7,array]=array(1,0,1,0,4,1,0,1,0,1,1)
    Grid[8,array]=array(1,0,1,0,0,0,5,1,0,1,1)
    Grid[9,array]=array(1,0,1,0,1,0,0,0,0,0,1)
   Grid[10,array]=array(1,2,0,1,1,1,5,1,1,3,1)
   Grid[11,array]=array(1,1,1,1,1,1,1,1,1,1,1)

}
if(Map==3){
    Grid=table()
    Origin=vec2(5,7) 
    #0=air 1=wall cube 2=flag 3=fake flag 4=turret 5=explosion
    #                   1 2 3 4 5 6 7 8 9 A B C D
    Grid[1,array]=array(1,1,1,1,1,1,1,1,1,5,1,0,1)
    Grid[2,array]=array(1,3,1,0,0,1,0,0,0,0,1,0,1)
    Grid[3,array]=array(1,0,1,1,0,1,1,0,1,0,0,0,1)
    Grid[4,array]=array(1,0,0,0,0,0,0,0,0,1,0,0,1)
    Grid[5,array]=array(1,1,1,0,0,1,0,1,1,1,1,0,1)
    Grid[6,array]=array(1,0,1,0,0,0,0,1,0,3,4,0,1)
    Grid[7,array]=array(1,0,1,0,4,1,0,1,0,1,1,1,1)
    Grid[8,array]=array(1,0,1,0,0,0,5,1,0,1,1,4,1)
    Grid[9,array]=array(1,0,0,0,1,0,0,0,0,0,5,0,1)
   Grid[10,array]=array(1,3,0,1,4,1,5,1,1,3,1,4,1)
   Grid[11,array]=array(1,0,1,1,0,1,0,1,0,1,1,0,1)
   Grid[12,array]=array(1,0,2,0,0,0,0,0,0,0,0,0,1)
   Grid[13,array]=array(1,1,1,1,1,1,1,1,1,1,1,5,1)

}
if(Map==4){
    Grid=table()
    Origin=vec2(3,3) 
    
    #0=air 1=wall cube 2=flag 3=fake flag 4=turret 5=explosion
    #                   1 2 3 4 5 6 7 8 9 A B
    Grid[1,array]=array(1,1,1,1,0,1,3,1,1,1,1)
    Grid[2,array]=array(1,4,0,1,0,1,0,0,0,0,1)
    Grid[3,array]=array(1,1,0,1,0,1,1,1,0,1,1)
    Grid[4,array]=array(1,0,0,0,0,0,0,0,0,0,5)
    Grid[5,array]=array(1,1,1,1,1,1,0,1,0,1,1)
    Grid[6,array]=array(1,0,0,0,0,0,0,1,0,3,1)
    Grid[7,array]=array(1,1,0,1,0,1,0,1,0,1,1)
    Grid[8,array]=array(1,0,3,0,5,1,1,1,0,1,1)
    Grid[9,array]=array(1,1,1,0,0,0,0,0,0,0,1)
   Grid[10,array]=array(1,2,0,0,1,1,5,1,1,3,1)
   Grid[11,array]=array(1,1,1,1,1,1,1,1,1,1,1)

} 
if(changed(Origin)){
    holoCreate(0,E:pos()+vec(Origin)*G,vec(Cubes:x(),Cubes:y(),1))
    holoColor(0,vec(1,0,0)*255)

}



if(Go){
    ID=0
    
    #ifdef boom(vector,number,number)
        #detonate explosions
        if(Grid[PLoc:x(),array][PLoc:y(),number]==5){boom(E:pos()+vec(G*PLoc:x(),G*PLoc:y(),0),200,G)}
    #endif
    
    #follow player as he goes through the maze, generate maze as he travels
    for(C=-2,2){ #X coordinate deals with array number
        for(D=-2,2){ #Y coordinate deals with the number in the array
            ID++
            Pos=E:pos()+vec(G*(PLoc:x()+C),G*(PLoc:y()+D),0)
            Box=Grid[PLoc:x()+C,array][PLoc:y()+D,number]
            #ID=10*(PLoc:x()+C)+(PLoc:y()+D)
            
            if(Box==1){
                holoPos(ID,Pos)
                holoScale(ID,Cubes)
                holoAng(ID,ang())
                holoModel(ID,"cube")
                holoColor(ID,Walls,255)
                
            }
            if(Box==2){
                if(!Ball){
                    Ball=propSpawn(Flag,Pos+vec(0,0,10),0)
                    Ball:setColor(FlagColor)
                }
            }
            if(Box==3){ #holo flag
                #ifdef holoModel(number,string,number)
                    holoPos(ID,Pos+vec(0,0,12))
                    holoScale(ID,vec(1,1,1))
                    holoColor(ID,FlagColor,255)
                    holoModel(ID,Flag,1)
                #endif
            }
            if(Box==4){ #holo turret
                #ifdef entity:shootTo(vector,number,number,number)
                Gun=1
                #endif
                if(Gun){
                    #Look up, down, left, right
                    #if up is open and left are open, then check if up and left is open.
                    
                    
                    
                    
                    
                    holoPos(ID,Pos)
                    holoColor(ID,vec(1,0,0)*255,255)
                    holoScale(ID,vec(1,1,1))
                    #ifdef holoModel(number,string,number)
                        holoModel(ID,Turret,1)
                    #else
                        if(convarnum("wire_holograms_modelany")==0){
                            holoModel(ID,"hq_tube_thick")
                        }else{holoModel(ID,Turret)}
                    #endif
                    Angle=Nearest:shootPos()-Pos
                    AN=Angle:normalized()
                    holoAng(ID,Angle:toAngle()+ang(-Angle:toAngle():pitch(),0,0))
                     TP=vec(PLoc:x()+C,PLoc:y()+D,0) #turret position in grid
                     RTP=TP-PLoc #Relative Turret Position to player
                     
                    #ifdef shootTo(angle,number,number,number)
                    findInCone(Nearest:pos(),-Angle:normalized(),G*1,30)
                    findSortByDistance(Pos)
                    findIncludeClass("gmod_wire_hologram")
                    #findIncludeClass("player")
    
                    Targ=find()
                    #Targ:setColor(vec(1,1,0)*255)
                    if(Targ==holoEntity(ID)){
                        holoEntity(ID):shootTo(Angle,0,100,1)
                        
                    } #endif
                } 
                
            }
            if(Box==5){
                #ifdef boom(vector,number,number)
                    holoPos(ID,Pos)
                    holoScale(ID,vec(1,1,1))
                    holoModel(ID,"models/dav0r/tnt/tnt.mdl",1)
                    holoColor(ID,vec(1,1,1)*255,32)
                    holoAng(ID,ang(90,0,0))
                #endif
            }
            

        }
    }
}else{

    for(C=1,25){
        #if(holoEntity(C)){holoDelete(C)}
        holoPos(C,E:pos()+vec(0,0,1))
        holoModel(C,"cube")
        holoScale(C,vec(1,1,1))
        holoAng(C,ang())
        
    }
}






if(first()){
#    Area=array()
#    Area=vec2(1,0)
#    Area=vec2(-1,0)
#    Area=vec2(0,1)
#    Area=vec2(0,-1)


    Max=vec2(Grid:count(),Grid[1,array]:count())  #size of grid, X is the number of arrays Y is their size.


    
    #####The funtion holoPos used to be holoCreate fix this
    for(C=1,25){
        holoCreate(C,E:pos()+vec(0,0,10),vec(1,1,1)*2)
    }
    if(Sides){
        holoCreate(50,E:pos()+vec(G,G,0),vec(Cubes:x(),Cubes:y(),1))
        holoCreate(51,E:pos()+vec(Max:x()*G,G,0),vec(Cubes:x(),Cubes:y(),1))
        holoCreate(52,E:pos()+vec(Max:x()*G,Max:y()*G,0),vec(Cubes:x(),Cubes:y(),1))
        holoCreate(53,E:pos()+vec(G,Max:y()*G,0),vec(Cubes:x(),Cubes:y(),1))
    }
    
    if(0){ #display the whole maze at once? 
        for(C=1,Grid:count()){
            for(D=1,Grid[1,array]:count()){
                Box=Grid[C,array][D,number]
                if(Box){
                    Pos=E:pos()+vec(G*C,G*D,0)
                    ID=(C*10)+D
                    if(Box==1){
                        holoCreate(ID,Pos,Cubes)
                    }
                    if(Box==2){
                        Ball=propSpawn(Flag,Pos+vec(0,0,10),0)
                    }
                    #ifdef holoCustomModel(number,string,number)
                    if(Box==3){ #holo flag
                        holoCreate(ID,Pos+vec(0,0,12),vec(1,1,1))
                        holoModel(ID,Flag,1)
                    }
                    if(Box==4){ #holo turret
                        holoCreate(ID,Pos,vec(1,1,1))
                        holoModel(ID,Turret,1)
                    }
                } #endif
            }
        }
    }
#    Grid=table()
#    Grid[1,array]=array(0,0,0,0,0,0,0,0,0,0)
#    Grid[2,array]=array(0,0,0,0,0,0,0,0,0,0)
#    Grid[3,array]=array(0,0,0,0,0,0,0,0,0,0)
#    Grid[4,array]=array(0,0,0,0,0,0,0,0,0,0)
#    Grid[5,array]=array(0,0,0,0,0,0,0,0,0,0)
#    Grid[6,array]=array(0,0,0,0,0,0,0,0,0,0)
#    Grid[7,array]=array(0,0,0,0,0,0,0,0,0,0)
#    Grid[8,array]=array(0,0,0,0,0,0,0,0,0,0)
#    Grid[9,array]=array(0,0,0,0,0,0,0,0,0,0)
#   Grid[10,array]=array(0,0,0,0,0,0,0,0,0,0)
}   


