]> icculus.org git repositories - divverent/nexuiz.git/blob - qcsrc/gamec/bot_misc.c
implemented rocket and electro fly sounds
[divverent/nexuiz.git] / qcsrc / gamec / bot_misc.c
1 /***********************************************
2 *                                              *
3 *              FrikBot Misc Code               *
4 *   "Because you can't name it anything else"  *
5 *                                              *
6 ***********************************************/
7
8 /*
9 This program is in the Public Domain. My crack legal
10 team would like to add:
11
12 RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS"
13 AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE
14 ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR
15 FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN
16 NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY
17 GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL,
18 EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC"
19 SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
20 DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES.
21
22 You accept this software on the condition that you
23 indemnify and hold harmless Ryan "FrikaC" Smith from
24 any and all liability or damages to third parties,
25 including attorney fees, court costs, and other
26 related costs and expenses, arising out of your use
27 of this software irrespective of the cause of said
28 liability.
29
30 The export from the United States or the subsequent
31 reexport of this software is subject to compliance
32 with United States export control and munitions
33 control restrictions. You agree that in the event you
34 seek to export this software, you assume full
35 responsibility for obtaining all necessary export
36 licenses and approvals and for assuring compliance
37 with applicable reexport restrictions.
38
39 Any reproduction of this software must contain
40 this notice in its entirety.
41
42 */
43
44 /*
45 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
46
47 BotName
48
49 Sets bot's name and colors
50
51 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
52 */
53 string(float r) BotName =
54 {
55         self.b_num = r;
56         if (r == 1)
57         {
58                 self.playermodel = "models/player/visitant.zym";
59                 self.playerskin = "0";
60                 return "Visitant";
61         }
62         else if (r == 2)
63         {
64                 self.playermodel = "models/player/marine.zym";
65                 self.playerskin = "0";
66                 return "Marine";
67         }
68         else if (r == 3)
69         {
70                 self.playermodel = "models/player/specop.zym";
71                 self.playerskin = "0";
72                 return "Specop";
73         }
74         else if (r == 4)
75         {
76                 self.playermodel = "models/player/nexus.zym";
77                 self.playerskin = "0";
78                 return "Nexus";
79         }
80         else if (r == 5)
81         {
82                 self.playermodel = "models/player/skadi.zym";
83                 self.playerskin = "0";
84                 return "Skadi";
85         }
86         else if (r == 6)
87         {
88                 self.playermodel = "models/player/lurk.zym";
89                 self.playerskin = "0";
90                 return "Lurk";
91         }
92         else if (r == 7)
93         {
94                 self.playermodel = "models/player/headhunter.zym";
95                 self.playerskin = "0";
96                 return "HeadHunter";
97         }
98         else if (r == 8)
99         {
100                 self.playermodel = "models/player/carni.zym";
101                 self.playerskin = "0";
102                 return "Carni";
103         }
104         else if (r == 9)
105         {
106                 self.playermodel = "models/player/grunt.zym";
107                 self.playerskin = "0";
108                 return "Grunt";
109         }
110         else if (r == 10)
111         {
112                 self.playermodel = "models/player/insurrectionist.zym";
113                 self.playerskin = "0";
114                 return "Insurrectionist";
115         }
116         else if (r == 11)
117         {
118                 self.playermodel = "models/player/jeandarc.zym";
119                 self.playerskin = "0";
120                 return "Jeandarc";
121         }
122         else if (r == 12)
123         {
124                 self.playermodel = "models/player/lycanthrope.zym";
125                 self.playerskin = "0";
126                 return "Lycanthrope";
127         }
128         else if (r == 13)
129         {
130                 self.playermodel = "models/player/pyria.zym";
131                 self.playerskin = "0";
132                 return "Pyria";
133         }
134         else if (r == 14)
135         {
136                 self.playermodel = "models/player/shock.zym";
137                 self.playerskin = "0";
138                 return "Shock";
139         }
140         else if (r == 15)
141         {
142                 self.playermodel = "models/player/marine.zym";
143                 self.playerskin = "1";
144                 return "Private";
145         }
146         else if (r == 16)
147         {
148                 self.playermodel = "models/player/nexus.zym";
149                 self.playerskin = "1";
150                 return "Mulder";
151         }
152         else if (r == 17)
153         {
154                 self.playermodel = "models/player/skadi.zym";
155                 self.playerskin = "1";
156                 return "Elite";
157         }
158         else if (r == 18)
159         {
160                 self.playermodel = "models/player/lurk.zym";
161                 self.playerskin = "1";
162                 return "Reptile";
163         }
164         else if (r == 19)
165         {
166                 self.playermodel = "models/player/crash.zym";
167                 self.playerskin = "2";
168                 return "mechanical";
169         }
170         else if (r == 20)
171         {
172                 self.playermodel = "models/player/crash.zym";
173                 self.playerskin = "1";
174                 return "Quark";
175         }
176         else if (r == 21)
177         {
178                 self.playermodel = "models/player/insurrectionist.zym";
179                 self.playerskin = "1";
180                 return "Anarchist";
181         }
182         else if (r == 22)
183         {
184                 self.playermodel = "models/player/jeandarc.zym";
185                 self.playerskin = "1";
186                 return "Heroine";
187         }
188         else if (r == 23)
189         {
190                 self.playermodel = "models/player/lycanthrope.zym";
191                 self.playerskin = "1";
192                 return "Wolf";
193         }
194         else if (r == 24)
195         {
196                 self.playermodel = "models/player/pyria.zym";
197                 self.playerskin = "1";
198                 return "Soldier";
199         }
200         else if (r == 25)
201         {
202                 self.playermodel = "models/player/rebel.zym";
203                 self.playerskin = "0";
204                 return "Rebel";
205         }
206         else
207         {
208                 self.playermodel = "models/player/crash.zym";
209                 self.playerskin = "0";
210                 return "Crash";
211         }
212
213 };
214 string () PickARandomName =
215 {
216         if (bot_count > 16)
217                 return "player";
218
219         local float y, test;
220         local string h;
221         local entity t;
222         y = TRUE;
223         while(y)
224         {
225                 test = ceil(random() * 16);
226                 h = BotName(test);
227                 t = find(world, netname, h);
228                 if (t == world)
229                         y = FALSE;
230         }
231         return h;
232 };
233
234
235
236 // I didn't like the old code so this is very stripped down
237
238 entity b_originator;
239 float b_topic;
240 /* FBX Topics
241
242 b_originator == self
243  1 - sign on
244  2 - killed targ
245  3 - team message "friendly eyes"
246  4 - team message "on your back"
247  5 - team message "need back up"
248  6 - excuses
249  ----
250  7 - gameover
251  ----
252  8 - welcoming someone onto server
253  9 - ridicule lost frag (killed self?)
254  10 - ridicule lost frag (lava)
255  11 - lag
256 b_originator == targ
257
258
259 */
260 void(float tpic) bot_start_topic =
261 {
262         if (random() < 0.2)
263         {
264                 b_topic = tpic;
265                 b_originator = self;
266         }
267         else
268                 b_topic = 0;
269 };
270
271 /*
272 void() bot_chat =
273 {
274         local float r;
275         if (b_options & OPT_NOCHAT)
276                 return;
277         r = ceil (random() * 6);
278
279         if (self.b_chattime > time)
280         {
281                 if (self.b_skill < 2)
282                         self.keys = self.button0 = self.button2 = 0;
283                 return;
284         }
285         else if (self.b_chattime)
286         {
287                 if (b_topic == 1)
288                 {
289                         if (b_originator == self)
290                         {
291                                 if (r == 1)
292                                 {
293                                         BotSay(": lo all\n");
294                                         bot_start_topic(8);
295                                 }
296                                 else if (r == 2)
297                                 {
298                                         BotSay(": hey everyone\n");
299                                         bot_start_topic(8);
300                                 }
301                                 else if (r == 3)
302                                 {
303                                         BotSay(": prepare to be fragged!\n");
304                                         bot_start_topic(0);
305                                 }
306                                 else if (r == 4)
307                                 {
308                                         BotSay(": boy this is laggy\n");
309                                         bot_start_topic(11);
310                                 }
311                                 else if (r == 5)
312                                 {
313                                         BotSay(": #mm getting some lag here\n");
314                                         bot_start_topic(11);
315                                 }
316                                 else
317                                 {
318                                         BotSay(": hi everyone\n");
319                                         bot_start_topic(8);
320                                 }
321                         }
322                 }
323                 else if (b_topic == 2)
324                 {
325                         if (b_originator == self)
326                         {
327                                 if (r == 1)
328                                         BotSay(": take that\n");
329                                 else if (r == 2)
330                                         BotSay(": yehaww!\n");
331                                 else if (r == 3)
332                                         BotSay(": wh00p\n");
333                                 else if (r == 4)
334                                         BotSay(": j00_sawk();\n");
335                                 else if (r == 5)
336                                         BotSay(": i rule\n");
337                                 else
338                                         BotSay(": eat that\n");
339                                 bot_start_topic(0);
340                         }
341                 }
342                 else if (b_topic == 3)
343                 {
344                         if (b_originator == self)
345                         {
346                                 if (r < 3)
347                                         BotSayTeam(": friendly eyes\n");
348                                 else
349                                         BotSayTeam(": team eyes\n");
350                                 bot_start_topic(0);
351                         }
352                 }
353                 else if (b_topic == 4)
354                 {
355                         if (b_originator == self)
356                         {
357                                 if (r < 3)
358                                         BotSayTeam(": on your back\n");
359                                 else
360                                         BotSayTeam(": I'm with you\n");
361                                 bot_start_topic(0);
362                         }
363                 }
364                 else if (b_topic == 5)
365                 {
366                         if (b_originator == self)
367                         {
368                                 if (r < 3)
369                                         BotSayTeam(": I need help\n");
370                                 else
371                                         BotSayTeam(": need backup\n");
372                                 bot_start_topic(0);
373                         }
374                 }
375                 else if (b_topic == 6)
376                 {
377                         if (b_originator == self)
378                         {
379                                 if (r == 1)
380                                 {
381                                         BotSay(": sun got in my eyes\n");
382                                         bot_start_topic(0);
383                                 }
384                                 else if (r == 2)
385                                 {
386                                         BotSay(": mouse needs cleaning\n");
387                                         bot_start_topic(0);
388                                 }
389                                 else if (r == 3)
390                                 {
391                                         BotSay(": i meant to do that\n");
392                                         bot_start_topic(0);
393                                 }
394                                 else if (r == 4)
395                                 {
396                                         BotSay(": lag\n");
397                                         bot_start_topic(11);
398                                 }
399                                 else if (r == 5)
400                                 {
401                                         BotSay(": killer lag\n");
402                                         bot_start_topic(11);
403                                 }
404                                 else
405                                 {
406                                         BotSay(": 100% lag\n");
407                                         bot_start_topic(11);
408                                 }
409                         }
410                 }
411                 else if (b_topic == 7)
412                 {
413                         if (r == 1)
414                                 BotSay(": gg\n");
415                         else if (r == 2)
416                                 BotSay(": gg all\n");
417                         else if (r == 3)
418                                 BotSay(": that was fun\n");
419                         else if (r == 4)
420                                 BotSay(": good game\n");
421                         else if (r == 5)
422                                 BotSay(": pah\n");
423                         else
424                                 BotSay(": hrm\n");
425                         bot_start_topic(0);
426                 }
427                 else if (b_topic == 8)
428                 {
429                         if (b_originator != self)
430                         {
431                                 if (r == 1)
432                                 {
433                                         BotSay(": heya\n");
434                                         bot_start_topic(0);
435                                 }
436                                 else if (r == 2)
437                                 {
438                                         BotSay(": welcome\n");
439                                         bot_start_topic(0);
440                                 }
441                                 else if (r == 3)
442                                 {
443                                         BotSayInit();
444                                         BotSay2(": hi ");
445                                         BotSay2(b_originator.netname);
446                                         BotSay2("\n");
447                                         bot_start_topic(0);
448                                 }
449                                 else if (r == 4)
450                                 {
451                                         BotSayInit();
452                                         BotSay2(": hey ");
453                                         BotSay2(b_originator.netname);
454                                         BotSay2("\n");
455                                         bot_start_topic(0);
456                                 }
457                                 else if (r == 5)
458                                 {
459                                         BotSay(": howdy\n");
460                                         bot_start_topic(0);
461                                 }
462                                 else
463                                 {
464                                         BotSay(": lo\n");
465                                         bot_start_topic(0);
466                                 }
467                         }
468                 }
469
470                 else if (b_topic == 9)
471                 {
472                         if (b_originator != self)
473                         {
474                                 if (r == 1)
475                                         BotSay(": hah\n");
476                                 else if (r == 2)
477                                         BotSay(": heheh\n");
478                                 else if (r == 3)
479                                 {
480                                         BotSayInit();
481                                         BotSay2(": good work ");
482                                         BotSay2(b_originator.netname);
483                                         BotSay2("\n");
484                                 }
485                                 else if (r == 4)
486                                 {
487                                         BotSayInit();
488                                         BotSay2(": nice1 ");
489                                         BotSay2(b_originator.netname);
490                                         BotSay2("\n");
491                                 }
492                                 else if (r == 5)
493                                         BotSay(": lol\n");
494                                 else
495                                         BotSay(": :)\n");
496                                 b_topic = 6;
497                         }
498                 }
499                 else if (b_topic == 10)
500                 {
501                         if (b_originator != self)
502                         {
503                                 if (r == 1)
504                                         BotSay(": have a nice dip?\n");
505                                 else if (r == 2)
506                                         BotSay(": bah I hate levels with lava\n");
507                                 else if (r == 3)
508                                 {
509                                         BotSayInit();
510                                         BotSay2(": good job ");
511                                         BotSay2(b_originator.netname);
512                                         BotSay2("\n");
513                                 }
514                                 else if (r == 4)
515                                 {
516                                         BotSayInit();
517                                         BotSay2(": nice backflip ");
518                                         BotSay2(b_originator.netname);
519                                         BotSay2("\n");
520                                 }
521                                 else if (r == 5)
522                                         BotSay(": watch your step\n");
523                                 else
524                                         BotSay(": hehe\n");
525                                 b_topic = 6;
526                         }
527                 }
528
529                 else if (b_topic == 11)
530                 {
531                         if (b_originator != self)
532                         {
533                                 if (r == 1)
534                                 {
535                                         BotSayInit();
536                                         BotSay2(": yeah right ");
537                                         BotSay2(b_originator.netname);
538                                         BotSay2("\n");
539                                         bot_start_topic(0);
540                                 }
541                                 else if (r == 2)
542                                 {
543                                         BotSay(": ping\n");
544                                         bot_start_topic(0);
545                                 }
546                                 else if (r == 3)
547                                 {
548                                         BotSay(": shuddup, you're an lpb\n");
549                                         bot_start_topic(0);
550                                 }
551                                 else if (r == 4)
552                                 {
553                                         BotSay(": lag my eye\n");
554                                         bot_start_topic(0);
555                                 }
556                                 else if (r == 5)
557                                 {
558                                         BotSay(": yeah\n");
559                                         bot_start_topic(11);
560                                 }
561                                 else
562                                 {
563                                         BotSay(": totally\n");
564                                         bot_start_topic(11);
565                                 }
566                         }
567                 }
568                 self.b_chattime = 0;
569         }
570         else if (b_topic)
571         {
572                 if (random() < 0.5)
573                 {
574                         if (self == b_originator)
575                         {
576                                 if (b_topic <= 7)
577                                         self.b_chattime = time + 2;
578                         }
579                         else
580                         {
581                                 if (b_topic >= 7)
582                                         self.b_chattime = time + 2;
583                         }
584                 }
585         }
586 };
587 */
588
589 /*
590 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
591
592 Kick A Bot.
593
594 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
595 */
596
597 void() KickABot =
598 {
599         local entity ty;
600         ty = find(world, classname, "player");
601         while (ty != world)
602         {
603                 if (!(ty.ishuman))
604                 {
605
606                         BotDisconnect(ty);
607                         ty.ishuman = TRUE;
608                         ty = world;
609                 }
610                 else
611                         ty = find(ty, classname, "player");
612         }
613
614 };
615
616
617 /*
618 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
619
620 Simplified origin checking.
621
622 God, I wish I had inline
623
624 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
625 */
626
627 vector(entity ent) realorigin =
628 {
629 // even more simplified...
630         return (ent.absmin + ent.absmax) * 0.5;
631 };
632
633 /*
634 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
635
636 fisible
637
638 a version of visible that checks for corners
639 of the bounding boxes
640
641 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
642 */
643
644 float (entity targ) fisible =
645 {
646         local vector    spot1, org;
647         local float thruwater, pc1, pc2;
648
649         org = realorigin(targ);
650         spot1 = self.origin + self.view_ofs;
651
652         if (targ.solid == SOLID_BSP)
653         {
654                 traceline (spot1, org, TRUE, self);
655                 if (trace_ent == targ)
656                         return TRUE;
657                 else if (trace_fraction == 1)
658                         return TRUE;
659                 return FALSE;
660         }
661         else
662         {
663                 pc1 = pointcontents(org);
664                 pc2 = pointcontents(spot1);
665                 if (targ.classname == "player")
666                         thruwater = FALSE;
667                 else if (pc1 == CONTENT_LAVA)
668                         return FALSE;
669                 else
670                         thruwater = TRUE;
671         }
672
673         if (pc1 < -1) // targ's origin is in water or other liquid
674         {
675                 if (pc2 != pc1)
676                 {
677                         // look for their head
678                         traceline (spot1, org + targ.mins, TRUE, self);
679                         // cross the water check
680                         if (trace_inopen)
681                                 if (trace_inwater)
682                                         if (!thruwater)
683                                                 return FALSE;
684                         if (trace_ent == targ)
685                                 return TRUE;
686                         else if (trace_fraction == 1)
687                                 return TRUE;
688                         return FALSE;
689                 }
690         }
691         else
692         {
693                 if (pc2 != pc1)
694                 {
695                         traceline (spot1, org + targ.maxs, TRUE, self);
696                         if (trace_inopen)
697                                 if (trace_inwater)
698                                         if (!thruwater)
699                                                 return FALSE;
700                         if (trace_ent == targ)
701                                 return TRUE;
702                         else if (trace_fraction == 1)
703                                 return TRUE;
704                         return FALSE;
705                 }
706         }
707         traceline (spot1, org, TRUE, self);
708         if (trace_ent == targ)
709                 return TRUE;
710         else if (trace_fraction == 1)
711                 return TRUE;
712         traceline (spot1, org + targ.maxs, TRUE, self);
713         if (trace_ent == targ)
714                 return TRUE;
715         else if (trace_fraction == 1)
716                 return TRUE;
717         traceline (spot1, org + targ.mins, TRUE, self);
718         if (trace_ent == targ)
719                 return TRUE;
720         else if (trace_fraction == 1)
721                 return TRUE;
722         return FALSE;
723 };
724
725
726 /*
727 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
728
729 Wisible
730
731 goes through movable brushes/entities, used
732 for waypoints
733
734 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
735 */
736
737 // this is used for waypoint stuff....
738 float (entity targ1, entity targ2) wisible =
739 {
740         local vector    spot1, spot2;
741         local entity ignore;
742
743         spot1 = targ1.origin;
744         spot2 = realorigin(targ2);
745
746         ignore = self;
747         do
748         {
749                 traceline (spot1, spot2, TRUE, ignore);
750                 spot1 = realorigin(trace_ent);
751                 ignore = trace_ent;
752         } while ((trace_ent != world) && (trace_fraction != 1));
753         if (trace_endpos == spot2)
754                 return TRUE;
755         else
756                 return FALSE;
757 };
758
759
760 /*
761 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
762
763 sisible
764
765 Now this is getting ridiculous. Simple visible,
766 used when we need just a simple traceline nothing else
767
768 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
769 */
770
771 float (entity targ) sisible =
772 {
773         traceline (self.origin, targ.origin, TRUE, self);
774         if (trace_ent == targ)
775                 return TRUE;
776         else if (trace_fraction == 1)
777                 return TRUE;
778         return FALSE;
779 };
780 /*
781 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
782
783 angcomp
784
785 subtracts one angle from another
786
787 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
788 */
789
790 float (float y1, float y2) angcomp =
791 {
792         y1 = frik_anglemod(y1);
793         y2 = frik_anglemod(y2);
794
795         local float answer;
796         answer = y1 - y2;
797         if (answer > 180)
798                 answer = (360 - answer) * -1;
799         else if (answer < -180)
800                 answer = answer + 360;
801         return answer;
802 };
803
804 /*
805 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
806
807 fov
808
809 is the entity in the bot's field of view
810
811 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
812 */
813 float (entity targ) fov =
814 {
815         local vector yawn;
816         local float g;
817         yawn = realorigin(targ);
818         yawn = (yawn + targ.view_ofs) - (self.origin + self.view_ofs);
819         yawn = normalize(yawn);
820         yawn = vectoangles(yawn);
821         g = angcomp(self.v_angle_x, yawn_x);
822         if (fabs(g) > 45)
823                 return FALSE;
824         g = angcomp(self.v_angle_y, yawn_y);
825         if (fabs(g) > 60)
826                 return FALSE;
827
828         return TRUE;
829 };
830
831 /*
832 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
833
834 frik_anglemod
835
836 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
837 */
838 float(float v) frik_anglemod =
839 {
840         return v - floor(v/360) * 360;
841 };