@name Auto Removal Robot
@inputs Stool:wirelink
@outputs F:entity RFire LFire Reload Scan:entity [Target]:array Master Self  Down Up Object:string
@persist [S E O F]:entity Ro:ranger [Safe]:array SAFE:string HitList:array
@persist Self Master #use this number for all your networking needs
@persist Object:string
@trigger 
@model models/props_junk/PopCan01a.mdl
if(duped()){reset()}
runOnChat(1)
O=owner()
Chat=O:lastSaid()
if(chatClk()&Chat=="get this"&O:aimEntity()){
    Object=O:aimEntity():type() 
    gSetStr("object",Object)
    if(Self==Master){print("Hived Remover Drones have targeted: "+Object)}
}
if(first()){Object=gGetStr("object")}
#D-Link Network Code Copy and paste this into your contraption
#by Captain Maim
gSetGroup("Remover Robot")
runOnLast(1)
Diag=1
NetMax=20 #this is the maximum number of networked items, surplus are removed
ID="ID"
EID=entity():id()
EIDS=toString(EID)
if(!Self){
    ScanN=gGetStr(ID) 
    NetT=vonDecodeTable(ScanN) 
    Brk="<"
        for(C=1,NetMax){if(!ScanN:find(Brk+C+Brk)){Self=C break}} 
        if(!Self){if(Diag){print("Self Destructing Excess Clones!")} selfDestructAll()
        }
    NetT[EIDS,string]=Brk+Self+Brk
    gSetStr(ID,vonEncode(NetT))
        if(Diag){print("Self="+Self)} #you can remove this if you want it's diagnostic
}
if(last()){
    NetT=vonDecodeTable(gGetStr(ID))
    NetT[EIDS,string]=""
    gSetStr(ID,vonEncode(NetT))
    Robots=gGetStr("robots")
    gSetStr("robots",Robots:replace(SAFE,""))
    if(Diag){print("ID "+Self+" Deleted")} #diagnostic non critical
}
#these little bit identifies the master network ID as the lowest existing ID.
ScanN=gGetStr(ID)
NetT=vonDecodeTable(ScanN) 
for(C=1,NetMax){if(ScanN:find(Brk+C+Brk)){Master=C break}} 

#End of D-Link Network Code


LFire=owner():keyUse()
Ri="RightClick"
Le="LeftClick"
Re="Reload"
S=Stool:entity()#:isConstrainedTo()
#Self=Stool:entity()
HH=50 #hover height
Up=Down=0
#####ranger trances and attack behavior######
if(!F){
    XYZ=entity():pos()+vec(0,0,HH)
}else{ #GO GET IT
    Safe1=Safe:clone()
    Safe1:pushEntity(F)
    rangerFilter(Safe1)
    Up=rangerOffset(F:radius()+HH,F:pos(),vec(0,0,1)):hit()
    rangerFilter(Safe1)
    Down=rangerOffset(F:radius()+HH,F:pos(),vec(0,0,-1)):hit()
    if(Down){XYZ=F:pos()+vec(0,0,F:radius()+HH)}
    elseif(Up){XYZ=F:pos()+vec(0,0,F:radius()-HH)}
#        else{
#        rangerFilter(Safe1)
#        Left=rangerOffset(F:radius()+HH,F:pos(),vec(0,-1,0)):hit()
#        rangerFilter(Safe1)
#        Right=rangerOffset(F:radius()+HH,F:pos(),vec(0,1,0)):hit()
#        rangerFilter(Safe1)
#        For=rangerOffset(F:radius()+HH,F:pos(),vec(1,0,0)):hit()
#        rangerFilter(Safe1)
#        Aft=rangerOffset(F:radius()+HH,F:pos(),vec(-1,0,0)):hit()
#        if(Left){XYZ=F:pos()+vec(0,F:radius()+HH,0)}
#        elseif(Right){XYZ=F:pos()+vec(0,F:radius()-HH,0)}
#        elseif(For){XYZ=F:pos()+vec(F:radius()-HH,0,0)}
#        elseif(Aft){XYZ=F:pos()+vec(F:radius()+HH,0,0)}
#        else{XYZ=entity():pos()+vec(0,0,HH)}
#        }
    #####Laser
    rangerFilter(Safe)
    Stool["Fire",number]=1
    Stool["Mode",string]="remover"
    Scan=rangerOffset(1000,S:pos(),S:forward()):entity()
    #if(Scan==F){
        LFire=1
        
        Stool[Le,number]=1
       
    #}else{LFire=0}
}
#Stool[Ri,number]=RFire
#Stool[Le,number]=LFire
Speed=50*(S:mass()/4)
S:applyForce(Speed*(XYZ-S:pos())-(S:vel()/2)*S:mass())

if(Stool["Current",string]!="remover"){Stool["Tool",string]="remover"}

if(first()|dupefinished()){
    
    runOnTick(1)
    #O = owner()
    E = entity()
    #S = Self
    #G = Grab:entity()
    #G:setMass(50000)
    Safe=array(S,Stool:entity(),entity())
    Robots=gGetStr("robots")
    SAFE=S:id()+"<"+Stool:entity():id()+"<"+entity():id()+"<"
    Robots=Robots+SAFE
    print(Robots)
    #rangerFilter(Safe)
    rangerPersist(0)
    gSetStr("robots",Robots)
}
if(last()){ #my robot arm is being removed from the network
    gSetStr("robots",gGetStr("robots"):replace(SAFE,""))
}
if(clk("delay")){dsSend("cleanup","cleanup",HitList)}
dsJoinGroup("cleanup")
if(dsClk()){Target=dsGetArray()}
if(findCanQuery()){

    if(Master==Self){
        SAFETY=gGetStr("robots"):explode("<")
        
        
        
        Safety=array()
        for(C=1,SAFETY:count()){
            Safety:pushEntity(entity(SAFETY[C,string]:toNumber()))
        }
        if(Object){
            findInSphere(entity():pos(),20000)
            findSortByDistance(entity():pos())
            findIncludeClass(Object)
            findExcludeEntities(Safety)
            findExcludeEntities(Safe)
            #findExcludePlayerProps(O)
            HitList=findToArray()
        }
        #gSetStr("Target",vonEncode(findToArray())) #issues orders to slaves
        timer("delay",100)
        
        F = HitList[HitList:count(),entity] #takes self order
        if(!F:pos():isInWorld()){
            HitList:popEntity()
            F=HitList[HitList:count(),entity]
        }
    }else{
        #Target=vonDecode(gGetStr("Target"))
        
        F=Target[HitList:count()-Self+1,entity]
    }
}

Pos = E:toWorld(vec(0,0,40))

Dir = S:pos()-(F:pos()+F:vel()/(10))

AltAng = E:angles()
        if(S:type():find("stool")){
            Q = quat(Dir:toAngle())*qRotation(vec(0,0,1),180) #X stool turret
        }
        if(S:type():find("user")){
            Q = quat(Dir:toAngle())*qRotation(vec(0,1,0),-90) #Z user
        }
        #Q = quat(Dir:toAngle())*qRotation(vec(0,0,1),90) #Y
        #Q = quat(Dir:toAngle())*qRotation(vec(0,0,1),-90) #-Y
S:applyTorque((150*S:toLocal(rotationVector(Q/quat(S))+S:pos()) - 12*S:angVelVector())*S:inertia())

