@name 4 Team CTF
#@inputs On1 On2 On3 On4 
#@inputs T1:entity T2:entity T3:entity T4:entity
#@inputs T1a T2a T3a T4a
#@outputs E1:entity E2:entity E3:entity E4:entity
#@outputs N1 N2 N3 N4 T1a T2a T3a T4a 
@inputs Goals:array FlagEnts:array
#@inputs HBV VRad
@outputs FlagEnts:array
#holographics
@outputs Blue:vector Red:vector Green:vector Yellow:vector Fade
@outputs On1 On2 On3 On4 
#did you win?
@persist Trigger Go Win
#Goal Entities
@persist G1:entity G2:entity G3:entity G4:entity 
#Flag to Goal Distance Arrays
@persist BF:array RF:array GF:array YF:array
#Flag locations
@persist XYZ1:vector XYZ2:vector XYZ3:vector XYZ4:vector
@persist ScoreB ScoreR ScoreG ScoreY
Time=20
interval(Time)
Chat = entity():owner():lastSaid()
#K = curtime() - entity():owner():lastSaidWhen() < (Time*1)/1000
Klick = (curtime()-lastSpoke():lastSaidWhen()) < ((Time*2)/1000)
Klick1 = (curtime()-entity():owner():lastSaidWhen()) < ((Time*2)/1000)
gSetGroup("CTF")
Zoff = 115
Fade = 255

#This has to do with the flying function
Speed=10 K=10
#finding the flags
#Model = "models/Roller.mdl"
#findInSphere(entity():pos(),100000)
#findClipFromSphere(entity():pos(),100)
#findIncludePlayerProps(entity():owner())
#findClipToModel(Model)
#findIncludeModel(Model)
#findClipToClass("gmod_light")
#E1 = findResult(1)
#E2 = findResult(2)
#E3 = findResult(3)
#E4 = findResult(4)
#FlagEnts[1,entity]=E1
#FlagEnts[2,entity]=E2
#FlagEnts[3,entity]=E3
#FlagEnts[4,entity]=E4
E1=FlagEnts[1,entity]
E2=FlagEnts[2,entity]
E3=FlagEnts[3,entity]
E4=FlagEnts[4,entity]
G1 = Goals:entity(1)
G2 = Goals:entity(2)
G3 = Goals:entity(3)
G4 = Goals:entity(4)
N1 = E1:id()
N2 = E2:id()
N3 = E3:id()
N4 = E4:id()
T1a = gDeleteNum("T1a")
T2a = gDeleteNum("T2a")
T3a = gDeleteNum("T3a")
T4a = gDeleteNum("T4a")
T1 = entity(T1a)
T2 = entity(T2a)
T3 = entity(T3a)
T4 = entity(T4a)
entity():setColor(0,255,255)
if(Klick1&Chat:find("Reset")){ScoreB=ScoreR=ScoreG=ScoreY=0 Go=1 Win=0}
if (T1:id()!=0) {XYZ1 = T1:pos() On1 = 1} else {On1 = 0}
if (T2:id()!=0) {XYZ2 = T2:pos() On2 = 1} else {On2 = 0}
if (T3:id()!=0) {XYZ3 = T3:pos() On3 = 1} else {On3 = 0}
if (T4:id()!=0) {XYZ4 = T4:pos() On4 = 1} else {On4 = 0}

gSetNum("N1",N1)
gSetNum("N2",N2)
gSetNum("N3",N3)
gSetNum("N4",N4)
#Winner Text
BT="Blue"
RT="Red"
GT="Green"
YT="Yellow"
TeamWins=" Team Wins!"


#Material = "models/shiney"
#Material = "building_template/building_template010a" 
#E1:setMaterial(Material)
#E2:setMaterial(Material)
#E3:setMaterial(Material)
#E4:setMaterial(Material)


#This has to do with the visual holographic display
R=15 
Sp=0.2
Off=2
Hb=63 
Xb=Yb=35 
Xr=Yr=35
Xg=Yg=35 
Xy=Yy=35
#In Vehicle Adjustments
Disable=0 #disabled code remove this and the below if
if(Disable){
VRad=19
HBV=36
if(T1:inVehicle()){
R=VRad
Hb=HBV
}
if(T2:inVehicle()){
R=VRad
Hb=HBV
}
if(T3:inVehicle()){
R=VRad
Hb=HBV
}
if(T4:inVehicle()){
R=VRad
Hb=HBV
}
}#end of disabled code
Hr=Hb-1*Off Hg=Hb-2*Off Hy=Hb-3*Off

#This is a string table for chat commands to drop flags
Com="drop"
FlagB="blue"
FlagR="red"
FlagG="green"
FlagY="yellow"
FlagA="all"
GetScore="score"
#Processing Chat commands for dropping flags
BHold=T1:lastSaid()
RHold=T2:lastSaid()
GHold=T3:lastSaid()
YHold=T4:lastSaid()
Anyone=lastSaid()

Trigger=BHold:find(Com)|RHold:find(Com)|GHold:find(Com)|YHold:find(Com)
BDrop=(BHold:find(FlagB)|BHold:find(FlagA))&Trigger
RDrop=(RHold:find(FlagR)|BHold:find(FlagA))&Trigger
GDrop=(GHold:find(FlagG)|BHold:find(FlagA))&Trigger
YDrop=(YHold:find(FlagY)|BHold:find(FlagA))&Trigger

if(BDrop){On1=0}
if(RDrop){On2=0}
if(GDrop){On3=0}
if(YDrop){On4=0}

#green 65,163,0  Red 255,0,0 Blue 0,0,255 yellow 255,255,0
#Material is building_template010a
#model is roller mine "ragdoll" 

#Flag to Goal distance evaluation
BF:setNumber(1,E1:pos():distance(G1:pos()))
BF:setNumber(2,E1:pos():distance(G2:pos()))
BF:setNumber(3,E1:pos():distance(G3:pos()))
BF:setNumber(4,E1:pos():distance(G4:pos()))
BProx=BF:minIndex()
RF:setNumber(1,E2:pos():distance(G1:pos()))
RF:setNumber(2,E2:pos():distance(G2:pos()))
RF:setNumber(3,E2:pos():distance(G3:pos()))
RF:setNumber(4,E2:pos():distance(G4:pos()))
RProx=RF:minIndex()
GF:setNumber(1,E3:pos():distance(G1:pos()))
GF:setNumber(2,E3:pos():distance(G2:pos()))
GF:setNumber(3,E3:pos():distance(G3:pos()))
GF:setNumber(4,E3:pos():distance(G4:pos()))
GProx=GF:minIndex()
YF:setNumber(1,E4:pos():distance(G1:pos()))
YF:setNumber(2,E4:pos():distance(G2:pos()))
YF:setNumber(3,E4:pos():distance(G3:pos()))
YF:setNumber(4,E4:pos():distance(G4:pos()))
YProx=YF:minIndex()
#GD is Goal Distance GD1 is the narrow band in which scoring occurs
GD=150
GD1=GD-10
Scorecap=5
NoScore=1000
if(ScoreB>=Scorecap){
    BF:setNumber(1,NoScore)
    RF:setNumber(1,NoScore)
    GF:setNumber(1,NoScore)
    YF:setNumber(1,NoScore)}
if(ScoreR>=Scorecap){
    BF:setNumber(2,NoScore)
    RF:setNumber(2,NoScore)
    GF:setNumber(2,NoScore)
    YF:setNumber(2,NoScore)}
if(ScoreG>=Scorecap){
    BF:setNumber(3,NoScore)
    RF:setNumber(3,NoScore)
    GF:setNumber(3,NoScore)
    YF:setNumber(3,NoScore)}
if(ScoreY>=Scorecap){
    BF:setNumber(4,NoScore)
    RF:setNumber(4,NoScore)
    GF:setNumber(4,NoScore)
    YF:setNumber(4,NoScore)}
Win1=ScoreB>=Scorecap
Win2=ScoreR>=Scorecap    
Win3=ScoreG>=Scorecap
Win4=ScoreY>=Scorecap
#if (BF:number(1)==0){Win1=1} #we don't need a solo team winner
if (RF:number(2)==0){Win2=1}
if (GF:number(3)==0){Win3=1}
if (YF:number(4)==0){Win4=1}
#Diagnostics for distances
#timer("xx",10000)
if(clk("xx")){
    print(BF:concat(" "))
    print(RF:concat(" "))
    print(GF:concat(" "))
    print(YF:concat(" "))
}
#End Diagnostics for distances
if(!Win1&Win2&Win3&Win4&!Go){print(BT+TeamWins) Go=1 Win=1}
if(Win1&!Win2&Win3&Win4&!Go){print(RT+TeamWins) Go=1 Win=2}
if(Win1&Win2&!Win3&Win4&!Go){print(GT+TeamWins) Go=1 Win=3}
if(Win1&Win2&Win3&!Win4&!Go){print(YT+TeamWins) Go=1 Win=4}
if(Anyone:find(GetScore)&Klick){
    Last=lastSpoke()
    Last:chatPrint("The score is:")
    Last:chatPrint(BT+": "+ScoreB)
    Last:chatPrint(RT+": "+ScoreR)
    Last:chatPrint(GT+": "+ScoreG)
    Last:chatPrint(YT+": "+ScoreY)
    if(Win==1){Last:chatPrint(BT+TeamWins)}
    if(Win==2){Last:chatPrint(RT+TeamWins)}
    if(Win==3){Last:chatPrint(GT+TeamWins)}
    if(Win==4){Last:chatPrint(YT+TeamWins)}
}
#Are the flags within the goal zone? And does the goal exist?
BGoal=BF:number(BProx)<GD&BF:number(BProx)!=0
RGoal=RF:number(RProx)<GD&RF:number(RProx)!=0
GGoal=GF:number(GProx)<GD&GF:number(GProx)!=0
YGoal=YF:number(YProx)<GD&YF:number(YProx)!=0


Spawn=vec(0,0,100)
Dropit="The flag must be flying above you to be scoreable"
if(BGoal){
        if(On1&BProx!=1&(BF:number(BProx)>GD1)){
            if(!E1:isPlayerHolding()){
            ScoreB+=1
            clamp(ScoreB,0,Scorecap)
            T1:chatPrint("You scored on Blue")
            T1:chatPrint("Blue Has: "+ScoreB)
            E1:setPos(G1:pos()+Spawn)}else{
T1:chatPrint(Dropit)}}
    On1=0 }
if(RGoal){
        if(On2&RProx!=2&(RF:number(RProx)>GD1)){
            if(!E2:isPlayerHolding()){
            ScoreR+=1
            clamp(ScoreR,0,Scorecap)
            T2:chatPrint("You scored on Red")
            T2:chatPrint("Red Has: "+ScoreR)
    E2:setPos(G2:pos()+Spawn)}else{  
T2:chatPrint(Dropit)}}
    On2=0 }
if(GGoal){
        if(On3&GProx!=3&(GF:number(GProx)>GD1)){
            if(!E3:isPlayerHolding()){
            ScoreG+=1
            clamp(ScoreG,0,Scorecap)
            T3:chatPrint("You scored on Green")
            T3:chatPrint("Green Has: "+ScoreG)
    E3:setPos(G3:pos()+Spawn)}else{
T3:chatPrint(Dropit)}}
    On3=0 }
if(YGoal){
        if(On4&YProx!=4&(YF:number(YProx)>GD1)){
            if(!E4:isPlayerHolding()){
            ScoreY+=1
            clamp(ScoreY,0,Scorecap)
            T4:chatPrint("You scored on Yellow")
            T4:chatPrint("Yellow Has: "+ScoreY)
    E4:setPos(G4:pos()+Spawn)}else{
T4:chatPrint(Dropit)}}
    On4=0 }





if(ScoreB>=Scorecap){
    On1=0 
    E1:setColor(255,255,255) 
    G1:setColor(255,255,255)}
    else{E1:setColor(0,0,255) G1:setColor(0,0,255)}
if(ScoreR>=Scorecap){
    On2=0
    E2:setColor(255,255,255) 
    G2:setColor(255,255,255)}
    else{E2:setColor(255,0,0) G2:setColor(255,0,0)}
if(ScoreG>=Scorecap){
    On3=0
    E3:setColor(255,255,255) 
    G3:setColor(255,255,255)}
    else{E3:setColor(65,163,0) G3:setColor(65,163,0)}
if(ScoreY>=Scorecap){
    On4=0
    E4:setColor(255,255,255) 
    G4:setColor(255,255,255)}
    else{E4:setColor(255,255,0) G4:setColor(255,255,0)}
#Flag Time Out Code.  After FlagTime in seconds the flag
#teleports back to the goal.  If it does not exist it goes to origin.
FlagTime=30
if(!On1&!BGoal){timer(BT,FlagTime*1000)}else{stoptimer(BT)}
if(!On2&!RGoal){timer(RT,FlagTime*1000)}else{stoptimer(RT)}
if(!On3&!GGoal){timer(GT,FlagTime*1000)}else{stoptimer(GT)}
if(!On4&!YGoal){timer(YT,FlagTime*1000)}else{stoptimer(YT)}
if(clk(BT)){E1:setPos(G1:pos()+Spawn)}
if(clk(RT)){E2:setPos(G2:pos()+Spawn)}
if(clk(GT)){E3:setPos(G3:pos()+Spawn)}
if(clk(YT)){E4:setPos(G4:pos()+Spawn)}



#Flag Mover Code
if (On1) {
#blue
E1=entity(N1)
A1=T1:angles()
E1:applyForce((20*((XYZ1-E1:pos())+vec(0,0,Zoff))-E1:vel())
*E1:mass()+T1:vel()*Speed)
Blue=T1:pos()+vec(R*cos(A1:yaw()+Xb),R*sin(A1:yaw()+Yb),Hb)+T2:vel()*Sp

}
if (On2) {
#red
E2=entity(N2)
A2 = T2:angles()
E2:applyForce((20*((XYZ2-E2:pos())+vec(0,0,Zoff))-E2:vel())
*E2:mass()+T2:vel()*Speed)
Red=T2:pos()+vec(R*cos(A2:yaw()+Xr),R*sin(A2:yaw()+Yr),Hr)+T2:vel()*Sp
}

if (On3) {
#green
E3=entity(N3)
A3 = T3:angles()
E3:applyForce((20*((XYZ3-E3:pos())+vec(0,0,Zoff))-E3:vel())
*E3:mass()+T3:vel()*Speed)
Green=T3:pos()+vec(R*cos(A3:yaw()+Xg),R*sin(A3:yaw()+Yg),Hg)+T2:vel()*Sp
}
if (On4) {
#yellow
E4=entity(N4)
A4 = T4:angles()
E4:applyForce((20*((XYZ4-E4:pos())+vec(0,0,Zoff))-E4:vel())
*E4:mass()+T4:vel()*Speed)
Yellow=T4:pos()+vec(R*cos(A4:yaw()+Xy),R*sin(A4:yaw()+Yy),Hy)+T2:vel()*Sp
}

