@name TF2 Controllable Bots
@inputs [Pod Cam EGP]:wirelink
@persist Diff View MoveYaw Spawned Jump Walk Shooting AmmoLeft Taunt Health Dead LoseHealth Reloading
@persist [Soldier Scout Use]:table 
@persist [ScoutSounds SoldierSounds FootSteps]:array
@persist [Ang]:angle 
@persist [O]:vector 
@persist [Bomb HB]:entity
@model models/props_borealis/bluebarrel001.mdl
if(first()){
 #Array handling
 FootSteps[1,string]="/mvm/player/footsteps/robostep_01.wav"
 FootSteps[2,string]="/mvm/player/footsteps/robostep_02.wav"
 FootSteps[3,string]="/mvm/player/footsteps/robostep_03.wav"
 FootSteps[4,string]="/mvm/player/footsteps/robostep_04.wav"
 FootSteps[5,string]="/mvm/player/footsteps/robostep_05.wav"
 FootSteps[6,string]="/mvm/player/footsteps/robostep_06.wav"
 FootSteps[7,string]="/mvm/player/footsteps/robostep_07.wav"
 FootSteps[8,string]="/mvm/player/footsteps/robostep_08.wav"
 FootSteps[9,string]="/mvm/player/footsteps/robostep_09.wav"
 FootSteps[10,string]="/mvm/player/footsteps/robostep_10.wav"
 FootSteps[11,string]="/mvm/player/footsteps/robostep_11.wav"
 FootSteps[12,string]="/mvm/player/footsteps/robostep_12.wav"
 FootSteps[13,string]="/mvm/player/footsteps/robostep_13.wav"
 FootSteps[14,string]="/mvm/player/footsteps/robostep_14.wav"
 FootSteps[15,string]="/mvm/player/footsteps/robostep_15.wav"
 FootSteps[16,string]="/mvm/player/footsteps/robostep_16.wav"
 FootSteps[17,string]="/mvm/player/footsteps/robostep_17.wav"
 FootSteps[18,string]="/mvm/player/footsteps/robostep_18.wav"

 SoldierSounds[1,string]="/vo/mvm/norm/soldier_mvm_robot01.mp3"
 SoldierSounds[2,string]="/vo/mvm/norm/soldier_mvm_robot02.mp3"
 SoldierSounds[3,string]="/vo/mvm/norm/soldier_mvm_robot04.mp3"
 SoldierSounds[4,string]="/vo/mvm/norm/soldier_mvm_robot04.mp3"
 SoldierSounds[5,string]="/vo/mvm/norm/soldier_mvm_robot05.mp3"
 SoldierSounds[6,string]="/vo/mvm/norm/soldier_mvm_robot06.mp3"
 SoldierSounds[7,string]="/vo/mvm/norm/soldier_mvm_robot07.mp3"
 SoldierSounds[8,string]="/vo/mvm/norm/soldier_mvm_robot08.mp3"
 SoldierSounds[9,string]="/vo/mvm/norm/soldier_mvm_robot09.mp3"
 SoldierSounds[10,string]="/vo/mvm/norm/soldier_mvm_robot10.mp3"
 SoldierSounds[11,string]="/vo/mvm/norm/soldier_mvm_robot11.mp3"
 SoldierSounds[12,string]="/vo/mvm/norm/soldier_mvm_robot12.mp3"
 SoldierSounds[13,string]="/vo/mvm/norm/soldier_mvm_robot13.mp3"
 SoldierSounds[14,string]="/vo/mvm/norm/soldier_mvm_robot14.mp3"
 SoldierSounds[15,string]="/vo/mvm/norm/soldier_mvm_robot15.mp3"
 SoldierSounds[16,string]="/vo/mvm/norm/soldier_mvm_robot16.mp3"
 SoldierSounds[17,string]="/vo/mvm/norm/soldier_mvm_robot17.mp3"
 SoldierSounds[18,string]="/vo/mvm/norm/soldier_mvm_robot18.mp3"
 SoldierSounds[19,string]="/vo/mvm/norm/soldier_mvm_robot19.mp3"
 SoldierSounds[20,string]="/vo/mvm/norm/soldier_mvm_robot20.mp3"
 SoldierSounds[21,string]="/vo/mvm/norm/soldier_mvm_robot21.mp3"
 SoldierSounds[22,string]="/vo/mvm/norm/soldier_mvm_robot22.mp3"
 SoldierSounds[23,string]="/vo/mvm/norm/soldier_mvm_robot23.mp3"
 SoldierSounds[24,string]="/vo/mvm/norm/soldier_mvm_robot24.mp3"
 SoldierSounds[25,string]="/vo/mvm/norm/soldier_mvm_robot25.mp3"
 SoldierSounds[26,string]="/vo/mvm/norm/soldier_mvm_robot26.mp3"
 SoldierSounds[27,string]="/vo/mvm/norm/soldier_mvm_robot27.mp3"
 SoldierSounds[28,string]="/vo/mvm/norm/soldier_mvm_robot28.mp3"
 SoldierSounds[29,string]="/vo/mvm/norm/soldier_mvm_robot29.mp3" 
    
 ScoutSounds[1,string]="/vo/mvm/norm/scout_mvm_domination01.mp3"
 ScoutSounds[2,string]="/vo/mvm/norm/scout_mvm_domination02.mp3"
 ScoutSounds[3,string]="/vo/mvm/norm/scout_mvm_domination03.mp3"
 ScoutSounds[4,string]="/vo/mvm/norm/scout_mvm_domination04.mp3"
 ScoutSounds[5,string]="/vo/mvm/norm/scout_mvm_domination05.mp3"
 ScoutSounds[6,string]="/vo/mvm/norm/scout_mvm_domination06.mp3"
 ScoutSounds[7,string]="/vo/mvm/norm/scout_mvm_domination07.mp3"
 ScoutSounds[8,string]="/vo/mvm/norm/scout_mvm_domination08.mp3" 
 ScoutSounds[9,string]="/vo/mvm/norm/scout_mvm_domination09.mp3"
 ScoutSounds[10,string]="/vo/mvm/norm/scout_mvm_domination10.mp3"
 ScoutSounds[11,string]="/vo/mvm/norm/scout_mvm_domination11.mp3"
 ScoutSounds[12,string]="/vo/mvm/norm/scout_mvm_domination12.mp3"
 ScoutSounds[13,string]="/vo/mvm/norm/scout_mvm_domination13.mp3"
 ScoutSounds[14,string]="/vo/mvm/norm/scout_mvm_domination14.mp3"
 ScoutSounds[15,string]="/vo/mvm/norm/scout_mvm_domination15.mp3"
 ScoutSounds[16,string]="/vo/mvm/norm/scout_mvm_domination16.mp3"
 ScoutSounds[17,string]="/vo/mvm/norm/scout_mvm_domination17.mp3"
 ScoutSounds[18,string]="/vo/mvm/norm/scout_mvm_domination18.mp3"
 ScoutSounds[19,string]="/vo/mvm/norm/scout_mvm_domination19.mp3"
 ScoutSounds[20,string]="/vo/mvm/norm/scout_mvm_domination20.mp3"
 ScoutSounds[21,string]="/vo/mvm/norm/scout_mvm_domination21.mp3"

    
 #Table handling
 Soldier["MoveSpeed",number]=10
 Soldier["Model",string]="models/bots/soldier/bot_soldier.mdl"
 Soldier["Weapon",string]="models/weapons/w_models/w_rocketlauncher.mdl"
 Soldier["AnimWeapon",string]="PRIMARY"
 Soldier["Sound",string]="/mvm/giant_soldier/giant_soldier_loop.wav"
 Soldier["VelDiv",number]=250
 Soldier["UseWep",number]=1
 Soldier["Name",string]="Soldier"
 Soldier["FootStepRate",number]=350
 Soldier["Array",array]=SoldierSounds
 
 Scout["MoveSpeed",number]=20
 Scout["Model",string]="models/bots/scout/bot_scout.mdl"
 Scout["Weapon",string]="models/weapons/w_models/w_scattergun.mdl"
 Scout["AnimWeapon",string]="PRIMARY"
 Scout["Sound",string]="/mvm/giant_scout/giant_scout_loop.wav"
 Scout["VelDiv",number]=500
 Scout["UseWep",number]=1
 Scout["Name",string]="Scout"
 Scout["FootStepRate",number]=200
 Scout["Array",array]=ScoutSounds

 entity():setColor(0,0,0,0)
 entity():propFreeze(0)

 EGP:egpClear()
 
 Use = Scout
 Diff = 52
 View = 1
 AmmoLeft = 8
 Health = 6

 holoCreate(1)
 holoModel(1,Use["Model",string])
 holoPos(1,entity():toWorld(vec(0,0,-Diff)))
 holoParent(1,entity())
 holoAnim(1,"Stand_"+Use["AnimWeapon",string])
 holoSkin(1,round(random(0,1)))

 holoCreate(3)
 holoAlpha(3,0)

 if(Use["Name",string]=="Soldier"){
 holoCreate(5)
 holoModel(5,"hq_sphere")
 holoColor(5,vec(255,100,0),150)
 }

 if(Use["UseWep",number]==1){
 holoCreate(2)
 holoModel(2,Use["Weapon",string])
 holoPos(2,holoEntity(1):attachmentPos("weapon_bone"))
 holoAng(2,holoEntity(1):attachmentAng("weapon_bone")-ang(0,90,90))
 holoParentAttachment(2,holoEntity(1),"weapon_bone")
 }

 #soundStop(2)
 #soundPlay(2,0,Use["Sound",string])

function entity:turnTo(Tarang:angle){
V = This:toLocal(rotationVector(quat(Tarang)/quat(This))+This:pos())
This:applyTorque((100*V - 30*This:angVelVector())*This:inertia()/3)
}
function entity:goto(Vector:vector){
 This:applyForce(((Vector-This:pos())*25-This:vel())*This:mass())   
}

 runOnTick(1)
 runOnChat(1)
 timer("spawn",250)
 timer("snd",random(6000,10000))
}

if(clk("spawn")){
 Spawned = 1   
 for(I=1,2){
 holoAlpha(I,255)   
}
}

if(clk("snd")){
 stoptimer("snd")
 timer("snd",random(6000,10000))
 soundPlay(1,0,Use["Array",array][round(random(1,Use["Array",array]:count())),string])
}

if(Spawned){
 if(!Dead){
 if(Pod:entity():isValid()){
 #Pod controller
 W = Pod["W",number] 
 A = Pod["A",number]
 S = Pod["S",number]
 D = Pod["D",number]
 Reload = Pod["R",number]
 M1 = Pod["Mouse1",number]
 M2 = Pod["Mouse2",number]
 Space = Pod["Space",number]
 Shift = Pod["Shift",number]
 Active = Pod["Active",number]
 Seat = Pod["Entity",entity]
 Driver = Seat:driver()
 if(Active){
 if(chatClk(owner())){
 if(owner():lastSaid():lower()=="/eject"){
 hideChat(1)
 Seat:ejectPod()   
 }   
 }
 Ang = Driver:eyeAngles()
 }else{
 View = 1
 }
 
 if(changed(Active)){
 if(Active){
    print(Driver:name()+" is in your chair, type /eject to take them out")
 }   
 }

 #Reloading
 if(changed(Reload)&Reload&AmmoLeft<8){
 Reloading = 1 
 }
    
 #Rangers, applyForce, & applyTorque
 R = rangerOffset(Diff+5,entity():pos(),vec(0,0,-1))
 if(R:hit()&!Jump){
    V = R:pos()+vec(0,0,Diff)+O
    AngT = ang(0,Ang:yaw(),0)
    entity():goto(V)
    #if(!Taunt){
    entity():turnTo(AngT)
    #}
 }

 if(changed(R:hit())){
    if(!R:hit()){
     holoAnim(1,"Airwalk_"+Use["AnimWeapon",string])   
    }
    if(R:hit()){
     Jump = 0
     soundPlay(75,0,FootSteps[round(random(1,FootSteps:count())),string])
     if(Walk){
     holoAnim(1,"Run_"+Use["AnimWeapon",string])
    }elseif(!Walk){ holoAnim(1,"Stand_"+Use["AnimWeapon",string]) }
    }
 }

 #Taunting
 if(changed(Shift)){
 if(Shift&!Taunt&R:hit()){
    Taunt = 1
    holoAlpha(2,0)
    holoAnim(1,"taunt0"+round(random(1,2)))
    timer("finishtaunt",holoAnimLength(1)*1000)
    O = entity():forward()*0
 }   
 }
 
 if(clk("finishtaunt")){
    Taunt = 0
    holoAlpha(2,255)
    if(Walk){
    holoAnim(1,"Run_"+Use["AnimWeapon",string])
    }else{
    holoAnim(1,"Stand_"+Use["AnimWeapon",string])
    }
 }


 #Walking & holoSetPose
 if(Active&!Taunt){
 O = (entity():forward()*(W-S)*Use["MoveSpeed",number])+(entity():right()*(D-A)*Use["MoveSpeed",number])
 if(W|A|S|D){
    Walk = 1
 }else{ Walk = 0 }
 holoSetPose(1,"move_yaw",MoveYaw)
 holoSetPose(1,"body_pitch",-Ang:pitch())
 if(changed(Walk)&R:hit()){
    if(Walk){
     holoAnim(1,"Run_"+Use["AnimWeapon",string])
    }   
    if(!Walk){
     if(R:hit()){
     holoAnim(1,"Stand_"+Use["AnimWeapon",string])
    }
    }
 }
 if(Walk){
    holoSetPose(1,"move_scale",entity():vel():length()/Use["VelDiv",number])
    if(W&!A&!S&!D){
        MoveYaw = 0
    }elseif(!W&A&!S&!D){
        MoveYaw = 90
    }elseif(!W&!A&S&!D){
        MoveYaw = 180
    }elseif(!W&!A&!S&D){
        MoveYaw = -90
    }elseif(W&A&!S&!D){
        MoveYaw = 45
    }elseif(W&!A&!S&D){
        MoveYaw = -45
    }elseif(!W&A&S&!D){
        MoveYaw = 135
    }elseif(!W&!A&S&D){
        MoveYaw = -135
    }
 }else{MoveYaw=0}
 }

 #Jumping   
 if(R:hit()&changed(Space)&Space&!Taunt){
    Jump = 1
 }else{Jump = 0}
 
 if(changed(Jump)){
 if(Jump){
 applyForce(entity():up()*25000)  
 }   
 }

 #Cam controller
 holoPos(3,holoEntity(1):attachmentPos("eye_1"))
 holoAng(3,Ang)
 if(Active){
 if(changed(M2)&M2){
 View = !View   
 }
 if(View){
 Cam["Position",vector]=holoEntity(3):toWorld(vec(-75,0,0))   
 }else{Cam["Position",vector]=holoEntity(3):pos()}
 Cam["Activated",number]=1
 Cam["Angle",angle]=holoEntity(3):angles()
 }else{Cam["Activated",number]=0}

 holoVisible(1,Seat:driver(),View)

 #Rocket Shooting
 if(Use["Name",string]=="Soldier"){
 WR = rangerOffset(999999999999999999999,holoEntity(2):pos(),holoEntity(2):forward())
 holoPos(5,WR:pos())

 EGP:egpRoundedBox(1,vec2(55,30),vec2(100,50))
 EGP:egpText(2,"Ammo: "+AmmoLeft,vec2(20,21))
 EGP:egpColor(1,vec4(teamColor(owner():team()):x(),teamColor(owner():team()):y(),teamColor(owner():team()):z(),150))

 if(changed(AmmoLeft)&!AmmoLeft){
    timer("reload",10000)
    timer("rsnd",1666)
    Reloading = 1
 }
 
if(Reloading){
 if(clk("rsnd")){
 stoptimer("rsnd")
 timer("sndstp",1000)
 if(AmmoLeft<8){
 timer("rsnd",1666)
 soundPlay(77,0,"/weapons/rocket_clipin.wav")
 AmmoLeft++
 }else{
 Reloading = 0
 }
 }
}

 if(clk("sndstp")){
 stoptimer("sndstp")
 soundStop(77)   
 }

 if(changed(Reloading)){
 if(Reloading){
    timer("rsnd",1666)
 }   
 }

 if(changed(M1)&M1&!Shooting&AmmoLeft>0&!Taunt){
    Reloading = 0
    stoptimer("rsnd")
    AmmoLeft -= 1
    Shooting = 1
    holoCreate(4)
    holoModel(4,"models/weapons/w_models/w_rocket.mdl")
    holoPos(4,holoEntity(2):pos())
    holoAng(4,holoEntity(2):angles())
    holoEntity(4):setTrails(10,10,1,"trails/smoke",vec(255),255)
    soundPlay(3,0,"/weapons/rocket_blackbox_shoot.wav")
    timer("tm",3000)
 }
 if(Shooting){
    RR = rangerOffset(50,holoEntity(4):pos(),holoEntity(4):forward())
    holoPos(4,holoEntity(4):pos()+holoEntity(4):forward()*25)
    if(RR:hit()|clk("tm")){
     if(holoEntity(4):pos():distance(entity():pos())<75){
        Jump = 1
        applyForce(entity():up()*50000)
        soundStop(1)
        soundPlay(76,0,"/vo/mvm/norm/soldier_mvm_painsevere0"+round(random(1,6))+".mp3")
    }
     soundStop(3)
     stoptimer("tm")
     Shooting = 0
     Bomb = propSpawn("models/props_phx/ww2bomb.mdl",holoEntity(4):pos(),1)
     Bomb:propBreak()
     holoDelete(4)   
    }
 }
 }
 
 #Health
 if(HB:isValid()&!Dead){   
 HB:setPos(entity():toWorld(vec(10,0,30)))
 HB:propNotSolid(1)
 }else{
 Health = Health-1
 Seat:hintDriver("Health is now at "+Health*20,3)
 HB = propSpawn("models/props_phx/misc/potato_launcher_explosive.mdl",vec(),1)
 HB:setColor(0,0,0,0)
 Jump = 1
 applyForce(entity():up()*15000)
 applyAngForce(ang(random(1,360),random(1,360),random(1,360))*10)
 timer("regen",10000)
 }
 
 if(clk("regen")){
 stoptimer("regen")
 if(Health<5){
    timer("regen",10000)
    Health++
    Seat:hintDriver("Health regenerated to "+Health*20,3)
 }   
 }

 #Death detecting
 if(entity():isOnFire()|entity():angles():pitch()>85||entity():angles():pitch()<-85||entity():angles():roll()>85||entity():angles():roll()<-85|entity():isUnderWater()|Health==0){
 Dead = 1   
 }

 #END
}
}
if(changed(Dead)){
 if(Dead){
    Cam["Activated",number]=0
    Seat:hintDriver(Use["Name",string]+" is dead :D",3)
    stoptimer("snd")
    soundStop(1)
    soundStop(2)
    soundStop(3)
    soundPlay(5,0,"/vo/mvm/norm/"+Use["Name",string]:lower()+"_mvm_paincrticialdeath0"+round(random(1,4))+".mp3")
    holoSetPose(1,"mode_scale",0)
    holoAnim(1,"dieviolent",0,0.5)
    timer("delete",3000)
    holoDelete(2)
    holoCreate(3)
    holoEntity(3):removeTrails()
    holoModel(3,"models/buildables/sapper_dispenser.mdl")
    holoAlpha(3,0)
    holoParent(3,entity())
    holoCreate(4)
    holoModel(4,"models/buildables/sapper_sentry3.mdl")
    holoPos(4,holoEntity(3):toWorld(vec(0,0,-10)))
    holoAlpha(4,0)
    holoParent(4,entity())     
}   
}
if(Dead){
 HB:propDelete()
 if(clk("delete")){
    reset()
}   
}
}
