@name Hived ball collector
@inputs 
@outputs Thrust Turning Grab Strength Hydrolic
@outputs Master Self Squad Enemy:entity 
@persist Master Self Squad #all the variables required for networking
@trigger 
E=entity()

Strength=10000
runOnTick(1)


#D-Link by Captain Maim STEAM_0:1:8017844 

#D-Link is designed as a plug and play hive mind.  
#Once installed duplicates of your contraptions can coordinate and act as a single hive mind.
#Or you can disable the hivemind and use it to create a simple network.
#Installation: 
#1) Edit the network name below, (gSetGroup(S)).
#2) Write your own find functions under if(HiveMind){...}
#3) Make use of the resulting Enemy:entity as you please.
#Result: every unit in the network will be given a single unique target from the Master unit.
#The master unit will itself take a 

gSetGroup("Network") #give your unit network a unique name.
if(duped()){reset()}
runOnLast(1)
Diag=1 #this prints network reports to chat
NetMax=20 #this is the maximum number of networked units, surplus units are removed automatically.
ID="ID"
Erase=0 #set this to 1 to erase the entire unit network, (diagnostic only)
MasterInterval=500 #frequency units check for updates on who is the master unit.
HiveMind=1 #1 enables a client/server AKA master/slave mode (used for hiveminds.) 0 limits use to simple network ID generation.
MakeSquads=0 #create squads
Squadsize=4 #choose a squad size, 0 also disables it. 
Brk="<" #separation or "break" character, used to create a unique string to help mass search the network table with.
if(!Self){
    EID=entity():id()
    EIDS=toString(EID)
    ScanN=gGetStr(ID) 
    NetT=glonDecodeTable(ScanN) 
    
    for(C=1,NetMax){if(!ScanN:find(Brk+C)){Self=C break}} #locate a hole and take that slot
    if(HiveMind){
        for(C=1,NetMax){if(ScanN:find(Brk+C)){Master=C break}} #locate first unit and mark that unit
        if(!Master){Master=Self}
    }
    if(!Self){
        if(Diag){print("Self Destructing Excess Clones!")} 
        selfDestructAll()
    }
    NetT[Brk+Self,number]=EID
    if(Self==Master&HiveMind){gSetNum("master",Self)}
    gSetStr(ID,glonEncode(NetT))
    if(Diag){print("Self="+Self)} #you can remove this if you want it's diagnostic
}
if(last()){
    NetT=glonDecodeTable(gGetStr(ID))
    NetT:remove(Brk+Self)
    if(Self==Master&HiveMind){ #passing the torch
        for(C=1,NetMax){
            if(NetT[Brk+C,number]){
                gSetNum("master",C)
                Master=0
                if(Diag){print("Unit "+Self+" is passing leadership to "+C)}
                break
            }
        }
        if(Master){ #if there is no unit to pass the torch to
            gSetNum("master",0) 
            if(Diag){print("Unit "+Self+" was unable to pass leadership.")}
        }
    }
    gSetStr(ID,glonEncode(NetT))
    if(Diag){print("Unit "+Self+" Deleted")} #diagnostic non critical
}
if(Erase){gSetStr(ID,"")}
#periodically checks to see if the master has passed the torch
if(HiveMind){
    timer("master",MasterInterval)
    if(clk("master")){Master=gGetNum("master")}
    
    #Add your own targeting code below
    if(findCanQuery()){
        #This collpases the unit spread and organizes their orders.        
        NetT=glonDecodeTable(gGetStr(ID))
        Units=array() 
        Orders=table()
        for(C=1,NetMax){if(NetT[Brk+C,number]){Units:pushNumber(C)}} #collapse the spread of units on the network 
        Orders=invert(Units) #we want the collapsed units indexed by self ID
        
        if(Master==Self){ #actions for the network master
############your find functions here################

            findInSphere(entity():pos(),1000) #demo only
            findIncludeClass("sent_ball")
            
#############then let this command the hive#########
            Target=findToArray()
            gSetStr("Target",glonEncode(Target)) #issues orders to slaves
            
        }else{Target=glonDecode(gGetStr("Target"))} #all slaves take orders
    Enemy=Target[Orders[toString(Self),number],entity] #if there are more units than targets the surplus units are idle.
    }
    
}
if(MakeSquads&Squadsize){
    Squad=Self%Squadsize+((Self%Squadsize)==0)*Squadsize #assigns squads
}else{Squad=0}
#End of D-Link Network Code

if(Enemy&!(owner():lastSaid()=="kill it")){
    Bearing=E:isConstrainedTo():bearing(Enemy:pos())
    Distance=E:isConstrainedTo():pos():distance(Enemy:pos())
    Thrust=((Distance>30) - (Distance<10) )*50
    Turning=sign(Bearing)*400
    Grab=(Distance<30)
    Hydrolic=10
}
