remstart Info on type _Bot: x#: X Position y#: Y Position team: Bot's team number aim#: Aiming direction walk#: Walking direction score: Player score life: Bot's life amount left t: Bot's target: 0 for main target, greater than 0 for another bot's ID tb: If target is main target, tb is main target's ID rstart: Time (in milisec) when reload started. bullets: Number of bullets in magazine. shoot: Time shot started. mode: 0 for attacking, 1 for defending. offset#: Angle offset when walking and turning arround in defend mode. form: Formation mode - 0=none, 1=leader of formation, 2=in formation, but not the leader formx#: If 'form' is set to 2, then 'formx#' is bot's X position in the formation. formy#: If 'form' is set to 2, then 'formy#' is bot's Y position in the formation. leader: If 'form' is set to 2, then 'leader' is bot's formation leader. skill#: When a bot hits its target, his skill is growing. It is used as a factor when calculating if shot will hit or not. Info on type _Team: color: Team's color score: Team's total score x#: Team base X position y#: Team base Y position Bots#: Number of team's bots; Float value because it's needed for later calculations. time: Value of timer when started (if 0, then no timer) remend type _Bot x#=0 y#=0 team=1 aim#=0 walk#=0 score=0 life=100 t=0 tb=0 rstart=0 bullets=10 shoot=0 mode=0 offset#=0 form=0 formx#=0 formy#=0 leader=0 skill#=1 endtype type _Team color=0 score=0 x#=0 y#=0 Bots#=6 time=0 BotCam=0 endtype global win_delay=5, attacking_team=1, formation=0 global l_team=1 global cam_team=1 :`Current team for cam 1 global _cam=0 :`Current camera global l_cam=0 :`Last camera - used for camera changing global r_wait=2000 :`Time to wait to finish reloading (in milisec) global top_min=4 :`Bitmap minimize factor global _top_h,_top_w,_top_x,_top_y,_m=1 global key_min=0,key_plus=0,key_tab=0 global dim key_num(3) global dim Bots(12) as _Bot global dim Teams(2) as _Team set display mode 800,600,16 if check display mode(1024,768,16)=1 set display mode 1024,768,32 else if check display mode(800,600,16)=1 set display mode 800,600,16 else if check display mode(640,480,16)=1 set display mode 640,480,16 endif endif endif sync on : sync rate 100 backdrop on color backdrop rgb(200,200,200) hide mouse set text font "arial" set text size 14 set text to bold set text transparent sync : center text screen width()/2, screen height()/2,"Loading..." : sync set text size 20 set current camera 0 autocam off gosub _load gosub _setup do gosub _ai_calc gosub _check_keyboard gosub _print_stats gosub _render_fps gosub _render_topview sync loop end _ai_calc: for i=1 to array count(Bots(0)) if Bots(i).life>0 if Bots(i).t>0 :`Target is another bot if Bots(Bots(i).t).team=Bots(i).team :`Check target is within the other team Bots(i).t=0 else if Bots(Bots(i).t).life>0 if mode=0 ChaseBot(i,Bots(i).t) else if GetDist(Bots(Bots(i).t).x#,Bots(Bots(i).t).y#,Teams(Bots(i).tb).x#,Teams(Bots(i).tb).y#)<300 xm#=(Bots(Bots(i).t).x#+Teams(Bots(i).tb).x#)/2 ym#=(Bots(Bots(i).t).y#+Teams(Bots(i).tb).y#)/2 if Bots(i).x#>xm#-16 and Bots(i).x#<xm#+16 and Bots(i).y#>ym#-16 and Bots(i).y#<ym#+16 ChaseBot(i,Bots(i).t) else AdvancePos(i,xm#,ym#) endif else ChaseBot(i,Bots(i).t) endif endif else Bots(i).t=0 endif endif else :`Target is main target AdvanceToMainTarget(i) endif endif next i CheckTimer() return _check_keyboard: l_team=cam_team l_cam=_cam if keystate(15)=1 :`Tab key if key_tab=0 attacking_team=3-attacking_team :`Swap teams Teams(1).time=0 Teams(2).time=0 gosub _setup endif key_tab=1 else key_tab=0 endif if keystate(74)=1 :`Numpad minus key if top_min<8 and key_min=0 inc top_min gosub _set_bitmap_pos endif key_min=1 else key_min=0 endif if keystate(78)=1 :`Numpad plus key if top_min>1 and key_plus=0 dec top_min gosub _set_bitmap_pos endif key_plus=1 else key_plus=0 endif if keystate(11)=1 :`0 key if l_cam<>0 and key_num(1)=0 l_cam=_cam _cam=0 endif key_num(1)=1 else key_num(1)=0 endif if keystate(2)=1 :`1 key if key_num(2)=0 if l_cam<>1 l_cam=_cam _cam=1 endif cam_team=1 if l_team=cam_team inc Teams(1).BotCam if Teams(1).BotCam>int(Teams(1).Bots#) then dec Teams(1).BotCam,int(Teams(1).Bots#) endif endif key_num(2)=1 else key_num(2)=0 endif if keystate(3)=1 :`2 key if key_num(3)=0 if l_cam<>1 l_cam=_cam _cam=1 endif cam_team=2 if l_team=cam_team inc Teams(2).BotCam if Teams(2).BotCam>int(Teams(2).Bots#) then dec Teams(2).BotCam,int(Teams(2).Bots#) endif endif key_num(3)=1 else key_num(3)=0 endif return _print_stats: `Print FPS rate ink rgb(0,0,128),0 text 10,10,"FPS: "+str$(screen fps()) for i=1 to array count(Teams(0)) ink Teams(i).color,0 text 10,screen height()-20-(array count(Teams(0))-i)*15,"Team "+str$(i)+": "+str$(Teams(i).score) next i ink rgb(0,0,128),0 for i=1 to array count(Bots(0)) if timer()<Bots(i).rstart+r_wait r_str$=" [ Reloading ]" else r_str$="" endif text 10,50+i*15, "Bot "+str$(i) text 70,50+i*15, "Life: "+str$(Bots(i).life) text 150,50+i*15, "Target: "+str$(Bots(i).t) text 230,50+i*15, r_str$ next i return _render_topview: for i=1 to array count(Teams(0)) ink Teams(i).color,Teams(i).color box _top_x+(int(Teams(i).x#)-16)/top_min,_top_y+(int(Teams(i).y#)-16)/top_min,_top_x+(int(Teams(i).x#)+16)/top_min,_top_y+(int(Teams(i).y#)+16)/top_min next i for i=1 to array count(Bots(0)) if Bots(i).life>0 ink Teams(Bots(i).team).color,Teams(Bots(i).team).color circle _top_x+(int(Bots(i).x#))/top_min,_top_y+(int(Bots(i).y#))/top_min,16/top_min line _top_x+(int(Bots(i).x#))/top_min,_top_y+(int(Bots(i).y#))/top_min,_top_x+(int(Bots(i).x#+cos(Bots(i).aim#)*16))/top_min,_top_y+(int(Bots(i).y#+sin(Bots(i).aim#)*16))/top_min endif next i return _render_fps: for i=1 to array count(Bots(0)) if Bots(i).life>0 position object i,Bots(i).x#,16,Bots(i).y# if object visible(i)=0 then show object i else if object visible(i)=1 then hide object i endif next i for i=1 to array count(Teams(0)) j=array count(Bots(0))+i position object j,Teams(i).x#,16,Teams(i).y# next i if _cam=1 CamFollowBot() else if _cam<>l_cam ResetCam() endif endif return _setup: ResetCam() randomize timer() Teams(1).color=rgb(0,0,255) Teams(1).x#=(screen width())-128 Teams(1).y#=rnd((screen height())-128*2)+128 Teams(1).Bots#=6 Teams(1).BotCam=1 Teams(2).color=rgb(255,0,0) Teams(2).x#=128 Teams(2).y#=(screen height())-Teams(1).y# Teams(2).Bots#=6 Teams(2).BotCam=7 cteam=1 j#=1 a#=1 for i=1 to array count(Teams(0)) j=array count(Bots(0))+i CheckDelObj(j) make object cube j,32 set object cull j,0 color object j,Teams(i).color position object j,Teams(i).x#,16,Teams(i).y# next i for i=1 to array count(Bots(0)) if j#>Teams(cteam).Bots# inc cteam j#=1 endif a#=j#/(Teams(cteam).Bots#)*360.0 Bots(i).team=cteam Bots(i).x#=Teams(cteam).x#+cos(a#)*64 Bots(i).y#=Teams(cteam).y#+sin(a#)*64 Bots(i).t=0 Bots(i).mode=(cteam=3-attacking_team) Bots(i).tb=3-attacking_team Bots(i).life=100 if cteam=attacking_team if int(j#)=1 then Bots(i).form=1 else Bots(i).form=2 endif CheckDelObj(i) make object sphere i,32 set object cull i,0 color object i,Teams(Bots(i).team).color position object i,Bots(i).x#,16,Bots(i).y# inc j# next i randomize timer() formation=rnd(1) SwitchLeader(1) return _load: gosub _set_bitmap_pos create bitmap 1,10,10 set current bitmap 1 ink 0,0 box 1,1,5,5 box 6,6,10,10 ink rgb(255,255,255),0 box 6,1,10,5 box 1,6,5,10 get image 1,1,1,10,10 set current bitmap 0 make matrix _m,screen width(),screen height(),10,10 prepare matrix texture _m,1,1,1 delete bitmap 1 sync return _set_bitmap_pos: _top_w=screen width()/top_min _top_h=screen height()/top_min _top_x=0 _top_y=screen height()-_top_h return function ResetCam() scr#=sqrt( (screen width()/2)^2 + (screen height()/2)^2 ) offsetxz=100 offsety=80 position camera -1*offsetxz,offsety,-1*offsetxz xzdist#=sqrt(2*offsetxz^2) yrotate camera 0,45 xrotate camera 0,-1*int(atan( -1*offsety/(scr#+xzdist#) )) endfunction function CamFollowBot() __retry_bot: b=Teams(cam_team).BotCam if Bots(b).life<=0 inc Teams(cam_team).BotCam if Teams(cam_team).BotCam>int(Teams(cam_team).Bots#) then dec Teams(cam_team).BotCam,int(Teams(cam_team).Bots#) goto __retry_bot endif position camera 0,Bots(b).x#+cos(Bots(b).aim#-180)*100,16,Bots(b).y#+sin(Bots(b).aim#-180)*100 rotate camera 0,0,wrapvalue(90-Bots(b).aim#),0 endfunction function CheckDelObj(id) if object exist(id)=1 then delete object id endfunction function GetAngle(x1#,y1#,x2#,y2#) a#=90-atanfull(x2#-x1#,y2#-y1#) endfunction a# function GetDist(x1#,y1#,x2#,y2#) d#=sqrt((x1#-x2#)^2+(y1#-y2#)^2) endfunction d# function AdvancePos(n,x#,y#) Bots(n).walk#=GetAngle(Bots(n).x#,Bots(n).y#,x#,y#) Bots(n).aim#=GetAngle(Bots(n).x#,Bots(n).y#,x#,y#) Advance(n,2) TryToShoot(n,Bots(n).t) endfunction function Advance(n,d#) lx#=Bots(n).x# ly#=Bots(n).y# Bots(n).x#=Bots(n).x#+cos(Bots(n).walk#)*d# Bots(n).y#=Bots(n).y#+sin(Bots(n).walk#)*d# BotCollision(n) `BoxCollision(n) WallCollision(n) endfunction function BotCollision(n) for i=1 to array count(Bots(0)) if i<>n and Bots(i).life>0 and GetDist(Bots(n).x#,Bots(n).y#,Bots(i).x#,Bots(i).y#)<32 :`Collision found a#=GetAngle(Bots(i).x#,Bots(i).y#,Bots(n).x#,Bots(n).y#) d#=32-GetDist(Bots(n).x#,Bots(n).y#,Bots(i).x#,Bots(i).y#) Bots(n).x#=Bots(n).x#+cos(a#)*d# Bots(n).y#=Bots(n).y#+sin(a#)*d# endif next i endfunction function BoxCollision(n) x#=Bots(n).x# y#=Bots(n).y# for i=1 to array count(Teams(0)) tx#=Teams(i).x# ty#=Teams(i).y# if GetDist(tx#,ty#,x#,y#)<(16/cos(GetAngle(tx#,ty#,x#,y#)))+16 :`Collision between circle and box if x#<tx#+16+16 :`Right side of box d#=tx#-x#+16+16 a#=180.0 endif if x#>tx#-16-16 :`Left side d#=x#-tx#+16+16 a#=0.0 endif if y#<ty#+16+16 :`Bottom side d#=ty#-y#+16+16 a#=270.0 endif if y#>ty#-16-16 :`Top side d#=y#-ty#+16+16 a#=90.0 endif Bots(n).x#=Bots(n).x#+cos(a#)*d# Bots(n).y#=Bots(n).y#+sin(a#)*d# endif next i endfunction function WallCollision(n) col=0 x#=Bots(n).x# y#=Bots(n).y# if x#<16 :`Collision with left wall d#=x#-16 a#=180.0 col=1 endif if x#>(screen width())-16 :`Right wall d#=(screen width())-x#-16 a#=0.0 col=1 endif if y#<16 :`Top wall d#=y#-16 a#=270.0 col=1 endif if y#>(screen height())-16 :`Bottom wall d#=(screen height())-y#-16 a#=90.0 col=1 endif if col=1 Bots(n).x#=Bots(n).x#+cos(a#)*d# Bots(n).y#=Bots(n).y#+sin(a#)*d# endif endfunction function Shoot(n,t) if timer()<Bots(n).shoot+500 then exitfunction l=8 if Bots(n).mode=1 then l=10 :`If in defend mode, set bullets to be more powerful randomize timer() if rnd(int(GetDist(Bots(n).x#,Bots(n).y#,Bots(t).x#,Bots(t).y#)/40/Bots(n).skill#))=0 :`Closer than 40 will always hit dec Bots(t).life,l inc Bots(n).skill#,0.08 endif dec Bots(n).bullets Bots(n).shoot=timer() if Bots(t).life<0 then Bots(t).life=0 endfunction function TryToShoot(n,t) if Bots(n).bullets>0 if timer()>Bots(n).rstart+r_wait Shoot(n,t) endif else Bots(n).rstart=timer() Bots(n).bullets=10 endif endfunction function LookForTarget(n) t=FindNearestEnemy(n,250) if t>0 then Bots(n).t=t endfunction function FindNearestEnemy(n,range#) mindist#=0 t=0 for i=1 to array count(Bots(0)) if Bots(n).team<>Bots(i).team and Bots(i).life>0 a#=GetAngle(Bots(n).x#,Bots(n).y#,Bots(i).x#,Bots(i).y#) dist#=GetDist(Bots(n).x#,Bots(n).y#,Bots(i).x#,Bots(i).y#) if (a#>Bots(n).aim#-45 and a#<Bots(n).aim#+45) :`Check if bot is in FOV if (dist#<mindist# or mindist#=0) and dist#<range# mindist#=dist# t=i endif endif endif next i endfunction t function AimTo(n,x#,y#) Bots(n).aim#=GetAngle(Bots(n).x#,Bots(n).y#,x#,y#) Bots(n).walk#=Bots(n).aim# endfunction function ChaseBot(n,t) AimTo(n,Bots(t).x#,Bots(t).y#) dist#=GetDist(Bots(n).x#,Bots(n).y#,Bots(t).x#,Bots(t).y#) if dist#<70 Bots(n).walk#=wrapvalue(Bots(n).walk#) Advance(n,2) TryToShoot(n,t) else if dist#>80 Advance(n,2) TryToShoot(n,t) else Bots(n).walk#=wrapvalue(Bots(n).walk#+90) Advance(n,2) Bots(n).walk#=wrapvalue(Bots(n).walk#-90) TryToShoot(n,t) endif endif endfunction function AdvanceToMainTarget(n) if Bots(n).mode=0 AdvanceAndAttack(n) else AdvanceAndDefend(n) endif endfunction function AdvanceAndAttack(n) t=Bots(n).tb AimTo(n,Teams(t).x#,Teams(t).y#) dist#=GetDist(Bots(n).x#,Bots(n).y#,Teams(t).x#,Teams(t).y#) if dist#<16 :`Bot touches target if Teams(t).time+win_delay*1000<timer() then Teams(t).time=timer() else adv#=2 if Bots(n).form=2 if Bots(Bots(n).leader).life<40 SwitchLeader(Bots(i).team) else dist#=GetDist(Bots(n).x#,Bots(n).y#,Bots(n).formx#,Bots(n).formy#) if dist#>10 then AimTo(n,Bots(n).formx#,Bots(n).formy#) endif endif if Bots(n).form=1 bots$="" for i=(n+1) to (n+int(Teams(Bots(n).team).Bots#)-1) bots$=bots$+chr$(i) next i if FindNearestEnemy(n,320)>0 :`Can see enemy LineFormation(n,bots$) else if formation=1 CircleFormation(n,bots$) else VFormation(n,bots$) endif endif if BotsInFormation(n,bots$)=0 then adv#=1.0 endif Advance(n,adv#) LookForTarget(n) endif endfunction function AdvanceAndDefend(n) t=Bots(n).tb tx#=Teams(t).x# ty#=Teams(t).y# dist#=GetDist(Bots(n).x#,Bots(n).y#,tx#,ty#) AimTo(n,tx#,ty#) Bots(n).aim#=wrapvalue(Bots(n).aim#+180) if dist#<120 if dist#<110 Bots(n).walk#=Bots(n).aim# else Bots(n).walk#=wrapvalue(Bots(n).walk#+90) endif endif Advance(n,2) Bots(n).aim#=wrapvalue(Bots(n).aim#+Bots(n).offset#) inc Bots(n).offset#,10 LookForTarget(n) endfunction function CheckTimer() dim t(array count(Teams(0))) for i=1 to array count(Teams(0)) t(i)=1 if Teams(i).time>0 center text screen width()/2,20,"Time left: "+str$(win_delay-int((timer()-Teams(i).time)/1000)) t_timeleft=timer() if Teams(i).time+win_delay*1000+200>=timer() WinGame(3-i) endif endif next i j=0 cteam=1 for i=1 to array count(Bots(0)) inc j if j>int(Teams(cteam).Bots#) j=1 inc cteam endif t(cteam)=(t(cteam) and (Bots(i).life<=0)) next i for i=1 to array count(Teams(0)) Teams(i).time=0 if t(i)=1 WinGame(3-i) endif next i endfunction function WinGame(n) Teams(n).time=0 inc Teams(n).score attacking_team=3-attacking_team :`Swap teams gosub _setup endfunction function VFormation(leader,bots$) Bots(leader).form=1 for i=1 to len(bots$) n=asc(left$(mid$(bots$,i),1)) Bots(n).form=2 Bots(n).leader=leader if i mod 2=0 a#=135 else a#=225 endif a#=a#+Bots(leader).walk# Bots(n).formx#=Bots(leader).x#+cos(a#)*64*((i+(i mod 2))/2) Bots(n).formy#=Bots(leader).y#+sin(a#)*64*((i+(i mod 2))/2) Bots(n).aim#=Bots(leader).aim# next i if (len(bots$) mod 2)=1 n=asc(right$(bots$,1)) a#=180+Bots(leader).walk# Bots(n).formx#=Bots(leader).x#+cos(a#)*64 Bots(n).formy#=Bots(leader).y#+sin(a#)*64 endif endfunction function CircleFormation(leader,bots$) Bots(leader).form=1 i#=0 for i=1 to len(bots$) inc i# n=asc(left$(mid$(bots$,i),1)) Bots(n).form=2 Bots(n).leader=leader a#=i#/len(bots$)*360.0 Bots(n).formx#=Bots(leader).x#+cos(a#)*64 Bots(n).formy#=Bots(leader).y#+sin(a#)*64 Bots(n).aim#=a# next i endfunction function LineFormation(leader,bots$) Bots(leader).form=1 for i=1 to len(bots$) n=asc(left$(mid$(bots$,i),1)) Bots(n).form=2 Bots(n).leader=leader if i mod 2=0 a#=-1 else a#=1 endif a#=a#*90+Bots(leader).walk# Bots(n).formx#=Bots(leader).x#+cos(a#)*64*((i+(i mod 2))/2) Bots(n).formy#=Bots(leader).y#+sin(a#)*64*((i+(i mod 2))/2) Bots(n).aim#=Bots(leader).aim# next i endfunction function BotsInFormation(leader,bots$) for i=1 to len(bots$) n=asc(left$(mid$(bots$,i),1)) dist#=GetDist(Bots(n).x#,Bots(n).y#,Bots(n).formx#,Bots(n).formy#) if dist#>17 then exitfunction 0 next i endfunction 1 function SwitchLeader(t) max=0 for i=1 to array count(Bots(0)) if Bots(i).team=t and Bots(i).life>=40 and Bots(i).life>max max=Bots(i).life l=i endif next i Bots(l).form=1 Bots(l).leader=0 for i=1 to array count(Bots(0)) if Bots(i).team=t and Bots(i).life>=40 and i<>l Bots(i).form=2 Bots(i).leader=l endif next i endfunction