]> icculus.org git repositories - divverent/nexuiz.git/blob - qcsrc/gamec/bot_misc.c
Got rid of sparks
[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 void() bot_chat =
272 {
273         local float r;
274 //      if (b_options & OPT_NOCHAT)
275                 return;
276         r = ceil (random() * 6);
277
278         if (self.b_chattime > time)
279         {
280                 if (self.b_skill < 2)
281                         self.keys = self.button0 = self.button2 = 0;
282                 return;
283         }
284         else if (self.b_chattime)
285         {
286                 if (b_topic == 1)
287                 {
288                         if (b_originator == self)
289                         {
290                                 if (r == 1)
291                                 {
292                                         BotSay(": lo all\n");
293                                         bot_start_topic(8);
294                                 }
295                                 else if (r == 2)
296                                 {
297                                         BotSay(": hey everyone\n");
298                                         bot_start_topic(8);
299                                 }
300                                 else if (r == 3)
301                                 {
302                                         BotSay(": prepare to be fragged!\n");
303                                         bot_start_topic(0);
304                                 }
305                                 else if (r == 4)
306                                 {
307                                         BotSay(": boy this is laggy\n");
308                                         bot_start_topic(11);
309                                 }
310                                 else if (r == 5)
311                                 {
312                                         BotSay(": #mm getting some lag here\n");
313                                         bot_start_topic(11);
314                                 }
315                                 else
316                                 {
317                                         BotSay(": hi everyone\n");
318                                         bot_start_topic(8);
319                                 }
320                         }
321                 }
322                 else if (b_topic == 2)
323                 {
324                         if (b_originator == self)
325                         {
326                                 if (r == 1)
327                                         BotSay(": take that\n");
328                                 else if (r == 2)
329                                         BotSay(": yehaww!\n");
330                                 else if (r == 3)
331                                         BotSay(": wh00p\n");
332                                 else if (r == 4)
333                                         BotSay(": j00_sawk();\n");
334                                 else if (r == 5)
335                                         BotSay(": i rule\n");
336                                 else
337                                         BotSay(": eat that\n");
338                                 bot_start_topic(0);
339                         }
340                 }
341                 else if (b_topic == 3)
342                 {
343                         if (b_originator == self)
344                         {
345                                 if (r < 3)
346                                         BotSayTeam(": friendly eyes\n");
347                                 else
348                                         BotSayTeam(": team eyes\n");
349                                 bot_start_topic(0);
350                         }
351                 }
352                 else if (b_topic == 4)
353                 {
354                         if (b_originator == self)
355                         {
356                                 if (r < 3)
357                                         BotSayTeam(": on your back\n");
358                                 else
359                                         BotSayTeam(": I'm with you\n");
360                                 bot_start_topic(0);
361                         }
362                 }
363                 else if (b_topic == 5)
364                 {
365                         if (b_originator == self)
366                         {
367                                 if (r < 3)
368                                         BotSayTeam(": I need help\n");
369                                 else
370                                         BotSayTeam(": need backup\n");
371                                 bot_start_topic(0);
372                         }
373                 }
374                 else if (b_topic == 6)
375                 {
376                         if (b_originator == self)
377                         {
378                                 if (r == 1)
379                                 {
380                                         BotSay(": sun got in my eyes\n");
381                                         bot_start_topic(0);
382                                 }
383                                 else if (r == 2)
384                                 {
385                                         BotSay(": mouse needs cleaning\n");
386                                         bot_start_topic(0);
387                                 }
388                                 else if (r == 3)
389                                 {
390                                         BotSay(": i meant to do that\n");
391                                         bot_start_topic(0);
392                                 }
393                                 else if (r == 4)
394                                 {
395                                         BotSay(": lag\n");
396                                         bot_start_topic(11);
397                                 }
398                                 else if (r == 5)
399                                 {
400                                         BotSay(": killer lag\n");
401                                         bot_start_topic(11);
402                                 }
403                                 else
404                                 {
405                                         BotSay(": 100% lag\n");
406                                         bot_start_topic(11);
407                                 }
408                         }
409                 }
410                 else if (b_topic == 7)
411                 {
412                         if (r == 1)
413                                 BotSay(": gg\n");
414                         else if (r == 2)
415                                 BotSay(": gg all\n");
416                         else if (r == 3)
417                                 BotSay(": that was fun\n");
418                         else if (r == 4)
419                                 BotSay(": good game\n");
420                         else if (r == 5)
421                                 BotSay(": pah\n");
422                         else
423                                 BotSay(": hrm\n");
424                         bot_start_topic(0);
425                 }
426                 else if (b_topic == 8)
427                 {
428                         if (b_originator != self)
429                         {
430                                 if (r == 1)
431                                 {
432                                         BotSay(": heya\n");
433                                         bot_start_topic(0);
434                                 }
435                                 else if (r == 2)
436                                 {
437                                         BotSay(": welcome\n");
438                                         bot_start_topic(0);
439                                 }
440                                 else if (r == 3)
441                                 {
442                                         BotSayInit();
443                                         BotSay2(": hi ");
444                                         BotSay2(b_originator.netname);
445                                         BotSay2("\n");
446                                         bot_start_topic(0);
447                                 }
448                                 else if (r == 4)
449                                 {
450                                         BotSayInit();
451                                         BotSay2(": hey ");
452                                         BotSay2(b_originator.netname);
453                                         BotSay2("\n");
454                                         bot_start_topic(0);
455                                 }
456                                 else if (r == 5)
457                                 {
458                                         BotSay(": howdy\n");
459                                         bot_start_topic(0);
460                                 }
461                                 else
462                                 {
463                                         BotSay(": lo\n");
464                                         bot_start_topic(0);
465                                 }
466                         }
467                 }
468
469                 else if (b_topic == 9)
470                 {
471                         if (b_originator != self)
472                         {
473                                 if (r == 1)
474                                         BotSay(": hah\n");
475                                 else if (r == 2)
476                                         BotSay(": heheh\n");
477                                 else if (r == 3)
478                                 {
479                                         BotSayInit();
480                                         BotSay2(": good work ");
481                                         BotSay2(b_originator.netname);
482                                         BotSay2("\n");
483                                 }
484                                 else if (r == 4)
485                                 {
486                                         BotSayInit();
487                                         BotSay2(": nice1 ");
488                                         BotSay2(b_originator.netname);
489                                         BotSay2("\n");
490                                 }
491                                 else if (r == 5)
492                                         BotSay(": lol\n");
493                                 else
494                                         BotSay(": :)\n");
495                                 b_topic = 6;
496                         }
497                 }
498                 else if (b_topic == 10)
499                 {
500                         if (b_originator != self)
501                         {
502                                 if (r == 1)
503                                         BotSay(": have a nice dip?\n");
504                                 else if (r == 2)
505                                         BotSay(": bah I hate levels with lava\n");
506                                 else if (r == 3)
507                                 {
508                                         BotSayInit();
509                                         BotSay2(": good job ");
510                                         BotSay2(b_originator.netname);
511                                         BotSay2("\n");
512                                 }
513                                 else if (r == 4)
514                                 {
515                                         BotSayInit();
516                                         BotSay2(": nice backflip ");
517                                         BotSay2(b_originator.netname);
518                                         BotSay2("\n");
519                                 }
520                                 else if (r == 5)
521                                         BotSay(": watch your step\n");
522                                 else
523                                         BotSay(": hehe\n");
524                                 b_topic = 6;
525                         }
526                 }
527
528                 else if (b_topic == 11)
529                 {
530                         if (b_originator != self)
531                         {
532                                 if (r == 1)
533                                 {
534                                         BotSayInit();
535                                         BotSay2(": yeah right ");
536                                         BotSay2(b_originator.netname);
537                                         BotSay2("\n");
538                                         bot_start_topic(0);
539                                 }
540                                 else if (r == 2)
541                                 {
542                                         BotSay(": ping\n");
543                                         bot_start_topic(0);
544                                 }
545                                 else if (r == 3)
546                                 {
547                                         BotSay(": shuddup, you're an lpb\n");
548                                         bot_start_topic(0);
549                                 }
550                                 else if (r == 4)
551                                 {
552                                         BotSay(": lag my eye\n");
553                                         bot_start_topic(0);
554                                 }
555                                 else if (r == 5)
556                                 {
557                                         BotSay(": yeah\n");
558                                         bot_start_topic(11);
559                                 }
560                                 else
561                                 {
562                                         BotSay(": totally\n");
563                                         bot_start_topic(11);
564                                 }
565                         }
566                 }
567                 self.b_chattime = 0;
568         }
569         else if (b_topic)
570         {
571                 if (random() < 0.5)
572                 {
573                         if (self == b_originator)
574                         {
575                                 if (b_topic <= 7)
576                                         self.b_chattime = time + 2;
577                         }
578                         else
579                         {
580                                 if (b_topic >= 7)
581                                         self.b_chattime = time + 2;
582                         }
583                 }
584         }
585 };
586
587 /*
588 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
589
590 Kick A Bot.
591
592 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
593 */
594
595 void() KickABot =
596 {
597         local entity ty;
598         ty = find(world, classname, "player");
599         while (ty != world)
600         {
601                 if (!(ty.ishuman))
602                 {
603
604                         BotDisconnect(ty);
605                         ty.ishuman = TRUE;
606                         ty = world;
607                 }
608                 else
609                         ty = find(ty, classname, "player");
610         }
611
612 };
613
614
615 /*
616 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
617
618 Simplified origin checking.
619
620 God, I wish I had inline
621
622 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
623 */
624
625 vector(entity ent) realorigin =
626 {
627 // even more simplified...
628         return (ent.absmin + ent.absmax) * 0.5;
629 };
630
631 /*
632 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
633
634 fisible
635
636 a version of visible that checks for corners
637 of the bounding boxes
638
639 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
640 */
641
642 float (entity targ) fisible =
643 {
644         local vector    spot1, org;
645         local float thruwater, pc1, pc2;
646
647         org = realorigin(targ);
648         spot1 = self.origin + self.view_ofs;
649
650         if (targ.solid == SOLID_BSP)
651         {
652                 traceline (spot1, org, TRUE, self);
653                 if (trace_ent == targ)
654                         return TRUE;
655                 else if (trace_fraction == 1)
656                         return TRUE;
657                 return FALSE;
658         }
659         else
660         {
661                 pc1 = pointcontents(org);
662                 pc2 = pointcontents(spot1);
663                 if (targ.classname == "player")
664                         thruwater = FALSE;
665                 else if (pc1 == CONTENT_LAVA)
666                         return FALSE;
667                 else
668                         thruwater = TRUE;
669         }
670
671         if (pc1 < -1) // targ's origin is in water or other liquid
672         {
673                 if (pc2 != pc1)
674                 {
675                         // look for their head
676                         traceline (spot1, org + targ.mins, TRUE, self);
677                         // cross the water check
678                         if (trace_inopen)
679                                 if (trace_inwater)
680                                         if (!thruwater)
681                                                 return FALSE;
682                         if (trace_ent == targ)
683                                 return TRUE;
684                         else if (trace_fraction == 1)
685                                 return TRUE;
686                         return FALSE;
687                 }
688         }
689         else
690         {
691                 if (pc2 != pc1)
692                 {
693                         traceline (spot1, org + targ.maxs, TRUE, self);
694                         if (trace_inopen)
695                                 if (trace_inwater)
696                                         if (!thruwater)
697                                                 return FALSE;
698                         if (trace_ent == targ)
699                                 return TRUE;
700                         else if (trace_fraction == 1)
701                                 return TRUE;
702                         return FALSE;
703                 }
704         }
705         traceline (spot1, org, TRUE, self);
706         if (trace_ent == targ)
707                 return TRUE;
708         else if (trace_fraction == 1)
709                 return TRUE;
710         traceline (spot1, org + targ.maxs, TRUE, self);
711         if (trace_ent == targ)
712                 return TRUE;
713         else if (trace_fraction == 1)
714                 return TRUE;
715         traceline (spot1, org + targ.mins, TRUE, self);
716         if (trace_ent == targ)
717                 return TRUE;
718         else if (trace_fraction == 1)
719                 return TRUE;
720         return FALSE;
721 };
722
723
724 /*
725 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
726
727 Wisible
728
729 goes through movable brushes/entities, used
730 for waypoints
731
732 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
733 */
734
735 // this is used for waypoint stuff....
736 float (entity targ1, entity targ2) wisible =
737 {
738         local vector    spot1, spot2;
739         local entity ignore;
740
741         spot1 = targ1.origin;
742         spot2 = realorigin(targ2);
743
744         ignore = self;
745         do
746         {
747                 traceline (spot1, spot2, TRUE, ignore);
748                 spot1 = realorigin(trace_ent);
749                 ignore = trace_ent;
750         } while ((trace_ent != world) && (trace_fraction != 1));
751         if (trace_endpos == spot2)
752                 return TRUE;
753         else
754                 return FALSE;
755 };
756
757
758 /*
759 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
760
761 sisible
762
763 Now this is getting ridiculous. Simple visible,
764 used when we need just a simple traceline nothing else
765
766 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
767 */
768
769 float (entity targ) sisible =
770 {
771         traceline (self.origin, targ.origin, TRUE, self);
772         if (trace_ent == targ)
773                 return TRUE;
774         else if (trace_fraction == 1)
775                 return TRUE;
776         return FALSE;
777 };
778 /*
779 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
780
781 angcomp
782
783 subtracts one angle from another
784
785 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
786 */
787
788 float (float y1, float y2) angcomp =
789 {
790         y1 = frik_anglemod(y1);
791         y2 = frik_anglemod(y2);
792
793         local float answer;
794         answer = y1 - y2;
795         if (answer > 180)
796                 answer = (360 - answer) * -1;
797         else if (answer < -180)
798                 answer = answer + 360;
799         return answer;
800 };
801
802 /*
803 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
804
805 fov
806
807 is the entity in the bot's field of view
808
809 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
810 */
811 float (entity targ) fov =
812 {
813         local vector yawn;
814         local float g;
815         yawn = realorigin(targ);
816         yawn = (yawn + targ.view_ofs) - (self.origin + self.view_ofs);
817         yawn = normalize(yawn);
818         yawn = vectoangles(yawn);
819         g = angcomp(self.v_angle_x, yawn_x);
820         if (fabs(g) > 45)
821                 return FALSE;
822         g = angcomp(self.v_angle_y, yawn_y);
823         if (fabs(g) > 60)
824                 return FALSE;
825
826         return TRUE;
827 };
828
829 /*
830 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
831
832 frik_anglemod
833
834 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
835 */
836 float(float v) frik_anglemod =
837 {
838         return v - floor(v/360) * 360;
839 };