@name Defence Bot
@outputs Fire
@persist EO:entity State Name:string Follow:entity Aim Accuracy Firez Weapon Range Height Pos:vector Grabed:entity Target:entity Online Grab Hold:vector
@trigger none

interval(40)
EE=entity()

#Init, this line initiates all variables
if (first()) {
    EO=EE:owner()
    Online = 0, Name = "Bot", Accuracy = 2, State = 1, Firez = 0, Aim = 1, Weapon = 0, Range = 100, Height = 35, Pos = vec(0,0,0), Target = EO, Grab = 0
    findExcludePlayer(EO)
    runOnChat(1)
    hint("Thank you for using this Personal Protection Bot",5)
    hint("If you need help simply say '"+Name+", help'",10)
}
#End Init

if (chatClk(EO)) {
    String = EO:lastSaid():lower()
    if (String:left(Name:length()) == Name:lower()) {
        String = String:sub(Name:length()+3,String:length())
        if(String:left(4) == "hold") {
            State = 0
            Pos = EO:pos()
        }
        elseif (String:left(4) == "help") {
            String = String:sub(6,String:length())
            if(String:left(8) == "commands"){
                hint("Commandlist:",25)
                hint("Hold, Follow, Follow that",25)
                hint("Grab, Drop, Throw",25)
                hint("Rape, Status, Give",25)
                hint("Goto, Help, Harakiri",25)
                hint("Fire, ReGrab",25)
            }elseif(String:left(9) == "variables") {
                hint("Variables;",25)
                hint("Example: '"+Name+", range: 100'",15)
                hint("Variables:",25)
                hint("Range, Height, Mass",25)
                hint("Weapons, Aim, Name",25)
                hint("Fire",25)
            }elseif(String:left(11) == "follow that"){
                hint("This will tell the bot to follow the entity under your cursor",10)
            }elseif(String:left(6) == "follow") {
                hint("Say this to tell the bot that you want it to follow you",10)
            }elseif(String:left(4) == "hold") {
                hint("Will tell the bot to stay where it is",10)
            }elseif(String:left(4) == "grab") {
                hint("Tell the bot to grab whatever prop you're aiming at",10)
            }elseif(String:left(4) == "drop") {
                hint("The bot will let go of whatever prop it's holding",10)
            }elseif(String:left(5) == "throw") {
                hint("This will tell the bot to throw whatever it is holding",10)
            }elseif(String:left(4) == "rape") {
                hint("Saying Rape will tell the bot to target whatever is under your cursor",10)
            }elseif(String:left(6) == "status") {
                hint("This will tell the bot to do a status report",10)
            }elseif(String:left(4) == "give") {
                hint("Say Give to give the bot to whoever you're aiming at",10)
            }elseif(String:left(4) == "goto") {
                hint("Say this to tell the bot to hold at whatever position you're aiming at",10)
            }elseif(String:left(8) == "harakiri") {
                hint("Harakiri will make the bot remove itself",10)
            }elseif(String:left(4) == "range") {
                hint("This will change how far away to hold stuff you grab",10)
                hint("Allowed values: Integer",10)
            }elseif(String:left(6) == "height") {
                hint("Will change how high it should hover",10)
                hint("Allowed values: Integer, 35 is just above a players head",10)
            }elseif(String:left(4) == "mass") {
                hint("This will change the bots mass",10)
                hint("Allowed values: Integer, between 1 - 50000",10)
            }elseif(String:left(6) == "weapons") {
                hint("Will change the weapon status",10)
                hint("Allowed values: On, Off, Auto",10)
                hint("Effect:",10)
                hint("Off - Will tell the bot to aim straight up",10)
                hint("On - Will tell the bot to aim to where you aim",10)
                hint("Auto - The bot will target the closest player",10)
            }elseif(String:left(3) == "aim") {
                hint("This decides the aim speed of the bot",10)
                hint("Allowed values: Integer, 0 - 100",10)
                hint("A good value is somewhere between 1 and 10",10)
            }elseif(String:left(4) == "name") {
                hint("Will change the name of the bot",10)
                hint("Allowed values: String",10)
            }elseif(String:left(4) == "fire") {
                hint("This command/variable has several modes",10)
                hint("it can be used to set autofire and autofire accuracy",10)
                hint("Furthermore it can also be used to fire the bots weapons",10)
                hint("Allowed values: String (On, Off), Integer(0 - 180)",10)
            }elseif(String:left(6) == "regrab") {
                hint("This will regrab the last grabbed object",10)
            }elseif(String:left(5) == "about") {
                hint("This bot was written by 'Ace (SWE)'",30)
                hint("The only reason this bot exists is because I saw that SVN added a 'chat.lua' to E2",30)
                hint("Most of the bots code was written on a train to/from school and then saved on a USB memory",30)
                hint("It took me three days to get the bot working with all functions I wanted",30)
                hint("330 lines, 13367 characters of code",30)
            }
            else{
                hint("PPB Help Menu:",5)
                hint("Every command is entered through chat",5)
                hint("Say '"+Name+", ' and the command",5)
                hint("Example: '"+Name+", hold'",5)
                hint("Variables are entered through chat too",5)
                hint("Example: '"+Name+", aim: 10",5)
                hint("To turn the bot on or off say '"+Name+", turn on/off'",10)
                hint("For a commandlist say '"+Name+", help commands'",15)
                hint("For a variable list say '"+Name+", help variables'",15)
                hint("For details on a command/variable say '"+Name+", help <command>'",15)
                hint("For some bot details say '"+Name+", help about'",15)
            }
        }
        elseif (String:left(6) == "follow") {
            if (String:sub(8,String:length()) == "that") {
                if(EO:aimEntity()){
                    Follow = EO:aimEntity()
                    State = 2
                }
            }
            else{
                State = 1
            }
        }
        elseif (String:left(8) == "radius: ") {
            Radius = String:sub(9,String:length()):toNumber()
        }
        elseif (String:left(5) == "aim: ") {
            AimOffset = String:sub(6,String:length()):toNumber()
        }
        elseif (String:left(4) == "fire") {
            if(String:sub(6,String:length()) == "on"){
                hint("Autofire: on",5)
                Firez = 1}
            elseif(String:sub(6,String:length()) == "off") {
                hint("Autofire: off",5)
                Firez = 0}
            elseif(String:left(5) == "fire:"){
                Accuracy = String:sub(7,String:length()):toNumber()
                hint("Accuracy: "+toString(Accuracy),5)}
            else{
                Firez = 2
                hint("Firing",5)
            }
        }
        elseif (String:left(4) == "grab") {
            if(EO:aimEntity()){
                Grabed = EO:aimEntity()
                Grab = 1
            }
        }
        elseif (String:left(6) == "regrab") {
            if(Grabed){
                Grab = 1
            }
        }
        elseif (String:left(4) == "drop") {
            Grab = 0
        }
        elseif (String:left(4) == "goto") {
            Pos = EO:aimPos()
            State = 0
        }
        elseif (String:left(4) == "give") {
            if (EO:aimEntity():isPlayer()){ 
                EO = EO:aimEntity()
            }
        }
        elseif (String:left(8) == "harakiri") {
            selfDestructAll()
        }
        elseif (String:left(6) == "name: ") {
            Name = String:sub(7,String:length())
        }
        elseif (String:left(4) == "rape") {
            if(EO:aimEntity()){
                Target = EO:aimEntity()
                Weapon = 3
            }
        }
        elseif (String:left(5) == "throw") {
            TVe = EE:pos() + EE:up() * 500000000
            EVe = Grabed:massCenter()
            EEe = Grabed
            Grab = 0
            Grabed:applyForce((TVe-EVe)*(EEe:mass()*10))
        }
        elseif (String:left(8) == "height: ") {
            Height = String:sub(9,String:length()):toNumber()
        }
        elseif (String:left(7) == "range: ") {
            Range = String:sub(8,String:length()):toNumber()
        }
        elseif (String:left(9) == "weapons: ") {
            if (String:sub(10,String:length()) == "on") {
                Weapon = 1
                hint("Weapons: Online",4)
            }elseif (String:sub(10,String:length()) == "off") {
                Weapon = 0,Fire = 0     
                hint("Weapons: Offline",4)
            }elseif (String:sub(10,String:length()) == "auto"){
                Weapon = 2
                hint("Weapons: Auto",4)
            }elseif (String:sub(10,String:length()) == "hold") {
                Weapon = 4, Hold = EO:aimPos()
                hint("Weapons: Holding",4)
            }
        }
        elseif (String:left(6) == "mass: ") {
            EE:setMass(String:sub(7,String:length()):toNumber())
        }
        elseif (String:left(4) == "turn") {
        if (String:sub(6,String:length()) == "on") {
                Online = 1
                hint("Bot: Online",4)
            }else{
                Online = 0
                hint("Bot: Offline",4)
            }
        }
        elseif (String:left(6) == "status") {
            hint("Name: "+Name,5)
            hint("Status: "+toString(Online),5)
            hint("Weapons: "+toString(Weapon),5)
            hint("Height: "+toString(Height),5)
            hint("Range: "+toString(Range),5)
            hint("Mass: "+toString(EE:mass()),5)
            hint("Aim speed: "+toString(Aim),5)
            hint("Accuracy: "+toString(Accuracy),5)
            if(Grab){
                hint("Holding a prop",5)
                hint("Model: "+Grabed:model(),5)
                hint("Mass: "+Grabed:mass(),5)
            }
        }
    }
}


if(Online){
    EV=EE:pos(),EU=EE:up(),EF=EE:forward(),ER=EE:right()

    if(State == 1){
        TV = EO:pos() + vec(0,0,Height*3) + EO:vel()/7
    }elseif(State == 0){
        TV = Pos + vec(0,0,Height*3)
    }else{
        TV = Follow:pos() + vec(0,0,Height*3) + Follow:vel()/5
    }
    
    applyForce((TV-EV-EE:vel()/10)*(EE:mass()*10))

    if (Grab){
        TVe = EE:pos() + (EE:up() * Range)
        EVe = Grabed:massCenter()
        EEe = Grabed
        EEe:applyForce((TVe-EVe-EEe:vel()/10)*(EEe:mass()*10))
    }   
    
    if(Weapon>0){
        if(Weapon == 1){
            TL = EO:aimPos()}
        elseif(Weapon == 2){
            findByClass("player")
            findClipFromName(EO:name())
            findSortByDistance(EV)
            TL = findToArray():entity(1):pos()}
        elseif(Weapon == 3){
            if(Target){
                TL = Target:pos()
            }else{
                Weapon = 0
            }
        }
        elseif(Weapon == 4){
            TL = Hold
        }
        
        applyOffsetForce(((TL-TV)/(EV:distance(TL)/10))*entity():mass()/10, EV+(EU*Aim))
        applyOffsetForce((-(TL-TV)/(EV:distance(TL)/10))*entity():mass()/10, EV-(EU*Aim))
   
        Ele = EE:elevation(TL)-90
             
        if(Firez == 2){
            if(Grab){
                TVe = EE:pos() + EE:up() * 500000000000
                EVe = Grabed:massCenter()
                EEe = Grabed
                EAe = (EEe:angles()+(EEe:angVel()*2))/2
                Grabed:applyForce((TVe-EVe)*(EEe:mass()*10))
                Grab = 0
            }else{
                Fire = 1
            }
            Firez = 0
        }
        
        if(Ele>-Accuracy&Firez == 1){
            if(Grab){
                TVe = EE:pos() + EE:up() * 500000000000
                EVe = Grabed:massCenter()
                EEe = Grabed
                EAe = (EEe:angles()+(EEe:angVel()*2))/2
                Grabed:applyForce((TVe-EVe)*(EEe:mass()*10))
                Grab = 0
            }else{
                Fire = 1
            }
        }
        else{
            Fire = 0
        }
       
        EA=EE:angVel()
    }else{
        EA=(EE:angles()+(EE:angVel()*2))/2
    }
    applyOffsetForce(( EU*EA:pitch()/10)*entity():mass()/10,EV+EF)
    applyOffsetForce((-EU*EA:pitch()/10)*entity():mass()/10,EV-EF)
    applyOffsetForce(( ER*EA:yaw()/10)*entity():mass()/10  ,EV+EF)
    applyOffsetForce((-ER*EA:yaw()/10)*entity():mass()/10  ,EV-EF)
    applyOffsetForce(( EU*EA:roll()/10)*entity():mass()/10 ,EV+ER)
    applyOffsetForce((-EU*EA:roll()/10)*entity():mass()/10 ,EV-ER)
}else{
    Fire = 0
}