home *** CD-ROM | disk | FTP | other *** search
/ Superpower (Alt) / SUPERPOWER.iso / q / patch / mbq073 / iwbot1.pat next >
Encoding:
Text File  |  1996-09-01  |  109.0 KB  |  3,304 lines

  1. diff -ur --new-file d:\quakestu\qcc\send\v101qc/bot.h backup4/bot.h
  2. --- d:\quakestu\qcc\send\v101qc/bot.h    Thu Jan  1 00:00:00 1970
  3. +++ backup4/bot.h    Thu Aug 29 06:11:58 1996
  4. @@ -0,0 +1,53 @@
  5. +/*
  6. +==============================================================================
  7. +
  8. +TM BOT HEADER FILE
  9. +
  10. +==============================================================================
  11. +*/
  12. +/*
  13. +// Global Constants
  14. +
  15. +float   BOT_TOGGLE                = 100;        // impulse constant
  16. +float    BOT_AUTO_TOGGLE            = 101;        // impulse constant
  17. +float    BOT_MOVE_FIRE            = 102;        // impulse constant
  18. +float     BOT_LEFT_FIRE_TOGGLE    = 103;        // impulse constant
  19. +float    BOT_RIGHT_TELEPORT        = 104;        // impulse constant
  20. +float    STAND                    = 0;        // move_flag constant
  21. +float    WALK                    = 1;        // move_flag constant
  22. +float    RUN                        = 2;        // move_flag constant
  23. +*/
  24. +// Bot Prototypes - called by player
  25. +
  26. +void () Bot_Precache;        // Precache information for the bot
  27. +//void () BotActivate;            // Activate bot
  28. +//void () BotDeActivate;          // DeActivate bot
  29. +//void () BotToggle;                      // Toggle bot on and off
  30. +//void () BotAutoToggle;          // Toggle automatic/manual control of bot
  31. +//void () BotMoveToggle;          // Toggle movement (walk, run, stand) in man mode
  32. +//void () BotTurnRight;           // Turn bot to the right by 22.5 degrees in man mode
  33. +//void () BotTurnLeft;            // Turn bot to the left by 22.5 degrees in man mode
  34. +//void () BotFireToggle;          // Toggle bot's auto-firing in auto mode
  35. +//void () BotFire;                        // Have bot fire at its current target in auto mode
  36. +//void () BotTeleportHome;        // Have bot teleport back to its owner
  37. +
  38. +// Botai Prototypes - called by bot (mostly modified versions of existing code)
  39. +
  40. +float    ()                                BotFindTarget;
  41. +void    ()                                BotFoundTarget;
  42. +void    ()                                BotSightSound;
  43. +void    ()                                BotHuntTarget;
  44. +void    ()                                bot_ai_stand;
  45. +void    (float dist)                    bot_ai_walk;
  46. +void    (float dist)                    bot_ai_run;
  47. +void    ()                                                              bot_die;
  48. +void    ()                                                              bot_ai_turn;
  49. +void    ()                                bot_fire;
  50. +void    (void () thinkst)                BotCheckRefire;        // Replaces SUB_CheckRefire
  51. +void    ()                                BotSelfDeActivate;
  52. +
  53. +// Bot_ext Prototypes - called by triggers.qc
  54. +
  55. +void    ()        bot_counter_use;
  56. +void    ()        bot_trigger_onlyregistered_touch;
  57. +
  58. diff -ur --new-file d:\quakestu\qcc\send\v101qc/bot.qc backup4/bot.qc
  59. --- d:\quakestu\qcc\send\v101qc/bot.qc    Thu Jan  1 00:00:00 1970
  60. +++ backup4/bot.qc    Sat Aug 31 23:32:40 1996
  61. @@ -0,0 +1,133 @@
  62. +/*
  63. +==============================================================================
  64. +
  65. +BOT
  66. +
  67. +==============================================================================
  68. +*/
  69. +
  70. +// Prototypes
  71. +entity ()       SelectSpawnPoint; // bens
  72. +
  73. +void    ()        Bot_Precache;
  74. +void (vector org) spawn_tfog;
  75. +
  76. +float   modelindex_eyes, modelindex_bot;
  77. +
  78. +//=============================================================
  79. +// Bot_Precache - called by Worldspawn
  80. +//=============================================================
  81. +void () Bot_Precache =
  82. +{
  83. +        precache_model ("progs/s_explod.spr");
  84. +        precache_model ("progs/player.mdl");
  85. +        precache_model ("progs/h_player.mdl");
  86. +    precache_model2 ("progs/laser.mdl");
  87. +        precache_model ("progs/null.spr");
  88. +    precache_sound2 ("enforcer/death1.wav");
  89. +    precache_sound2 ("enforcer/enfire.wav");
  90. +    precache_sound2 ("enforcer/enfstop.wav");
  91. +    precache_sound2 ("enforcer/idle1.wav");
  92. +    precache_sound2 ("enforcer/pain1.wav");
  93. +    precache_sound2 ("enforcer/pain2.wav");
  94. +    precache_sound2 ("enforcer/sight1.wav");
  95. +    precache_sound2 ("enforcer/sight2.wav");
  96. +    precache_sound2 ("enforcer/sight3.wav");
  97. +    precache_sound2 ("enforcer/sight4.wav");
  98. +};
  99. +
  100. +void () BotStartDM =
  101. +{
  102. +// sounds and models precached in the world.qc file
  103. +
  104. +    local entity    newbot;
  105. +        local entity    spot;
  106. +    newbot = spawn();
  107. +        newbot.solid = SOLID_SLIDEBOX;
  108. +        newbot.movetype = MOVETYPE_STEP;
  109. +        newbot.angles = self.angles;
  110. +        newbot.classname = "bot";
  111. +        newbot.netname = "BOT";
  112. +        newbot.owner=newbot;
  113. +        self.bot_flag = TRUE;
  114. +    newbot.health = 100;
  115. +        newbot.takedamage = DAMAGE_YES;
  116. +        newbot.goalentity = self;
  117. +        newbot.movetarget = self;
  118. +    newbot.pausetime = time + 2;
  119. +        newbot.weapon = 1;
  120. +        newbot.ammo_shells = 25;
  121. +    newbot.ideal_yaw = newbot.angles * '0 1 0';
  122. +    newbot.yaw_speed = 30;
  123. +    newbot.view_ofs = '0 0 25';
  124. +    newbot.th_stand = bot_stand1;
  125. +    newbot.th_walk = bot_walk1;
  126. +        newbot.th_stuff = bot_stuff1;
  127. +        newbot.th_dodge = bot_dodge1;
  128. +    newbot.th_run = bot_run1;
  129. +    newbot.th_pain = bot_pain;
  130. +    newbot.th_die = bot_die;
  131. +    newbot.th_missile = bot_atk1;
  132. +        setmodel (newbot, "progs/eyes.mdl");
  133. +    modelindex_eyes = self.modelindex;
  134. +        setmodel (newbot, "progs/player.mdl");
  135. +        modelindex_bot = self.modelindex;
  136. +    setsize (newbot, '-16 -16 -24', '16 16 40');
  137. +        spot = SelectSpawnPoint ();
  138. +        newbot.origin = spot.origin + '0 0 1';
  139. +        newbot.angles = spot.angles;
  140. +        newbot.fixangle = TRUE;             
  141. +        bot_client();
  142. +    spawn_tfog (newbot.origin);
  143. +    newbot.nextthink = time + 0.1;
  144. +    newbot.think = newbot.th_stand;
  145. +
  146. +};
  147. +void (float frgs,entity tmp) BotReStartDM =
  148. +{
  149. +// sounds and models precached in the world.qc file
  150. +
  151. +    local entity    newbot;
  152. +        local entity    spot;
  153. +    newbot = spawn();
  154. +        newbot.solid = SOLID_SLIDEBOX;
  155. +        newbot.movetype = MOVETYPE_STEP;
  156. +        newbot.angles = self.angles;
  157. +        newbot.classname = "bot";
  158. +        newbot.netname = "BOT";
  159. +        newbot.owner=newbot;
  160. +    newbot.health = 100;
  161. +        newbot.takedamage = DAMAGE_YES;
  162. +        newbot.goalentity = tmp;
  163. +        newbot.movetarget = tmp;
  164. +    newbot.pausetime = time + 2;
  165. +        newbot.weapon = 1;
  166. +        newbot.ammo_shells = 25;
  167. +
  168. +    newbot.ideal_yaw = newbot.angles * '0 1 0';
  169. +    newbot.yaw_speed = 30;
  170. +    newbot.view_ofs = '0 0 25';
  171. +        newbot.enemy = tmp;
  172. +        newbot.frags = frgs;
  173. +    newbot.th_stand = bot_stand1;
  174. +    newbot.th_walk = bot_walk1;
  175. +    newbot.th_run = bot_run1;
  176. +        newbot.th_stuff = bot_stuff1;
  177. +        newbot.th_dodge = bot_dodge1;
  178. +        newbot.th_pain = bot_pain;
  179. +    newbot.th_die = bot_die;
  180. +    newbot.th_missile = bot_atk1;
  181. +        setmodel (newbot, "progs/eyes.mdl");
  182. +    modelindex_eyes = self.modelindex;
  183. +        setmodel (newbot, "progs/player.mdl");
  184. +        modelindex_bot = self.modelindex;
  185. +    setsize (newbot, '-16 -16 -24', '16 16 40');
  186. +        spot = SelectSpawnPoint ();
  187. +        newbot.origin = spot.origin + '0 0 1';
  188. +        newbot.angles = spot.angles;
  189. +        newbot.fixangle = TRUE;             
  190. +        bot_client();
  191. +    spawn_tfog (newbot.origin);
  192. +    newbot.nextthink = time + 0.1;
  193. +        newbot.think = newbot.th_run;
  194. +};
  195. diff -ur --new-file d:\quakestu\qcc\send\v101qc/bot_ext.qc backup4/bot_ext.qc
  196. --- d:\quakestu\qcc\send\v101qc/bot_ext.qc    Thu Jan  1 00:00:00 1970
  197. +++ backup4/bot_ext.qc    Fri Aug 30 21:21:56 1996
  198. @@ -0,0 +1,50 @@
  199. +/*
  200. +==============================================================================
  201. +
  202. +BOT EXTENSIONS
  203. +
  204. +==============================================================================
  205. +*/
  206. +
  207. +// Prototypes
  208. +
  209. +void    ()        bot_counter_use;
  210. +void    ()        bot_trigger_onlyregistered_touch;
  211. +
  212. +
  213. +void() bot_counter_use =
  214. +{
  215. +    local string junk;
  216. +
  217. +    self.count = self.count - 1;
  218. +    if (self.count < 0)
  219. +        return;
  220. +    
  221. +    self.enemy = activator;
  222. +    multi_trigger ();
  223. +};
  224. +
  225. +
  226. +void() bot_trigger_onlyregistered_touch =
  227. +{
  228. +    if (self.attack_finished > time)
  229. +        return;
  230. +
  231. +    self.attack_finished = time + 2;
  232. +    if (cvar("registered"))
  233. +    {
  234. +        self.message = "";
  235. +        SUB_UseTargets ();
  236. +        remove (self);
  237. +    }
  238. +    else
  239. +    {
  240. +        if (self.message != "")
  241. +        {
  242. +            sprint (other.owner, "Incoming message from bot:\n");
  243. +            centerprint (other.owner, self.message);
  244. +            sound (other.owner, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
  245. +        }
  246. +    }
  247. +};
  248. +
  249. diff -ur --new-file d:\quakestu\qcc\send\v101qc/botai.qc backup4/botai.qc
  250. --- d:\quakestu\qcc\send\v101qc/botai.qc    Thu Jan  1 00:00:00 1970
  251. +++ backup4/botai.qc    Sun Sep  1 19:52:24 1996
  252. @@ -0,0 +1,1904 @@
  253. +
  254. +/*
  255. +==============================================================================
  256. +
  257. +BOT AI
  258. +
  259. +==============================================================================
  260. +*/
  261. +
  262. +// Prototypes
  263. +void(float shotcount, vector dir, vector spread) FireBullets;
  264. +void () bot_upabit;
  265. +float() check_dodge;
  266. +void () bot_start_dodge;
  267. +void () bot_run_mdodge;
  268. +void () bot_end_dodge;
  269. +void () bot_start_circle;
  270. +void () bot_end_circle;
  271. +void () bot_enemy_image;
  272. +void () bot_remove_enemy_image;
  273. +void () bot_ai_face;
  274. +float(entity targ, entity targ2) infrontr;
  275. +void() bot_firebullets;
  276. +void () BotFoundRocket;
  277. +void () BotStartDM;
  278. +void (float frgs,entity tmp) BotReStartDM;
  279. +void () bot_run_dodge;
  280. +float    ()                                BotFindTarget;
  281. +void () bot_run_circle;
  282. +void    ()                                bot_ai_stand;
  283. +void    ()                                bot_die;
  284. +void    ()                                BotSightSound;
  285. +void    ()                                BotFoundTarget;
  286. +void    ()                                BotHuntTarget;
  287. +void    (float dist)                    bot_ai_walk;
  288. +void    ()                                bot_ai_turn;
  289. +void    (float dist)                    bot_ai_run;
  290. +void    (void () thinkst)                BotCheckRefire;
  291. +void    ()                                BotSelfDeActivate;
  292. +void    ()                                              bot_attack;
  293. +void    ()                                              bot_shoot;
  294. +void    ()                                bot_fire;
  295. +void    ()                                              bot_nail;
  296. +void    ()                                              bot_nail2;
  297. +void    ()                                              enforcer_fire;
  298. +void    (vector offset)                                 benforcer_fire;
  299. +void    (vector org, vector dir)                        launch_spike;
  300. +void    ()                                              spike_touch;
  301. +void ()                                                 superspike_touch;
  302. +void (entity oldself) Bot_PostThink;
  303. +void (entity oldself) Bot_PreThink;
  304. +//void () bot_remove_controller;
  305. +void () bot_think;
  306. +void () Bot_PostThinkb;
  307. +void () Bot_PreThinkb;
  308. +void () bot_thinkb;
  309. +void() BotCheckPowerupsb;
  310. +float   modelindex_eyes, modelindex_bot;
  311. +void () BotFoundItem;
  312. +float () BotFindItem;
  313. +void () BOTFireGrenade;
  314. +void () BOTGrenadeTouch;
  315. +void () BOTGrenadeExplode;
  316. +void () s_explode1;
  317. +void    (float dist)                                    bot_ai_stuff;
  318. +void    ()                                              BotFoundStuff;
  319. +void    ()                                              BotHuntStuff;
  320. +float    ()                                              BotFindStuff;
  321. +
  322. +//void () set_ai_think;
  323. +$cd /raid/quake/id1/models/player_4
  324. +$origin 0 -6 24
  325. +$base base        
  326. +$skin skin
  327. +
  328. +//
  329. +// running
  330. +//
  331. +$frame axrun1 axrun2 axrun3 axrun4 axrun5 axrun6
  332. +
  333. +$frame rockrun1 rockrun2 rockrun3 rockrun4 rockrun5 rockrun6
  334. +
  335. +//
  336. +// standing
  337. +//
  338. +$frame stand1 stand2 stand3 stand4 stand5
  339. +
  340. +$frame axstnd1 axstnd2 axstnd3 axstnd4 axstnd5 axstnd6
  341. +$frame axstnd7 axstnd8 axstnd9 axstnd10 axstnd11 axstnd12
  342. +
  343. +
  344. +//
  345. +// pain
  346. +//
  347. +$frame axpain1 axpain2 axpain3 axpain4 axpain5 axpain6
  348. +
  349. +$frame pain1 pain2 pain3 pain4 pain5 pain6
  350. +
  351. +
  352. +//
  353. +// death
  354. +//
  355. +
  356. +$frame axdeth1 axdeth2 axdeth3 axdeth4 axdeth5 axdeth6
  357. +$frame axdeth7 axdeth8 axdeth9
  358. +
  359. +$frame deatha1 deatha2 deatha3 deatha4 deatha5 deatha6 deatha7 deatha8
  360. +$frame deatha9 deatha10 deatha11
  361. +
  362. +$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
  363. +$frame deathb9
  364. +
  365. +$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
  366. +$frame deathc9 deathc10 deathc11 deathc12 deathc13 deathc14 deathc15
  367. +
  368. +$frame deathd1 deathd2 deathd3 deathd4 deathd5 deathd6 deathd7
  369. +$frame deathd8 deathd9
  370. +
  371. +$frame deathe1 deathe2 deathe3 deathe4 deathe5 deathe6 deathe7
  372. +$frame deathe8 deathe9
  373. +
  374. +//
  375. +// attacks
  376. +//
  377. +$frame nailatt1 nailatt2
  378. +
  379. +$frame light1 light2
  380. +
  381. +$frame rockatt1 rockatt2 rockatt3 rockatt4 rockatt5 rockatt6
  382. +
  383. +$frame shotatt1 shotatt2 shotatt3 shotatt4 shotatt5 shotatt6
  384. +
  385. +$frame axatt1 axatt2 axatt3 axatt4 axatt5 axatt6
  386. +
  387. +$frame axattb1 axattb2 axattb3 axattb4 axattb5 axattb6
  388. +
  389. +$frame axattc1 axattc2 axattc3 axattc4 axattc5 axattc6
  390. +
  391. +$frame axattd1 axattd2 axattd3 axattd4 axattd5 axattd6
  392. +
  393. +
  394. +void()    bot_stand1    =[    $stand1,    bot_stand2    ] {bot_ai_stand();};
  395. +void()    bot_stand2    =[    $stand2,    bot_stand3    ] {bot_ai_stand();};
  396. +void()    bot_stand3    =[    $stand3,    bot_stand4    ] {bot_ai_stand();};
  397. +void()    bot_stand4    =[    $stand4,    bot_stand5    ] {bot_ai_stand();};
  398. +void()  bot_stand5      =[      $stand5,        bot_stand1      ] {bot_ai_stand();};
  399. +
  400. +void()  bot_walk1       =[      $rockrun1 ,        bot_walk2       ]
  401. +{
  402. +    if (random() < 0.2)
  403. +        sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
  404. +        bot_ai_walk(6);
  405. +};
  406. +void()  bot_walk2       =[      $rockrun1 ,        bot_walk3       ] {bot_ai_walk(10);};
  407. +void()  bot_walk3       =[      $rockrun2 ,        bot_walk4       ] {bot_ai_walk(10);};
  408. +void()  bot_walk4       =[      $rockrun2 ,        bot_walk5       ] {bot_ai_walk(8);};
  409. +void()  bot_walk5       =[      $rockrun3 ,        bot_walk6       ] {bot_ai_walk(4);};
  410. +void()  bot_walk6       =[      $rockrun3 ,        bot_walk7       ] {bot_ai_walk(6);bot_upabit();};
  411. +void()  bot_walk7       =[      $rockrun4 ,        bot_walk8       ] {bot_ai_walk(10);};
  412. +void()  bot_walk8       =[      $rockrun4 ,        bot_walk9       ] {bot_ai_walk(10);};
  413. +void()  bot_walk9       =[      $rockrun5 ,        bot_walk10       ] {bot_ai_walk(8);};
  414. +void()  bot_walk10       =[      $rockrun5 ,        bot_walk11       ] {bot_ai_walk(4);};
  415. +void()  bot_walk11       =[      $rockrun6 ,        bot_walk12       ] {bot_ai_walk(6);};
  416. +void()  bot_walk12       =[      $rockrun6 ,        bot_walk1       ] {bot_ai_walk(8);bot_upabit();};
  417. +
  418. +void()  bot_run1        =[      $rockrun1  ,        bot_run2        ]
  419. +{
  420. +    if (random() < 0.2)
  421. +        sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
  422. +        bot_ai_run(30);//18
  423. +};
  424. +void()  bot_run2        =[      $rockrun2  ,        bot_run3        ] {bot_ai_run(30);};//14
  425. +void()  bot_run3        =[      $rockrun3  ,        bot_run4        ] {bot_ai_run(30);bot_upabit();};//7
  426. +void()  bot_run4        =[      $rockrun4  ,        bot_run5        ] {bot_ai_run(30);};//12
  427. +void()  bot_run5        =[      $rockrun5  ,        bot_run6        ] {bot_ai_run(30);};//14
  428. +void()  bot_run6        =[      $rockrun6  ,        bot_run1        ] {bot_ai_run(30);bot_upabit();};//14
  429. +
  430. +void()  bot_dodge1        =[      $shotatt1,       bot_dodge2        ] {bot_ai_face();bot_start_dodge();bot_run_dodge();};
  431. +void()  bot_dodge2        =[      $shotatt2,       bot_dodge3        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  432. +void()  bot_dodge3        =[      $shotatt3,       bot_dodge4        ] {bot_ai_face();bot_run_dodge();};
  433. +void()  bot_dodge4        =[      $shotatt4,       bot_dodge5        ] {bot_ai_face();bot_run_dodge();};
  434. +void()  bot_dodge5        =[      $shotatt5,       bot_dodge6        ] {bot_ai_face();bot_run_dodge();};
  435. +
  436. +void()  bot_dodge6        =[      $rockrun1  ,        bot_dodge7        ]
  437. +{bot_ai_face();
  438. +    if (random() < 0.2)
  439. +        sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
  440. +        bot_run_dodge();
  441. +};
  442. +void()  bot_dodge7        =[      $rockrun2  ,        bot_dodge8        ] {bot_ai_face();bot_run_dodge();};
  443. +void()  bot_dodge8        =[      $rockrun3  ,        bot_dodge9        ] {bot_ai_face();bot_run_dodge();};
  444. +void()  bot_dodge9        =[      $rockrun4  ,        bot_dodge10       ] {bot_ai_face();bot_run_dodge();};
  445. +void()  bot_dodge10       =[      $rockrun5  ,        bot_dodge11       ] {bot_ai_face();bot_run_dodge();};
  446. +void()  bot_dodge11       =[      $shotatt1,       bot_dodge12        ] {bot_ai_face();bot_run_dodge();};
  447. +void()  bot_dodge12       =[      $shotatt2,       bot_dodge13        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  448. +void()  bot_dodge13       =[      $shotatt3,       bot_dodge14       ] {bot_ai_face();bot_run_dodge();};
  449. +void()  bot_dodge14       =[      $shotatt4,       bot_dodge15        ] {bot_ai_face();bot_run_dodge();};
  450. +void()  bot_dodge15        =[      $shotatt5,       bot_dodge16        ] {bot_ai_face();bot_run_dodge();};
  451. +void()  bot_dodge16        =[      $shotatt6,       bot_dodge17        ] {bot_ai_face();bot_run_dodge();};
  452. +void()  bot_dodge17        =[      $rockrun3  ,        bot_dodge18        ] {bot_ai_face();bot_run_dodge();};
  453. +void()  bot_dodge18        =[      $rockrun4  ,        bot_dodge19        ] {bot_ai_face();bot_run_dodge();};
  454. +void()  bot_dodge19        =[      $rockrun5  ,        bot_dodge20        ] {bot_ai_face();bot_run_dodge();};
  455. +void()  bot_dodge20       =[      $rockrun6  ,        bot_run1        ] {bot_ai_face();bot_run_dodge();bot_end_dodge();};
  456. +
  457. +void()  bot_dodgen1        =[      $nailatt2,       bot_dodgen2        ] {bot_ai_face();bot_start_dodge();bot_run_dodge();};
  458. +void()  bot_dodgen2        =[      $nailatt1,       bot_dodgen3        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  459. +void()  bot_dodgen3        =[      $nailatt2,       bot_dodgen4        ] {bot_ai_face();bot_run_dodge();};
  460. +void()  bot_dodgen4        =[      $nailatt1,       bot_dodgen5        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  461. +void()  bot_dodgen5        =[      $nailatt2,       bot_dodgen6        ] {bot_ai_face();bot_run_dodge();};
  462. +
  463. +void()  bot_dodgen6        =[      $rockrun1  ,        bot_dodgen7        ]
  464. +{bot_ai_face();
  465. +    if (random() < 0.2)
  466. +        sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
  467. +        bot_run_dodge();
  468. +};
  469. +void()  bot_dodgen7        =[      $rockrun2  ,        bot_dodgen8        ] {bot_ai_face();bot_run_dodge();};
  470. +void()  bot_dodgen8        =[      $rockrun3  ,        bot_dodgen9        ] {bot_ai_face();bot_run_dodge();};
  471. +void()  bot_dodgen9        =[      $rockrun4  ,        bot_dodgen10       ] {bot_ai_face();bot_run_dodge();};
  472. +void()  bot_dodgen10       =[      $rockrun5  ,        bot_dodgen11       ] {bot_ai_face();bot_run_dodge();};
  473. +void()  bot_dodgen11       =[      $nailatt2,       bot_dodgen12        ] {bot_ai_face();bot_run_dodge();};
  474. +void()  bot_dodgen12       =[      $nailatt1,       bot_dodgen13        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  475. +void()  bot_dodgen13       =[      $nailatt2,       bot_dodgen14       ] {bot_ai_face();bot_run_dodge();};
  476. +void()  bot_dodgen14       =[      $nailatt1,       bot_dodgen15        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  477. +void()  bot_dodgen15        =[      $nailatt2,       bot_dodgen16        ] {bot_ai_face();bot_run_dodge();};
  478. +void()  bot_dodgen16        =[      $nailatt1,       bot_dodgen17        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  479. +void()  bot_dodgen17        =[      $rockrun3  ,        bot_dodgen18        ] {bot_ai_face();bot_run_dodge();};
  480. +void()  bot_dodgen18        =[      $rockrun4  ,        bot_dodgen19        ] {bot_ai_face();bot_run_dodge();};
  481. +void()  bot_dodgen19        =[      $rockrun5  ,        bot_dodgen20        ] {bot_ai_face();bot_run_dodge();};
  482. +void()  bot_dodgen20       =[      $rockrun6  ,        bot_run1        ] {bot_ai_face();bot_run_dodge();bot_end_dodge();};
  483. +
  484. +void()  bot_dodgesn1        =[      $nailatt2,       bot_dodgesn2        ] {bot_ai_face();bot_start_dodge();bot_run_dodge();};
  485. +void()  bot_dodgesn2        =[      $nailatt1,       bot_dodgesn3        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  486. +void()  bot_dodgesn3        =[      $nailatt1,       bot_dodgesn4        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  487. +void()  bot_dodgesn4        =[      $nailatt2,       bot_dodgesn5        ] {bot_ai_face();bot_run_dodge();};
  488. +void()  bot_dodgesn5        =[      $nailatt1,       bot_dodgesn6        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  489. +
  490. +void()  bot_dodgesn6        =[      $rockrun1  ,        bot_dodgesn7        ]
  491. +{bot_ai_face();
  492. +    if (random() < 0.2)
  493. +        sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
  494. +        bot_run_dodge();
  495. +};
  496. +void()  bot_dodgesn7        =[      $rockrun2  ,        bot_dodgesn8        ] {bot_ai_face();bot_run_dodge();};
  497. +void()  bot_dodgesn8        =[      $rockrun3  ,        bot_dodgesn9        ] {bot_ai_face();bot_run_dodge();};
  498. +void()  bot_dodgesn9        =[      $rockrun4  ,        bot_dodgesn10       ] {bot_ai_face();bot_run_dodge();};
  499. +void()  bot_dodgesn10       =[      $rockrun5  ,        bot_dodgesn11       ] {bot_ai_face();bot_run_dodge();};
  500. +void()  bot_dodgesn11       =[      $nailatt2,       bot_dodgesn12        ] {bot_ai_face();bot_run_dodge();};
  501. +void()  bot_dodgesn12       =[      $nailatt1,       bot_dodgesn13        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  502. +void()  bot_dodgesn13       =[      $nailatt1,       bot_dodgesn14       ] {bot_ai_face();bot_attack();bot_run_dodge();};
  503. +void()  bot_dodgesn14       =[      $nailatt2,       bot_dodgesn15        ] {bot_ai_face();bot_run_dodge();};
  504. +void()  bot_dodgesn15        =[      $nailatt1,       bot_dodgesn16        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  505. +void()  bot_dodgesn16        =[      $nailatt1,       bot_dodgesn17        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  506. +void()  bot_dodgesn17        =[      $rockrun3  ,        bot_dodgesn18        ] {bot_ai_face();bot_run_dodge();};
  507. +void()  bot_dodgesn18        =[      $rockrun4  ,        bot_dodgesn19        ] {bot_ai_face();bot_run_dodge();};
  508. +void()  bot_dodgesn19        =[      $rockrun5  ,        bot_dodgesn20        ] {bot_ai_face();bot_run_dodge();};
  509. +void()  bot_dodgesn20       =[      $rockrun6  ,        bot_run1        ] {bot_ai_face();bot_run_dodge();bot_end_dodge();};
  510. +
  511. +void()  bot_dodger1        =[      $rockatt1,       bot_dodger2        ] {bot_ai_face();bot_start_dodge();bot_attack();bot_run_dodge();};
  512. +void()  bot_dodger2        =[      $rockatt2,       bot_dodger3        ] {bot_ai_face();bot_run_dodge();};
  513. +void()  bot_dodger3        =[      $rockatt3,       bot_dodger4        ] {bot_ai_face();bot_run_dodge();};
  514. +void()  bot_dodger4        =[      $rockatt4,       bot_dodger5        ] {bot_ai_face();bot_run_dodge();};
  515. +void()  bot_dodger5        =[      $rockatt5,       bot_dodger6        ] {bot_ai_face();bot_run_dodge();};
  516. +
  517. +void()  bot_dodger6        =[      $rockrun1  ,        bot_dodger7        ]
  518. +{bot_ai_face();
  519. +    if (random() < 0.2)
  520. +        sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
  521. +        bot_run_dodge();
  522. +};
  523. +void()  bot_dodger7        =[      $rockrun2  ,        bot_dodger8        ] {bot_ai_face();bot_run_dodge();};
  524. +void()  bot_dodger8        =[      $rockrun3  ,        bot_dodger9        ] {bot_ai_face();bot_run_dodge();};
  525. +void()  bot_dodger9        =[      $rockrun4  ,        bot_dodger10       ] {bot_ai_face();bot_run_dodge();};
  526. +void()  bot_dodger10       =[      $rockrun5  ,        bot_dodger11       ] {bot_ai_face();bot_run_dodge();};
  527. +void()  bot_dodger11       =[      $rockatt1,       bot_dodger12        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  528. +void()  bot_dodger12       =[      $rockatt2,       bot_dodger13        ] {bot_ai_face();bot_run_dodge();};
  529. +void()  bot_dodger13       =[      $rockatt3,       bot_dodger14       ] {bot_ai_face();bot_run_dodge();};
  530. +void()  bot_dodger14       =[      $rockatt4,       bot_dodger15        ] {bot_ai_face();bot_run_dodge();};
  531. +void()  bot_dodger15        =[      $rockatt5,       bot_dodger16        ] {bot_ai_face();bot_run_dodge();};
  532. +void()  bot_dodger16        =[      $rockatt6,       bot_dodger17        ] {bot_ai_face();bot_run_dodge();};
  533. +void()  bot_dodger17        =[      $rockrun3  ,        bot_dodger18        ] {bot_ai_face();bot_run_dodge();};
  534. +void()  bot_dodger18        =[      $rockrun4  ,        bot_dodger19        ] {bot_ai_face();bot_run_dodge();};
  535. +void()  bot_dodger19        =[      $rockrun5  ,        bot_dodger20        ] {bot_ai_face();bot_run_dodge();};
  536. +void()  bot_dodger20       =[      $rockrun6  ,        bot_run1        ] {bot_ai_face();bot_run_dodge();bot_end_dodge();};
  537. +
  538. +void()  bot_circle1        =[      $shotatt1,       bot_circle2        ] {bot_ai_face();bot_start_circle();bot_run_circle();};
  539. +void()  bot_circle2        =[      $shotatt2,       bot_circle3        ] {bot_ai_face();bot_attack();bot_run_circle();};
  540. +void()  bot_circle3        =[      $shotatt3,       bot_circle4        ] {bot_ai_face();bot_run_circle();};
  541. +void()  bot_circle4        =[      $shotatt4,       bot_circle5        ] {bot_ai_face();bot_run_circle();};
  542. +void()  bot_circle5        =[      $shotatt5,       bot_circle6        ] {bot_ai_face();bot_run_circle();};
  543. +
  544. +void()  bot_circle6        =[      $rockrun1  ,        bot_circle7        ]
  545. +{bot_ai_face();
  546. +    if (random() < 0.2)
  547. +        sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
  548. +        bot_run_circle();
  549. +};
  550. +void()  bot_circle7        =[      $rockrun2  ,        bot_circle8        ] {bot_ai_face();bot_run_circle();};
  551. +void()  bot_circle8        =[      $rockrun3  ,        bot_circle9        ] {bot_ai_face();bot_run_circle();};
  552. +void()  bot_circle9        =[      $rockrun4  ,        bot_circle10       ] {bot_ai_face();bot_run_circle();};
  553. +void()  bot_circle10       =[      $rockrun5  ,        bot_circle11       ] {bot_ai_face();bot_run_circle();};
  554. +void()  bot_circle11       =[      $shotatt1,       bot_circle12        ] {bot_ai_face();bot_run_circle();};
  555. +void()  bot_circle12       =[      $shotatt2,       bot_circle13        ] {bot_ai_face();bot_attack();bot_run_circle();};
  556. +void()  bot_circle13       =[      $shotatt3,       bot_circle14       ] {bot_ai_face();bot_run_circle();};
  557. +void()  bot_circle14       =[      $shotatt4,       bot_circle15        ] {bot_ai_face();bot_run_circle();};
  558. +void()  bot_circle15        =[      $shotatt5,       bot_circle16        ] {bot_ai_face();bot_run_circle();};
  559. +void()  bot_circle16        =[      $shotatt6,       bot_circle17        ] {bot_ai_face();bot_run_circle();};
  560. +void()  bot_circle17        =[      $rockrun3  ,        bot_circle18        ] {bot_ai_face();bot_run_circle();};
  561. +void()  bot_circle18        =[      $rockrun4  ,        bot_circle19        ] {bot_ai_face();bot_run_circle();};
  562. +void()  bot_circle19        =[      $rockrun5  ,        bot_circle20        ] {bot_ai_face();bot_run_circle();};
  563. +void()  bot_circle20       =[      $rockrun6  ,        bot_circle1        ] {bot_ai_face();bot_run_circle();bot_end_circle();};
  564. +
  565. +
  566. +
  567. +void()  bot_atk1        =[      $shotatt1,       bot_atk2        ] {bot_ai_face();};
  568. +void()  bot_atk2        =[      $shotatt2,       bot_atk3        ] {bot_ai_face();bot_attack();};
  569. +void()  bot_atk3        =[      $shotatt3,       bot_atk4        ] {bot_ai_face();};
  570. +void()  bot_atk4        =[      $shotatt4,       bot_atk5        ] {bot_ai_face();};
  571. +void()  bot_atk5        =[      $shotatt5,       bot_atk6        ] {bot_ai_face();};
  572. +void()  bot_atk6        =[      $shotatt6,       bot_run1        ] {bot_ai_face();
  573. +        bot_ai_face();
  574. +    BotCheckRefire (bot_atk1);
  575. +};
  576. +void()  bot_atkn1        =[      $nailatt2,       bot_atkn2        ] {bot_ai_face();};
  577. +void()  bot_atkn2        =[      $nailatt1,       bot_atkn3        ] {bot_ai_face();bot_attack();};
  578. +void()  bot_atkn3        =[      $nailatt2,       bot_atkn4        ] {bot_ai_face();};
  579. +void()  bot_atkn4        =[      $nailatt1,       bot_atkn5        ] {bot_ai_face();bot_attack();};
  580. +void()  bot_atkn5        =[      $nailatt2,       bot_atkn6        ] {bot_ai_face();};
  581. +void()  bot_atkn6        =[      $nailatt1,       bot_run1        ] {bot_ai_face();bot_attack();
  582. +        bot_ai_face();
  583. +        BotCheckRefire (bot_atkn1);
  584. +};
  585. +void()  bot_atksn1        =[      $nailatt2,       bot_atksn2        ] {bot_ai_face();};
  586. +void()  bot_atksn2        =[      $nailatt1,       bot_atksn3        ] {bot_ai_face();bot_attack();};
  587. +void()  bot_atksn3        =[      $nailatt1,       bot_atksn4        ] {bot_ai_face();bot_attack();};
  588. +void()  bot_atksn4        =[      $nailatt2,       bot_atksn5        ] {bot_ai_face();};
  589. +void()  bot_atksn5        =[      $nailatt1,       bot_atksn6        ] {bot_ai_face();bot_attack();};
  590. +void()  bot_atksn6        =[      $nailatt1,       bot_run1        ] {bot_ai_face();bot_attack();
  591. +        bot_ai_face();
  592. +        BotCheckRefire (bot_atksn1);
  593. +};
  594. +
  595. +void()  bot_atkr1        =[      $rockatt1,       bot_atkr2        ] {bot_ai_face();bot_attack();};
  596. +void()  bot_atkr2        =[      $rockatt2,       bot_atkr3        ] {bot_ai_face();};
  597. +void()  bot_atkr3        =[      $rockatt3,       bot_atkr4        ] {bot_ai_face();};
  598. +void()  bot_atkr4        =[      $rockatt4,       bot_atkr5        ] {bot_ai_face();};
  599. +void()  bot_atkr5        =[      $rockatt5,       bot_atkr6        ] {bot_ai_face();};
  600. +void()  bot_atkr6        =[      $rockatt6,       bot_run1        ] {bot_ai_face();
  601. +        bot_ai_face();
  602. +        BotCheckRefire (bot_atkr1);
  603. +};
  604. +
  605. +void()  bot_stuff1        =[      $rockrun1  ,        bot_stuff2        ]
  606. +{
  607. +    if (random() < 0.2)
  608. +        sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
  609. +        bot_ai_stuff(18);
  610. +};
  611. +void()  bot_stuff2        =[      $rockrun2  ,        bot_stuff3        ] {bot_ai_stuff(14);};
  612. +void()  bot_stuff3        =[      $rockrun3  ,        bot_stuff4        ] {bot_ai_stuff(7);bot_upabit();};
  613. +void()  bot_stuff4        =[      $rockrun4  ,        bot_stuff5        ] {bot_ai_stuff(12);};
  614. +void()  bot_stuff5        =[      $rockrun5  ,        bot_stuff6        ] {bot_ai_stuff(14);};
  615. +void()  bot_stuff6        =[      $rockrun6  ,        bot_walk1        ] {bot_ai_stuff(14);bot_upabit();};
  616. +
  617. +
  618. +void()  bot_diea1    =       [       $deatha1,       bot_diea2    ] {};
  619. +void()  bot_diea2    =       [       $deatha2,       bot_diea3    ] {};
  620. +void()  bot_diea3    =       [       $deatha3,       bot_diea4    ]
  621. +{
  622. +    self.solid = SOLID_NOT;
  623. +    DropBackpack();
  624. +};
  625. +
  626. +void()  bot_diea4    =       [       $deatha4,       bot_diea5    ] {};
  627. +void()  bot_diea5    =       [       $deatha5,       bot_diea6    ] {};
  628. +void()  bot_diea6    =       [       $deatha6,       bot_diea7    ] {};
  629. +void()  bot_diea7    =       [       $deatha7,       bot_diea8    ] {};
  630. +void()  bot_diea8    =       [       $deatha8,       bot_diea9    ] {};
  631. +void()  bot_diea9    =       [       $deatha9,       bot_diea10   ] {};
  632. +void()  bot_diea10   =       [       $deatha10,      bot_diea11   ] {};
  633. +void()  bot_diea11   =       [       $deatha11,      bot_diea11 ] {BotSelfDeActivate();};
  634. +
  635. +void()  bot_dieb1    =       [       $deathb1,       bot_dieb2    ] {};
  636. +void()  bot_dieb2    =       [       $deathb2,       bot_dieb3    ] {};
  637. +void()  bot_dieb3    =       [       $deathb3,       bot_dieb4    ] 
  638. +{
  639. +    self.solid = SOLID_NOT;
  640. +    DropBackpack();
  641. +};
  642. +
  643. +void()  bot_dieb4    =       [       $deathb4,       bot_dieb5    ] {};
  644. +void()  bot_dieb5    =       [       $deathb5,       bot_dieb6    ] {};
  645. +void()  bot_dieb6    =       [       $deathb6,       bot_dieb7    ] {};
  646. +void()  bot_dieb7    =       [       $deathb7,       bot_dieb8    ] {};
  647. +void()  bot_dieb8    =       [       $deathb8,       bot_dieb9    ] {};
  648. +void()  bot_dieb9    =       [       $deathb9,       bot_dieb9    ] {BotSelfDeActivate();};
  649. +
  650. +void()  bot_diec1    =       [       $deathc1,       bot_diec2    ] {};
  651. +void()  bot_diec2    =       [       $deathc2,       bot_diec3    ] {};
  652. +void()  bot_diec3    =       [       $deathc3,       bot_diec4    ] 
  653. +{
  654. +    self.solid = SOLID_NOT;
  655. +    DropBackpack();
  656. +};
  657. +
  658. +void()  bot_diec4    =       [       $deathc4,       bot_diec5    ] {};
  659. +void()  bot_diec5    =       [       $deathc5,       bot_diec6    ] {};
  660. +void()  bot_diec6    =       [       $deathc6,       bot_diec7    ] {};
  661. +void()  bot_diec7    =       [       $deathc7,       bot_diec8    ] {};
  662. +void()  bot_diec8    =       [       $deathc8,       bot_diec9    ] {};
  663. +void()  bot_diec9    =       [       $deathc9,       bot_diec10   ] {};
  664. +void()  bot_diec10   =       [       $deathc10,      bot_diec11   ] {};
  665. +void()  bot_diec11   =       [       $deathc11,      bot_diec12   ] {};
  666. +void()  bot_diec12   =       [       $deathc12,      bot_diec13   ] {};
  667. +void()  bot_diec13   =       [       $deathc13,      bot_diec14   ] {};
  668. +void()  bot_diec14   =       [       $deathc14,      bot_diec15   ] {};
  669. +void()  bot_diec15   =       [       $deathc15,      bot_diec15 ] {BotSelfDeActivate();};
  670. +
  671. +void()  bot_died1    =       [       $deathd1,       bot_died2    ] {};
  672. +void()  bot_died2    =       [       $deathd2,       bot_died3    ] {};
  673. +void()  bot_died3    =       [       $deathd3,       bot_died4    ] 
  674. +{
  675. +    self.solid = SOLID_NOT;
  676. +    DropBackpack();
  677. +};
  678. +
  679. +void()  bot_died4    =       [       $deathd4,       bot_died5    ] {};
  680. +void()  bot_died5    =       [       $deathd5,       bot_died6    ] {};
  681. +void()  bot_died6    =       [       $deathd6,       bot_died7    ] {};
  682. +void()  bot_died7    =       [       $deathd7,       bot_died8    ] {};
  683. +void()  bot_died8    =       [       $deathd8,       bot_died9    ] {};
  684. +void()  bot_died9    =       [       $deathd9,       bot_died9    ] {BotSelfDeActivate();};
  685. +
  686. +void()  bot_diee1    =       [       $deathe1,       bot_diee2    ] {};
  687. +void()  bot_diee2    =       [       $deathe2,       bot_diee3    ] {};
  688. +void()  bot_diee3    =       [       $deathe3,       bot_diee4    ] 
  689. +{
  690. +    self.solid = SOLID_NOT;
  691. +    DropBackpack();
  692. +};
  693. +
  694. +void()  bot_diee4    =       [       $deathe4,       bot_diee5    ] {};
  695. +void()  bot_diee5    =       [       $deathe5,       bot_diee6    ] {};
  696. +void()  bot_diee6    =       [       $deathe6,       bot_diee7    ] {};
  697. +void()  bot_diee7    =       [       $deathe7,       bot_diee8    ] {};
  698. +void()  bot_diee8    =       [       $deathe8,       bot_diee9    ] {};
  699. +void()  bot_diee9    =       [       $deathe9,       bot_diee9    ] {BotSelfDeActivate();};
  700. +
  701. +                                                        
  702. +void()  bot_qatk1        =[      $shotatt1,       bot_qatk2        ] {bot_ai_face();bot_run_dodge();};
  703. +void()  bot_qatk2        =[      $shotatt2,       bot_qatk3        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  704. +void()  bot_qatk3        =[      $shotatt3,       bot_qatk4        ] {bot_ai_face();bot_run_dodge();};
  705. +void()  bot_qatk4        =[      $shotatt4,       bot_qatk5        ] {bot_ai_face();bot_run_dodge();};
  706. +void()  bot_qatk5        =[      $shotatt5,       bot_atk1        ] {bot_ai_face();bot_run_dodge();};
  707. +
  708. +void()  bot_qatkn1        =[      $nailatt2,       bot_qatkn2        ] {bot_ai_face();bot_run_dodge();};
  709. +void()  bot_qatkn2        =[      $nailatt1,       bot_qatkn3        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  710. +void()  bot_qatkn3        =[      $nailatt2,       bot_qatkn4        ] {bot_ai_face();bot_run_dodge();};
  711. +void()  bot_qatkn4        =[      $nailatt1,       bot_qatkn5        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  712. +void()  bot_qatkn5        =[      $nailatt2,       bot_atkn1        ] {bot_ai_face();bot_run_dodge();};
  713. +
  714. +void()  bot_qatksn1        =[      $nailatt2,       bot_qatksn2        ] {bot_ai_face();bot_run_dodge();};
  715. +void()  bot_qatksn2        =[      $nailatt1,       bot_qatksn3        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  716. +void()  bot_qatksn3        =[      $nailatt1,       bot_qatksn4        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  717. +void()  bot_qatksn4        =[      $nailatt2,       bot_qatksn5        ] {bot_ai_face();bot_run_dodge();};
  718. +void()  bot_qatksn5        =[      $nailatt1,       bot_atksn1        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  719. +
  720. +void()  bot_qatkr1        =[      $rockatt1,       bot_qatkr2        ] {bot_ai_face();bot_attack();bot_run_dodge();};
  721. +void()  bot_qatkr2        =[      $rockatt2,       bot_qatkr3        ] {bot_ai_face();bot_run_dodge();};
  722. +void()  bot_qatkr3        =[      $rockatt3,       bot_qatkr4        ] {bot_ai_face();bot_run_dodge();};
  723. +void()  bot_qatkr4        =[      $rockatt4,       bot_qatkr5        ] {bot_ai_face();bot_run_dodge();};
  724. +void()  bot_qatkr5        =[      $rockatt5,       bot_atkr1        ] {bot_ai_face();bot_run_dodge();};
  725. +
  726. +void()  bot_dodgern1        =[      $rockrun1  ,        bot_dodgern2       ]
  727. +{bot_ai_face();
  728. +    if (random() < 0.2)
  729. +        sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
  730. +        bot_start_dodge();
  731. +        bot_run_dodge();
  732. +};
  733. +void()  bot_dodgern2        =[      $rockrun2  ,        bot_dodgern3        ] {bot_ai_face();bot_run_dodge();};
  734. +void()  bot_dodgern3        =[      $rockrun3  ,        bot_dodgern4        ] {bot_ai_face();bot_run_dodge();};
  735. +void()  bot_dodgern4        =[      $rockrun4  ,        bot_dodgern5       ] {bot_ai_face();bot_run_dodge();};
  736. +void()  bot_dodgern5       =[      $rockrun5  ,        bot_dodgern6       ] {bot_ai_face();bot_run_dodge();};
  737. +void()  bot_dodgern6        =[      $rockrun6  ,        bot_run1        ] {bot_ai_face();bot_run_dodge();bot_end_dodge();};
  738. +
  739. +
  740. +//=============================================================
  741. +// BotFindTarget
  742. +// Self is currently not attacking anything, so try to find a target
  743. +// Sets self.enemy and returns TRUE if an enemy was sighted
  744. +// Sets self.enemy to world and returns FALSE if no enemy sighted
  745. +//=============================================================
  746. +float() BotFindTarget =
  747. +{
  748. +    local entity head, selected;
  749. +        local float dist;
  750. +
  751. +    dist = 1500;    // awareness radius of bot, increasing it slows down game
  752. +    selected = world;
  753. +
  754. +    head = findradius(self.origin, 1500);
  755. +    while(head)
  756. +    {
  757. +                if(!(head.flags & FL_NOTARGET))// && (head.flags & FL_MONSTER))
  758. +            if (visible(head))
  759. +                if (trace_plane_dist < dist)
  760. +                                        if ((head.health > 0) && (head !=self))
  761. +                    {
  762. +                        selected = head;
  763. +                        dist = trace_plane_dist;
  764. +                    }
  765. +        head = head.chain;
  766. +    }
  767. +
  768. +    self.enemy = selected;
  769. +        
  770. +    if (self.enemy == world)
  771. +        return FALSE;
  772. +    else
  773. +    {
  774. +        BotFoundTarget();
  775. +        return TRUE;
  776. +    }
  777. +};
  778. +//=============================================================
  779. +// BotFinditem
  780. +// Self is currently not attacking anything, so try to find an item
  781. +// Sets self.movetarget and returns TRUE if an item was sighted
  782. +// Sets self.movetarget to world and returns FALSE if no enemy sighted
  783. +//=============================================================
  784. +float() BotFindItem =
  785. +{
  786. +    local entity head, selected;
  787. +        local float dist;
  788. +
  789. +    dist = 1500;    // awareness radius of bot, increasing it slows down game
  790. +    selected = world;
  791. +
  792. +    head = findradius(self.origin, 1500);
  793. +    while(head)
  794. +    {
  795. +                if (head.flags == FL_ITEM)
  796. +                        if (visible(head))
  797. +                                if (trace_plane_dist < dist)
  798. +                                {
  799. +                                        selected = head;
  800. +                                        dist = trace_plane_dist;
  801. +                                }
  802. +        head = head.chain;
  803. +    }
  804. +        self.goalentity = selected;
  805. +        self.movetarget = selected;
  806. +        
  807. +        if (self.movetarget == world)
  808. +        return FALSE;
  809. +    else
  810. +    {
  811. +                BotFoundItem();
  812. +        return TRUE;
  813. +    }
  814. +};
  815. +
  816. +float() BotFindRocket =
  817. +{
  818. +    local entity head, selected;
  819. +        local float dist;
  820. +
  821. +    dist = 1500;    // awareness radius of bot, increasing it slows down game
  822. +    selected = world;
  823. +
  824. +    head = findradius(self.origin, 1500);
  825. +    while(head)
  826. +    {
  827. +                if((head.movetype == MOVETYPE_FLYMISSILE))// && (head.flags & FL_MONSTER))
  828. +            if (visible(head))
  829. +                                if (infrontr(self,head))
  830. +                                        if (trace_plane_dist < dist)
  831. +                                                if ((head !=self))                                                
  832. +                                        
  833. +                                                {
  834. +                                                        selected = head;
  835. +                                                        dist = trace_plane_dist;
  836. +                                                }
  837. +        head = head.chain;
  838. +    }
  839. +
  840. +        self.rcktdtct = selected;
  841. +        
  842. +        if (self.rcktdtct == world)
  843. +        return FALSE;
  844. +    else
  845. +    {
  846. +                BotFoundRocket();
  847. +        return TRUE;
  848. +    }
  849. +};
  850. +
  851. +
  852. +//=============================================================
  853. +// bot_ai_stand - bot stands in place until target acquired,
  854. +// and starts to walk if pausetime has expired
  855. +//=============================================================
  856. +void() bot_ai_stand =
  857. +{
  858. +//        set_ai_think();
  859. +    if (BotFindTarget ())
  860. +        return;
  861. +    
  862. +        if ((BotFindStuff ()) && (visible(self.stuff)))
  863. +                return;
  864. +
  865. +
  866. +    if (time > self.pausetime)
  867. +    {
  868. +        self.th_walk ();
  869. +        return;
  870. +    }
  871. +};
  872. +
  873. +
  874. +//=============================================================
  875. +// bot_pain
  876. +//=============================================================
  877. +void(entity attacker, float damage)    bot_pain =
  878. +{
  879. +    local float r;
  880. +    local entity oldself;
  881. +
  882. +    r = random ();
  883. +    if (self.pain_finished > time)
  884. +        return;
  885. +
  886. +        if (self.enemy != attacker)
  887. +        {
  888. +                self.oldenemy = self.enemy;
  889. +                self.enemy = attacker;
  890. +        }
  891. +    if (r < 0.5)
  892. +        sound (self, CHAN_VOICE, "enforcer/pain1.wav", 1, ATTN_NORM);
  893. +    else
  894. +        sound (self, CHAN_VOICE, "enforcer/pain2.wav", 1, ATTN_NORM);
  895. +        if (range(self.enemy) >= RANGE_NEAR)
  896. +                        self.th_dodge();
  897. +        else if (range(self.enemy) == RANGE_MELEE) 
  898. +                        self.th_qatk();
  899. +};
  900. +
  901. +//=============================================================
  902. +// bot_die
  903. +//=============================================================
  904. +float() zrandom =
  905. +{
  906. +        return 2*(random());
  907. +};
  908. +
  909. +void() bot_die =
  910. +{
  911. +    sound (self, CHAN_VOICE, "enforcer/death1.wav", 1, ATTN_NORM);
  912. +
  913. +        if (zrandom() > 1.6)
  914. +                bot_diea1 ();
  915. +        else if (zrandom() > 1.2)
  916. +                bot_dieb1 ();
  917. +        else if (zrandom() > 0.8)
  918. +                bot_diec1 ();
  919. +        else if (zrandom() > 0.4)
  920. +                bot_died1 ();
  921. +        else bot_diee1 ();
  922. +
  923. +
  924. +
  925. +// death frame sequence includes bot deactivation    
  926. +};
  927. +
  928. +
  929. +//=============================================================
  930. +// BotSightSound
  931. +//=============================================================
  932. +void() BotSightSound =
  933. +{
  934. +    local float    rsnd;
  935. +
  936. +    rsnd = rint(random() * 3);            
  937. +    if (rsnd == 1)
  938. +        sound (self, CHAN_VOICE, "enforcer/sight1.wav", 1, ATTN_NORM);
  939. +    else if (rsnd == 2)
  940. +        sound (self, CHAN_VOICE, "enforcer/sight2.wav", 1, ATTN_NORM);
  941. +    else if (rsnd == 0)
  942. +        sound (self, CHAN_VOICE, "enforcer/sight3.wav", 1, ATTN_NORM);
  943. +    else
  944. +        sound (self, CHAN_VOICE, "enforcer/sight4.wav", 1, ATTN_NORM);
  945. +};
  946. +
  947. +
  948. +//=============================================================
  949. +// BotHuntTarget
  950. +//=============================================================
  951. +void() BotHuntTarget =
  952. +{
  953. +    self.goalentity = self.enemy;
  954. +//        self.think = self.th_run;
  955. +    self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
  956. +//        self.nextthink = time + 0.1;
  957. +    SUB_AttackFinished (0.5);    // wait a while before first attack
  958. +        self.th_run();
  959. +};
  960. +
  961. +
  962. +//=============================================================
  963. +// BotFoundTarget
  964. +//=============================================================
  965. +void() BotFoundTarget =
  966. +{
  967. +    local float f_dist;
  968. +    local string s_dist;
  969. +        local string frgs;
  970. +    f_dist = vlen (self.enemy.origin - self.origin);
  971. +    s_dist = ftos (f_dist);
  972. +        frgs = ftos (self.frags);
  973. +    self.show_hostile = time + 1;        // wake up other monsters
  974. +    
  975. +//sprints changed to sprint to enemy for purpose of debugging
  976. +        sprint (self.enemy, "targetting: ");
  977. +        sprint (self.enemy, self.enemy.classname);
  978. +        sprint (self.enemy, "\n");
  979. +        sprint (self.enemy, "Frags: ");
  980. +        sprint (self.enemy, frgs);
  981. +        sprint (self.enemy, "\n");
  982. +    BotSightSound ();
  983. +    BotHuntTarget ();
  984. +};
  985. +//=============================================================
  986. +// BotFoundItem
  987. +//=============================================================
  988. +void() BotFoundItem =
  989. +{
  990. +    local float f_dist;
  991. +    local string s_dist;
  992. +        f_dist = vlen (self.movetarget.origin - self.origin);
  993. +    s_dist = ftos (f_dist);
  994. +        movetogoal(20);
  995. +};
  996. +
  997. +void() BotFoundRocket =
  998. +{
  999. +    local float f_dist;
  1000. +    local string s_dist;
  1001. +        f_dist = vlen (self.rcktdtct.origin - self.origin);
  1002. +    s_dist = ftos (f_dist);
  1003. +
  1004. +    self.show_hostile = time + 1;        // wake up other monsters
  1005. +    
  1006. +        sprint (self.rcktdtct.owner, "evading: ");
  1007. +        sprint (self.rcktdtct.owner, self.rcktdtct.classname);
  1008. +        sprint (self.rcktdtct.owner, "\n");
  1009. +        sprint (self.rcktdtct.owner, "  distance: ");
  1010. +        sprint (self.rcktdtct.owner, s_dist);
  1011. +        sprint (self.rcktdtct.owner, "\n");
  1012. +    BotSightSound ();
  1013. +        bot_run_dodge ();
  1014. +
  1015. +
  1016. +};
  1017. +
  1018. +
  1019. +//=============================================================
  1020. +// bot_ai_walk - bot is walking, looking for enemies
  1021. +//=============================================================
  1022. +void(float dist) bot_ai_walk =
  1023. +{
  1024. +//        set_ai_think();
  1025. +    if (BotFindTarget ())
  1026. +        return;
  1027. +        if ((BotFindStuff ()) && (visible(self.stuff)))
  1028. +                return;
  1029. +
  1030. +        bot_upabit();
  1031. +    movetogoal (dist);
  1032. +};
  1033. +
  1034. +void() bot_run_dodge =
  1035. +{
  1036. +    local float    ofs;
  1037. +//        set_ai_think();                 
  1038. +        if (self.enemy.attack_state == AS_MELEE)
  1039. +                bot_run_mdodge();
  1040. +//        if (range(self.enemy) == RANGE_MELEE)
  1041. +//                bot_circle1();                
  1042. +
  1043. +        movedist = 18;
  1044. +        bot_enemy_image();                        
  1045. +
  1046. +        self.ideal_yaw = enemy_yaw;
  1047. +    ChangeYaw ();
  1048. +        if (self.lefty == 1)
  1049. +                ofs = 45;
  1050. +        else 
  1051. +                ofs = -45;
  1052. +    
  1053. +    if (walkmove (self.ideal_yaw + ofs, movedist))
  1054. +        return;
  1055. +        
  1056. +        self.lefty = 1 - self.lefty;         
  1057. +    walkmove (self.ideal_yaw - ofs, movedist);
  1058. +        bot_ai_face();
  1059. +};
  1060. +
  1061. +void() bot_run_circle =
  1062. +{
  1063. +    local float    ofs;
  1064. +                 
  1065. +//        set_ai_think();
  1066. +
  1067. +        movedist = 15;
  1068. +        self.ideal_yaw = enemy_yaw;
  1069. +    ChangeYaw ();
  1070. +        if (self.lefty == 1)
  1071. +                ofs = 90;
  1072. +        else 
  1073. +                ofs = -90;
  1074. +    
  1075. +    if (walkmove (self.ideal_yaw + ofs, movedist))
  1076. +        return;
  1077. +        
  1078. +        if (infrontr(self.enemy, self))
  1079. +                self.lefty = 1 - self.lefty;
  1080. +    walkmove (self.ideal_yaw - ofs, movedist);
  1081. +};
  1082. +
  1083. +void() bot_run_mdodge =
  1084. +{
  1085. +    local float    ofs;
  1086. +         
  1087. +//        set_ai_think();
  1088. +
  1089. +        movedist = 20;
  1090. +        self.ideal_yaw = enemy_yaw;
  1091. +    ChangeYaw ();
  1092. +        if (self.lefty == 1)
  1093. +                ofs = 135;
  1094. +        else 
  1095. +                ofs = -135;
  1096. +    
  1097. +    if (walkmove (self.ideal_yaw + ofs, movedist))
  1098. +        return;
  1099. +        
  1100. +        self.lefty = 1 - self.lefty;         
  1101. +    walkmove (self.ideal_yaw - ofs, movedist);
  1102. +};
  1103. +
  1104. +//=============================================================
  1105. +// bot_ai_turn - turn towards ideal_yaw if no enemy sighted
  1106. +//=============================================================
  1107. +void() bot_ai_turn =
  1108. +{
  1109. +//        set_ai_think();
  1110. +
  1111. +    if (BotFindTarget ())
  1112. +        return;
  1113. +    
  1114. +        if ((BotFindStuff ()) && (visible(self.stuff)))
  1115. +                return;
  1116. +
  1117. +    
  1118. +    ChangeYaw ();
  1119. +};
  1120. +
  1121. +
  1122. +//=============================================================
  1123. +// bot_ai_run - still needs a little work
  1124. +//=============================================================
  1125. +void(float dist) bot_ai_run =
  1126. +{
  1127. +    local    vector    delta;
  1128. +    local    float    axis;
  1129. +    local    float    direct, ang_rint, ang_floor, ang_ceil;
  1130. +    
  1131. +    movedist = dist;
  1132. +//        set_ai_think();
  1133. +        bot_enemy_image();                        
  1134. +
  1135. +
  1136. +        if (BotFindRocket())
  1137. +        {
  1138. +                if (check_dodge() == FALSE)
  1139. +                        bot_dodgern1();
  1140. +        }
  1141. +
  1142. +
  1143. +    if (self.enemy.health <= 0)
  1144. +    {
  1145. +        self.enemy = world;
  1146. +        if (self.oldenemy.health > 0)
  1147. +        {
  1148. +            self.enemy = self.oldenemy;
  1149. +                        bot_enemy_image();                        
  1150. +            BotHuntTarget ();
  1151. +        }
  1152. +        else
  1153. +        {
  1154. +                        bot_enemy_image();
  1155. +
  1156. +            if (BotFindTarget())
  1157. +                        {
  1158. +                                if ((visible(self.enemy)) == (FALSE))
  1159. +                                        movetogoal(dist);
  1160. +                                else if ((visible(self.enemy)) == (TRUE))
  1161. +//                                        sprint (self.enemy, "tracing: ");
  1162. +                                        bot_enemy_image();
  1163. +                
  1164. +                return;
  1165. +                        }
  1166. +            else
  1167. +            {
  1168. +                                self.movetarget = self.owner;
  1169. +                self.th_walk ();
  1170. +                return;
  1171. +            }
  1172. +        }
  1173. +    }
  1174. +
  1175. +    self.show_hostile = time + 1;        // wake up other monsters
  1176. +        bot_enemy_image();
  1177. +    enemy_vis = visible(self.enemy);
  1178. +    if (enemy_vis)
  1179. +        self.search_time = time + 5;
  1180. +
  1181. +    enemy_infront = infront(self.enemy);
  1182. +        enemy_range = range(self.enemy);
  1183. +    enemy_yaw = vectoyaw(self.enemy.origin - self.origin);
  1184. +        
  1185. +        if (BotFindRocket())
  1186. +        {
  1187. +                if (check_dodge() == FALSE)
  1188. +                        bot_dodgern1();
  1189. +        }
  1190. +        if (random() <= 0.25)
  1191. +                self.th_dodge();
  1192. +
  1193. +        if (self.attack_state == AS_MISSILE)
  1194. +    {
  1195. +        ai_run_missile ();
  1196. +        return;
  1197. +    }
  1198. +    if (self.attack_state == AS_MELEE)
  1199. +    {
  1200. +        ai_run_melee ();
  1201. +        return;
  1202. +    }
  1203. +
  1204. +    if (CheckAnyAttack ())
  1205. +        return;                    // beginning an attack
  1206. +        
  1207. +    if (self.attack_state == AS_SLIDING)
  1208. +    {
  1209. +        ai_run_slide ();
  1210. +        return;
  1211. +    }
  1212. +        bot_upabit(); 
  1213. +    movetogoal (dist);        // done in C code...
  1214. +};
  1215. +
  1216. +
  1217. +//=============================================================
  1218. +// BotCheckRefire
  1219. +//=============================================================
  1220. +void (void () thinkst) BotCheckRefire =
  1221. +{
  1222. +    if (!visible (self.enemy) || (self.enemy.health <= 0))
  1223. +        return;
  1224. +    self.think = thinkst;
  1225. +};
  1226. +
  1227. +
  1228. +//=============================================================
  1229. +// BotSelfDeActivate - Bot deactivates itself
  1230. +//=============================================================
  1231. +void () BotSelfDeActivate =
  1232. +{
  1233. +        WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  1234. +        WriteByte (MSG_BROADCAST, TE_TELEPORT);
  1235. +        WriteCoord (MSG_BROADCAST, self.origin_x);
  1236. +        WriteCoord (MSG_BROADCAST, self.origin_y);
  1237. +        WriteCoord (MSG_BROADCAST, self.origin_z);
  1238. +        sound (self, CHAN_BODY, "misc/r_tele1.wav", 1, ATTN_NORM);        
  1239. +        remove (self);
  1240. +        BotReStartDM(self.frags, self.attackr);
  1241. +};
  1242. +
  1243. +//=============================================================
  1244. +// bot_fire
  1245. +//=============================================================
  1246. +void () bot_fire =
  1247. +{
  1248. +// in future, adjust frame sequence to not show firing if auto_fire off
  1249. +
  1250. +        if (BotFindRocket())
  1251. +        {
  1252. +                if (check_dodge() == FALSE)                                
  1253. +                        bot_dodgern1();
  1254. +        }
  1255. +
  1256. +    if (self.enemy.health <= 0)
  1257. +    {
  1258. +        self.enemy = world;
  1259. +        if (self.oldenemy.health > 0)
  1260. +        {
  1261. +            self.enemy = self.oldenemy;
  1262. +            BotHuntTarget ();
  1263. +        }
  1264. +        else
  1265. +        {
  1266. +            if (BotFindTarget())
  1267. +                        {
  1268. +                                if ((visible(self.enemy)) == (FALSE))
  1269. +                                        movetogoal(30);
  1270. +                                else if ((visible(self.enemy)) == (TRUE))
  1271. +//                                        sprint (self.enemy, "tracing: ");
  1272. +                                        bot_enemy_image();
  1273. +                                return;
  1274. +                        }
  1275. +                        else
  1276. +            {
  1277. +                self.movetarget = self.owner;
  1278. +                self.th_walk ();
  1279. +                return;
  1280. +            }
  1281. +        }
  1282. +    }
  1283. +
  1284. +        bot_ai_face();
  1285. +        if ((infront(self.enemy)) && (visible(self.enemy)))
  1286. +    {
  1287. +                bot_enemy_image();
  1288. +                bot_firebullets();
  1289. +                sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
  1290. +    }
  1291. +        else if (!(visible(self.enemy)))
  1292. +                movetogoal(20);
  1293. +                
  1294. +        return;
  1295. +};
  1296. +float(entity targ, entity targ2) infrontr =
  1297. +{
  1298. +    local vector    vec;
  1299. +    local float        dot;
  1300. +    
  1301. +        makevectors (targ2.angles);
  1302. +        vec = normalize (targ.origin - targ2.origin);
  1303. +    dot = vec * v_forward;
  1304. +    
  1305. +    if ( dot > 0.3)
  1306. +    {
  1307. +        return TRUE;
  1308. +    }
  1309. +    return FALSE;
  1310. +};
  1311. +void() bot_ai_face =
  1312. +{
  1313. +        bot_enemy_image();
  1314. +    self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
  1315. +    ChangeYaw ();
  1316. +
  1317. +};
  1318. +// create ghost image of enemy to move to....
  1319. +
  1320. +void () bot_enemy_image = 
  1321. +{
  1322. +               local    entity newbot;
  1323. +
  1324. +               
  1325. +               newbot=spawn();
  1326. +
  1327. +               newbot.classname = "enemy";
  1328. +               newbot.movetype= MOVETYPE_NONE;
  1329. +               newbot.solid = SOLID_TRIGGER;
  1330. +
  1331. +               setsize (newbot, '0 0 1', '0 0 1');        
  1332. +//               setmodel (newbot, "progs/laser.mdl");//for debugging
  1333. +               setmodel (newbot, "progs/null.spr");
  1334. +               newbot.origin = self.enemy.origin;
  1335. +               newbot.owner=self;
  1336. +               newbot.touch=bot_remove_enemy_image;
  1337. +               newbot.nextthink=time+10;
  1338. +               newbot.think=SUB_Remove;
  1339. +               self.goalentity = newbot;
  1340. +               self.movetarget = newbot;
  1341. +};
  1342. +
  1343. +void () bot_remove_enemy_image =
  1344. +       {
  1345. +        if (self.owner == other)
  1346. +                remove(self);
  1347. +        };
  1348. +void () bot_start_dodge =
  1349. +        {
  1350. +                self.dodge = TRUE;
  1351. +                if ((random() * 1) >= 0.5)
  1352. +                        self.lefty = 1;
  1353. +                else self.lefty = 0;
  1354. +                    
  1355. +        };
  1356. +void () bot_end_dodge =
  1357. +        {
  1358. +                self.dodge = FALSE;
  1359. +        };
  1360. +float() check_dodge =
  1361. +        {
  1362. +                if (self.dodge == FALSE)
  1363. +                       return FALSE;
  1364. +                else if (self.dodge == TRUE)
  1365. +                        return TRUE;
  1366. +        };
  1367. +void () bot_start_circle =
  1368. +        {
  1369. +                self.dodge = TRUE;
  1370. +        };
  1371. +void () bot_end_circle =
  1372. +        {
  1373. +                self.dodge = FALSE;
  1374. +        };
  1375. +void() bot_firebullets =
  1376. +{
  1377. +    local    vector    dir;
  1378. +    local    entity    en;
  1379. +    
  1380. +        bot_ai_face();
  1381. +    
  1382. +// fire somewhat behind the player, so a dodging player is harder to hit
  1383. +    en = self.enemy;
  1384. +    
  1385. +    dir = en.origin - en.velocity*0.2;
  1386. +    dir = normalize (dir - self.origin);
  1387. +    
  1388. +        FireBullets (6, dir, '0.1 0.1 0');
  1389. +};
  1390. +
  1391. +void() bot_FireShotgun =
  1392. +{
  1393. +    local vector dir;
  1394. +    local    entity    en;
  1395. +
  1396. +    self.currentammo = self.ammo_shells = self.ammo_shells - 1;
  1397. +    en = self.enemy;
  1398. +    dir = en.origin - en.velocity*0.2;
  1399. +    dir = normalize (dir - self.origin);
  1400. +
  1401. +//        dir = aim (self, 100000);
  1402. +        FireBullets (6, dir, '0.1 0.1 0');
  1403. +};
  1404. +
  1405. +void() bot_FireSuperShotgun =
  1406. +{
  1407. +    local vector dir;
  1408. +        local   entity  en;
  1409. +        if (self.currentammo == 1)
  1410. +    {
  1411. +                bot_FireShotgun ();
  1412. +        return;
  1413. +    }
  1414. +    self.currentammo = self.ammo_shells = self.ammo_shells - 2;
  1415. +    en = self.enemy;
  1416. +    dir = en.origin - en.velocity*0.2;
  1417. +    dir = normalize (dir - self.origin);
  1418. +    FireBullets (14, dir, '0.14 0.08 0');
  1419. +};
  1420. +
  1421. +void() bot_FireRocket =
  1422. +{
  1423. +    local    entity missile, mpuff;
  1424. +        local   vector  dir;
  1425. +        local   entity  en;
  1426. +        self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  1427. +    
  1428. +    missile = spawn ();
  1429. +    missile.owner = self;
  1430. +    missile.movetype = MOVETYPE_FLYMISSILE;
  1431. +    missile.solid = SOLID_BBOX;
  1432. +        makevectors (self.angles);
  1433. +    en = self.enemy;
  1434. +    dir = en.origin - en.velocity*0.2;
  1435. +    dir = normalize (dir - self.origin);
  1436. +        missile.velocity = dir;
  1437. +    missile.velocity = missile.velocity * 1000;
  1438. +    missile.angles = vectoangles(missile.velocity);
  1439. +    missile.touch = T_MissileTouch;
  1440. +    missile.nextthink = time + 5;
  1441. +    missile.think = SUB_Remove;
  1442. +    setmodel (missile, "progs/missile.mdl");
  1443. +    setsize (missile, '0 0 0', '0 0 0');        
  1444. +        setorigin (missile, self.origin + '0 0 16');
  1445. +};
  1446. +
  1447. +void () bot_nail =
  1448. +{
  1449. +    local vector org;
  1450. +        local vector dir;
  1451. +        local float ox;
  1452. +        
  1453. +        ox = 4;
  1454. +
  1455. +    self.effects = self.effects | EF_MUZZLEFLASH;
  1456. +    makevectors (self.angles);
  1457. +    sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
  1458. +    self.currentammo = self.ammo_nails = self.ammo_nails - 1;
  1459. +        org = self.origin + v_forward * 30 + v_right*ox + '0 0 16';
  1460. +        dir = self.enemy.origin - self.origin;
  1461. +        dir = normalize(dir);
  1462. +        launch_spike(org, dir);
  1463. +};
  1464. +
  1465. +void () bot_nail2 =
  1466. +{
  1467. +    local vector    dir;
  1468. +        local vector    org;
  1469. +    
  1470. +        self.oldenemy = self.enemy;
  1471. +        if (!visible (self.enemy) || (self.enemy.health <= 0))
  1472. +        {
  1473. +                if (BotFindTarget ())
  1474. +                        return;
  1475. +    
  1476. +                ChangeYaw ();
  1477. +                self.enemy = self.oldenemy;
  1478. +        }
  1479. +
  1480. +    makevectors (self.angles);
  1481. +    sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
  1482. +    self.currentammo = self.ammo_nails = self.ammo_nails - 2;
  1483. +        org = self.origin + '0 0 16';
  1484. +        dir = self.enemy.origin - self.origin;
  1485. +        dir = normalize(dir);
  1486. +        launch_spike (org, dir);
  1487. +    newmis.touch = superspike_touch;
  1488. +    setmodel (newmis, "progs/s_spike.mdl");
  1489. +    setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);        
  1490. +};
  1491. +
  1492. +void(vector offset) benforcer_fire =
  1493. +{
  1494. +    local vector org;
  1495. +        local vector dir;
  1496. +        local float ox;
  1497. +        
  1498. +        ox = 4;
  1499. +
  1500. +    self.effects = self.effects | EF_MUZZLEFLASH;
  1501. +    makevectors (self.angles);
  1502. +    sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
  1503. +    
  1504. +        org = self.origin + v_forward * 30 + v_right*ox + '0 0 16';
  1505. +        dir = self.enemy.origin - self.origin;
  1506. +        dir = normalize(dir);
  1507. +        launch_spike(org, dir);
  1508. +        org = org + offset;
  1509. +        launch_spike(org, dir);
  1510. +};
  1511. +
  1512. +void() bot_SetCurrentAmmo =
  1513. +{
  1514. +    self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) );
  1515. +    
  1516. +        if (self.weapon == IT_SHOTGUN)
  1517. +    {
  1518. +        self.currentammo = self.ammo_shells;
  1519. +        self.items = self.items | IT_SHELLS;
  1520. +                self.th_stand = bot_stand1;
  1521. +                self.th_walk = bot_walk1;
  1522. +                self.th_run = bot_run1;
  1523. +                self.th_stuff = bot_stuff1;
  1524. +                self.th_dodge = bot_dodge1;
  1525. +                self.th_pain = bot_pain;
  1526. +                self.th_die = bot_die;
  1527. +                self.th_missile = bot_atk1;
  1528. +                self.th_qatk = bot_qatk1;
  1529. +    }
  1530. +    else if (self.weapon == IT_SUPER_SHOTGUN)
  1531. +    {
  1532. +        self.currentammo = self.ammo_shells;
  1533. +        self.items = self.items | IT_SHELLS;
  1534. +                self.th_stand = bot_stand1;
  1535. +                self.th_walk = bot_walk1;
  1536. +                self.th_run = bot_run1;
  1537. +                self.th_stuff = bot_stuff1;
  1538. +                self.th_dodge = bot_dodge1;
  1539. +                self.th_pain = bot_pain;
  1540. +                self.th_die = bot_die;
  1541. +                self.th_missile = bot_atk1;
  1542. +                self.th_qatk = bot_qatk1;
  1543. +
  1544. +    }
  1545. +    else if (self.weapon == IT_NAILGUN)
  1546. +    {
  1547. +        self.currentammo = self.ammo_nails;
  1548. +        self.items = self.items | IT_NAILS;
  1549. +                self.th_stand = bot_stand1;
  1550. +                self.th_walk = bot_walk1;
  1551. +                self.th_run = bot_run1;
  1552. +                self.th_stuff = bot_stuff1;
  1553. +                self.th_dodge = bot_dodgen1;
  1554. +                self.th_pain = bot_pain;
  1555. +                self.th_die = bot_die;
  1556. +                self.th_missile = bot_atkn1;
  1557. +                self.th_qatk = bot_qatkn1;
  1558. +    }
  1559. +    else if (self.weapon == IT_SUPER_NAILGUN)
  1560. +    {
  1561. +        self.currentammo = self.ammo_nails;
  1562. +        self.items = self.items | IT_NAILS;
  1563. +                self.th_stand = bot_stand1;
  1564. +                self.th_walk = bot_walk1;
  1565. +                self.th_run = bot_run1;
  1566. +                self.th_stuff = bot_stuff1;
  1567. +                self.th_dodge = bot_dodgesn1;
  1568. +                self.th_pain = bot_pain;
  1569. +                self.th_die = bot_die;
  1570. +                self.th_missile = bot_atksn1;
  1571. +                self.th_qatk = bot_qatksn1;                
  1572. +    }
  1573. +        else if (self.weapon == IT_GRENADE_LAUNCHER)
  1574. +        {
  1575. +                self.currentammo = self.ammo_rockets;
  1576. +                self.items = self.items | IT_ROCKETS;
  1577. +                self.th_stand = bot_stand1;
  1578. +                self.th_walk = bot_walk1;
  1579. +                self.th_run = bot_run1;
  1580. +                self.th_stuff = bot_stuff1;
  1581. +                self.th_dodge = bot_dodger1;
  1582. +                self.th_pain = bot_pain;
  1583. +                self.th_die = bot_die;
  1584. +                self.th_missile = bot_atkr1;
  1585. +                self.th_qatk = bot_qatkr1;
  1586. +
  1587. +        }
  1588. +    else if (self.weapon == IT_ROCKET_LAUNCHER)
  1589. +    {
  1590. +        self.currentammo = self.ammo_rockets;
  1591. +        self.items = self.items | IT_ROCKETS;
  1592. +                self.th_stand = bot_stand1;
  1593. +                self.th_walk = bot_walk1;
  1594. +                self.th_run = bot_run1;
  1595. +                self.th_stuff = bot_stuff1;
  1596. +                self.th_dodge = bot_dodger1;
  1597. +                self.th_pain = bot_pain;
  1598. +                self.th_die = bot_die;
  1599. +                self.th_missile = bot_atkr1;
  1600. +                self.th_qatk = bot_qatkr1;
  1601. +
  1602. +    }
  1603. +    else
  1604. +    {
  1605. +        self.currentammo = 0;
  1606. +        self.weaponmodel = "";
  1607. +        self.weaponframe = 0;
  1608. +    }
  1609. +};
  1610. +/*
  1611. +====================================================
  1612. +bot_bestweapon - AI to choose which weapon is best
  1613. +====================================================
  1614. +*/
  1615. +float () bot_bestweapon =
  1616. +{
  1617. +    local    float    it;
  1618. +    
  1619. +    it = self.items;
  1620. +
  1621. +        if(self.ammo_rockets >= 1 && (it & IT_ROCKET_LAUNCHER) )
  1622. +        return IT_ROCKET_LAUNCHER;
  1623. +    else if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) )
  1624. +        return IT_SUPER_NAILGUN;
  1625. +    else if(self.ammo_shells >= 2 && (it & IT_SUPER_SHOTGUN) )
  1626. +        return IT_SUPER_SHOTGUN;
  1627. +    else if(self.ammo_nails >= 1 && (it & IT_NAILGUN) )
  1628. +        return IT_NAILGUN;
  1629. +        else if (self.ammo_rockets>= 1 && (it & IT_GRENADE_LAUNCHER) )
  1630. +                return IT_GRENADE_LAUNCHER;
  1631. +        return IT_SHOTGUN;
  1632. +
  1633. +};
  1634. +/*
  1635. +===============================================
  1636. +bot_CheckNoAmmo - checks to see if he has ammo 
  1637. +===============================================
  1638. +*/
  1639. +float() bot_CheckNoAmmo =
  1640. +{
  1641. +    if (self.currentammo > 0)
  1642. +        return TRUE;
  1643. +
  1644. +        self.weapon = bot_bestweapon ();
  1645. +
  1646. +        bot_SetCurrentAmmo ();
  1647. +    
  1648. +    return FALSE;
  1649. +};
  1650. +/*
  1651. +==========================
  1652. +bot_attack - fires weapon
  1653. +==========================
  1654. +*/
  1655. +void() bot_attack =
  1656. +{
  1657. +        bot_SetCurrentAmmo (); 
  1658. +        if (BotFindRocket())
  1659. +        {
  1660. +                if (check_dodge() == FALSE)                                
  1661. +                        bot_dodgern1();
  1662. +        }
  1663. +
  1664. +    if (self.enemy.health <= 0)
  1665. +    {
  1666. +        self.enemy = world;
  1667. +        if (self.oldenemy.health > 0)
  1668. +        {
  1669. +            self.enemy = self.oldenemy;
  1670. +            BotHuntTarget ();
  1671. +        }
  1672. +        else
  1673. +        {
  1674. +            if (BotFindTarget())
  1675. +                        {
  1676. +                                if (visible(self.enemy) == FALSE)
  1677. +                                        movetogoal(30);
  1678. +                                else if (visible(self.enemy) == TRUE)
  1679. +//                                        sprint (self.enemy, "tracing: ");
  1680. +                                        bot_enemy_image();
  1681. +                                return;
  1682. +                        }
  1683. +                        else
  1684. +            {
  1685. +                self.movetarget = self.owner;
  1686. +                self.th_walk ();
  1687. +                return;
  1688. +            }
  1689. +        }
  1690. +    }
  1691. +
  1692. +        bot_ai_face();
  1693. +        if ((infront(self.enemy)) && (visible(self.enemy)))
  1694. +    {
  1695. +                bot_enemy_image();
  1696. +                bot_shoot();
  1697. +    }
  1698. +        else if (!(visible(self.enemy)))
  1699. +                movetogoal(20);
  1700. +                
  1701. +        return;
  1702. +};                                                
  1703. +void () bot_shoot =
  1704. +{
  1705. +    local    float    r;
  1706. +
  1707. +        if (!visible (self.enemy) || (self.enemy.health <= 0))
  1708. +                return;
  1709. +
  1710. +        if (!bot_CheckNoAmmo ())
  1711. +        return;
  1712. +
  1713. +        makevectors     (self.angles);     
  1714. +    self.show_hostile = time + 1;    // wake monsters up
  1715. +
  1716. +        if (self.weapon == IT_SHOTGUN)
  1717. +    {                
  1718. +                bot_FireShotgun ();
  1719. +                bot_SetCurrentAmmo (); 
  1720. +    }
  1721. +    else if (self.weapon == IT_SUPER_SHOTGUN)
  1722. +    {
  1723. +                bot_FireSuperShotgun ();
  1724. +                bot_SetCurrentAmmo (); 
  1725. +    }
  1726. +    else if (self.weapon == IT_NAILGUN)
  1727. +    {
  1728. +                bot_nail ();
  1729. +                bot_SetCurrentAmmo (); 
  1730. +    }
  1731. +    else if (self.weapon == IT_SUPER_NAILGUN)
  1732. +    {
  1733. +                bot_nail2 ();
  1734. +                bot_SetCurrentAmmo (); 
  1735. +        }
  1736. +        else if (self.weapon == IT_GRENADE_LAUNCHER)
  1737. +        {
  1738. +                BOTFireGrenade();
  1739. +                bot_SetCurrentAmmo (); 
  1740. +        }
  1741. +    else if (self.weapon == IT_ROCKET_LAUNCHER)
  1742. +    {
  1743. +                bot_FireRocket();
  1744. +                bot_SetCurrentAmmo (); 
  1745. +
  1746. +        }
  1747. +};
  1748. +void() BOTGrenadeExplode =
  1749. +{
  1750. +        T_RadiusDamage (self, self.owner, 30, world);
  1751. +    sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
  1752. +
  1753. +    WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  1754. +    WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  1755. +    WriteCoord (MSG_BROADCAST, self.origin_x);
  1756. +    WriteCoord (MSG_BROADCAST, self.origin_y);
  1757. +    WriteCoord (MSG_BROADCAST, self.origin_z);
  1758. +
  1759. +    self.velocity = '0 0 0';
  1760. +    self.touch = SUB_Null;
  1761. +    setmodel (self, "progs/s_explod.spr");
  1762. +    self.solid = SOLID_NOT;
  1763. +    s_explode1 ();
  1764. +};
  1765. +
  1766. +void() BOTGrenadeTouch =
  1767. +{
  1768. +    if (other == self.owner)
  1769. +        return;        // don't explode on owner
  1770. +        if (other.takedamage == DAMAGE_AIM) 
  1771. +    {
  1772. +                BOTGrenadeExplode();
  1773. +        return;
  1774. +    }
  1775. +    sound (self, CHAN_VOICE, "weapons/bounce.wav", 1, ATTN_NORM);    // bounce sound
  1776. +    if (self.velocity == '0 0 0')
  1777. +        self.avelocity = '0 0 0';
  1778. +};
  1779. +
  1780. +
  1781. +/*
  1782. +================
  1783. +BOTFireGrenade
  1784. +================
  1785. +*/
  1786. +
  1787. +void() BOTFireGrenade =
  1788. +{
  1789. +    local    entity missile, mpuff;
  1790. +    local float zchange;
  1791. +
  1792. +       // knock off a rocket
  1793. +       self.ammo_rockets = self.ammo_rockets - 1;
  1794. +    
  1795. +    missile = spawn ();
  1796. +    missile.owner = self;
  1797. +    missile.movetype = MOVETYPE_BOUNCE;
  1798. +    missile.solid = SOLID_BBOX;
  1799. +        
  1800. +// set missile speed    
  1801. +
  1802. +    makevectors (self.angles);
  1803. +
  1804. +    missile.velocity = normalize(self.enemy.origin - self.origin);
  1805. +        missile.velocity = missile.velocity * 600;
  1806. +    missile.velocity_z = 200;
  1807. +    zchange = self.origin_z - self.enemy.origin_z;
  1808. +    missile.velocity_z = missile.velocity_z - (zchange+10);
  1809. +    missile.avelocity = '300 300 300';
  1810. +
  1811. +    missile.angles = vectoangles(missile.velocity);
  1812. +    
  1813. +        missile.touch = BOTGrenadeTouch;
  1814. +    
  1815. +// set missile duration
  1816. +    missile.nextthink = time + 2.5;
  1817. +        missile.think = BOTGrenadeExplode;
  1818. +
  1819. +        setmodel (missile, "progs/grenade.mdl");
  1820. +    setsize (missile, '0 0 0', '0 0 0');        
  1821. +    setorigin (missile, self.origin);
  1822. +};
  1823. +
  1824. +/*
  1825. +================
  1826. +BotCheckPowerups
  1827. +
  1828. +Check for turning off powerups
  1829. +================
  1830. +*/
  1831. +void(entity oldself) BotCheckPowerups =
  1832. +{
  1833. +//        sprint(self.enemy, "I'm Thinking!!!");
  1834. +
  1835. +// invisibility
  1836. +        if (oldself.invisible_finished)
  1837. +    {
  1838. +// sound and screen flash when items starts to run out
  1839. +
  1840. +
  1841. +                if (oldself.invisible_finished < time)
  1842. +        {    // just stopped
  1843. +                        oldself.items = oldself.items - IT_INVISIBILITY;
  1844. +                        oldself.invisible_finished = 0;
  1845. +                        oldself.invisible_time = 0;
  1846. +        }
  1847. +        
  1848. +    // use the eyes
  1849. +                oldself.frame = 0;
  1850. +                oldself.modelindex = modelindex_eyes;
  1851. +    }
  1852. +    else
  1853. +                oldself.modelindex = modelindex_bot;    // don't use eyes
  1854. +
  1855. +// invincibility
  1856. +        if (oldself.invincible_finished)
  1857. +    {
  1858. +                if (oldself.invincible_finished < time)
  1859. +        {    // just stopped
  1860. +                        oldself.items = oldself.items - IT_INVULNERABILITY;
  1861. +                        oldself.invincible_time = 0;
  1862. +                        oldself.invincible_finished = 0;
  1863. +        }
  1864. +                if (oldself.invincible_finished > time)
  1865. +                        oldself.effects = oldself.effects & EF_DIMLIGHT;
  1866. +        else
  1867. +                        oldself.effects = oldself.effects - (oldself.effects & EF_DIMLIGHT);
  1868. +    }
  1869. +
  1870. +// super damage
  1871. +        if (oldself.super_damage_finished)
  1872. +    {
  1873. +
  1874. +                if (oldself.super_damage_finished < time)
  1875. +        {    // just stopped
  1876. +                        oldself.items = oldself.items - IT_QUAD;
  1877. +                        oldself.super_damage_finished = 0;
  1878. +                        oldself.super_time = 0;
  1879. +                        oldself.effects = oldself.effects - (oldself.effects & EF_DIMLIGHT);
  1880. +
  1881. +        }
  1882. +                if (oldself.super_damage_finished > time)
  1883. +                        oldself.effects = oldself.effects & EF_DIMLIGHT;
  1884. +        else
  1885. +                        oldself.effects = oldself.effects - (oldself.effects & EF_DIMLIGHT);
  1886. +    }    
  1887. +
  1888. +// suit    
  1889. +        if (oldself.radsuit_finished)
  1890. +    {
  1891. +                oldself.air_finished = time + 12;          // don't drown
  1892. +
  1893. +                if (oldself.radsuit_finished < time)
  1894. +        {    // just stopped
  1895. +                        oldself.items = oldself.items - IT_SUIT;
  1896. +                        oldself.rad_time = 0;
  1897. +                        oldself.radsuit_finished = 0;
  1898. +        }
  1899. +    }    
  1900. +
  1901. +};
  1902. +
  1903. +
  1904. +void () bot_client =
  1905. +{
  1906. +               local    entity newbot;
  1907. +
  1908. +               newbot=spawn();
  1909. +               newbot.classname = "bot_controller";
  1910. +               newbot.movetype= MOVETYPE_NONE;
  1911. +               newbot.solid = SOLID_NOT;
  1912. +
  1913. +               setsize (newbot, '0 0 0', '0 0 0');        
  1914. +               setmodel (newbot, "progs/null.spr");
  1915. +               newbot.origin = self.origin;
  1916. +               newbot.owner=self;
  1917. +               self.controller = newbot;
  1918. +               newbot.nextthink=time+1;
  1919. +               newbot.think=bot_think;
  1920. +                
  1921. +};
  1922. +void () bot_think =
  1923. +{
  1924. +        local entity oldself;
  1925. +        oldself = self.owner;
  1926. +
  1927. +        if (oldself.health <=0)
  1928. +        {
  1929. +                remove(self);
  1930. +        }
  1931. +        else
  1932. +        {
  1933. +        Bot_PreThink(oldself);
  1934. +        self.nextthink = time+1;
  1935. +        }
  1936. +};
  1937. +
  1938. +void(entity oldself) Bot_PreThink =
  1939. +{
  1940. +//        sprint(oldself.enemy, "I'm Thinking!!!");
  1941. +        BotCheckPowerups(oldself);
  1942. +};
  1943. +void(entity oldself) Bot_PostThink =
  1944. +{
  1945. +        BotCheckPowerups(oldself);
  1946. +};
  1947. +
  1948. +void () bot_thinkb =
  1949. +{
  1950. +
  1951. +        Bot_PreThinkb();
  1952. +        self.nextthink = time+0.1;
  1953. +};
  1954. +
  1955. +void() Bot_PreThinkb =
  1956. +{
  1957. +//        sprint(self.enemy, "I'm Thinking!!!");
  1958. +        BotCheckPowerupsb();
  1959. +};
  1960. +void() Bot_PostThinkb =
  1961. +{
  1962. +        BotCheckPowerupsb();
  1963. +};
  1964. +
  1965. +
  1966. +/*
  1967. +================
  1968. +BotCheckPowerupsb
  1969. +
  1970. +Check for turning off powerups
  1971. +================
  1972. +*/
  1973. +void() BotCheckPowerupsb =
  1974. +{
  1975. +
  1976. +// invisibility
  1977. +        if (self.invisible_finished)
  1978. +    {
  1979. +// sound and screen flash when items starts to run out
  1980. +
  1981. +
  1982. +                if (self.invisible_finished < time)
  1983. +        {    // just stopped
  1984. +                        self.items = self.items - IT_INVISIBILITY;
  1985. +                        self.invisible_finished = 0;
  1986. +                        self.invisible_time = 0;
  1987. +        }
  1988. +        
  1989. +    // use the eyes
  1990. +                self.frame = 0;
  1991. +                self.modelindex = modelindex_eyes;
  1992. +    }
  1993. +    else
  1994. +                self.modelindex = modelindex_bot;    // don't use eyes
  1995. +
  1996. +// invincibility
  1997. +        if (self.invincible_finished)
  1998. +    {
  1999. +                if (self.invincible_finished < time)
  2000. +        {    // just stopped
  2001. +                        self.items = self.items - IT_INVULNERABILITY;
  2002. +                        self.invincible_time = 0;
  2003. +                        self.invincible_finished = 0;
  2004. +        }
  2005. +                if (self.invincible_finished > time)
  2006. +                        self.effects = self.effects & EF_DIMLIGHT;
  2007. +        else
  2008. +                        self.effects = self.effects - (self.effects & EF_DIMLIGHT);
  2009. +    }
  2010. +
  2011. +// super damage
  2012. +        if (self.super_damage_finished)
  2013. +    {
  2014. +
  2015. +                if (self.super_damage_finished < time)
  2016. +        {    // just stopped
  2017. +                        self.items = self.items - IT_QUAD;
  2018. +                        self.super_damage_finished = 0;
  2019. +                        self.super_time = 0;
  2020. +                        self.effects = self.effects - (self.effects & EF_DIMLIGHT);
  2021. +
  2022. +        }
  2023. +                if (self.super_damage_finished > time)
  2024. +                        self.effects = self.effects & EF_DIMLIGHT;
  2025. +        else
  2026. +                        self.effects = self.effects - (self.effects & EF_DIMLIGHT);
  2027. +    }    
  2028. +
  2029. +// suit    
  2030. +        if (self.radsuit_finished)
  2031. +    {
  2032. +                self.air_finished = time + 12;          // don't drown
  2033. +
  2034. +                if (self.radsuit_finished < time)
  2035. +        {    // just stopped
  2036. +                        self.items = self.items - IT_SUIT;
  2037. +                        self.rad_time = 0;
  2038. +                        self.radsuit_finished = 0;
  2039. +        }
  2040. +    }    
  2041. +
  2042. +};
  2043. +/*
  2044. +void() set_ai_think =
  2045. +{
  2046. +        self.nextthink = time +0.1;
  2047. +        self.think = bot_thinkb;
  2048. +
  2049. +};
  2050. +*/
  2051. +// BG Bot - begin hack to check for items
  2052. +float() BotFindStuff =
  2053. +{
  2054. +        local entity head, selected;
  2055. +    local float dist;
  2056. +        dist = 200; 
  2057. +    selected = world;
  2058. +
  2059. +        head = findradius(self.origin, 200);
  2060. +    while(head)
  2061. +    {
  2062. +                if ((head.classname == "weapon_supernailgun") ||
  2063. +                   (head.classname == "weapon_supershotgun") || 
  2064. +                   (head.classname == "weapon_rocketlauncher") || 
  2065. +                   (head.classname == "weapon_grenadelauncher") || 
  2066. +                   (head.classname == "weapon_nailgun") ||
  2067. +                   (head.classname == "backpack") ||
  2068. +                   (head.classname == "shells") ||
  2069. +                   (head.classname == "cells") ||
  2070. +                   (head.classname == "nails") ||
  2071. +                   (head.classname == "rockets") ||
  2072. +                   (head.classname == "item_armor1") ||
  2073. +                   (head.classname == "item_armor2") ||
  2074. +                   (head.classname == "item_armorInv") ||
  2075. +                   (head.classname == "item_artifact_invulnerability") ||
  2076. +                   (head.classname == "item_artifact_invisibility") ||
  2077. +                   (head.classname == "item_artifact_envirosuit") ||
  2078. +                   (head.classname == "item_artifact_super_damage") ||
  2079. +                   ((head.healtype == 1) && (self.health < 100)) ||
  2080. +                   ((head.healtype == 2) && (self.health < 100))) 
  2081. +
  2082. +                   {
  2083. +//                        if (visible(head))
  2084. +//                        {
  2085. +                        selected = head;
  2086. +                        dist = trace_plane_dist;
  2087. +//                      }
  2088. +                   }
  2089. +        head = head.chain;
  2090. +    }
  2091. +        self.stuff = selected;
  2092. +        
  2093. +        if (self.stuff == world)
  2094. +        return FALSE;
  2095. +        else
  2096. +        {
  2097. +                BotFoundStuff();
  2098. +        return TRUE;
  2099. +    }
  2100. +};
  2101. +//=============================================================
  2102. +// BotHuntStuff - Look for items
  2103. +//=============================================================
  2104. +void() BotHuntStuff =
  2105. +{
  2106. +        self.goalentity = self.stuff;
  2107. +        self.think = self.th_stuff;
  2108. +
  2109. +        self.ideal_yaw = vectoyaw(self.stuff.origin - self.origin);
  2110. +    self.nextthink = time + 0.1;
  2111. +};
  2112. +
  2113. +//=============================================================
  2114. +// BotFoundStuff - Items
  2115. +//=============================================================
  2116. +void() BotFoundStuff =
  2117. +{
  2118. +        local float f_dist;
  2119. +        local string s_dist;
  2120. +        f_dist = vlen (self.stuff.origin - self.origin);
  2121. +        s_dist = ftos (f_dist);
  2122. +
  2123. +        BotHuntStuff ();
  2124. +};
  2125. +
  2126. +//=============================================================
  2127. +// bot_ai_stuff - crappy hack
  2128. +//=============================================================
  2129. +void(float dist) bot_ai_stuff =
  2130. +{
  2131. +    local    vector    delta;
  2132. +    local    float    axis;
  2133. +    local    float    direct, ang_rint, ang_floor, ang_ceil;
  2134. +    
  2135. +    movedist = dist;
  2136. +
  2137. +        enemy_vis = visible(self.stuff);
  2138. +    if (enemy_vis)
  2139. +        self.search_time = time + 5;
  2140. +
  2141. +        enemy_infront = infront(self.stuff);
  2142. +        enemy_range = range(self.stuff);
  2143. +        enemy_yaw = vectoyaw(self.stuff.origin - self.origin);
  2144. +    
  2145. +//        if (CheckAnyAttack ())
  2146. +//               return;                                 // beginning an attack
  2147. +        
  2148. +    movetogoal (dist);        // done in C code...
  2149. +};
  2150. +
  2151. +void() bot_upabit =
  2152. +{
  2153. +        self.velocity_z = (self.velocity_z + 35);
  2154. +};
  2155. diff -ur --new-file d:\quakestu\qcc\send\v101qc/buttons.qc backup4/buttons.qc
  2156. --- d:\quakestu\qcc\send\v101qc/buttons.qc    Wed Jul 24 23:51:22 1996
  2157. +++ backup4/buttons.qc    Sat Aug 31 23:43:24 1996
  2158. @@ -53,7 +53,7 @@
  2159.  
  2160.  void() button_touch =
  2161.  {
  2162. -    if (other.classname != "player")
  2163. +        if ((other.classname != "player") && (other.classname !="bot"))
  2164.          return;
  2165.      self.enemy = other;
  2166.      button_fire ();
  2167. diff -ur --new-file d:\quakestu\qcc\send\v101qc/client.qc backup4/client.qc
  2168. --- d:\quakestu\qcc\send\v101qc/client.qc    Wed Jul 24 23:51:22 1996
  2169. +++ backup4/client.qc    Sat Aug 31 23:44:12 1996
  2170. @@ -1,5 +1,6 @@
  2171.  
  2172.  // prototypes
  2173. +void () BotStartDM;
  2174.  void () W_WeaponFrame;
  2175.  void() W_SetCurrentAmmo;
  2176.  void() player_pain;
  2177. @@ -467,6 +468,10 @@
  2178.      self.effects = 0;
  2179.      self.invincible_time = 0;
  2180.  
  2181. +// TM Bot - begin new start settings
  2182. +//        self.bot_flag = FALSE;
  2183. +// TM Bot - end new start settings
  2184. +
  2185.      DecodeLevelParms ();
  2186.      
  2187.      W_SetCurrentAmmo ();
  2188. @@ -495,7 +500,11 @@
  2189.      setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
  2190.      
  2191.      self.view_ofs = '0 0 22';
  2192. -
  2193. +       if (deathmatch)
  2194. +               if (self.bot_flag == FALSE)
  2195. +               {
  2196. +                        BotStartDM ();
  2197. +                        self.bot_flag == TRUE;
  2198. +               }
  2199. +       }
  2200.      player_stand1 ();
  2201.      
  2202.      if (deathmatch || coop)
  2203. @@ -581,13 +590,14 @@
  2204.  
  2205.  void() DumpScore =
  2206.  {
  2207. -    local entity    e, sort, walk;
  2208. +        local entity    e, sort, walk, f;
  2209.  
  2210.      if (world.chain)
  2211.          error ("DumpScore: world.chain is set");
  2212.  
  2213.  // build a sorted lis
  2214. -    e = find(world, classname, "player");
  2215. +        e = find(world, classname, "player");
  2216. +        
  2217.      sort = world;
  2218.      while (e)
  2219.      {
  2220. @@ -597,7 +607,7 @@
  2221.              e.chain = world;
  2222.          }
  2223.          else
  2224. -        {
  2225. +                {
  2226.              if (e.frags > sort.frags)
  2227.              {
  2228.                  e.chain = sort;
  2229. @@ -623,9 +633,50 @@
  2230.                  } while (walk.chain != e);
  2231.              }
  2232.          }
  2233. -        
  2234. -        e = find(e, classname, "player");
  2235. +       
  2236. +                e = find(e, classname, "player");
  2237.      }
  2238. +        f = find(world, classname, "bot");
  2239. +        
  2240. +    sort = world;
  2241. +        while (f)
  2242. +    {
  2243. +        if (!sort)
  2244. +        {
  2245. +                        sort = f;
  2246. +                        f.chain = world;
  2247. +        }
  2248. +        else
  2249. +                {
  2250. +                        if (f.frags > sort.frags)
  2251. +            {
  2252. +                                f.chain = sort;
  2253. +                                sort = f;
  2254. +            }
  2255. +            else
  2256. +            {
  2257. +                walk = sort;
  2258. +                do
  2259. +                {
  2260. +                    if (!walk.chain)
  2261. +                    {
  2262. +                                                f.chain = world;
  2263. +                                                walk.chain = f;
  2264. +                    }
  2265. +                                        else if (walk.chain.frags < f.frags)
  2266. +                    {
  2267. +                                                f.chain = walk.chain;
  2268. +                                                walk.chain = f;
  2269. +                    }
  2270. +                    else
  2271. +                        walk = walk.chain;
  2272. +                                } while (walk.chain != f);
  2273. +            }
  2274. +        }
  2275. +       
  2276. +                f = find(f, classname, "bot");
  2277. +    }
  2278. +
  2279.  
  2280.  // print the list
  2281.      
  2282. @@ -1218,7 +1269,7 @@
  2283.      local    string deathstring, deathstring2;
  2284.      rnum = random();
  2285.  
  2286. -    if (targ.classname == "player")
  2287. +        if ((attacker.classname == "player") || (attacker.classname == "bot"))
  2288.      {
  2289.          if (attacker.classname == "teledeath")
  2290.          {
  2291. @@ -1241,7 +1292,7 @@
  2292.              return;
  2293.          }
  2294.  
  2295. -        if (attacker.classname == "player")
  2296. +                if ((attacker.classname == "player") || (attacker.classname == "bot"))
  2297.          {
  2298.              if (targ == attacker)
  2299.              {
  2300. @@ -1320,7 +1371,12 @@
  2301.                      else
  2302.                          deathstring2 = "'s shaft\n";
  2303.                  }
  2304. -                bprint (targ.netname);
  2305. +//                                if (attacker.classname == "bot")
  2306. +//                                {                                       
  2307. +//                                        deathstring = " eats ";
  2308. +//                                        deathstring2 = "'s laser blast\n";
  2309. +//                                }
  2310. +                                bprint (targ.netname);
  2311.                  bprint (deathstring);
  2312.                  bprint (attacker.netname);
  2313.                  bprint (deathstring2);
  2314. @@ -1365,6 +1421,7 @@
  2315.  
  2316.              if (attacker.flags & FL_MONSTER)
  2317.              {
  2318. +                                
  2319.                  if (attacker.classname == "monster_army")
  2320.                      bprint (" was shot by a Grunt\n");
  2321.                  if (attacker.classname == "monster_demon1")
  2322. diff -ur --new-file d:\quakestu\qcc\send\v101qc/combat.qc backup4/combat.qc
  2323. --- d:\quakestu\qcc\send\v101qc/combat.qc    Wed Jul 24 23:51:22 1996
  2324. +++ backup4/combat.qc    Sat Aug 31 01:45:50 1996
  2325. @@ -4,7 +4,6 @@
  2326.  void(entity targ, entity attacker) ClientObituary;
  2327.  
  2328.  void() monster_death_use;
  2329. -
  2330.  //============================================================================
  2331.  
  2332.  /*
  2333. @@ -83,7 +82,11 @@
  2334.      
  2335.      self.takedamage = DAMAGE_NO;
  2336.      self.touch = SUB_Null;
  2337. -
  2338. +        if (self.classname == "bot")
  2339. +        {
  2340. +              //  (attacker.frags = attacker.frags + 1);
  2341. +                self.attackr = attacker;
  2342. +        }
  2343.      monster_death_use();
  2344.      self.th_die ();
  2345.      
  2346. @@ -140,13 +143,12 @@
  2347.      }
  2348.  
  2349.  // figure momentum add
  2350. -    if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) )
  2351. +        if ((inflictor != world) && ((targ.movetype == MOVETYPE_WALK) || (targ.classname == "bot")))
  2352.      {
  2353.          dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
  2354.          dir = normalize(dir);
  2355.          targ.velocity = targ.velocity + dir*damage*8;
  2356.      }
  2357. -
  2358.  // check for godmode or invincibility
  2359.      if (targ.flags & FL_GODMODE)
  2360.          return;
  2361. @@ -177,7 +179,7 @@
  2362.      oldself = self;
  2363.      self = targ;
  2364.  
  2365. -    if ( (self.flags & FL_MONSTER) && attacker != world)
  2366. +        if (( (self.flags & FL_MONSTER) && attacker != world) || (self.classname == "bot") && attacker !=world)
  2367.      {
  2368.      // get mad unless of the same class (except for soldiers)
  2369.          if (self != attacker && attacker != self.enemy)
  2370. @@ -191,6 +193,13 @@
  2371.                  FoundTarget ();
  2372.              }
  2373.          }
  2374. +                if (self.classname == "bot")
  2375. +        {
  2376. +                         self.oldenemy = self.enemy;
  2377. +                         self.enemy = attacker;
  2378. +                         BotFoundTarget ();
  2379. +        }
  2380. +
  2381.      }
  2382.  
  2383.      if (self.th_pain)
  2384. diff -ur --new-file d:\quakestu\qcc\send\v101qc/defs.qc backup4/defs.qc
  2385. --- d:\quakestu\qcc\send\v101qc/defs.qc    Wed Jul 24 23:51:22 1996
  2386. +++ backup4/defs.qc    Sun Sep  1 18:39:24 1996
  2387. @@ -211,6 +211,25 @@
  2388.  void        end_sys_fields;            // flag for structure dumping
  2389.  //================================================
  2390.  
  2391. +
  2392. +// TM Bot - begin new entity fields
  2393. +.entity        bot;                // pointer to the bot
  2394. +.float        bot_flag;            // existence of bot (TRUE or FALSE)
  2395. +.float        bot_auto;            // auto mode of bot (TRUE or FALSE)
  2396. +.float        move_flag;            // movement of bot (STAND, WALK, or RUN)
  2397. +.float        auto_fire;            // status of bot's auto fire (TRUE or FALSE)
  2398. +.entity         rcktdtct;                       // detecting rockets(FLY_MISSILE's)
  2399. +.entity         attackr;                        // remembering who killed bot
  2400. +.entity         bot_enemy_entity;               // remembering where enemy is
  2401. +.entity         bot_controller;     // the thinking half of the bot
  2402. +.float          dodge;                          // to prevent dodgeing while dodgeing
  2403. +.void()         th_dodge;                       // dodge action
  2404. +.entity         controller;                     // who the thinker is
  2405. +.void()         th_stuff;                       // for searching items
  2406. +.entity         stuff;                          // what item to get 
  2407. +.void()         th_qatk;                        // quick attack
  2408. +// TM Bot - end new entity fields
  2409. +
  2410.  /*
  2411.  ==============================================================================
  2412.  
  2413. diff -ur --new-file d:\quakestu\qcc\send\v101qc/doors.qc backup4/doors.qc
  2414. --- d:\quakestu\qcc\send\v101qc/doors.qc    Wed Jul 24 23:51:22 1996
  2415. +++ backup4/doors.qc    Sun Sep  1 00:03:24 1996
  2416. @@ -195,19 +195,20 @@
  2417.  */
  2418.  void() door_touch =
  2419.  {
  2420. -    if (other.classname != "player")
  2421. +        if ((other.classname != "player") && (other.classname !="bot"))
  2422.          return;
  2423.      if (self.owner.attack_finished > time)
  2424.          return;
  2425.  
  2426.      self.owner.attack_finished = time + 2;
  2427. -
  2428. -    if (self.owner.message != "")
  2429. -    {
  2430. -        centerprint (other, self.owner.message);
  2431. -        sound (other, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
  2432. -    }
  2433. -    
  2434. +        if (other.classname == "player")
  2435. +        {
  2436. +                if (self.owner.message != "")
  2437. +                {
  2438. +                        centerprint (other, self.owner.message);
  2439. +                         sound (other, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);      
  2440. +                }
  2441. +        }
  2442.  // key door stuff
  2443.      if (!self.items)
  2444.          return;
  2445. @@ -217,40 +218,48 @@
  2446.      {
  2447.          if (self.owner.items == IT_KEY1)
  2448.          {
  2449. -            if (world.worldtype == 2)
  2450. -            {
  2451. -                centerprint (other, "You need the silver keycard");
  2452. -                sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
  2453. -            }
  2454. -            else if (world.worldtype == 1)
  2455. -            {
  2456. -                centerprint (other, "You need the silver runekey");
  2457. -                sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
  2458. -            }
  2459. -            else if (world.worldtype == 0)
  2460. -            {
  2461. -                centerprint (other, "You need the silver key");
  2462. -                sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
  2463. -            }
  2464. -        }
  2465. +                        if (other.classname == "player")
  2466. +                        {
  2467. +
  2468. +                                if (world.worldtype == 2)
  2469. +                                {
  2470. +                                        centerprint (other, "You need the silver keycard");
  2471. +                                        sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
  2472. +                                }
  2473. +                                else if (world.worldtype == 1)
  2474. +                                {
  2475. +                                        centerprint (other, "You need the silver runekey");
  2476. +                                        sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
  2477. +                                }
  2478. +                                else if (world.worldtype == 0)
  2479. +                                {
  2480. +                                        centerprint (other, "You need the silver key");
  2481. +                                        sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
  2482. +                                }
  2483. +                        }
  2484. +                }
  2485.          else
  2486.          {
  2487. -            if (world.worldtype == 2)
  2488. -            {
  2489. -                centerprint (other, "You need the gold keycard");
  2490. -                sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
  2491. -            }
  2492. -            else if (world.worldtype == 1)
  2493. -            {
  2494. -                centerprint (other, "You need the gold runekey");
  2495. -                sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);            
  2496. -            }
  2497. -            else if (world.worldtype == 0)
  2498. -            {
  2499. -                centerprint (other, "You need the gold key");
  2500. -                sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
  2501. -            }
  2502. -        }
  2503. +                        if (other.classname == "player")
  2504. +                        {
  2505. +
  2506. +                                if (world.worldtype == 2)
  2507. +                                {
  2508. +                                        centerprint (other, "You need the gold keycard");
  2509. +                                        sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
  2510. +                                }
  2511. +                                else if (world.worldtype == 1)
  2512. +                                {
  2513. +                                        centerprint (other, "You need the gold runekey");
  2514. +                                        sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);             
  2515. +                                }
  2516. +                                else if (world.worldtype == 0)
  2517. +                                {
  2518. +                                        centerprint (other, "You need the gold key");
  2519. +                                        sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
  2520. +                                }
  2521. +                        }
  2522. +                }
  2523.          return;
  2524.      }
  2525.  
  2526. @@ -687,18 +696,22 @@
  2527.  */
  2528.  void() secret_touch =
  2529.  {
  2530. -    if (other.classname != "player")
  2531. +        if ((other.classname != "player") && (other.classname != "bot"))
  2532.          return;
  2533.      if (self.attack_finished > time)
  2534.          return;
  2535.  
  2536.      self.attack_finished = time + 2;
  2537.      
  2538. -    if (self.message)
  2539. -    {
  2540. -        centerprint (other, self.message);
  2541. -        sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
  2542. -    }
  2543. +        if (other.classname == "player")
  2544. +        {
  2545. +
  2546. +                if (self.message)
  2547. +                {
  2548. +                        centerprint (other, self.message);
  2549. +                        sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
  2550. +                }
  2551. +        }
  2552.  };
  2553.  
  2554.  
  2555. diff -ur --new-file d:\quakestu\qcc\send\v101qc/items.qc backup4/items.qc
  2556. --- d:\quakestu\qcc\send\v101qc/items.qc    Wed Jul 24 23:51:24 1996
  2557. +++ backup4/items.qc    Sun Sep  1 00:26:50 1996
  2558. @@ -1,4 +1,6 @@
  2559.  void() W_SetCurrentAmmo;
  2560. +void() bot_SetCurrentAmmo;
  2561. +float() bot_bestweapon;
  2562.  /* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD
  2563.  BE .8 .3 .4 IN COLOR */
  2564.  
  2565. @@ -152,7 +154,7 @@
  2566.      local    float amount;
  2567.      local    string    s;
  2568.      
  2569. -    if (other.classname != "player")
  2570. +        if (other.classname != "player" && other.classname != "bot")
  2571.          return;
  2572.      
  2573.      if (self.healtype == 2) // Megahealth?  Ignore max_health...
  2574. @@ -167,17 +169,18 @@
  2575.          if (!T_Heal(other, self.healamount, 0))
  2576.              return;
  2577.      }
  2578. -    
  2579. -    sprint(other, "You receive ");
  2580. -    s = ftos(self.healamount);
  2581. -    sprint(other, s);
  2582. -    sprint(other, " health\n");
  2583. -    
  2584. +        if (other.classname == "player")
  2585. +        {
  2586. +                sprint(other, "You receive ");
  2587. +                s = ftos(self.healamount);
  2588. +                sprint(other, s);
  2589. +                sprint(other, " health\n");
  2590. +
  2591.  // health touch sound
  2592. -    sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  2593. +                sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  2594.  
  2595. -    stuffcmd (other, "bf\n");
  2596. -    
  2597. +                stuffcmd (other, "bf\n");
  2598. +        }
  2599.      self.model = string_null;
  2600.      self.solid = SOLID_NOT;
  2601.  
  2602. @@ -241,7 +244,7 @@
  2603.      
  2604.      if (other.health <= 0)
  2605.          return;
  2606. -    if (other.classname != "player")
  2607. +        if (other.classname != "player" && other.classname != "bot")
  2608.          return;
  2609.  
  2610.      if (self.classname == "item_armor1")
  2611. @@ -275,11 +278,13 @@
  2612.          self.nextthink = time + 20;
  2613.      self.think = SUB_regen;
  2614.  
  2615. -    sprint(other, "You got armor\n");
  2616. +        if (other.classname == "player")
  2617. +        {
  2618. +                sprint(other, "You got armor\n");
  2619.  // armor touch sound
  2620.      sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM);
  2621.      stuffcmd (other, "bf\n");
  2622. -    
  2623. +        }
  2624.      activator = other;
  2625.      SUB_UseTargets();                // fire all targets / killtargets
  2626.  };
  2627. @@ -391,17 +396,18 @@
  2628.  
  2629.  void() weapon_touch =
  2630.  {
  2631. -    local    float    hadammo, best, new, old;
  2632. +        local   float   hadammo, best, new, old, bbest;
  2633.      local    entity    stemp;
  2634.      local    float    leave;
  2635.  
  2636. -    if (!(other.flags & FL_CLIENT))
  2637. +        if (!(other.flags & FL_CLIENT) && other.classname != "bot")
  2638.          return;
  2639.  
  2640.  // if the player was using his best weapon, change up to the new one if better        
  2641.      stemp = self;
  2642.      self = other;
  2643.      best = W_BestWeapon();
  2644. +        bbest = bot_bestweapon();
  2645.      self = stemp;
  2646.  
  2647.      if (deathmatch == 2 || coop)
  2648. @@ -459,14 +465,15 @@
  2649.      }
  2650.      else
  2651.          objerror ("weapon_touch: unknown classname");
  2652. -
  2653. -    sprint (other, "You got the ");
  2654. -    sprint (other, self.netname);
  2655. -    sprint (other, "\n");
  2656. +        if (other.classname == "player")
  2657. +        {
  2658. +                sprint (other, "You got the ");
  2659. +                sprint (other, self.netname);
  2660. +                sprint (other, "\n");
  2661.  // weapon touch sound
  2662. -    sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  2663. -    stuffcmd (other, "bf\n");
  2664. -
  2665. +                sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  2666. +                stuffcmd (other, "bf\n");
  2667. +        }
  2668.      bound_other_ammo ();
  2669.  
  2670.  // change to the weapon
  2671. @@ -480,10 +487,15 @@
  2672.          self.weapon = new;
  2673.      else
  2674.          Deathmatch_Weapon (old, new);
  2675. -
  2676. +        if (other.classname == "player")
  2677. +        {
  2678.      W_SetCurrentAmmo();
  2679. -
  2680. -    self = stemp;
  2681. +        }
  2682. +        if (other.classname == "bot")
  2683. +        {
  2684. +        bot_SetCurrentAmmo();
  2685. +        }
  2686. +        self = stemp;
  2687.  
  2688.      if (leave)
  2689.          return;
  2690. @@ -597,9 +609,9 @@
  2691.  void() ammo_touch =
  2692.  {
  2693.  local entity    stemp;
  2694. -local float        best;
  2695. +local float             best,bbest;
  2696.  
  2697. -    if (other.classname != "player")
  2698. +        if (other.classname != "player" && other.classname != "bot")
  2699.          return;
  2700.      if (other.health <= 0)
  2701.          return;
  2702. @@ -608,6 +620,7 @@
  2703.      stemp = self;
  2704.      self = other;
  2705.      best = W_BestWeapon();
  2706. +        bbest = bot_bestweapon();
  2707.      self = stemp;
  2708.  
  2709.  
  2710. @@ -644,31 +657,46 @@
  2711.      }
  2712.  
  2713.      bound_other_ammo ();
  2714. -    
  2715. -    sprint (other, "You got the ");
  2716. -    sprint (other, self.netname);
  2717. -    sprint (other, "\n");
  2718. -// ammo touch sound
  2719. -    sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  2720. -    stuffcmd (other, "bf\n");
  2721. -
  2722. +        if (other.classname == "player")
  2723. +        {
  2724. +                sprint (other, "You got the ");
  2725. +                sprint (other, self.netname);
  2726. +                sprint (other, "\n");
  2727. +        // ammo touch sound
  2728. +                sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  2729. +                stuffcmd (other, "bf\n");
  2730.  // change to a better weapon if appropriate
  2731.  
  2732. -    if ( other.weapon == best )
  2733. -    {
  2734. -        stemp = self;
  2735. -        self = other;
  2736. -        self.weapon = W_BestWeapon();
  2737. -        W_SetCurrentAmmo ();
  2738. -        self = stemp;
  2739. -    }
  2740. +                if ( other.weapon == best )
  2741. +                {
  2742. +                       stemp = self;
  2743. +                        self = other;
  2744. +                        self.weapon = W_BestWeapon();
  2745. +                        W_SetCurrentAmmo ();
  2746. +                        self = stemp;
  2747. +                }
  2748.  
  2749.  // if changed current ammo, update it
  2750. -    stemp = self;
  2751. -    self = other;
  2752. -    W_SetCurrentAmmo();
  2753. -    self = stemp;
  2754. -
  2755. +                stemp = self;
  2756. +                self = other;
  2757. +                W_SetCurrentAmmo();
  2758. +                self = stemp;
  2759. +        }
  2760. +        if (other.classname == "bot")
  2761. +        {
  2762. +                if (other.weapon == bbest)
  2763. +                {
  2764. +                        stemp = self;
  2765. +                        self = other;
  2766. +                        self.weapon = bot_bestweapon();
  2767. +                        bot_SetCurrentAmmo();
  2768. +                        self = stemp;
  2769. +                }
  2770. +                stemp = self;
  2771. +                self = other;
  2772. +                bot_SetCurrentAmmo();
  2773. +                self = stemp;
  2774. +        }
  2775.  // remove it in single player, or setup for respawning in deathmatch
  2776.      self.model = string_null;
  2777.      self.solid = SOLID_NOT;
  2778. @@ -706,6 +734,7 @@
  2779.          self.aflag = 20;
  2780.      }
  2781.      self.weapon = 1;
  2782. +        self.classname = "shells";
  2783.      self.netname = "shells";
  2784.      setsize (self, '0 0 0', '32 32 56');
  2785.      StartItem ();
  2786. @@ -731,6 +760,7 @@
  2787.          self.aflag = 25;
  2788.      }
  2789.      self.weapon = 2;
  2790. +        self.classname = "nails";
  2791.      self.netname = "nails";
  2792.      setsize (self, '0 0 0', '32 32 56');
  2793.      StartItem ();
  2794. @@ -756,6 +786,7 @@
  2795.          self.aflag = 5;
  2796.      }
  2797.      self.weapon = 3;
  2798. +        self.classname = "rockets";
  2799.      self.netname = "rockets";
  2800.      setsize (self, '0 0 0', '32 32 56');
  2801.      StartItem ();
  2802. @@ -782,6 +813,7 @@
  2803.          self.aflag = 6;
  2804.      }
  2805.      self.weapon = 4;
  2806. +        self.classname = "cells";
  2807.      self.netname = "cells";
  2808.      setsize (self, '0 0 0', '32 32 56');
  2809.      StartItem ();
  2810. @@ -1081,15 +1113,16 @@
  2811.  local entity    stemp;
  2812.  local float        best;
  2813.  
  2814. -    if (other.classname != "player")
  2815. +        if (other.classname != "player" && other.classname != "bot")
  2816.          return;
  2817.      if (other.health <= 0)
  2818.          return;
  2819. -
  2820. -    sprint (other, "You got the ");
  2821. -    sprint (other, self.netname);
  2822. -    sprint (other,"\n");
  2823. -
  2824. +        if (other.classname == "player")
  2825. +        {
  2826. +                sprint (other, "You got the ");
  2827. +                sprint (other, self.netname);
  2828. +                sprint (other,"\n");
  2829. +        }
  2830.      if (deathmatch)
  2831.      {
  2832.          self.mdl = self.model;
  2833. @@ -1103,8 +1136,11 @@
  2834.          self.think = SUB_regen;
  2835.      }    
  2836.  
  2837. -    sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
  2838. -    stuffcmd (other, "bf\n");
  2839. +        if (other.classname == "player")
  2840. +        {
  2841. +                sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
  2842. +                stuffcmd (other, "bf\n");
  2843. +        }                
  2844.      self.solid = SOLID_NOT;
  2845.      other.items = other.items | self.items;
  2846.      self.model = string_null;
  2847. @@ -1120,6 +1156,8 @@
  2848.      {
  2849.          other.invincible_time = 1;
  2850.          other.invincible_finished = time + 30;
  2851. +                if (other.classname == "bot")
  2852. +                        other.effects = other.effects + EF_DIMLIGHT;
  2853.      }
  2854.      
  2855.      if (self.classname == "item_artifact_invisibility")
  2856. @@ -1132,7 +1170,10 @@
  2857.      {
  2858.          other.super_time = 1;
  2859.          other.super_damage_finished = time + 30;
  2860. -    }    
  2861. +                if (other.classname == "bot")
  2862. +                        other.effects = other.effects + EF_DIMLIGHT;
  2863. +
  2864. +    }
  2865.  
  2866.      activator = other;
  2867.      SUB_UseTargets();                // fire all targets / killtargets
  2868. @@ -1190,7 +1231,7 @@
  2869.      precache_sound ("items/inv2.wav");
  2870.      precache_sound ("items/inv3.wav");
  2871.      self.noise = "items/inv1.wav";
  2872. -    setmodel (self, "progs/invisibl.mdl");
  2873. +    setmodel (self, "progs/invisibl.mdl");       
  2874.      self.netname = "Ring of Shadows";
  2875.      self.items = IT_INVISIBILITY;
  2876.      setsize (self, '-16 -16 -24', '16 16 32');
  2877. @@ -1230,10 +1271,10 @@
  2878.  void() BackpackTouch =
  2879.  {
  2880.      local string    s;
  2881. -    local    float    best;
  2882. +        local   float   best,bbest;
  2883.      local        entity    stemp;
  2884.      
  2885. -    if (other.classname != "player")
  2886. +        if (other.classname != "player" && other.classname != "bot")
  2887.          return;
  2888.      if (other.health <= 0)
  2889.          return;
  2890. @@ -1242,64 +1283,81 @@
  2891.      stemp = self;
  2892.      self = other;
  2893.      best = W_BestWeapon();
  2894. +        bbest = bot_bestweapon();
  2895.      self = stemp;
  2896.  
  2897.  // change weapons
  2898.      other.ammo_shells = other.ammo_shells + self.ammo_shells;
  2899.      other.ammo_nails = other.ammo_nails + self.ammo_nails;
  2900. -    other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
  2901. +        other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
  2902.      other.ammo_cells = other.ammo_cells + self.ammo_cells;
  2903.  
  2904.      other.items = other.items | self.items;
  2905.      
  2906.      bound_other_ammo ();
  2907. -
  2908. -    sprint (other, "You get ");
  2909. -
  2910. -    if (self.ammo_shells)
  2911. -    {
  2912. -        s = ftos(self.ammo_shells);
  2913. -        sprint (other, s);
  2914. -        sprint (other, " shells  ");
  2915. -    }
  2916. -    if (self.ammo_nails)
  2917. -    {
  2918. -        s = ftos(self.ammo_nails);
  2919. -        sprint (other, s);
  2920. -        sprint (other, " nails ");
  2921. -    }
  2922. -    if (self.ammo_rockets)
  2923. -    {
  2924. -        s = ftos(self.ammo_rockets);
  2925. -        sprint (other, s);
  2926. -        sprint (other, " rockets  ");
  2927. -    }
  2928. -    if (self.ammo_cells)
  2929. -    {
  2930. -        s = ftos(self.ammo_cells);
  2931. -        sprint (other, s);
  2932. -        sprint (other, " cells  ");
  2933. -    }
  2934. +        if (other.classname == "player")
  2935. +        {
  2936. +                sprint (other, "You get ");
  2937. +                if (self.ammo_shells)
  2938. +                {
  2939. +                        s = ftos(self.ammo_shells);
  2940. +                        sprint (other, s);
  2941. +                        sprint (other, " shells  ");
  2942. +                }
  2943. +                if (self.ammo_nails)
  2944. +                {
  2945. +                        s = ftos(self.ammo_nails);
  2946. +                        sprint (other, s);
  2947. +                        sprint (other, " nails ");
  2948. +                }
  2949. +                if (self.ammo_rockets)
  2950. +                {
  2951. +                        s = ftos(self.ammo_rockets);
  2952. +                        sprint (other, s);
  2953. +                        sprint (other, " rockets  ");
  2954. +                }
  2955. +                if (self.ammo_cells)
  2956. +                {
  2957. +                        s = ftos(self.ammo_cells);
  2958. +                        sprint (other, s);
  2959. +                        sprint (other, " cells  ");
  2960. +                }
  2961.      
  2962. -    sprint (other, "\n");
  2963. +                sprint (other, "\n");
  2964.  // backpack touch sound
  2965. -    sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  2966. -    stuffcmd (other, "bf\n");
  2967. +                sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  2968. +                stuffcmd (other, "bf\n");
  2969.  
  2970.  // change to a better weapon if appropriate
  2971. -    if ( other.weapon == best )
  2972. -    {
  2973. -        stemp = self;
  2974. -        self = other;
  2975. -        self.weapon = W_BestWeapon();
  2976. -        self = stemp;
  2977. -    }
  2978. -
  2979. +                if ( other.weapon == best )
  2980. +                {
  2981. +                        stemp = self;
  2982. +                        self = other;
  2983. +                        self.weapon = W_BestWeapon();
  2984. +                        W_SetCurrentAmmo ();
  2985. +                        self = stemp;
  2986. +                }
  2987. +
  2988. +        }
  2989. +        if (other.classname == "bot")
  2990. +        {
  2991. +                if (other.weapon == bbest)
  2992. +                {
  2993. +                        stemp = self;
  2994. +                        self = other;
  2995. +                        self.weapon = bot_bestweapon();
  2996. +                        bot_SetCurrentAmmo();
  2997. +                        self = stemp;
  2998. +                }
  2999. +                stemp = self;
  3000. +                self = other;
  3001. +                bot_SetCurrentAmmo();
  3002. +                self = stemp;
  3003. +        }
  3004.      
  3005.      remove(self);
  3006.      
  3007.      self = other;
  3008. -    W_SetCurrentAmmo ();
  3009.  };
  3010.  
  3011.  /*
  3012. diff -ur --new-file d:\quakestu\qcc\send\v101qc/plats.qc backup4/plats.qc
  3013. --- d:\quakestu\qcc\send\v101qc/plats.qc    Wed Jul 24 23:51:24 1996
  3014. +++ backup4/plats.qc    Wed Aug 21 20:56:46 1996
  3015. @@ -72,7 +72,8 @@
  3016.  
  3017.  void() plat_center_touch =
  3018.  {
  3019. -    if (other.classname != "player")
  3020. +// TM Bot - added recognition of "bot" classname
  3021. +    if ((other.classname != "player") && (other.classname != "bot"))
  3022.          return;
  3023.          
  3024.      if (other.health <= 0)
  3025. @@ -87,7 +88,8 @@
  3026.  
  3027.  void() plat_outside_touch =
  3028.  {
  3029. -    if (other.classname != "player")
  3030. +// TM Bot - added recognition of "bot" classname
  3031. +    if ((other.classname != "player") && (other.classname != "bot"))
  3032.          return;
  3033.  
  3034.      if (other.health <= 0)
  3035. diff -ur --new-file d:\quakestu\qcc\send\v101qc/player.qc backup4/player.qc
  3036. --- d:\quakestu\qcc\send\v101qc/player.qc    Wed Jul 24 23:51:24 1996
  3037. +++ backup4/player.qc    Mon Aug 26 00:38:20 1996
  3038. @@ -544,6 +544,7 @@
  3039.      if (self.velocity_z < 10)
  3040.          self.velocity_z = self.velocity_z + random()*300;
  3041.  
  3042. +    
  3043.      if (self.health < -40)
  3044.      {
  3045.          GibPlayer ();
  3046. diff -ur --new-file d:\quakestu\qcc\send\v101qc/progs.src backup4/progs.src
  3047. --- d:\quakestu\qcc\send\v101qc/progs.src    Wed Jul 24 23:51:28 1996
  3048. +++ backup4/progs.src    Sun Sep  1 20:31:42 1996
  3049. @@ -1,21 +1,33 @@
  3050.  ../progs.dat
  3051.  
  3052. -defs.qc
  3053. -subs.qc
  3054. +defs.qc        // Modified - TM Bot
  3055. +
  3056. +// TM Bot Header File
  3057. +bot.h
  3058. +
  3059. +subs.qc        // Modified - TM Bot
  3060.  fight.qc
  3061.  ai.qc
  3062.  combat.qc
  3063.  items.qc
  3064. -weapons.qc
  3065. -world.qc
  3066. -client.qc
  3067. -player.qc
  3068. +
  3069. +// TM Bot source code
  3070. +botai.qc
  3071. +bot.qc
  3072. +
  3073. +weapons.qc    // Modified - TM Bot
  3074. +world.qc    // Modified - TM Bot
  3075. +client.qc    // Modified - TM Bot
  3076. +player.qc    // Modified - TM Bot
  3077.  monsters.qc
  3078.  doors.qc
  3079.  buttons.qc
  3080. -triggers.qc
  3081. -plats.qc
  3082. +triggers.qc    // Modified - TM Bot
  3083. +plats.qc    // Modified - TM Bot
  3084.  misc.qc
  3085. +
  3086. +// TM Bot extensions
  3087. +bot_ext.qc
  3088.  
  3089.  ogre.qc
  3090.  demon.qc
  3091. diff -ur --new-file d:\quakestu\qcc\send\v101qc/subs.qc backup4/subs.qc
  3092. --- d:\quakestu\qcc\send\v101qc/subs.qc    Wed Jul 24 23:51:24 1996
  3093. +++ backup4/subs.qc    Wed Aug 21 20:49:40 1996
  3094. @@ -1,5 +1,3 @@
  3095. -
  3096. -
  3097.  void() SUB_Null = {};
  3098.  
  3099.  void() SUB_Remove = {remove(self);};
  3100. @@ -238,6 +236,16 @@
  3101.          if (!self.noise)
  3102.              sound (activator, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
  3103.      }
  3104. +
  3105. +// TM Bot - begin new code 
  3106. +    if (activator.classname == "bot" && self.message != "")
  3107. +    {
  3108. +        sprint (activator.owner, "Incoming message from bot:\n");
  3109. +        centerprint (activator.owner, self.message);
  3110. +        if (!self.noise)
  3111. +            sound (activator.owner, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
  3112. +    }
  3113. +// TM Bot - end new code
  3114.  
  3115.  //
  3116.  // kill the killtagets
  3117. diff -ur --new-file d:\quakestu\qcc\send\v101qc/triggers.qc backup4/triggers.qc
  3118. --- d:\quakestu\qcc\send\v101qc/triggers.qc    Wed Jul 24 23:51:24 1996
  3119. +++ backup4/triggers.qc    Sun Sep  1 00:04:02 1996
  3120. @@ -36,8 +36,11 @@
  3121.  
  3122.      if (self.classname == "trigger_secret")
  3123.      {
  3124. -        if (self.enemy.classname != "player")
  3125. +// TM Bot - added recognition of "bot" classname
  3126. +                if ((self.enemy.classname != "player") && (self.enemy.classname != "bot"))
  3127.              return;
  3128. +        if (self.enemy.classname != "bot") // otherwise owner might not know
  3129. +            centerprint (self.enemy.owner, "bot found a secret!\n");
  3130.          found_secrets = found_secrets + 1;
  3131.          WriteByte (MSG_ALL, SVC_FOUNDSECRET);
  3132.      }
  3133. @@ -80,7 +83,8 @@
  3134.  
  3135.  void() multi_touch =
  3136.  {
  3137. -    if (other.classname != "player")
  3138. +// TM Bot - added recognition of "bot" classname
  3139. +        if ((other.classname != "player") && (other.classname != "bot"))
  3140.          return;
  3141.      
  3142.  // if the trigger has an angles field, check player's facing direction
  3143. @@ -221,6 +225,13 @@
  3144.  
  3145.  void() counter_use =
  3146.  {
  3147. +// TM Bot - uses the bot_ext.qc version of counter_use for bots
  3148. +    if (activator.classname == "bot")
  3149. +    {
  3150. +        bot_counter_use ();
  3151. +        return;
  3152. +    }
  3153. +
  3154.      local string junk;
  3155.  
  3156.      self.count = self.count - 1;
  3157. @@ -321,11 +332,13 @@
  3158.          return;
  3159.  
  3160.  // frag anyone who teleports in on top of an invincible player
  3161. -    if (other.classname == "player")
  3162. +
  3163. +// TM Bot - added recognition for classname "bot"
  3164. +        if ((other.classname == "player") || (other.classname == "bot"))
  3165.      {
  3166.          if (other.invincible_finished > time)
  3167.              self.classname = "teledeath2";
  3168. -        if (self.owner.classname != "player")
  3169. +                if ((self.owner.classname != "player") && (self.owner.classname != "bot"))
  3170.          {    // other monsters explode themselves
  3171.              T_Damage (self.owner, self, self, 50000);
  3172.              return;
  3173. @@ -337,7 +350,7 @@
  3174.      {
  3175.          T_Damage (other, self, self, 50000);
  3176.      }
  3177. -};
  3178. +};                                                                                   
  3179.  
  3180.  
  3181.  void(vector org, entity death_owner) spawn_tdeath =
  3182. @@ -374,7 +387,8 @@
  3183.  
  3184.      if (self.spawnflags & PLAYER_ONLY)
  3185.      {
  3186. -        if (other.classname != "player")
  3187. +// TM Bot - added recognition for classname "bot"
  3188. +                if ((other.classname != "player") && (other.classname != "bot"))
  3189.              return;
  3190.      }
  3191.  
  3192. @@ -408,7 +422,8 @@
  3193.  
  3194.      setorigin (other, t.origin);
  3195.      other.angles = t.mangle;
  3196. -    if (other.classname == "player")
  3197. +// TM Bot - added recognition of "bot" classname
  3198. +        if ((other.classname == "player") || (other.classname == "bot"))
  3199.      {
  3200.          other.fixangle = 1;        // turn this way immediately
  3201.          other.teleport_time = time + 0.7;
  3202. @@ -474,7 +489,7 @@
  3203.  
  3204.  void() trigger_skill_touch =
  3205.  {
  3206. -    if (other.classname != "player")
  3207. +        if ((other.classname != "player") && (other.classname != "bot"))
  3208.          return;
  3209.          
  3210.      cvar_set ("skill", self.message);
  3211. @@ -501,6 +516,13 @@
  3212.  
  3213.  void() trigger_onlyregistered_touch =
  3214.  {
  3215. +// TM Bot - uses bot_ext.qc version for bots
  3216. +    if (other.classname == "bot")
  3217. +    {
  3218. +        bot_trigger_onlyregistered_touch ();
  3219. +        return;
  3220. +    }
  3221. +
  3222.      if (other.classname != "player")
  3223.          return;
  3224.      if (self.attack_finished > time)
  3225. @@ -578,12 +600,18 @@
  3226.      else if (other.health > 0)
  3227.      {
  3228.          other.velocity = self.speed * self.movedir * 10;
  3229. -        if (other.classname == "player")
  3230. +
  3231. +// TM Bot - added recognition of "bot" classname
  3232. +                if ((other.classname == "player") || (other.classname == "bot"))
  3233.          {
  3234.              if (other.fly_sound < time)
  3235.              {
  3236.                  other.fly_sound = time + 1.5;
  3237.                  sound (other, CHAN_AUTO, "ambience/windfly.wav", 1, ATTN_NORM);
  3238. +
  3239. +// TM Bot - added notification for the bot's owner
  3240. +                if (other.classname == "bot")
  3241. +                    sprint (other.owner, "bot pushed a trigger\n");
  3242.              }
  3243.          }
  3244.      }
  3245. diff -ur --new-file d:\quakestu\qcc\send\v101qc/weapons.qc backup4/weapons.qc
  3246. --- d:\quakestu\qcc\send\v101qc/weapons.qc    Wed Aug  7 17:10:06 1996
  3247. +++ backup4/weapons.qc    Thu Aug 29 05:48:00 1996
  3248. @@ -52,7 +52,7 @@
  3249.          SpawnBlood (org, '0 0 0', 20);
  3250.          T_Damage (trace_ent, self, self, 20);
  3251.      }
  3252. -    else
  3253. +        else
  3254.      {    // hit wall
  3255.          sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
  3256.          WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  3257. @@ -221,7 +221,7 @@
  3258.          WriteCoord (MSG_BROADCAST, org_x);
  3259.          WriteCoord (MSG_BROADCAST, org_y);
  3260.          WriteCoord (MSG_BROADCAST, org_z);
  3261. -        }
  3262. +    }
  3263.  };
  3264.  
  3265.  /*
  3266. @@ -436,8 +436,8 @@
  3267.          particle (trace_endpos, '0 0 100', 225, damage*4);
  3268.          T_Damage (trace_ent, from, from, damage);
  3269.          if (self.classname == "player")
  3270. -        {
  3271. -            if (other.classname == "player")
  3272. +                {
  3273. +                        if ((other.classname == "player") || (other.classname == "bot"))
  3274.                  trace_ent.velocity_z = trace_ent.velocity_z + 400;
  3275.          }
  3276.      }
  3277. @@ -1160,6 +1160,11 @@
  3278.  */
  3279.  void() ImpulseCommands =
  3280.  {
  3281. +
  3282. +// New code
  3283. +//        CheckSecondaryImpulseCommands();
  3284. +
  3285. +
  3286.      if (self.impulse >= 1 && self.impulse <= 8)
  3287.          W_ChangeWeapon ();
  3288.  
  3289. diff -ur --new-file d:\quakestu\qcc\send\v101qc/world.qc backup4/world.qc
  3290. --- d:\quakestu\qcc\send\v101qc/world.qc    Wed Jul 24 23:51:24 1996
  3291. +++ backup4/world.qc    Wed Aug 21 22:41:56 1996
  3292. @@ -287,6 +287,9 @@
  3293.      precache_model ("progs/zom_gib.mdl");
  3294.  
  3295.      precache_model ("progs/v_light.mdl");
  3296. +
  3297. +// TM Bot - precaches for the bot
  3298. +    Bot_Precache ();
  3299.      
  3300.  
  3301.  //
  3302.