home *** CD-ROM | disk | FTP | other *** search
/ Superpower (Alt) / SUPERPOWER.iso / q / patch / mbq073 / iwbotsrc / botai.qc < prev    next >
Encoding:
Text File  |  1996-09-01  |  66.3 KB  |  1,905 lines

  1. 
  2. /*
  3. ==============================================================================
  4.  
  5. BOT AI
  6.  
  7. ==============================================================================
  8. */
  9.  
  10. // Prototypes
  11. void(float shotcount, vector dir, vector spread) FireBullets;
  12. void () bot_upabit;
  13. float() check_dodge;
  14. void () bot_start_dodge;
  15. void () bot_run_mdodge;
  16. void () bot_end_dodge;
  17. void () bot_start_circle;
  18. void () bot_end_circle;
  19. void () bot_enemy_image;
  20. void () bot_remove_enemy_image;
  21. void () bot_ai_face;
  22. float(entity targ, entity targ2) infrontr;
  23. void() bot_firebullets;
  24. void () BotFoundRocket;
  25. void () BotStartDM;
  26. void (float frgs,entity tmp) BotReStartDM;
  27. void () bot_run_dodge;
  28. float    ()                                BotFindTarget;
  29. void () bot_run_circle;
  30. void    ()                                bot_ai_stand;
  31. void    ()                                bot_die;
  32. void    ()                                BotSightSound;
  33. void    ()                                BotFoundTarget;
  34. void    ()                                BotHuntTarget;
  35. void    (float dist)                    bot_ai_walk;
  36. void    ()                                bot_ai_turn;
  37. void    (float dist)                    bot_ai_run;
  38. void    (void () thinkst)                BotCheckRefire;
  39. void    ()                                BotSelfDeActivate;
  40. void    ()                                              bot_attack;
  41. void    ()                                              bot_shoot;
  42. void    ()                                bot_fire;
  43. void    ()                                              bot_nail;
  44. void    ()                                              bot_nail2;
  45. void    ()                                              enforcer_fire;
  46. void    (vector offset)                                 benforcer_fire;
  47. void    (vector org, vector dir)                        launch_spike;
  48. void    ()                                              spike_touch;
  49. void ()                                                 superspike_touch;
  50. void (entity oldself) Bot_PostThink;
  51. void (entity oldself) Bot_PreThink;
  52. //void () bot_remove_controller;
  53. void () bot_think;
  54. void () Bot_PostThinkb;
  55. void () Bot_PreThinkb;
  56. void () bot_thinkb;
  57. void() BotCheckPowerupsb;
  58. float   modelindex_eyes, modelindex_bot;
  59. void () BotFoundItem;
  60. float () BotFindItem;
  61. void () BOTFireGrenade;
  62. void () BOTGrenadeTouch;
  63. void () BOTGrenadeExplode;
  64. void () s_explode1;
  65. void    (float dist)                                    bot_ai_stuff;
  66. void    ()                                              BotFoundStuff;
  67. void    ()                                              BotHuntStuff;
  68. float    ()                                              BotFindStuff;
  69.  
  70. //void () set_ai_think;
  71.  
  72. $cd /raid/quake/id1/models/player_4
  73. $origin 0 -6 24
  74. $base base        
  75. $skin skin
  76.  
  77. //
  78. // running
  79. //
  80. $frame axrun1 axrun2 axrun3 axrun4 axrun5 axrun6
  81.  
  82. $frame rockrun1 rockrun2 rockrun3 rockrun4 rockrun5 rockrun6
  83.  
  84. //
  85. // standing
  86. //
  87. $frame stand1 stand2 stand3 stand4 stand5
  88.  
  89. $frame axstnd1 axstnd2 axstnd3 axstnd4 axstnd5 axstnd6
  90. $frame axstnd7 axstnd8 axstnd9 axstnd10 axstnd11 axstnd12
  91.  
  92.  
  93. //
  94. // pain
  95. //
  96. $frame axpain1 axpain2 axpain3 axpain4 axpain5 axpain6
  97.  
  98. $frame pain1 pain2 pain3 pain4 pain5 pain6
  99.  
  100.  
  101. //
  102. // death
  103. //
  104.  
  105. $frame axdeth1 axdeth2 axdeth3 axdeth4 axdeth5 axdeth6
  106. $frame axdeth7 axdeth8 axdeth9
  107.  
  108. $frame deatha1 deatha2 deatha3 deatha4 deatha5 deatha6 deatha7 deatha8
  109. $frame deatha9 deatha10 deatha11
  110.  
  111. $frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
  112. $frame deathb9
  113.  
  114. $frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
  115. $frame deathc9 deathc10 deathc11 deathc12 deathc13 deathc14 deathc15
  116.  
  117. $frame deathd1 deathd2 deathd3 deathd4 deathd5 deathd6 deathd7
  118. $frame deathd8 deathd9
  119.  
  120. $frame deathe1 deathe2 deathe3 deathe4 deathe5 deathe6 deathe7
  121. $frame deathe8 deathe9
  122.  
  123. //
  124. // attacks
  125. //
  126. $frame nailatt1 nailatt2
  127.  
  128. $frame light1 light2
  129.  
  130. $frame rockatt1 rockatt2 rockatt3 rockatt4 rockatt5 rockatt6
  131.  
  132. $frame shotatt1 shotatt2 shotatt3 shotatt4 shotatt5 shotatt6
  133.  
  134. $frame axatt1 axatt2 axatt3 axatt4 axatt5 axatt6
  135.  
  136. $frame axattb1 axattb2 axattb3 axattb4 axattb5 axattb6
  137.  
  138. $frame axattc1 axattc2 axattc3 axattc4 axattc5 axattc6
  139.  
  140. $frame axattd1 axattd2 axattd3 axattd4 axattd5 axattd6
  141.  
  142.  
  143. void()    bot_stand1    =[    $stand1,    bot_stand2    ] {bot_ai_stand();};
  144. void()    bot_stand2    =[    $stand2,    bot_stand3    ] {bot_ai_stand();};
  145. void()    bot_stand3    =[    $stand3,    bot_stand4    ] {bot_ai_stand();};
  146. void()    bot_stand4    =[    $stand4,    bot_stand5    ] {bot_ai_stand();};
  147. void()  bot_stand5      =[      $stand5,        bot_stand1      ] {bot_ai_stand();};
  148.  
  149. void()  bot_walk1       =[      $rockrun1 ,        bot_walk2       ]
  150. {
  151.     if (random() < 0.2)
  152.         sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
  153.         bot_ai_walk(6);
  154. };
  155. void()  bot_walk2       =[      $rockrun1 ,        bot_walk3       ] {bot_ai_walk(10);};
  156. void()  bot_walk3       =[      $rockrun2 ,        bot_walk4       ] {bot_ai_walk(10);};
  157. void()  bot_walk4       =[      $rockrun2 ,        bot_walk5       ] {bot_ai_walk(8);};
  158. void()  bot_walk5       =[      $rockrun3 ,        bot_walk6       ] {bot_ai_walk(4);};
  159. void()  bot_walk6       =[      $rockrun3 ,        bot_walk7       ] {bot_ai_walk(6);bot_upabit();};
  160. void()  bot_walk7       =[      $rockrun4 ,        bot_walk8       ] {bot_ai_walk(10);};
  161. void()  bot_walk8       =[      $rockrun4 ,        bot_walk9       ] {bot_ai_walk(10);};
  162. void()  bot_walk9       =[      $rockrun5 ,        bot_walk10       ] {bot_ai_walk(8);};
  163. void()  bot_walk10       =[      $rockrun5 ,        bot_walk11       ] {bot_ai_walk(4);};
  164. void()  bot_walk11       =[      $rockrun6 ,        bot_walk12       ] {bot_ai_walk(6);};
  165. void()  bot_walk12       =[      $rockrun6 ,        bot_walk1       ] {bot_ai_walk(8);bot_upabit();};
  166.  
  167. void()  bot_run1        =[      $rockrun1  ,        bot_run2        ]
  168. {
  169.     if (random() < 0.2)
  170.         sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
  171.         bot_ai_run(30);//18
  172. };
  173. void()  bot_run2        =[      $rockrun2  ,        bot_run3        ] {bot_ai_run(30);};//14
  174. void()  bot_run3        =[      $rockrun3  ,        bot_run4        ] {bot_ai_run(30);bot_upabit();};//7
  175. void()  bot_run4        =[      $rockrun4  ,        bot_run5        ] {bot_ai_run(30);};//12
  176. void()  bot_run5        =[      $rockrun5  ,        bot_run6        ] {bot_ai_run(30);};//14
  177. void()  bot_run6        =[      $rockrun6  ,        bot_run1        ] {bot_ai_run(30);bot_upabit();};//14
  178.  
  179. void()  bot_dodge1        =[      $shotatt1,       bot_dodge2        ] {bot_ai_face();bot_start_dodge();bot_run_dodge();};
  180. void()  bot_dodge2        =[      $shotatt2,       bot_dodge3        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  181. void()  bot_dodge3        =[      $shotatt3,       bot_dodge4        ] {bot_ai_face();bot_run_dodge();};
  182. void()  bot_dodge4        =[      $shotatt4,       bot_dodge5        ] {bot_ai_face();bot_run_dodge();};
  183. void()  bot_dodge5        =[      $shotatt5,       bot_dodge6        ] {bot_ai_face();bot_run_dodge();};
  184.  
  185. void()  bot_dodge6        =[      $rockrun1  ,        bot_dodge7        ]
  186. {bot_ai_face();
  187.     if (random() < 0.2)
  188.         sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
  189.         bot_run_dodge();
  190. };
  191. void()  bot_dodge7        =[      $rockrun2  ,        bot_dodge8        ] {bot_ai_face();bot_run_dodge();};
  192. void()  bot_dodge8        =[      $rockrun3  ,        bot_dodge9        ] {bot_ai_face();bot_run_dodge();};
  193. void()  bot_dodge9        =[      $rockrun4  ,        bot_dodge10       ] {bot_ai_face();bot_run_dodge();};
  194. void()  bot_dodge10       =[      $rockrun5  ,        bot_dodge11       ] {bot_ai_face();bot_run_dodge();};
  195. void()  bot_dodge11       =[      $shotatt1,       bot_dodge12        ] {bot_ai_face();bot_run_dodge();};
  196. void()  bot_dodge12       =[      $shotatt2,       bot_dodge13        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  197. void()  bot_dodge13       =[      $shotatt3,       bot_dodge14       ] {bot_ai_face();bot_run_dodge();};
  198. void()  bot_dodge14       =[      $shotatt4,       bot_dodge15        ] {bot_ai_face();bot_run_dodge();};
  199. void()  bot_dodge15        =[      $shotatt5,       bot_dodge16        ] {bot_ai_face();bot_run_dodge();};
  200. void()  bot_dodge16        =[      $shotatt6,       bot_dodge17        ] {bot_ai_face();bot_run_dodge();};
  201. void()  bot_dodge17        =[      $rockrun3  ,        bot_dodge18        ] {bot_ai_face();bot_run_dodge();};
  202. void()  bot_dodge18        =[      $rockrun4  ,        bot_dodge19        ] {bot_ai_face();bot_run_dodge();};
  203. void()  bot_dodge19        =[      $rockrun5  ,        bot_dodge20        ] {bot_ai_face();bot_run_dodge();};
  204. void()  bot_dodge20       =[      $rockrun6  ,        bot_run1        ] {bot_ai_face();bot_run_dodge();bot_end_dodge();};
  205.  
  206. void()  bot_dodgen1        =[      $nailatt2,       bot_dodgen2        ] {bot_ai_face();bot_start_dodge();bot_run_dodge();};
  207. void()  bot_dodgen2        =[      $nailatt1,       bot_dodgen3        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  208. void()  bot_dodgen3        =[      $nailatt2,       bot_dodgen4        ] {bot_ai_face();bot_run_dodge();};
  209. void()  bot_dodgen4        =[      $nailatt1,       bot_dodgen5        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  210. void()  bot_dodgen5        =[      $nailatt2,       bot_dodgen6        ] {bot_ai_face();bot_run_dodge();};
  211.  
  212. void()  bot_dodgen6        =[      $rockrun1  ,        bot_dodgen7        ]
  213. {bot_ai_face();
  214.     if (random() < 0.2)
  215.         sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
  216.         bot_run_dodge();
  217. };
  218. void()  bot_dodgen7        =[      $rockrun2  ,        bot_dodgen8        ] {bot_ai_face();bot_run_dodge();};
  219. void()  bot_dodgen8        =[      $rockrun3  ,        bot_dodgen9        ] {bot_ai_face();bot_run_dodge();};
  220. void()  bot_dodgen9        =[      $rockrun4  ,        bot_dodgen10       ] {bot_ai_face();bot_run_dodge();};
  221. void()  bot_dodgen10       =[      $rockrun5  ,        bot_dodgen11       ] {bot_ai_face();bot_run_dodge();};
  222. void()  bot_dodgen11       =[      $nailatt2,       bot_dodgen12        ] {bot_ai_face();bot_run_dodge();};
  223. void()  bot_dodgen12       =[      $nailatt1,       bot_dodgen13        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  224. void()  bot_dodgen13       =[      $nailatt2,       bot_dodgen14       ] {bot_ai_face();bot_run_dodge();};
  225. void()  bot_dodgen14       =[      $nailatt1,       bot_dodgen15        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  226. void()  bot_dodgen15        =[      $nailatt2,       bot_dodgen16        ] {bot_ai_face();bot_run_dodge();};
  227. void()  bot_dodgen16        =[      $nailatt1,       bot_dodgen17        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  228. void()  bot_dodgen17        =[      $rockrun3  ,        bot_dodgen18        ] {bot_ai_face();bot_run_dodge();};
  229. void()  bot_dodgen18        =[      $rockrun4  ,        bot_dodgen19        ] {bot_ai_face();bot_run_dodge();};
  230. void()  bot_dodgen19        =[      $rockrun5  ,        bot_dodgen20        ] {bot_ai_face();bot_run_dodge();};
  231. void()  bot_dodgen20       =[      $rockrun6  ,        bot_run1        ] {bot_ai_face();bot_run_dodge();bot_end_dodge();};
  232.  
  233. void()  bot_dodgesn1        =[      $nailatt2,       bot_dodgesn2        ] {bot_ai_face();bot_start_dodge();bot_run_dodge();};
  234. void()  bot_dodgesn2        =[      $nailatt1,       bot_dodgesn3        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  235. void()  bot_dodgesn3        =[      $nailatt1,       bot_dodgesn4        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  236. void()  bot_dodgesn4        =[      $nailatt2,       bot_dodgesn5        ] {bot_ai_face();bot_run_dodge();};
  237. void()  bot_dodgesn5        =[      $nailatt1,       bot_dodgesn6        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  238.  
  239. void()  bot_dodgesn6        =[      $rockrun1  ,        bot_dodgesn7        ]
  240. {bot_ai_face();
  241.     if (random() < 0.2)
  242.         sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
  243.         bot_run_dodge();
  244. };
  245. void()  bot_dodgesn7        =[      $rockrun2  ,        bot_dodgesn8        ] {bot_ai_face();bot_run_dodge();};
  246. void()  bot_dodgesn8        =[      $rockrun3  ,        bot_dodgesn9        ] {bot_ai_face();bot_run_dodge();};
  247. void()  bot_dodgesn9        =[      $rockrun4  ,        bot_dodgesn10       ] {bot_ai_face();bot_run_dodge();};
  248. void()  bot_dodgesn10       =[      $rockrun5  ,        bot_dodgesn11       ] {bot_ai_face();bot_run_dodge();};
  249. void()  bot_dodgesn11       =[      $nailatt2,       bot_dodgesn12        ] {bot_ai_face();bot_run_dodge();};
  250. void()  bot_dodgesn12       =[      $nailatt1,       bot_dodgesn13        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  251. void()  bot_dodgesn13       =[      $nailatt1,       bot_dodgesn14       ] {bot_ai_face();bot_attack();bot_run_dodge();};
  252. void()  bot_dodgesn14       =[      $nailatt2,       bot_dodgesn15        ] {bot_ai_face();bot_run_dodge();};
  253. void()  bot_dodgesn15        =[      $nailatt1,       bot_dodgesn16        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  254. void()  bot_dodgesn16        =[      $nailatt1,       bot_dodgesn17        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  255. void()  bot_dodgesn17        =[      $rockrun3  ,        bot_dodgesn18        ] {bot_ai_face();bot_run_dodge();};
  256. void()  bot_dodgesn18        =[      $rockrun4  ,        bot_dodgesn19        ] {bot_ai_face();bot_run_dodge();};
  257. void()  bot_dodgesn19        =[      $rockrun5  ,        bot_dodgesn20        ] {bot_ai_face();bot_run_dodge();};
  258. void()  bot_dodgesn20       =[      $rockrun6  ,        bot_run1        ] {bot_ai_face();bot_run_dodge();bot_end_dodge();};
  259.  
  260. void()  bot_dodger1        =[      $rockatt1,       bot_dodger2        ] {bot_ai_face();bot_start_dodge();bot_attack();bot_run_dodge();};
  261. void()  bot_dodger2        =[      $rockatt2,       bot_dodger3        ] {bot_ai_face();bot_run_dodge();};
  262. void()  bot_dodger3        =[      $rockatt3,       bot_dodger4        ] {bot_ai_face();bot_run_dodge();};
  263. void()  bot_dodger4        =[      $rockatt4,       bot_dodger5        ] {bot_ai_face();bot_run_dodge();};
  264. void()  bot_dodger5        =[      $rockatt5,       bot_dodger6        ] {bot_ai_face();bot_run_dodge();};
  265.  
  266. void()  bot_dodger6        =[      $rockrun1  ,        bot_dodger7        ]
  267. {bot_ai_face();
  268.     if (random() < 0.2)
  269.         sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
  270.         bot_run_dodge();
  271. };
  272. void()  bot_dodger7        =[      $rockrun2  ,        bot_dodger8        ] {bot_ai_face();bot_run_dodge();};
  273. void()  bot_dodger8        =[      $rockrun3  ,        bot_dodger9        ] {bot_ai_face();bot_run_dodge();};
  274. void()  bot_dodger9        =[      $rockrun4  ,        bot_dodger10       ] {bot_ai_face();bot_run_dodge();};
  275. void()  bot_dodger10       =[      $rockrun5  ,        bot_dodger11       ] {bot_ai_face();bot_run_dodge();};
  276. void()  bot_dodger11       =[      $rockatt1,       bot_dodger12        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  277. void()  bot_dodger12       =[      $rockatt2,       bot_dodger13        ] {bot_ai_face();bot_run_dodge();};
  278. void()  bot_dodger13       =[      $rockatt3,       bot_dodger14       ] {bot_ai_face();bot_run_dodge();};
  279. void()  bot_dodger14       =[      $rockatt4,       bot_dodger15        ] {bot_ai_face();bot_run_dodge();};
  280. void()  bot_dodger15        =[      $rockatt5,       bot_dodger16        ] {bot_ai_face();bot_run_dodge();};
  281. void()  bot_dodger16        =[      $rockatt6,       bot_dodger17        ] {bot_ai_face();bot_run_dodge();};
  282. void()  bot_dodger17        =[      $rockrun3  ,        bot_dodger18        ] {bot_ai_face();bot_run_dodge();};
  283. void()  bot_dodger18        =[      $rockrun4  ,        bot_dodger19        ] {bot_ai_face();bot_run_dodge();};
  284. void()  bot_dodger19        =[      $rockrun5  ,        bot_dodger20        ] {bot_ai_face();bot_run_dodge();};
  285. void()  bot_dodger20       =[      $rockrun6  ,        bot_run1        ] {bot_ai_face();bot_run_dodge();bot_end_dodge();};
  286.  
  287. void()  bot_circle1        =[      $shotatt1,       bot_circle2        ] {bot_ai_face();bot_start_circle();bot_run_circle();};
  288. void()  bot_circle2        =[      $shotatt2,       bot_circle3        ] {bot_ai_face();bot_attack();bot_run_circle();};
  289. void()  bot_circle3        =[      $shotatt3,       bot_circle4        ] {bot_ai_face();bot_run_circle();};
  290. void()  bot_circle4        =[      $shotatt4,       bot_circle5        ] {bot_ai_face();bot_run_circle();};
  291. void()  bot_circle5        =[      $shotatt5,       bot_circle6        ] {bot_ai_face();bot_run_circle();};
  292.  
  293. void()  bot_circle6        =[      $rockrun1  ,        bot_circle7        ]
  294. {bot_ai_face();
  295.     if (random() < 0.2)
  296.         sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
  297.         bot_run_circle();
  298. };
  299. void()  bot_circle7        =[      $rockrun2  ,        bot_circle8        ] {bot_ai_face();bot_run_circle();};
  300. void()  bot_circle8        =[      $rockrun3  ,        bot_circle9        ] {bot_ai_face();bot_run_circle();};
  301. void()  bot_circle9        =[      $rockrun4  ,        bot_circle10       ] {bot_ai_face();bot_run_circle();};
  302. void()  bot_circle10       =[      $rockrun5  ,        bot_circle11       ] {bot_ai_face();bot_run_circle();};
  303. void()  bot_circle11       =[      $shotatt1,       bot_circle12        ] {bot_ai_face();bot_run_circle();};
  304. void()  bot_circle12       =[      $shotatt2,       bot_circle13        ] {bot_ai_face();bot_attack();bot_run_circle();};
  305. void()  bot_circle13       =[      $shotatt3,       bot_circle14       ] {bot_ai_face();bot_run_circle();};
  306. void()  bot_circle14       =[      $shotatt4,       bot_circle15        ] {bot_ai_face();bot_run_circle();};
  307. void()  bot_circle15        =[      $shotatt5,       bot_circle16        ] {bot_ai_face();bot_run_circle();};
  308. void()  bot_circle16        =[      $shotatt6,       bot_circle17        ] {bot_ai_face();bot_run_circle();};
  309. void()  bot_circle17        =[      $rockrun3  ,        bot_circle18        ] {bot_ai_face();bot_run_circle();};
  310. void()  bot_circle18        =[      $rockrun4  ,        bot_circle19        ] {bot_ai_face();bot_run_circle();};
  311. void()  bot_circle19        =[      $rockrun5  ,        bot_circle20        ] {bot_ai_face();bot_run_circle();};
  312. void()  bot_circle20       =[      $rockrun6  ,        bot_circle1        ] {bot_ai_face();bot_run_circle();bot_end_circle();};
  313.  
  314.  
  315.  
  316. void()  bot_atk1        =[      $shotatt1,       bot_atk2        ] {bot_ai_face();};
  317. void()  bot_atk2        =[      $shotatt2,       bot_atk3        ] {bot_ai_face();bot_attack();};
  318. void()  bot_atk3        =[      $shotatt3,       bot_atk4        ] {bot_ai_face();};
  319. void()  bot_atk4        =[      $shotatt4,       bot_atk5        ] {bot_ai_face();};
  320. void()  bot_atk5        =[      $shotatt5,       bot_atk6        ] {bot_ai_face();};
  321. void()  bot_atk6        =[      $shotatt6,       bot_run1        ] {bot_ai_face();
  322.         bot_ai_face();
  323.     BotCheckRefire (bot_atk1);
  324. };
  325. void()  bot_atkn1        =[      $nailatt2,       bot_atkn2        ] {bot_ai_face();};
  326. void()  bot_atkn2        =[      $nailatt1,       bot_atkn3        ] {bot_ai_face();bot_attack();};
  327. void()  bot_atkn3        =[      $nailatt2,       bot_atkn4        ] {bot_ai_face();};
  328. void()  bot_atkn4        =[      $nailatt1,       bot_atkn5        ] {bot_ai_face();bot_attack();};
  329. void()  bot_atkn5        =[      $nailatt2,       bot_atkn6        ] {bot_ai_face();};
  330. void()  bot_atkn6        =[      $nailatt1,       bot_run1        ] {bot_ai_face();bot_attack();
  331.         bot_ai_face();
  332.         BotCheckRefire (bot_atkn1);
  333. };
  334. void()  bot_atksn1        =[      $nailatt2,       bot_atksn2        ] {bot_ai_face();};
  335. void()  bot_atksn2        =[      $nailatt1,       bot_atksn3        ] {bot_ai_face();bot_attack();};
  336. void()  bot_atksn3        =[      $nailatt1,       bot_atksn4        ] {bot_ai_face();bot_attack();};
  337. void()  bot_atksn4        =[      $nailatt2,       bot_atksn5        ] {bot_ai_face();};
  338. void()  bot_atksn5        =[      $nailatt1,       bot_atksn6        ] {bot_ai_face();bot_attack();};
  339. void()  bot_atksn6        =[      $nailatt1,       bot_run1        ] {bot_ai_face();bot_attack();
  340.         bot_ai_face();
  341.         BotCheckRefire (bot_atksn1);
  342. };
  343.  
  344. void()  bot_atkr1        =[      $rockatt1,       bot_atkr2        ] {bot_ai_face();bot_attack();};
  345. void()  bot_atkr2        =[      $rockatt2,       bot_atkr3        ] {bot_ai_face();};
  346. void()  bot_atkr3        =[      $rockatt3,       bot_atkr4        ] {bot_ai_face();};
  347. void()  bot_atkr4        =[      $rockatt4,       bot_atkr5        ] {bot_ai_face();};
  348. void()  bot_atkr5        =[      $rockatt5,       bot_atkr6        ] {bot_ai_face();};
  349. void()  bot_atkr6        =[      $rockatt6,       bot_run1        ] {bot_ai_face();
  350.         bot_ai_face();
  351.         BotCheckRefire (bot_atkr1);
  352. };
  353.  
  354. void()  bot_stuff1        =[      $rockrun1  ,        bot_stuff2        ]
  355. {
  356.     if (random() < 0.2)
  357.         sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
  358.         bot_ai_stuff(18);
  359. };
  360. void()  bot_stuff2        =[      $rockrun2  ,        bot_stuff3        ] {bot_ai_stuff(14);};
  361. void()  bot_stuff3        =[      $rockrun3  ,        bot_stuff4        ] {bot_ai_stuff(7);bot_upabit();};
  362. void()  bot_stuff4        =[      $rockrun4  ,        bot_stuff5        ] {bot_ai_stuff(12);};
  363. void()  bot_stuff5        =[      $rockrun5  ,        bot_stuff6        ] {bot_ai_stuff(14);};
  364. void()  bot_stuff6        =[      $rockrun6  ,        bot_walk1        ] {bot_ai_stuff(14);bot_upabit();};
  365.  
  366.  
  367. void()  bot_diea1    =       [       $deatha1,       bot_diea2    ] {};
  368. void()  bot_diea2    =       [       $deatha2,       bot_diea3    ] {};
  369. void()  bot_diea3    =       [       $deatha3,       bot_diea4    ]
  370. {
  371.     self.solid = SOLID_NOT;
  372.     DropBackpack();
  373. };
  374.  
  375. void()  bot_diea4    =       [       $deatha4,       bot_diea5    ] {};
  376. void()  bot_diea5    =       [       $deatha5,       bot_diea6    ] {};
  377. void()  bot_diea6    =       [       $deatha6,       bot_diea7    ] {};
  378. void()  bot_diea7    =       [       $deatha7,       bot_diea8    ] {};
  379. void()  bot_diea8    =       [       $deatha8,       bot_diea9    ] {};
  380. void()  bot_diea9    =       [       $deatha9,       bot_diea10   ] {};
  381. void()  bot_diea10   =       [       $deatha10,      bot_diea11   ] {};
  382. void()  bot_diea11   =       [       $deatha11,      bot_diea11 ] {BotSelfDeActivate();};
  383.  
  384. void()  bot_dieb1    =       [       $deathb1,       bot_dieb2    ] {};
  385. void()  bot_dieb2    =       [       $deathb2,       bot_dieb3    ] {};
  386. void()  bot_dieb3    =       [       $deathb3,       bot_dieb4    ] 
  387. {
  388.     self.solid = SOLID_NOT;
  389.     DropBackpack();
  390. };
  391.  
  392. void()  bot_dieb4    =       [       $deathb4,       bot_dieb5    ] {};
  393. void()  bot_dieb5    =       [       $deathb5,       bot_dieb6    ] {};
  394. void()  bot_dieb6    =       [       $deathb6,       bot_dieb7    ] {};
  395. void()  bot_dieb7    =       [       $deathb7,       bot_dieb8    ] {};
  396. void()  bot_dieb8    =       [       $deathb8,       bot_dieb9    ] {};
  397. void()  bot_dieb9    =       [       $deathb9,       bot_dieb9    ] {BotSelfDeActivate();};
  398.  
  399. void()  bot_diec1    =       [       $deathc1,       bot_diec2    ] {};
  400. void()  bot_diec2    =       [       $deathc2,       bot_diec3    ] {};
  401. void()  bot_diec3    =       [       $deathc3,       bot_diec4    ] 
  402. {
  403.     self.solid = SOLID_NOT;
  404.     DropBackpack();
  405. };
  406.  
  407. void()  bot_diec4    =       [       $deathc4,       bot_diec5    ] {};
  408. void()  bot_diec5    =       [       $deathc5,       bot_diec6    ] {};
  409. void()  bot_diec6    =       [       $deathc6,       bot_diec7    ] {};
  410. void()  bot_diec7    =       [       $deathc7,       bot_diec8    ] {};
  411. void()  bot_diec8    =       [       $deathc8,       bot_diec9    ] {};
  412. void()  bot_diec9    =       [       $deathc9,       bot_diec10   ] {};
  413. void()  bot_diec10   =       [       $deathc10,      bot_diec11   ] {};
  414. void()  bot_diec11   =       [       $deathc11,      bot_diec12   ] {};
  415. void()  bot_diec12   =       [       $deathc12,      bot_diec13   ] {};
  416. void()  bot_diec13   =       [       $deathc13,      bot_diec14   ] {};
  417. void()  bot_diec14   =       [       $deathc14,      bot_diec15   ] {};
  418. void()  bot_diec15   =       [       $deathc15,      bot_diec15 ] {BotSelfDeActivate();};
  419.  
  420. void()  bot_died1    =       [       $deathd1,       bot_died2    ] {};
  421. void()  bot_died2    =       [       $deathd2,       bot_died3    ] {};
  422. void()  bot_died3    =       [       $deathd3,       bot_died4    ] 
  423. {
  424.     self.solid = SOLID_NOT;
  425.     DropBackpack();
  426. };
  427.  
  428. void()  bot_died4    =       [       $deathd4,       bot_died5    ] {};
  429. void()  bot_died5    =       [       $deathd5,       bot_died6    ] {};
  430. void()  bot_died6    =       [       $deathd6,       bot_died7    ] {};
  431. void()  bot_died7    =       [       $deathd7,       bot_died8    ] {};
  432. void()  bot_died8    =       [       $deathd8,       bot_died9    ] {};
  433. void()  bot_died9    =       [       $deathd9,       bot_died9    ] {BotSelfDeActivate();};
  434.  
  435. void()  bot_diee1    =       [       $deathe1,       bot_diee2    ] {};
  436. void()  bot_diee2    =       [       $deathe2,       bot_diee3    ] {};
  437. void()  bot_diee3    =       [       $deathe3,       bot_diee4    ] 
  438. {
  439.     self.solid = SOLID_NOT;
  440.     DropBackpack();
  441. };
  442.  
  443. void()  bot_diee4    =       [       $deathe4,       bot_diee5    ] {};
  444. void()  bot_diee5    =       [       $deathe5,       bot_diee6    ] {};
  445. void()  bot_diee6    =       [       $deathe6,       bot_diee7    ] {};
  446. void()  bot_diee7    =       [       $deathe7,       bot_diee8    ] {};
  447. void()  bot_diee8    =       [       $deathe8,       bot_diee9    ] {};
  448. void()  bot_diee9    =       [       $deathe9,       bot_diee9    ] {BotSelfDeActivate();};
  449.  
  450.                                                         
  451. void()  bot_qatk1        =[      $shotatt1,       bot_qatk2        ] {bot_ai_face();bot_run_dodge();};
  452. void()  bot_qatk2        =[      $shotatt2,       bot_qatk3        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  453. void()  bot_qatk3        =[      $shotatt3,       bot_qatk4        ] {bot_ai_face();bot_run_dodge();};
  454. void()  bot_qatk4        =[      $shotatt4,       bot_qatk5        ] {bot_ai_face();bot_run_dodge();};
  455. void()  bot_qatk5        =[      $shotatt5,       bot_atk1        ] {bot_ai_face();bot_run_dodge();};
  456.  
  457. void()  bot_qatkn1        =[      $nailatt2,       bot_qatkn2        ] {bot_ai_face();bot_run_dodge();};
  458. void()  bot_qatkn2        =[      $nailatt1,       bot_qatkn3        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  459. void()  bot_qatkn3        =[      $nailatt2,       bot_qatkn4        ] {bot_ai_face();bot_run_dodge();};
  460. void()  bot_qatkn4        =[      $nailatt1,       bot_qatkn5        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  461. void()  bot_qatkn5        =[      $nailatt2,       bot_atkn1        ] {bot_ai_face();bot_run_dodge();};
  462.  
  463. void()  bot_qatksn1        =[      $nailatt2,       bot_qatksn2        ] {bot_ai_face();bot_run_dodge();};
  464. void()  bot_qatksn2        =[      $nailatt1,       bot_qatksn3        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  465. void()  bot_qatksn3        =[      $nailatt1,       bot_qatksn4        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  466. void()  bot_qatksn4        =[      $nailatt2,       bot_qatksn5        ] {bot_ai_face();bot_run_dodge();};
  467. void()  bot_qatksn5        =[      $nailatt1,       bot_atksn1        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  468.  
  469. void()  bot_qatkr1        =[      $rockatt1,       bot_qatkr2        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  470. void()  bot_qatkr2        =[      $rockatt2,       bot_qatkr3        ] {bot_ai_face();bot_run_dodge();};
  471. void()  bot_qatkr3        =[      $rockatt3,       bot_qatkr4        ] {bot_ai_face();bot_run_dodge();};
  472. void()  bot_qatkr4        =[      $rockatt4,       bot_qatkr5        ] {bot_ai_face();bot_run_dodge();};
  473. void()  bot_qatkr5        =[      $rockatt5,       bot_atkr1        ] {bot_ai_face();bot_run_dodge();};
  474.  
  475. void()  bot_dodgern1        =[      $rockrun1  ,        bot_dodgern2       ]
  476. {bot_ai_face();
  477.     if (random() < 0.2)
  478.         sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
  479.         bot_start_dodge();
  480.         bot_run_dodge();
  481. };
  482. void()  bot_dodgern2        =[      $rockrun2  ,        bot_dodgern3        ] {bot_ai_face();bot_run_dodge();};
  483. void()  bot_dodgern3        =[      $rockrun3  ,        bot_dodgern4        ] {bot_ai_face();bot_run_dodge();};
  484. void()  bot_dodgern4        =[      $rockrun4  ,        bot_dodgern5       ] {bot_ai_face();bot_run_dodge();};
  485. void()  bot_dodgern5       =[      $rockrun5  ,        bot_dodgern6       ] {bot_ai_face();bot_run_dodge();};
  486. void()  bot_dodgern6        =[      $rockrun6  ,        bot_run1        ] {bot_ai_face();bot_run_dodge();bot_end_dodge();};
  487.  
  488.  
  489. //=============================================================
  490. // BotFindTarget
  491. // Self is currently not attacking anything, so try to find a target
  492. // Sets self.enemy and returns TRUE if an enemy was sighted
  493. // Sets self.enemy to world and returns FALSE if no enemy sighted
  494. //=============================================================
  495. float() BotFindTarget =
  496. {
  497.     local entity head, selected;
  498.         local float dist;
  499.  
  500.     dist = 1500;    // awareness radius of bot, increasing it slows down game
  501.     selected = world;
  502.  
  503.     head = findradius(self.origin, 1500);
  504.     while(head)
  505.     {
  506.                 if(!(head.flags & FL_NOTARGET))// && (head.flags & FL_MONSTER))
  507.             if (visible(head))
  508.                 if (trace_plane_dist < dist)
  509.                                         if ((head.health > 0) && (head !=self))
  510.                     {
  511.                         selected = head;
  512.                         dist = trace_plane_dist;
  513.                     }
  514.         head = head.chain;
  515.     }
  516.  
  517.     self.enemy = selected;
  518.         
  519.     if (self.enemy == world)
  520.         return FALSE;
  521.     else
  522.     {
  523.         BotFoundTarget();
  524.         return TRUE;
  525.     }
  526. };
  527. //=============================================================
  528. // BotFinditem
  529. // Self is currently not attacking anything, so try to find an item
  530. // Sets self.movetarget and returns TRUE if an item was sighted
  531. // Sets self.movetarget to world and returns FALSE if no enemy sighted
  532. //=============================================================
  533. float() BotFindItem =
  534. {
  535.     local entity head, selected;
  536.         local float dist;
  537.  
  538.     dist = 1500;    // awareness radius of bot, increasing it slows down game
  539.     selected = world;
  540.  
  541.     head = findradius(self.origin, 1500);
  542.     while(head)
  543.     {
  544.                 if (head.flags == FL_ITEM)
  545.                         if (visible(head))
  546.                                 if (trace_plane_dist < dist)
  547.                                 {
  548.                                         selected = head;
  549.                                         dist = trace_plane_dist;
  550.                                 }
  551.         head = head.chain;
  552.     }
  553.         self.goalentity = selected;
  554.         self.movetarget = selected;
  555.         
  556.         if (self.movetarget == world)
  557.         return FALSE;
  558.     else
  559.     {
  560.                 BotFoundItem();
  561.         return TRUE;
  562.     }
  563. };
  564.  
  565. float() BotFindRocket =
  566. {
  567.     local entity head, selected;
  568.         local float dist;
  569.  
  570.     dist = 1500;    // awareness radius of bot, increasing it slows down game
  571.     selected = world;
  572.  
  573.     head = findradius(self.origin, 1500);
  574.     while(head)
  575.     {
  576.                 if((head.movetype == MOVETYPE_FLYMISSILE))// && (head.flags & FL_MONSTER))
  577.             if (visible(head))
  578.                                 if (infrontr(self,head))
  579.                                         if (trace_plane_dist < dist)
  580.                                                 if ((head !=self))                                                
  581.                                         
  582.                                                 {
  583.                                                         selected = head;
  584.                                                         dist = trace_plane_dist;
  585.                                                 }
  586.         head = head.chain;
  587.     }
  588.  
  589.         self.rcktdtct = selected;
  590.         
  591.         if (self.rcktdtct == world)
  592.         return FALSE;
  593.     else
  594.     {
  595.                 BotFoundRocket();
  596.         return TRUE;
  597.     }
  598. };
  599.  
  600.  
  601. //=============================================================
  602. // bot_ai_stand - bot stands in place until target acquired,
  603. // and starts to walk if pausetime has expired
  604. //=============================================================
  605. void() bot_ai_stand =
  606. {
  607. //        set_ai_think();
  608.     if (BotFindTarget ())
  609.         return;
  610.     
  611.         if ((BotFindStuff ()) && (visible(self.stuff)))
  612.                 return;
  613.  
  614.  
  615.     if (time > self.pausetime)
  616.     {
  617.         self.th_walk ();
  618.         return;
  619.     }
  620. };
  621.  
  622.  
  623. //=============================================================
  624. // bot_pain
  625. //=============================================================
  626. void(entity attacker, float damage)    bot_pain =
  627. {
  628.     local float r;
  629.     local entity oldself;
  630.  
  631.     r = random ();
  632.     if (self.pain_finished > time)
  633.         return;
  634.  
  635.         if (self.enemy != attacker)
  636.         {
  637.                 self.oldenemy = self.enemy;
  638.                 self.enemy = attacker;
  639.         }
  640.     if (r < 0.5)
  641.         sound (self, CHAN_VOICE, "enforcer/pain1.wav", 1, ATTN_NORM);
  642.     else
  643.         sound (self, CHAN_VOICE, "enforcer/pain2.wav", 1, ATTN_NORM);
  644.         if (range(self.enemy) >= RANGE_NEAR)
  645.                         self.th_dodge();
  646.         else if (range(self.enemy) == RANGE_MELEE) 
  647.                         self.th_qatk();
  648. };
  649.  
  650. //=============================================================
  651. // bot_die
  652. //=============================================================
  653. float() zrandom =
  654. {
  655.         return 2*(random());
  656. };
  657.  
  658. void() bot_die =
  659. {
  660.  
  661.     sound (self, CHAN_VOICE, "enforcer/death1.wav", 1, ATTN_NORM);
  662.  
  663.         if (zrandom() > 1.6)
  664.                 bot_diea1 ();
  665.         else if (zrandom() > 1.2)
  666.                 bot_dieb1 ();
  667.         else if (zrandom() > 0.8)
  668.                 bot_diec1 ();
  669.         else if (zrandom() > 0.4)
  670.                 bot_died1 ();
  671.         else bot_diee1 ();
  672.  
  673.  
  674.  
  675. // death frame sequence includes bot deactivation    
  676. };
  677.  
  678.  
  679. //=============================================================
  680. // BotSightSound
  681. //=============================================================
  682. void() BotSightSound =
  683. {
  684.     local float    rsnd;
  685.  
  686.     rsnd = rint(random() * 3);            
  687.     if (rsnd == 1)
  688.         sound (self, CHAN_VOICE, "enforcer/sight1.wav", 1, ATTN_NORM);
  689.     else if (rsnd == 2)
  690.         sound (self, CHAN_VOICE, "enforcer/sight2.wav", 1, ATTN_NORM);
  691.     else if (rsnd == 0)
  692.         sound (self, CHAN_VOICE, "enforcer/sight3.wav", 1, ATTN_NORM);
  693.     else
  694.         sound (self, CHAN_VOICE, "enforcer/sight4.wav", 1, ATTN_NORM);
  695. };
  696.  
  697.  
  698. //=============================================================
  699. // BotHuntTarget
  700. //=============================================================
  701. void() BotHuntTarget =
  702. {
  703.     self.goalentity = self.enemy;
  704. //        self.think = self.th_run;
  705.     self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
  706. //        self.nextthink = time + 0.1;
  707.     SUB_AttackFinished (0.5);    // wait a while before first attack
  708.         self.th_run();
  709. };
  710.  
  711.  
  712. //=============================================================
  713. // BotFoundTarget
  714. //=============================================================
  715. void() BotFoundTarget =
  716. {
  717.     local float f_dist;
  718.     local string s_dist;
  719.         local string frgs;
  720.     f_dist = vlen (self.enemy.origin - self.origin);
  721.     s_dist = ftos (f_dist);
  722.         frgs = ftos (self.frags);
  723.     self.show_hostile = time + 1;        // wake up other monsters
  724.     
  725. //sprints changed to sprint to enemy for purpose of debugging
  726.         sprint (self.enemy, "targetting: ");
  727.         sprint (self.enemy, self.enemy.classname);
  728.         sprint (self.enemy, "\n");
  729.         sprint (self.enemy, "Frags: ");
  730.         sprint (self.enemy, frgs);
  731.         sprint (self.enemy, "\n");
  732.     BotSightSound ();
  733.     BotHuntTarget ();
  734. };
  735. //=============================================================
  736. // BotFoundItem
  737. //=============================================================
  738. void() BotFoundItem =
  739. {
  740.     local float f_dist;
  741.     local string s_dist;
  742.         f_dist = vlen (self.movetarget.origin - self.origin);
  743.     s_dist = ftos (f_dist);
  744.         movetogoal(20);
  745. };
  746.  
  747. void() BotFoundRocket =
  748. {
  749.     local float f_dist;
  750.     local string s_dist;
  751.         f_dist = vlen (self.rcktdtct.origin - self.origin);
  752.     s_dist = ftos (f_dist);
  753.  
  754.     self.show_hostile = time + 1;        // wake up other monsters
  755.     
  756.         sprint (self.rcktdtct.owner, "evading: ");
  757.         sprint (self.rcktdtct.owner, self.rcktdtct.classname);
  758.         sprint (self.rcktdtct.owner, "\n");
  759.         sprint (self.rcktdtct.owner, "  distance: ");
  760.         sprint (self.rcktdtct.owner, s_dist);
  761.         sprint (self.rcktdtct.owner, "\n");
  762.     BotSightSound ();
  763.         bot_run_dodge ();
  764.  
  765.  
  766. };
  767.  
  768.  
  769. //=============================================================
  770. // bot_ai_walk - bot is walking, looking for enemies
  771. //=============================================================
  772. void(float dist) bot_ai_walk =
  773. {
  774. //        set_ai_think();
  775.     if (BotFindTarget ())
  776.         return;
  777.         if ((BotFindStuff ()) && (visible(self.stuff)))
  778.                 return;
  779.  
  780.         bot_upabit();
  781.     movetogoal (dist);
  782. };
  783.  
  784. void() bot_run_dodge =
  785. {
  786.     local float    ofs;
  787. //        set_ai_think();                 
  788.         if (self.enemy.attack_state == AS_MELEE)
  789.                 bot_run_mdodge();
  790. //        if (range(self.enemy) == RANGE_MELEE)
  791. //                bot_circle1();                
  792.  
  793.         movedist = 18;
  794.         bot_enemy_image();                        
  795.  
  796.         self.ideal_yaw = enemy_yaw;
  797.     ChangeYaw ();
  798.         if (self.lefty == 1)
  799.                 ofs = 45;
  800.         else 
  801.                 ofs = -45;
  802.     
  803.     if (walkmove (self.ideal_yaw + ofs, movedist))
  804.         return;
  805.         
  806.         self.lefty = 1 - self.lefty;         
  807.     walkmove (self.ideal_yaw - ofs, movedist);
  808.         bot_ai_face();
  809. };
  810.  
  811. void() bot_run_circle =
  812. {
  813.     local float    ofs;
  814.                  
  815. //        set_ai_think();
  816.  
  817.         movedist = 15;
  818.         self.ideal_yaw = enemy_yaw;
  819.     ChangeYaw ();
  820.         if (self.lefty == 1)
  821.                 ofs = 90;
  822.         else 
  823.                 ofs = -90;
  824.     
  825.     if (walkmove (self.ideal_yaw + ofs, movedist))
  826.         return;
  827.         
  828.         if (infrontr(self.enemy, self))
  829.                 self.lefty = 1 - self.lefty;
  830.     walkmove (self.ideal_yaw - ofs, movedist);
  831. };
  832.  
  833. void() bot_run_mdodge =
  834. {
  835.     local float    ofs;
  836.          
  837. //        set_ai_think();
  838.  
  839.         movedist = 20;
  840.         self.ideal_yaw = enemy_yaw;
  841.     ChangeYaw ();
  842.         if (self.lefty == 1)
  843.                 ofs = 135;
  844.         else 
  845.                 ofs = -135;
  846.     
  847.     if (walkmove (self.ideal_yaw + ofs, movedist))
  848.         return;
  849.         
  850.         self.lefty = 1 - self.lefty;         
  851.     walkmove (self.ideal_yaw - ofs, movedist);
  852. };
  853.  
  854. //=============================================================
  855. // bot_ai_turn - turn towards ideal_yaw if no enemy sighted
  856. //=============================================================
  857. void() bot_ai_turn =
  858. {
  859. //        set_ai_think();
  860.  
  861.     if (BotFindTarget ())
  862.         return;
  863.     
  864.         if ((BotFindStuff ()) && (visible(self.stuff)))
  865.                 return;
  866.  
  867.     
  868.     ChangeYaw ();
  869. };
  870.  
  871.  
  872. //=============================================================
  873. // bot_ai_run - still needs a little work
  874. //=============================================================
  875. void(float dist) bot_ai_run =
  876. {
  877.     local    vector    delta;
  878.     local    float    axis;
  879.     local    float    direct, ang_rint, ang_floor, ang_ceil;
  880.     
  881.     movedist = dist;
  882. //        set_ai_think();
  883.         bot_enemy_image();                        
  884.  
  885.  
  886.         if (BotFindRocket())
  887.         {
  888.                 if (check_dodge() == FALSE)
  889.                         bot_dodgern1();
  890.         }
  891.  
  892.  
  893.     if (self.enemy.health <= 0)
  894.     {
  895.         self.enemy = world;
  896.         if (self.oldenemy.health > 0)
  897.         {
  898.             self.enemy = self.oldenemy;
  899.                         bot_enemy_image();                        
  900.             BotHuntTarget ();
  901.         }
  902.         else
  903.         {
  904.                         bot_enemy_image();
  905.  
  906.             if (BotFindTarget())
  907.                         {
  908.                                 if ((visible(self.enemy)) == (FALSE))
  909.                                         movetogoal(dist);
  910.                                 else if ((visible(self.enemy)) == (TRUE))
  911. //                                        sprint (self.enemy, "tracing: ");
  912.                                         bot_enemy_image();
  913.                 
  914.                 return;
  915.                         }
  916.             else
  917.             {
  918.                                 self.movetarget = self.owner;
  919.                 self.th_walk ();
  920.                 return;
  921.             }
  922.         }
  923.     }
  924.  
  925.     self.show_hostile = time + 1;        // wake up other monsters
  926.         bot_enemy_image();
  927.     enemy_vis = visible(self.enemy);
  928.     if (enemy_vis)
  929.         self.search_time = time + 5;
  930.  
  931.     enemy_infront = infront(self.enemy);
  932.         enemy_range = range(self.enemy);
  933.     enemy_yaw = vectoyaw(self.enemy.origin - self.origin);
  934.         
  935.         if (BotFindRocket())
  936.         {
  937.                 if (check_dodge() == FALSE)
  938.                         bot_dodgern1();
  939.         }
  940.         if (random() <= 0.25)
  941.                 self.th_dodge();
  942.  
  943.         if (self.attack_state == AS_MISSILE)
  944.     {
  945.         ai_run_missile ();
  946.         return;
  947.     }
  948.     if (self.attack_state == AS_MELEE)
  949.     {
  950.         ai_run_melee ();
  951.         return;
  952.     }
  953.  
  954.     if (CheckAnyAttack ())
  955.         return;                    // beginning an attack
  956.         
  957.     if (self.attack_state == AS_SLIDING)
  958.     {
  959.         ai_run_slide ();
  960.         return;
  961.     }
  962.         bot_upabit(); 
  963.     movetogoal (dist);        // done in C code...
  964. };
  965.  
  966.  
  967. //=============================================================
  968. // BotCheckRefire
  969. //=============================================================
  970. void (void () thinkst) BotCheckRefire =
  971. {
  972.     if (!visible (self.enemy) || (self.enemy.health <= 0))
  973.         return;
  974.     self.think = thinkst;
  975. };
  976.  
  977.  
  978. //=============================================================
  979. // BotSelfDeActivate - Bot deactivates itself
  980. //=============================================================
  981. void () BotSelfDeActivate =
  982. {
  983.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  984.         WriteByte (MSG_BROADCAST, TE_TELEPORT);
  985.         WriteCoord (MSG_BROADCAST, self.origin_x);
  986.         WriteCoord (MSG_BROADCAST, self.origin_y);
  987.         WriteCoord (MSG_BROADCAST, self.origin_z);
  988.         sound (self, CHAN_BODY, "misc/r_tele1.wav", 1, ATTN_NORM);        
  989.         remove (self);
  990.         BotReStartDM(self.frags, self.attackr);
  991. };
  992.  
  993. //=============================================================
  994. // bot_fire
  995. //=============================================================
  996. void () bot_fire =
  997. {
  998. // in future, adjust frame sequence to not show firing if auto_fire off
  999.  
  1000.         if (BotFindRocket())
  1001.         {
  1002.                 if (check_dodge() == FALSE)                                
  1003.                         bot_dodgern1();
  1004.         }
  1005.  
  1006.     if (self.enemy.health <= 0)
  1007.     {
  1008.         self.enemy = world;
  1009.         if (self.oldenemy.health > 0)
  1010.         {
  1011.             self.enemy = self.oldenemy;
  1012.             BotHuntTarget ();
  1013.         }
  1014.         else
  1015.         {
  1016.             if (BotFindTarget())
  1017.                         {
  1018.                                 if ((visible(self.enemy)) == (FALSE))
  1019.                                         movetogoal(30);
  1020.                                 else if ((visible(self.enemy)) == (TRUE))
  1021. //                                        sprint (self.enemy, "tracing: ");
  1022.                                         bot_enemy_image();
  1023.                                 return;
  1024.                         }
  1025.                         else
  1026.             {
  1027.                 self.movetarget = self.owner;
  1028.                 self.th_walk ();
  1029.                 return;
  1030.             }
  1031.         }
  1032.     }
  1033.  
  1034.         bot_ai_face();
  1035.         if ((infront(self.enemy)) && (visible(self.enemy)))
  1036.     {
  1037.                 bot_enemy_image();
  1038.                 bot_firebullets();
  1039.                 sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
  1040.     }
  1041.         else if (!(visible(self.enemy)))
  1042.                 movetogoal(20);
  1043.                 
  1044.         return;
  1045. };
  1046. float(entity targ, entity targ2) infrontr =
  1047. {
  1048.     local vector    vec;
  1049.     local float        dot;
  1050.     
  1051.         makevectors (targ2.angles);
  1052.         vec = normalize (targ.origin - targ2.origin);
  1053.     dot = vec * v_forward;
  1054.     
  1055.     if ( dot > 0.3)
  1056.     {
  1057.         return TRUE;
  1058.     }
  1059.     return FALSE;
  1060. };
  1061. void() bot_ai_face =
  1062. {
  1063.         bot_enemy_image();
  1064.     self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
  1065.     ChangeYaw ();
  1066.  
  1067. };
  1068. // create ghost image of enemy to move to....
  1069.  
  1070. void () bot_enemy_image = 
  1071. {
  1072.                local    entity newbot;
  1073.  
  1074.                
  1075.                newbot=spawn();
  1076.  
  1077.                newbot.classname = "enemy";
  1078.                newbot.movetype= MOVETYPE_NONE;
  1079.                newbot.solid = SOLID_TRIGGER;
  1080.  
  1081.                setsize (newbot, '0 0 1', '0 0 1');        
  1082. //               setmodel (newbot, "progs/laser.mdl"); //for debugging
  1083.                setmodel (newbot, "progs/null.spr");
  1084.                newbot.origin = self.enemy.origin;
  1085.                newbot.owner=self;
  1086.                newbot.touch=bot_remove_enemy_image;
  1087.                newbot.nextthink=time+10;
  1088.                newbot.think=SUB_Remove;
  1089.                self.goalentity = newbot;
  1090.                self.movetarget = newbot;
  1091. };
  1092.  
  1093. void () bot_remove_enemy_image =
  1094.        {
  1095.         if (self.owner == other)
  1096.                 remove(self);
  1097.         };
  1098. void () bot_start_dodge =
  1099.         {
  1100.                 self.dodge = TRUE;
  1101.                 if ((random() * 1) >= 0.5)
  1102.                         self.lefty = 1;
  1103.                 else self.lefty = 0;
  1104.                     
  1105.         };
  1106. void () bot_end_dodge =
  1107.         {
  1108.                 self.dodge = FALSE;
  1109.         };
  1110. float() check_dodge =
  1111.         {
  1112.                 if (self.dodge == FALSE)
  1113.                        return FALSE;
  1114.                 else if (self.dodge == TRUE)
  1115.                         return TRUE;
  1116.         };
  1117. void () bot_start_circle =
  1118.         {
  1119.                 self.dodge = TRUE;
  1120.         };
  1121. void () bot_end_circle =
  1122.         {
  1123.                 self.dodge = FALSE;
  1124.         };
  1125. void() bot_firebullets =
  1126. {
  1127.     local    vector    dir;
  1128.     local    entity    en;
  1129.     
  1130.         bot_ai_face();
  1131.     
  1132. // fire somewhat behind the player, so a dodging player is harder to hit
  1133.     en = self.enemy;
  1134.     
  1135.     dir = en.origin - en.velocity*0.2;
  1136.     dir = normalize (dir - self.origin);
  1137.     
  1138.         FireBullets (6, dir, '0.1 0.1 0');
  1139. };
  1140.  
  1141. void() bot_FireShotgun =
  1142. {
  1143.     local vector dir;
  1144.     local    entity    en;
  1145.  
  1146.     self.currentammo = self.ammo_shells = self.ammo_shells - 1;
  1147.     en = self.enemy;
  1148.     dir = en.origin - en.velocity*0.2;
  1149.     dir = normalize (dir - self.origin);
  1150.  
  1151. //        dir = aim (self, 100000);
  1152.         FireBullets (6, dir, '0.1 0.1 0');
  1153. };
  1154.  
  1155. void() bot_FireSuperShotgun =
  1156. {
  1157.     local vector dir;
  1158.         local   entity  en;
  1159.         if (self.currentammo == 1)
  1160.     {
  1161.                 bot_FireShotgun ();
  1162.         return;
  1163.     }
  1164.     self.currentammo = self.ammo_shells = self.ammo_shells - 2;
  1165.     en = self.enemy;
  1166.     dir = en.origin - en.velocity*0.2;
  1167.     dir = normalize (dir - self.origin);
  1168.     FireBullets (14, dir, '0.14 0.08 0');
  1169. };
  1170.  
  1171. void() bot_FireRocket =
  1172. {
  1173.     local    entity missile, mpuff;
  1174.         local   vector  dir;
  1175.         local   entity  en;
  1176.         self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  1177.     
  1178.     missile = spawn ();
  1179.     missile.owner = self;
  1180.     missile.movetype = MOVETYPE_FLYMISSILE;
  1181.     missile.solid = SOLID_BBOX;
  1182.         makevectors (self.angles);
  1183.     en = self.enemy;
  1184.     dir = en.origin - en.velocity*0.2;
  1185.     dir = normalize (dir - self.origin);
  1186.         missile.velocity = dir;
  1187.     missile.velocity = missile.velocity * 1000;
  1188.     missile.angles = vectoangles(missile.velocity);
  1189.     missile.touch = T_MissileTouch;
  1190.     missile.nextthink = time + 5;
  1191.     missile.think = SUB_Remove;
  1192.     setmodel (missile, "progs/missile.mdl");
  1193.     setsize (missile, '0 0 0', '0 0 0');        
  1194.         setorigin (missile, self.origin + '0 0 16');
  1195. };
  1196.  
  1197. void () bot_nail =
  1198. {
  1199.     local vector org;
  1200.         local vector dir;
  1201.         local float ox;
  1202.         
  1203.         ox = 4;
  1204.  
  1205.     self.effects = self.effects | EF_MUZZLEFLASH;
  1206.     makevectors (self.angles);
  1207.     sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
  1208.     self.currentammo = self.ammo_nails = self.ammo_nails - 1;
  1209.         org = self.origin + v_forward * 30 + v_right*ox + '0 0 16';
  1210.         dir = self.enemy.origin - self.origin;
  1211.         dir = normalize(dir);
  1212.         launch_spike(org, dir);
  1213. };
  1214.  
  1215. void () bot_nail2 =
  1216. {
  1217.     local vector    dir;
  1218.         local vector    org;
  1219.     
  1220.         self.oldenemy = self.enemy;
  1221.         if (!visible (self.enemy) || (self.enemy.health <= 0))
  1222.         {
  1223.                 if (BotFindTarget ())
  1224.                         return;
  1225.     
  1226.                 ChangeYaw ();
  1227.                 self.enemy = self.oldenemy;
  1228.         }
  1229.  
  1230.     makevectors (self.angles);
  1231.     sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
  1232.     self.currentammo = self.ammo_nails = self.ammo_nails - 2;
  1233.         org = self.origin + '0 0 16';
  1234.         dir = self.enemy.origin - self.origin;
  1235.         dir = normalize(dir);
  1236.         launch_spike (org, dir);
  1237.     newmis.touch = superspike_touch;
  1238.     setmodel (newmis, "progs/s_spike.mdl");
  1239.     setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);        
  1240. };
  1241.  
  1242. void(vector offset) benforcer_fire =
  1243. {
  1244.     local vector org;
  1245.         local vector dir;
  1246.         local float ox;
  1247.         
  1248.         ox = 4;
  1249.  
  1250.     self.effects = self.effects | EF_MUZZLEFLASH;
  1251.     makevectors (self.angles);
  1252.     sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
  1253.     
  1254.         org = self.origin + v_forward * 30 + v_right*ox + '0 0 16';
  1255.         dir = self.enemy.origin - self.origin;
  1256.         dir = normalize(dir);
  1257.         launch_spike(org, dir);
  1258.         org = org + offset;
  1259.         launch_spike(org, dir);
  1260. };
  1261.  
  1262. void() bot_SetCurrentAmmo =
  1263. {
  1264.     self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) );
  1265.     
  1266.         if (self.weapon == IT_SHOTGUN)
  1267.     {
  1268.         self.currentammo = self.ammo_shells;
  1269.         self.items = self.items | IT_SHELLS;
  1270.                 self.th_stand = bot_stand1;
  1271.                 self.th_walk = bot_walk1;
  1272.                 self.th_run = bot_run1;
  1273.                 self.th_stuff = bot_stuff1;
  1274.                 self.th_dodge = bot_dodge1;
  1275.                 self.th_pain = bot_pain;
  1276.                 self.th_die = bot_die;
  1277.                 self.th_missile = bot_atk1;
  1278.                 self.th_qatk = bot_qatk1;
  1279.     }
  1280.     else if (self.weapon == IT_SUPER_SHOTGUN)
  1281.     {
  1282.         self.currentammo = self.ammo_shells;
  1283.         self.items = self.items | IT_SHELLS;
  1284.                 self.th_stand = bot_stand1;
  1285.                 self.th_walk = bot_walk1;
  1286.                 self.th_run = bot_run1;
  1287.                 self.th_stuff = bot_stuff1;
  1288.                 self.th_dodge = bot_dodge1;
  1289.                 self.th_pain = bot_pain;
  1290.                 self.th_die = bot_die;
  1291.                 self.th_missile = bot_atk1;
  1292.                 self.th_qatk = bot_qatk1;
  1293.  
  1294.     }
  1295.     else if (self.weapon == IT_NAILGUN)
  1296.     {
  1297.         self.currentammo = self.ammo_nails;
  1298.         self.items = self.items | IT_NAILS;
  1299.                 self.th_stand = bot_stand1;
  1300.                 self.th_walk = bot_walk1;
  1301.                 self.th_run = bot_run1;
  1302.                 self.th_stuff = bot_stuff1;
  1303.                 self.th_dodge = bot_dodgen1;
  1304.                 self.th_pain = bot_pain;
  1305.                 self.th_die = bot_die;
  1306.                 self.th_missile = bot_atkn1;
  1307.                 self.th_qatk = bot_qatkn1;
  1308.     }
  1309.     else if (self.weapon == IT_SUPER_NAILGUN)
  1310.     {
  1311.         self.currentammo = self.ammo_nails;
  1312.         self.items = self.items | IT_NAILS;
  1313.                 self.th_stand = bot_stand1;
  1314.                 self.th_walk = bot_walk1;
  1315.                 self.th_run = bot_run1;
  1316.                 self.th_stuff = bot_stuff1;
  1317.                 self.th_dodge = bot_dodgesn1;
  1318.                 self.th_pain = bot_pain;
  1319.                 self.th_die = bot_die;
  1320.                 self.th_missile = bot_atksn1;
  1321.                 self.th_qatk = bot_qatksn1;                
  1322.     }
  1323.         else if (self.weapon == IT_GRENADE_LAUNCHER)
  1324.         {
  1325.                 self.currentammo = self.ammo_rockets;
  1326.                 self.items = self.items | IT_ROCKETS;
  1327.                 self.th_stand = bot_stand1;
  1328.                 self.th_walk = bot_walk1;
  1329.                 self.th_run = bot_run1;
  1330.                 self.th_stuff = bot_stuff1;
  1331.                 self.th_dodge = bot_dodger1;
  1332.                 self.th_pain = bot_pain;
  1333.                 self.th_die = bot_die;
  1334.                 self.th_missile = bot_atkr1;
  1335.                 self.th_qatk = bot_qatkr1;
  1336.  
  1337.         }
  1338.     else if (self.weapon == IT_ROCKET_LAUNCHER)
  1339.     {
  1340.         self.currentammo = self.ammo_rockets;
  1341.         self.items = self.items | IT_ROCKETS;
  1342.                 self.th_stand = bot_stand1;
  1343.                 self.th_walk = bot_walk1;
  1344.                 self.th_run = bot_run1;
  1345.                 self.th_stuff = bot_stuff1;
  1346.                 self.th_dodge = bot_dodger1;
  1347.                 self.th_pain = bot_pain;
  1348.                 self.th_die = bot_die;
  1349.                 self.th_missile = bot_atkr1;
  1350.                 self.th_qatk = bot_qatkr1;
  1351.  
  1352.     }
  1353.     else
  1354.     {
  1355.         self.currentammo = 0;
  1356.         self.weaponmodel = "";
  1357.         self.weaponframe = 0;
  1358.     }
  1359. };
  1360. /*
  1361. ====================================================
  1362. bot_bestweapon - AI to choose which weapon is best
  1363. ====================================================
  1364. */
  1365. float () bot_bestweapon =
  1366. {
  1367.     local    float    it;
  1368.     
  1369.     it = self.items;
  1370.  
  1371.         if(self.ammo_rockets >= 1 && (it & IT_ROCKET_LAUNCHER) )
  1372.         return IT_ROCKET_LAUNCHER;
  1373.     else if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) )
  1374.         return IT_SUPER_NAILGUN;
  1375.     else if(self.ammo_shells >= 2 && (it & IT_SUPER_SHOTGUN) )
  1376.         return IT_SUPER_SHOTGUN;
  1377.     else if(self.ammo_nails >= 1 && (it & IT_NAILGUN) )
  1378.         return IT_NAILGUN;
  1379.         else if (self.ammo_rockets>= 1 && (it & IT_GRENADE_LAUNCHER) )
  1380.                 return IT_GRENADE_LAUNCHER;
  1381.         return IT_SHOTGUN;
  1382.  
  1383. };
  1384. /*
  1385. ===============================================
  1386. bot_CheckNoAmmo - checks to see if he has ammo 
  1387. ===============================================
  1388. */
  1389. float() bot_CheckNoAmmo =
  1390. {
  1391.     if (self.currentammo > 0)
  1392.         return TRUE;
  1393.  
  1394.         self.weapon = bot_bestweapon ();
  1395.  
  1396.         bot_SetCurrentAmmo ();
  1397.     
  1398.     return FALSE;
  1399. };
  1400. /*
  1401. ==========================
  1402. bot_attack - fires weapon
  1403. ==========================
  1404. */
  1405. void() bot_attack =
  1406. {
  1407.         bot_SetCurrentAmmo (); 
  1408.         if (BotFindRocket())
  1409.         {
  1410.                 if (check_dodge() == FALSE)                                
  1411.                         bot_dodgern1();
  1412.         }
  1413.  
  1414.     if (self.enemy.health <= 0)
  1415.     {
  1416.         self.enemy = world;
  1417.         if (self.oldenemy.health > 0)
  1418.         {
  1419.             self.enemy = self.oldenemy;
  1420.             BotHuntTarget ();
  1421.         }
  1422.         else
  1423.         {
  1424.             if (BotFindTarget())
  1425.                         {
  1426.                                 if (visible(self.enemy) == FALSE)
  1427.                                         movetogoal(30);
  1428.                                 else if (visible(self.enemy) == TRUE)
  1429. //                                        sprint (self.enemy, "tracing: ");
  1430.                                         bot_enemy_image();
  1431.                                 return;
  1432.                         }
  1433.                         else
  1434.             {
  1435.                 self.movetarget = self.owner;
  1436.                 self.th_walk ();
  1437.                 return;
  1438.             }
  1439.         }
  1440.     }
  1441.  
  1442.         bot_ai_face();
  1443.         if ((infront(self.enemy)) && (visible(self.enemy)))
  1444.     {
  1445.                 bot_enemy_image();
  1446.                 bot_shoot();
  1447.     }
  1448.         else if (!(visible(self.enemy)))
  1449.                 movetogoal(20);
  1450.                 
  1451.         return;
  1452. };                                                
  1453. void () bot_shoot =
  1454. {
  1455.     local    float    r;
  1456.  
  1457.         if (!visible (self.enemy) || (self.enemy.health <= 0))
  1458.                 return;
  1459.  
  1460.         if (!bot_CheckNoAmmo ())
  1461.         return;
  1462.  
  1463.         makevectors     (self.angles);     
  1464.     self.show_hostile = time + 1;    // wake monsters up
  1465.  
  1466.         if (self.weapon == IT_SHOTGUN)
  1467.     {                
  1468.                 bot_FireShotgun ();
  1469.                 bot_SetCurrentAmmo (); 
  1470.     }
  1471.     else if (self.weapon == IT_SUPER_SHOTGUN)
  1472.     {
  1473.                 bot_FireSuperShotgun ();
  1474.                 bot_SetCurrentAmmo (); 
  1475.     }
  1476.     else if (self.weapon == IT_NAILGUN)
  1477.     {
  1478.                 bot_nail ();
  1479.                 bot_SetCurrentAmmo (); 
  1480.     }
  1481.     else if (self.weapon == IT_SUPER_NAILGUN)
  1482.     {
  1483.                 bot_nail2 ();
  1484.                 bot_SetCurrentAmmo (); 
  1485.         }
  1486.         else if (self.weapon == IT_GRENADE_LAUNCHER)
  1487.         {
  1488.                 BOTFireGrenade();
  1489.                 bot_SetCurrentAmmo (); 
  1490.         }
  1491.     else if (self.weapon == IT_ROCKET_LAUNCHER)
  1492.     {
  1493.                 bot_FireRocket();
  1494.                 bot_SetCurrentAmmo (); 
  1495.  
  1496.         }
  1497. };
  1498. void() BOTGrenadeExplode =
  1499. {
  1500.         T_RadiusDamage (self, self.owner, 30, world);
  1501.     sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
  1502.  
  1503.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  1504.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  1505.     WriteCoord (MSG_BROADCAST, self.origin_x);
  1506.     WriteCoord (MSG_BROADCAST, self.origin_y);
  1507.     WriteCoord (MSG_BROADCAST, self.origin_z);
  1508.  
  1509.     self.velocity = '0 0 0';
  1510.     self.touch = SUB_Null;
  1511.     setmodel (self, "progs/s_explod.spr");
  1512.     self.solid = SOLID_NOT;
  1513.     s_explode1 ();
  1514. };
  1515.  
  1516. void() BOTGrenadeTouch =
  1517. {
  1518.     if (other == self.owner)
  1519.         return;        // don't explode on owner
  1520.         if (other.takedamage == DAMAGE_AIM) 
  1521.     {
  1522.                 BOTGrenadeExplode();
  1523.         return;
  1524.     }
  1525.     sound (self, CHAN_VOICE, "weapons/bounce.wav", 1, ATTN_NORM);    // bounce sound
  1526.     if (self.velocity == '0 0 0')
  1527.         self.avelocity = '0 0 0';
  1528. };
  1529.  
  1530.  
  1531. /*
  1532. ================
  1533. BOTFireGrenade
  1534. ================
  1535. */
  1536.  
  1537. void() BOTFireGrenade =
  1538. {
  1539.     local    entity missile, mpuff;
  1540.     local float zchange;
  1541.  
  1542.        // knock off a rocket
  1543.        self.ammo_rockets = self.ammo_rockets - 1;
  1544.     
  1545.     missile = spawn ();
  1546.     missile.owner = self;
  1547.     missile.movetype = MOVETYPE_BOUNCE;
  1548.     missile.solid = SOLID_BBOX;
  1549.         
  1550. // set missile speed    
  1551.  
  1552.     makevectors (self.angles);
  1553.  
  1554.     missile.velocity = normalize(self.enemy.origin - self.origin);
  1555.         missile.velocity = missile.velocity * 600;
  1556.     missile.velocity_z = 200;
  1557.     zchange = self.origin_z - self.enemy.origin_z;
  1558.     missile.velocity_z = missile.velocity_z - (zchange+10);
  1559.     missile.avelocity = '300 300 300';
  1560.  
  1561.     missile.angles = vectoangles(missile.velocity);
  1562.     
  1563.         missile.touch = BOTGrenadeTouch;
  1564.     
  1565. // set missile duration
  1566.     missile.nextthink = time + 2.5;
  1567.         missile.think = BOTGrenadeExplode;
  1568.  
  1569.         setmodel (missile, "progs/grenade.mdl");
  1570.     setsize (missile, '0 0 0', '0 0 0');        
  1571.     setorigin (missile, self.origin);
  1572. };
  1573.  
  1574. /*
  1575. ================
  1576. BotCheckPowerups
  1577.  
  1578. Check for turning off powerups
  1579. ================
  1580. */
  1581. void(entity oldself) BotCheckPowerups =
  1582. {
  1583. //        sprint(self.enemy, "I'm Thinking!!!");
  1584.  
  1585. // invisibility
  1586.         if (oldself.invisible_finished)
  1587.     {
  1588. // sound and screen flash when items starts to run out
  1589.  
  1590.  
  1591.                 if (oldself.invisible_finished < time)
  1592.         {    // just stopped
  1593.                         oldself.items = oldself.items - IT_INVISIBILITY;
  1594.                         oldself.invisible_finished = 0;
  1595.                         oldself.invisible_time = 0;
  1596.         }
  1597.         
  1598.     // use the eyes
  1599.                 oldself.frame = 0;
  1600.                 oldself.modelindex = modelindex_eyes;
  1601.     }
  1602.     else
  1603.                 oldself.modelindex = modelindex_bot;    // don't use eyes
  1604.  
  1605. // invincibility
  1606.         if (oldself.invincible_finished)
  1607.     {
  1608.                 if (oldself.invincible_finished < time)
  1609.         {    // just stopped
  1610.                         oldself.items = oldself.items - IT_INVULNERABILITY;
  1611.                         oldself.invincible_time = 0;
  1612.                         oldself.invincible_finished = 0;
  1613.         }
  1614.                 if (oldself.invincible_finished > time)
  1615.                         oldself.effects = oldself.effects & EF_DIMLIGHT;
  1616.         else
  1617.                         oldself.effects = oldself.effects - (oldself.effects & EF_DIMLIGHT);
  1618.     }
  1619.  
  1620. // super damage
  1621.         if (oldself.super_damage_finished)
  1622.     {
  1623.  
  1624.                 if (oldself.super_damage_finished < time)
  1625.         {    // just stopped
  1626.                         oldself.items = oldself.items - IT_QUAD;
  1627.                         oldself.super_damage_finished = 0;
  1628.                         oldself.super_time = 0;
  1629.                         oldself.effects = oldself.effects - (oldself.effects & EF_DIMLIGHT);
  1630.  
  1631.         }
  1632.                 if (oldself.super_damage_finished > time)
  1633.                         oldself.effects = oldself.effects & EF_DIMLIGHT;
  1634.         else
  1635.                         oldself.effects = oldself.effects - (oldself.effects & EF_DIMLIGHT);
  1636.     }    
  1637.  
  1638. // suit    
  1639.         if (oldself.radsuit_finished)
  1640.     {
  1641.                 oldself.air_finished = time + 12;          // don't drown
  1642.  
  1643.                 if (oldself.radsuit_finished < time)
  1644.         {    // just stopped
  1645.                         oldself.items = oldself.items - IT_SUIT;
  1646.                         oldself.rad_time = 0;
  1647.                         oldself.radsuit_finished = 0;
  1648.         }
  1649.     }    
  1650.  
  1651. };
  1652.  
  1653.  
  1654. void () bot_client =
  1655. {
  1656.                local    entity newbot;
  1657.  
  1658.                newbot=spawn();
  1659.                newbot.classname = "bot_controller";
  1660.                newbot.movetype= MOVETYPE_NONE;
  1661.                newbot.solid = SOLID_NOT;
  1662.  
  1663.                setsize (newbot, '0 0 0', '0 0 0');        
  1664.                setmodel (newbot, "progs/null.spr");
  1665.                newbot.origin = self.origin;
  1666.                newbot.owner=self;
  1667.                self.controller = newbot;
  1668.                newbot.nextthink=time+1;
  1669.                newbot.think=bot_think;
  1670.                 
  1671. };
  1672. void () bot_think =
  1673. {
  1674.         local entity oldself;
  1675.         oldself = self.owner;
  1676.  
  1677.         if (oldself.health <=0)
  1678.         {
  1679.                 remove(self);
  1680.         }
  1681.         else
  1682.         {
  1683.         Bot_PreThink(oldself);
  1684.         self.nextthink = time+1;
  1685.         }
  1686. };
  1687.  
  1688. void(entity oldself) Bot_PreThink =
  1689. {
  1690. //        sprint(oldself.enemy, "I'm Thinking!!!");
  1691.         BotCheckPowerups(oldself);
  1692. };
  1693. void(entity oldself) Bot_PostThink =
  1694. {
  1695.         BotCheckPowerups(oldself);
  1696. };
  1697.  
  1698. void () bot_thinkb =
  1699. {
  1700.  
  1701.         Bot_PreThinkb();
  1702.         self.nextthink = time+0.1;
  1703. };
  1704.  
  1705. void() Bot_PreThinkb =
  1706. {
  1707. //        sprint(self.enemy, "I'm Thinking!!!");
  1708.         BotCheckPowerupsb();
  1709. };
  1710. void() Bot_PostThinkb =
  1711. {
  1712.         BotCheckPowerupsb();
  1713. };
  1714.  
  1715.  
  1716. /*
  1717. ================
  1718. BotCheckPowerupsb
  1719.  
  1720. Check for turning off powerups
  1721. ================
  1722. */
  1723. void() BotCheckPowerupsb =
  1724. {
  1725.  
  1726. // invisibility
  1727.         if (self.invisible_finished)
  1728.     {
  1729. // sound and screen flash when items starts to run out
  1730.  
  1731.  
  1732.                 if (self.invisible_finished < time)
  1733.         {    // just stopped
  1734.                         self.items = self.items - IT_INVISIBILITY;
  1735.                         self.invisible_finished = 0;
  1736.                         self.invisible_time = 0;
  1737.         }
  1738.         
  1739.     // use the eyes
  1740.                 self.frame = 0;
  1741.                 self.modelindex = modelindex_eyes;
  1742.     }
  1743.     else
  1744.                 self.modelindex = modelindex_bot;    // don't use eyes
  1745.  
  1746. // invincibility
  1747.         if (self.invincible_finished)
  1748.     {
  1749.                 if (self.invincible_finished < time)
  1750.         {    // just stopped
  1751.                         self.items = self.items - IT_INVULNERABILITY;
  1752.                         self.invincible_time = 0;
  1753.                         self.invincible_finished = 0;
  1754.         }
  1755.                 if (self.invincible_finished > time)
  1756.                         self.effects = self.effects & EF_DIMLIGHT;
  1757.         else
  1758.                         self.effects = self.effects - (self.effects & EF_DIMLIGHT);
  1759.     }
  1760.  
  1761. // super damage
  1762.         if (self.super_damage_finished)
  1763.     {
  1764.  
  1765.                 if (self.super_damage_finished < time)
  1766.         {    // just stopped
  1767.                         self.items = self.items - IT_QUAD;
  1768.                         self.super_damage_finished = 0;
  1769.                         self.super_time = 0;
  1770.                         self.effects = self.effects - (self.effects & EF_DIMLIGHT);
  1771.  
  1772.         }
  1773.                 if (self.super_damage_finished > time)
  1774.                         self.effects = self.effects & EF_DIMLIGHT;
  1775.         else
  1776.                         self.effects = self.effects - (self.effects & EF_DIMLIGHT);
  1777.     }    
  1778.  
  1779. // suit    
  1780.         if (self.radsuit_finished)
  1781.     {
  1782.                 self.air_finished = time + 12;          // don't drown
  1783.  
  1784.                 if (self.radsuit_finished < time)
  1785.         {    // just stopped
  1786.                         self.items = self.items - IT_SUIT;
  1787.                         self.rad_time = 0;
  1788.                         self.radsuit_finished = 0;
  1789.         }
  1790.     }    
  1791.  
  1792. };
  1793. /*
  1794. void() set_ai_think =
  1795. {
  1796.         self.nextthink = time +0.1;
  1797.         self.think = bot_thinkb;
  1798.  
  1799. };
  1800. */
  1801. // BG Bot - begin hack to check for items
  1802. float() BotFindStuff =
  1803. {
  1804.         local entity head, selected;
  1805.     local float dist;
  1806.         dist = 200; 
  1807.     selected = world;
  1808.  
  1809.         head = findradius(self.origin, 200);
  1810.     while(head)
  1811.     {
  1812.                 if ((head.classname == "weapon_supernailgun") ||
  1813.                    (head.classname == "weapon_supershotgun") || 
  1814.                    (head.classname == "weapon_rocketlauncher") || 
  1815.                    (head.classname == "weapon_grenadelauncher") || 
  1816.                    (head.classname == "weapon_nailgun") ||
  1817.                    (head.classname == "backpack") ||
  1818.                    (head.classname == "shells") ||
  1819.                    (head.classname == "cells") ||
  1820.                    (head.classname == "nails") ||
  1821.                    (head.classname == "rockets") ||
  1822.                    (head.classname == "item_armor1") ||
  1823.                    (head.classname == "item_armor2") ||
  1824.                    (head.classname == "item_armorInv") ||
  1825.                    (head.classname == "item_artifact_invulnerability") ||
  1826.                    (head.classname == "item_artifact_invisibility") ||
  1827.                    (head.classname == "item_artifact_envirosuit") ||
  1828.                    (head.classname == "item_artifact_super_damage") ||
  1829.                    ((head.healtype == 1) && (self.health < 100)) ||
  1830.                    ((head.healtype == 2) && (self.health < 100))) 
  1831.  
  1832.                    {
  1833. //                        if (visible(head))
  1834. //                        {
  1835.                         selected = head;
  1836.                         dist = trace_plane_dist;
  1837. //                      }
  1838.                    }
  1839.         head = head.chain;
  1840.     }
  1841.         self.stuff = selected;
  1842.         
  1843.         if (self.stuff == world)
  1844.         return FALSE;
  1845.         else
  1846.         {
  1847.                 BotFoundStuff();
  1848.         return TRUE;
  1849.     }
  1850. };
  1851. //=============================================================
  1852. // BotHuntStuff - Look for items
  1853. //=============================================================
  1854. void() BotHuntStuff =
  1855. {
  1856.         self.goalentity = self.stuff;
  1857.         self.think = self.th_stuff;
  1858.  
  1859.         self.ideal_yaw = vectoyaw(self.stuff.origin - self.origin);
  1860.     self.nextthink = time + 0.1;
  1861. };
  1862.  
  1863. //=============================================================
  1864. // BotFoundStuff - Items
  1865. //=============================================================
  1866. void() BotFoundStuff =
  1867. {
  1868.         local float f_dist;
  1869.         local string s_dist;
  1870.         f_dist = vlen (self.stuff.origin - self.origin);
  1871.         s_dist = ftos (f_dist);
  1872.  
  1873.         BotHuntStuff ();
  1874. };
  1875.  
  1876. //=============================================================
  1877. // bot_ai_stuff - crappy hack
  1878. //=============================================================
  1879. void(float dist) bot_ai_stuff =
  1880. {
  1881.     local    vector    delta;
  1882.     local    float    axis;
  1883.     local    float    direct, ang_rint, ang_floor, ang_ceil;
  1884.     
  1885.     movedist = dist;
  1886.  
  1887.         enemy_vis = visible(self.stuff);
  1888.     if (enemy_vis)
  1889.         self.search_time = time + 5;
  1890.  
  1891.         enemy_infront = infront(self.stuff);
  1892.         enemy_range = range(self.stuff);
  1893.         enemy_yaw = vectoyaw(self.stuff.origin - self.origin);
  1894.     
  1895. //        if (CheckAnyAttack ())
  1896. //               return;                                 // beginning an attack
  1897.         
  1898.     movetogoal (dist);        // done in C code...
  1899. };
  1900.  
  1901. void() bot_upabit =
  1902. {
  1903.         self.velocity_z = (self.velocity_z + 35);
  1904. };
  1905.