1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 Copyright (C) 20?? COR Entertainment, LLC.
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
14 See the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "g_local.h"
26
27 typedef struct
28 {
29 char *name;
30 void (*spawn)(edict_t *ent);
31 } spawn_t;
32
33 spawn_t spawns[] = {
34 {"item_health", SP_item_health},
35 {"item_health_small", SP_item_health_small},
36 {"item_health_large", SP_item_health_large},
37 {"item_health_mega", SP_item_health_mega},
38
39 {"info_player_start", SP_info_player_start},
40 {"info_player_deathmatch", SP_info_player_deathmatch},
41 {"info_player_intermission", SP_info_player_intermission},
42 {"info_player_red", SP_info_player_red},
43 {"info_player_blue", SP_info_player_blue},
44
45 {"func_plat", SP_func_plat},
46 {"func_button", SP_func_button},
47 {"func_door", SP_func_door},
48 {"func_door_secret", SP_func_door_secret},
49 {"func_door_rotating", SP_func_door_rotating},
50 {"func_rotating", SP_func_rotating},
51 {"func_train", SP_func_train},
52 {"func_water", SP_func_water},
53 {"func_conveyor", SP_func_conveyor},
54 {"func_areaportal", SP_func_areaportal},
55 {"func_wall", SP_func_wall},
56 {"func_object", SP_func_object},
57 {"func_timer", SP_func_timer},
58 {"func_explosive", SP_func_explosive},
59 {"func_killbox", SP_func_killbox},
60
61 {"trigger_always", SP_trigger_always},
62 {"trigger_once", SP_trigger_once},
63 {"trigger_multiple", SP_trigger_multiple},
64 {"trigger_relay", SP_trigger_relay},
65 {"trigger_push", SP_trigger_push},
66 {"trigger_hurt", SP_trigger_hurt},
67 {"trigger_key", SP_trigger_key},
68 {"trigger_counter", SP_trigger_counter},
69 {"trigger_elevator", SP_trigger_elevator},
70 {"trigger_gravity", SP_trigger_gravity},
71 {"trigger_monsterjump", SP_trigger_monsterjump},
72 {"trigger_deathballtarget", SP_trigger_deathballtarget},
73 {"trigger_reddeathballtarget", SP_trigger_reddeathballtarget},
74 {"trigger_bluedeathballtarget", SP_trigger_bluedeathballtarget},
75 {"trigger_bluecowtarget", SP_trigger_bluecowtarget},
76 {"trigger_redcowtarget", SP_trigger_redcowtarget},
77
78 {"target_temp_entity", SP_target_temp_entity},
79 {"target_speaker", SP_target_speaker},
80 {"target_explosion", SP_target_explosion},
81 {"target_secret", SP_target_secret},
82 {"target_splash", SP_target_splash},
83 {"target_steam", SP_target_steam},
84 {"target_spawner", SP_target_spawner},
85 #ifndef ALTERIA
86 {"target_blaster", SP_target_blaster},
87 {"target_laser", SP_target_laser},
88 #endif
89 {"target_lightramp", SP_target_lightramp},
90 {"target_earthquake", SP_target_earthquake},
91 {"target_fire", SP_target_fire},
92 {"target_changelevel", SP_target_changelevel},
93
94 {"worldspawn", SP_worldspawn},
95
96 {"light", SP_light},
97 {"info_null", SP_info_null},
98 {"func_group", SP_info_null},
99 {"info_notnull", SP_info_notnull},
100 {"path_corner", SP_path_corner},
101 {"point_combat", SP_point_combat},
102
103 {"misc_teleporter", SP_misc_teleporter},
104 {"misc_teleporter_dest", SP_misc_teleporter_dest},
105
106 {"npc_cow", SP_npc_cow},
107 {"npc_deathray", SP_npc_deathray},
108
109 //TCA
110 {"misc_spiderpod", SP_misc_spiderpod},
111 {"misc_rednode", SP_misc_rednode},
112 {"misc_bluenode", SP_misc_bluenode},
113 {"misc_redspidernode", SP_misc_redspidernode},
114 {"misc_bluespidernode", SP_misc_bluespidernode},
115
116 //Tactical
117 {"misc_aliencomputer", SP_misc_aliencomputer},
118 {"misc_humancomputer", SP_misc_humancomputer},
119 {"misc_alienpowersrc", SP_misc_alienpowersrc},
120 {"misc_humanpowersrc", SP_misc_humanpowersrc},
121 {"misc_alienammodepot", SP_misc_alienammodepot},
122 {"misc_humanammodepot", SP_misc_humanammodepot},
123 {"misc_alienbackupgen", SP_misc_alienbackupgen},
124 {"misc_humanbackupgen", SP_misc_humanbackupgen},
125 {"misc_deathray", SP_misc_deathray}, //note - spawnflags determine team for this item(1 for human)
126 {"misc_laser", SP_misc_laser}, //spawnflag 1 for human
127
128 {"misc_mapmodel", SP_misc_mapmodel},
129 {"misc_watersplash", SP_misc_watersplash},
130 {"misc_electroflash", SP_misc_electroflash},
131 {NULL, NULL}
132 };
133
134 /*
135 ===============
136 ED_CallSpawn
137
138 Finds the spawn function for the entity and calls it
139 ===============
140 */
ED_CallSpawn(edict_t * ent)141 void ED_CallSpawn (edict_t *ent)
142 {
143 spawn_t *s;
144 gitem_t *item;
145 int i;
146
147 if (!ent->classname)
148 {
149 gi.dprintf ("ED_CallSpawn: NULL classname\n");
150 return;
151 }
152
153 // check item spawn functions
154 for (i=0,item=itemlist ; i<game.num_items ; i++,item++)
155 {
156 if (!item->classname)
157 continue;
158
159 //-JD - removing old weapons, and in the case of the vaporizer, duplicates.
160 if(!Q_strcasecmp(ent->classname, "weapon_grenadelauncher"))
161 ent->classname = "weapon_rocketlauncher"; //hack to remove old weapons
162 if(!Q_strcasecmp(ent->classname, "weapon_machinegun"))
163 ent->classname = "weapon_bfg"; //hack to remove old weapons
164 if(!Q_strcasecmp(ent->classname, "weapon_minderaser"))
165 continue; //never place one of these traditionally
166
167 if (!strcmp(item->classname, ent->classname))
168 { // found it
169 SpawnItem (ent, item);
170 return;
171 }
172 }
173
174 gi.WriteByte (svc_temp_entity);
175 gi.WriteByte (TE_TELEPORT_EFFECT);
176 gi.WritePosition (ent->s.origin);
177 gi.multicast (ent->s.origin, MULTICAST_PVS);
178
179 // check normal spawn functions
180 for (s=spawns ; s->name ; s++)
181 {
182 if (!strcmp(s->name, ent->classname))
183 { // found it
184 s->spawn (ent);
185 return;
186 }
187 }
188
189 gi.dprintf ("%s doesn't have a spawn function\n", ent->classname);
190 }
191
192 /*
193 =============
194 ED_NewString
195 =============
196 */
ED_NewString(char * string)197 char *ED_NewString (char *string)
198 {
199 char *newb, *new_p;
200 int i,l;
201
202 l = strlen(string) + 1;
203
204 newb = gi.TagMalloc (l, TAG_LEVEL);
205
206 new_p = newb;
207
208 for (i=0 ; i< l ; i++)
209 {
210 if (string[i] == '\\' && i < l-1)
211 {
212 i++;
213 if (string[i] == 'n')
214 *new_p++ = '\n';
215 else
216 *new_p++ = '\\';
217 }
218 else
219 *new_p++ = string[i];
220 }
221
222 return newb;
223 }
224
225
226
227
228 /*
229 ===============
230 ED_ParseField
231
232 Takes a key/value pair and sets the binary values
233 in an edict
234 ===============
235 */
ED_ParseField(char * key,char * value,edict_t * ent)236 void ED_ParseField (char *key, char *value, edict_t *ent)
237 {
238 field_t *f;
239 byte *b;
240 float v;
241 vec3_t vec;
242
243 for (f=fields ; f->name ; f++)
244 {
245 if (!Q_strcasecmp(f->name, key))
246 { // found it
247 if (f->flags & FFL_SPAWNTEMP)
248 b = (byte *)&st;
249 else
250 b = (byte *)ent;
251
252 switch (f->type)
253 {
254 case F_LSTRING:
255 *(char **)(b+f->ofs) = ED_NewString (value);
256 break;
257 case F_VECTOR:
258 sscanf (value, "%f %f %f", &vec[0], &vec[1], &vec[2]);
259 ((float *)(b+f->ofs))[0] = vec[0];
260 ((float *)(b+f->ofs))[1] = vec[1];
261 ((float *)(b+f->ofs))[2] = vec[2];
262 break;
263 case F_INT:
264 *(int *)(b+f->ofs) = atoi(value);
265 break;
266 case F_FLOAT:
267 *(float *)(b+f->ofs) = atof(value);
268 break;
269 case F_ANGLEHACK:
270 v = atof(value);
271 ((float *)(b+f->ofs))[0] = 0;
272 ((float *)(b+f->ofs))[1] = v;
273 ((float *)(b+f->ofs))[2] = 0;
274 break;
275 case F_IGNORE:
276 default:
277 break;
278 }
279 return;
280 }
281 }
282 gi.dprintf ("%s is not a field\n", key);
283 }
284
285 /*
286 ====================
287 ED_ParseEdict
288
289 Parses an edict out of the given string, returning the new position
290 ed should be a properly initialized empty edict.
291 ====================
292 */
ED_ParseEdict(char * data,edict_t * ent)293 char *ED_ParseEdict (char *data, edict_t *ent)
294 {
295 qboolean init;
296 char keyname[256];
297 char *com_token;
298
299 init = false;
300 memset (&st, 0, sizeof(st));
301
302 // go through all the dictionary pairs
303 while (1)
304 {
305 // parse key
306 com_token = COM_Parse (&data);
307 if (com_token[0] == '}')
308 break;
309 if (!data)
310 gi.error ("ED_ParseEntity: EOF without closing brace");
311
312 strncpy (keyname, com_token, sizeof(keyname)-1);
313
314 // parse value
315 com_token = COM_Parse (&data);
316 if (!data)
317 gi.error ("ED_ParseEntity: EOF without closing brace");
318
319 if (com_token[0] == '}')
320 gi.error ("ED_ParseEntity: closing brace without data");
321
322 init = true;
323
324 // keynames with a leading underscore are used for utility comments,
325 // and are immediately discarded by quake
326 if (keyname[0] == '_')
327 continue;
328
329 ED_ParseField (keyname, com_token, ent);
330 }
331
332 if (!init)
333 memset (ent, 0, sizeof(*ent));
334
335 return data;
336 }
337
338
339 /*
340 ================
341 G_FindTeams
342
343 Chain together all entities with a matching team field.
344
345 All but the first will have the FL_TEAMSLAVE flag set.
346 All but the last will have the teamchain field set to the next one
347 ================
348 */
G_FindTeams(void)349 void G_FindTeams (void)
350 {
351 edict_t *e, *e2, *chain;
352 int i, j;
353 int c, c2;
354
355 c = 0;
356 c2 = 0;
357 for (i=1, e=g_edicts+i ; i < globals.num_edicts ; i++,e++)
358 {
359 if (!e->inuse)
360 continue;
361 if (!e->team)
362 continue;
363 if (e->flags & FL_TEAMSLAVE)
364 continue;
365 chain = e;
366 e->teammaster = e;
367 c++;
368 c2++;
369 for (j=i+1, e2=e+1 ; j < globals.num_edicts ; j++,e2++)
370 {
371 if (!e2->inuse)
372 continue;
373 if (!e2->team)
374 continue;
375 if (e2->flags & FL_TEAMSLAVE)
376 continue;
377 if (!strcmp(e->team, e2->team))
378 {
379 c2++;
380 chain->teamchain = e2;
381 e2->teammaster = e;
382 chain = e2;
383 e2->flags |= FL_TEAMSLAVE;
384 }
385 }
386 }
387
388 gi.dprintf ("%i teams with %i entities\n", c, c2);
389 }
390
391 /*
392 ==============
393 SpawnEntities
394
395 Creates a server's entity / program execution context by
396 parsing textual entity definitions out of an ent file.
397 ==============
398 */
399 int levelnum;
SpawnEntities(char * mapname,char * entities,char * spawnpoint)400 void SpawnEntities (char *mapname, char *entities, char *spawnpoint)
401 {
402 edict_t *ent;
403 int inhibit;
404 char *com_token;
405 int i;
406 float skill_level;
407
408 skill_level = floor (skill->value);
409 if (skill_level < 0)
410 skill_level = 0;
411 if (skill_level > 3)
412 skill_level = 3;
413 if (skill->value != skill_level)
414 gi.cvar_forceset("skill", va("%f", skill_level));
415
416 SaveClientData ();
417
418 gi.FreeTags (TAG_LEVEL);
419
420 memset (&level, 0, sizeof(level));
421 memset (g_edicts, 0, game.maxentities * sizeof (g_edicts[0]));
422
423 strncpy (level.mapname, mapname, sizeof(level.mapname)-1);
424
425 // set client fields on player ents
426 for (i=0 ; i<game.maxclients ; i++)
427 g_edicts[i+1].client = game.clients + i;
428
429 ent = NULL;
430 inhibit = 0;
431 levelnum++;
432
433 // parse ents
434 while (1)
435 {
436 // parse the opening brace
437 com_token = COM_Parse (&entities);
438 if (!entities)
439 break;
440 if (com_token[0] != '{')
441 gi.error ("ED_LoadFromFile: found %s when expecting {",com_token);
442
443 if (!ent)
444 ent = g_edicts;
445 else
446 ent = G_Spawn ();
447 entities = ED_ParseEdict (entities, ent);
448
449 // yet another map hack
450 if (!Q_strcasecmp(level.mapname, "command") && !Q_strcasecmp(ent->classname, "trigger_once") && !Q_strcasecmp(ent->model, "*27"))
451 ent->spawnflags &= ~SPAWNFLAG_NOT_HARD;
452
453 // remove things (except the world) from different skill levels or deathmatch
454 if (ent != g_edicts)
455 {
456 if (deathmatch->value)
457 {
458 if ( ent->spawnflags & SPAWNFLAG_NOT_DEATHMATCH )
459 {
460 G_FreeEdict (ent);
461 inhibit++;
462 continue;
463 }
464 }
465 else
466 {
467 if (
468 ((skill->value == 0) && (ent->spawnflags & SPAWNFLAG_NOT_EASY)) ||
469 ((skill->value == 1) && (ent->spawnflags & SPAWNFLAG_NOT_MEDIUM)) ||
470 (((skill->value == 2) || (skill->value == 3)) && (ent->spawnflags & SPAWNFLAG_NOT_HARD))
471 )
472 {
473 G_FreeEdict (ent);
474 inhibit++;
475 continue;
476 }
477 }
478
479 ent->spawnflags &= ~(SPAWNFLAG_NOT_EASY|SPAWNFLAG_NOT_MEDIUM|SPAWNFLAG_NOT_HARD|SPAWNFLAG_NOT_DEATHMATCH);
480 }
481
482 ED_CallSpawn (ent);
483 }
484
485 gi.dprintf ("%i entities inhibited\n", inhibit);
486
487 //reset minderaser
488 mindEraserTime = level.time;
489
490 ACEND_InitNodes();
491 ACEND_LoadNodes();
492
493 G_FindTeams ();
494
495 PlayerTrail_Init ();
496 }
497
498
499 //===================================================================
500
501 #if 0
502 // cursor positioning
503 xl <value>
504 xr <value>
505 yb <value>
506 yt <value>
507 xv <value>
508 yv <value>
509
510 // drawing
511 statpic <name>
512 pic <stat>
513 num <fieldwidth> <stat>
514 string <stat>
515
516 // control
517 if <stat>
518 ifeq <stat> <value>
519 ifbit <stat> <value>
520 endif
521
522 #endif
523
524 char *dm_statusbar =
525 //background
526 "yb -256 "
527 "xl 0 "
528 "pic 0 "
529 "xr -130 "
530 "yt 2 "
531 "pic 18 "
532
533 // health
534 "yb -29 "
535 "xl 11 "
536 "hnum "
537
538 // ammo
539 "if 2 "
540 " xl 76 "
541 " anum "
542 "endif "
543
544 // armor
545 " xl 142 "
546 " rnum "
547
548 // timer
549 "if 9 "
550 " xv 262 "
551 " yb -24 "
552 " num 2 10 "
553 " xv 296 "
554 " yb -32 "
555 " pic 9 "
556 "endif "
557
558 // weapon icon
559 "if 11 "
560 " xr -72 "
561 " yt 196 "
562 " pic 11 "
563 "endif "
564
565 // frags
566 "xr -67 "
567 "yt 16 "
568 "num 3 14"
569
570 // deaths
571 "xr -67 "
572 "yt 48 "
573 "num 3 19 "
574
575 // high scorer
576 "yt 80 "
577 "num 3 20 "
578
579 // weapon stats
580 "if 25 "
581 "xr -72 "
582 "yt 227 "
583 "pic 25 "
584 "endif"
585
586 "if 26 "
587 "yt 258 "
588 "pic 26 "
589 "endif "
590
591 "if 27 "
592 "yt 289 "
593 "pic 27 "
594 "endif "
595
596 "if 28 "
597 "yt 320 "
598 "pic 28 "
599 "endif "
600
601 "if 29 "
602 "yt 351 "
603 "pic 29 "
604 "endif "
605
606 "if 30 "
607 "yt 382 "
608 "pic 30 "
609 "endif "
610
611 "if 31 "
612 "yt 413 "
613 "pic 31 "
614 "endif "
615 ;
616
617 char *team_statusbar =
618 // background
619 "yb -256 "
620 "xl 0 "
621 "pic 0 "
622 "xr -130 "
623 "yt 2 "
624 "pic 18 "
625
626 // health
627 "yb -29 "
628 "xl 11 "
629 "hnum "
630
631 // ammo
632 "if 2 "
633 " xl 76 "
634 " anum "
635 "endif "
636
637 // armor
638 " xl 142 "
639 " rnum "
640
641 // timer
642 "if 9 "
643 " xv 324 "
644 " yb -24 "
645 " num 2 10 "
646 " xv 358 "
647 " yb -32 "
648 " pic 9 "
649 "endif "
650
651 // weapon icon
652 "if 11 "
653 " xr -72 "
654 " yt 196 "
655 " pic 11 "
656 "endif "
657
658 // frags
659 "xr -67 "
660 "yt 16 "
661 "num 3 14"
662
663 // deaths
664 "xr -67 "
665 "yt 48 "
666 "num 3 19 "
667
668 // high scorer
669 "yt 80 "
670 "num 3 20 "
671
672 // red team
673 "yt 132 "
674 "num 3 21 "
675 // blue team
676 "yt 166 "
677 "num 3 22 "
678
679 // flag
680 " xv 128 "
681 " yb -64 "
682 " pic 23 "
683
684 // weapon stats
685 "if 25 "
686 "xr -72 "
687 "yt 227 "
688 "pic 25 "
689 "endif"
690
691 "if 26 "
692 "yt 258 "
693 "pic 26 "
694 "endif "
695
696 "if 27 "
697 "yt 289 "
698 "pic 27 "
699 "endif "
700
701 "if 28 "
702 "yt 320 "
703 "pic 28 "
704 "endif "
705
706 "if 29 "
707 "yt 351 "
708 "pic 29 "
709 "endif "
710
711 "if 30 "
712 "yt 382 "
713 "pic 30 "
714 "endif "
715
716 "if 31 "
717 "yt 413 "
718 "pic 31 "
719 "endif "
720 ;
721
722 char *tca_statusbar =
723 // background
724 "yb -256 "
725 "xl 0 "
726 "pic 0 "
727 "xr -130 "
728 "yt 2 "
729 "pic 18 "
730
731 // health
732 "yb -29 "
733 "xl 11 "
734 "hnum "
735
736 // ammo
737 "if 2 "
738 " xl 76 "
739 " anum "
740 "endif "
741
742 // armor
743 " xl 142 "
744 " rnum "
745
746 // timer
747 "if 9 "
748 " xv 324 "
749 " yb -24 "
750 " num 2 10 "
751 " xv 358 "
752 " yb -32 "
753 " pic 9 "
754 "endif "
755
756 // weapon icon
757 "if 11 "
758 " xr -72 "
759 " yt 196 "
760 " pic 11 "
761 "endif "
762
763 // frags
764 "xr -67 "
765 "yt 16 "
766 "num 3 14"
767
768 // deaths
769 "xr -67 "
770 "yt 48 "
771 "num 3 19 "
772
773 // high scorer
774 "yt 80 "
775 "num 3 20 "
776
777 // red team
778 "yt 132 "
779 "num 1 6 "
780 "xr -27 "
781 "num 1 21 "
782 // blue team
783 "yt 166 "
784 "num 1 22 "
785 "xr -67 "
786 "num 1 7 "
787 // red label
788 "yt 124 "
789 "xr -30 "
790 "string nodes "
791 "xr -70 "
792 "string matches "
793 // blue label
794 "yt 158 "
795 "xr -30 "
796 "string nodes "
797 "xr -70 "
798 "string matches "
799
800 // flag
801 " xv 128 "
802 " yb -64 "
803 " pic 23 "
804
805 // weapon stats
806 "if 25 "
807 "xr -72 "
808 "yt 227 "
809 "pic 25 "
810 "endif"
811
812 "if 26 "
813 "yt 258 "
814 "pic 26 "
815 "endif "
816
817 "if 27 "
818 "yt 289 "
819 "pic 27 "
820 "endif "
821
822 "if 28 "
823 "yt 320 "
824 "pic 28 "
825 "endif "
826
827 "if 29 "
828 "yt 351 "
829 "pic 29 "
830 "endif "
831
832 "if 30 "
833 "yt 382 "
834 "pic 30 "
835 "endif "
836
837 "if 31 "
838 "yt 413 "
839 "pic 31 "
840 "endif "
841 ;
842
843 char *tactical_statusbar =
844 // background
845 "yb -256 "
846 "xl 0 "
847 "pic 0 "
848 "xr -130 "
849 "yt 2 "
850 "pic 8 "
851
852 // health
853 "yb -29 "
854 "xl 11 "
855 "hnum "
856
857 // ammo
858 "if 2 "
859 " xl 76 "
860 " anum "
861 "endif "
862
863 // armor
864 " xl 142 "
865 " rnum "
866
867 // Human Computer
868 "xr -67 "
869 "yt 16 "
870 "num 3 25 "
871
872 // Human Power
873 "yt 48 "
874 "num 3 26 "
875
876 // Human Ammo Depot
877 "yt 80 "
878 "num 3 27 "
879
880 // Alien Computer
881 "yt 122 "
882 "num 3 28 "
883
884 // Alien Power
885 "yt 154 "
886 "num 3 29 "
887
888 // Alien Ammo Depot
889 "yt 186 "
890 "num 3 30 "
891
892 // timer
893 "if 9 "
894 " xv 324 "
895 " yb -24 "
896 " num 2 10 "
897 " xv 358 "
898 " yb -32 "
899 " pic 9 "
900 "endif "
901
902 // weapon icon
903 "if 11 "
904 " xr -72 "
905 " yt 196 "
906 " pic 11 "
907 "endif "
908
909
910 ;
911 /*QUAKED worldspawn (0 0 0) ?
912
913 Only used for the world.
914 "sky" environment map name
915 "skyaxis" vector axis for rotating sky
916 "skyrotate" speed of rotation in degrees/second
917 "sounds" music cd track number
918 "gravity" 800 is default gravity
919 "message" text to print at user logon
920 */
SP_worldspawn(edict_t * ent)921 void SP_worldspawn (edict_t *ent)
922 {
923 ent->movetype = MOVETYPE_PUSH;
924 ent->solid = SOLID_BSP;
925 ent->inuse = true; // since the world doesn't use G_Spawn()
926 ent->s.modelindex = 1; // world model is always index 1
927
928 //---------------
929
930 // reserve some spots for dead player bodies for coop / deathmatch
931 InitBodyQue ();
932
933 // set configstrings for items
934 SetItemNames ();
935
936 if (st.nextmap)
937 strcpy (level.nextmap, st.nextmap);
938
939 // make some data visible to the server
940
941 if (ent->message && ent->message[0])
942 {
943 gi.configstring (CS_NAME, ent->message);
944 strncpy (level.level_name, ent->message, sizeof(level.level_name));
945 }
946 else
947 strncpy (level.level_name, level.mapname, sizeof(level.level_name));
948
949 if (st.sky && st.sky[0])
950 gi.configstring (CS_SKY, st.sky);
951 else
952 gi.configstring (CS_SKY, "space1");
953
954 gi.configstring (CS_SKYROTATE, va("%f", st.skyrotate) );
955
956 gi.configstring (CS_SKYAXIS, va("%f %f %f",
957 st.skyaxis[0], st.skyaxis[1], st.skyaxis[2]) );
958
959 gi.configstring (CS_MAXCLIENTS, va("%i", g_maxclients->integer ) );
960
961 // status bar program
962 if ((dmflags->integer & DF_SKINTEAMS) || ctf->integer || cp->integer)
963 {
964 gi.configstring (CS_STATUSBAR, team_statusbar);
965 if(ctf->value)
966 CTFPrecache();
967 }
968 else if (tca->integer)
969 gi.configstring (CS_STATUSBAR, tca_statusbar);
970 else if (g_tactical->integer)
971 gi.configstring (CS_STATUSBAR, tactical_statusbar);
972 else
973 gi.configstring (CS_STATUSBAR, dm_statusbar);
974
975 //---------------
976
977
978 // help icon for statusbar
979 level.pic_health = gi.imageindex ("i_health");
980 gi.imageindex ("help");
981
982 if (!st.gravity) {
983 if(low_grav->value)
984 gi.cvar_set("sv_gravity", "300");
985 else
986 gi.cvar_set("sv_gravity", "800");
987 }
988 else
989 gi.cvar_set("sv_gravity", st.gravity);
990
991 //prechaches
992
993 PrecacheItem (FindItem ("Blaster"));
994 PrecacheItem (FindItem ("Violator"));
995
996 gi.soundindex ("player/lava1.wav");
997 gi.soundindex ("player/lava2.wav");
998
999 gi.soundindex ("misc/pc_up.wav");
1000 gi.soundindex ("misc/talk1.wav");
1001
1002 gi.soundindex ("items/respawn1.wav");
1003
1004 // sexed sounds
1005 gi.soundindex ("*death1.wav");
1006 gi.soundindex ("*death2.wav");
1007 gi.soundindex ("*death3.wav");
1008 gi.soundindex ("*death4.wav");
1009 gi.soundindex ("*fall1.wav");
1010 gi.soundindex ("*fall2.wav");
1011 gi.soundindex ("*gurp1.wav"); // drowning damage
1012 gi.soundindex ("*gurp2.wav");
1013 gi.soundindex ("*jump1.wav"); // player jump
1014 gi.soundindex ("*pain25_1.wav");
1015 gi.soundindex ("*pain25_2.wav");
1016 gi.soundindex ("*pain50_1.wav");
1017 gi.soundindex ("*pain50_2.wav");
1018 gi.soundindex ("*pain75_1.wav");
1019 gi.soundindex ("*pain75_2.wav");
1020 gi.soundindex ("*pain100_1.wav");
1021 gi.soundindex ("*pain100_2.wav");
1022
1023 //-------------------
1024
1025 gi.soundindex ("player/gasp1.wav"); // gasping for air
1026 gi.soundindex ("player/gasp2.wav"); // head breaking surface, not gasping
1027
1028 gi.soundindex ("player/watr_in.wav"); // feet hitting water
1029 gi.soundindex ("player/watr_out.wav"); // feet leaving water
1030
1031 gi.soundindex ("player/watr_un.wav"); // head going underwater
1032
1033 gi.soundindex ("items/damage.wav");
1034 gi.soundindex ("items/protect.wav");
1035 gi.soundindex ("items/protect4.wav");
1036 gi.soundindex ("weapons/noammo.wav");
1037
1038 gi.soundindex ("weapons/whoosh.wav");
1039
1040 gi.soundindex ("misc/1frags.wav");
1041 gi.soundindex ("misc/2frags.wav");
1042 gi.soundindex ("misc/3frags.wav");
1043 gi.soundindex ("misc/one.wav");
1044 gi.soundindex ("misc/two.wav");
1045 gi.soundindex ("misc/three.wav");
1046 gi.soundindex ("misc/godlike.wav");
1047 gi.soundindex ("misc/rampage.wav");
1048 gi.soundindex ("misc/fight.wav");
1049 gi.soundindex ("misc/minderaser.wav");
1050
1051 //if maxclients is 0 or 1, it means someone is probably just testing a map
1052 //or testing some code, so we really don't need to precache all this crap
1053 if (game.maxclients > 1) {
1054 //precache all base player taunts
1055 gi.soundindex ("taunts/martianenforcer/taunt1.wav");
1056 gi.soundindex ("taunts/martianenforcer/taunt2.wav");
1057 gi.soundindex ("taunts/martianenforcer/taunt3.wav");
1058 gi.soundindex ("taunts/martianenforcer/taunt4.wav");
1059 gi.soundindex ("taunts/martianenforcer/taunt5.wav");
1060
1061 gi.soundindex ("taunts/martiancyborg/taunt1.wav");
1062 gi.soundindex ("taunts/martiancyborg/taunt2.wav");
1063 gi.soundindex ("taunts/martiancyborg/taunt3.wav");
1064 gi.soundindex ("taunts/martiancyborg/taunt4.wav");
1065 gi.soundindex ("taunts/martiancyborg/taunt5.wav");
1066
1067 gi.soundindex ("taunts/commander/taunt1.wav");
1068 gi.soundindex ("taunts/commander/taunt2.wav");
1069 gi.soundindex ("taunts/commander/taunt3.wav");
1070 gi.soundindex ("taunts/commander/taunt4.wav");
1071 gi.soundindex ("taunts/commander/taunt5.wav");
1072
1073 gi.soundindex ("taunts/enforcer/taunt1.wav");
1074 gi.soundindex ("taunts/enforcer/taunt2.wav");
1075 gi.soundindex ("taunts/enforcer/taunt3.wav");
1076 gi.soundindex ("taunts/enforcer/taunt4.wav");
1077 gi.soundindex ("taunts/enforcer/taunt5.wav");
1078
1079 gi.soundindex ("taunts/slashbot/taunt1.wav");
1080 gi.soundindex ("taunts/slashbot/taunt2.wav");
1081 gi.soundindex ("taunts/slashbot/taunt3.wav");
1082 gi.soundindex ("taunts/slashbot/taunt4.wav");
1083 gi.soundindex ("taunts/slashbot/taunt5.wav");
1084
1085 gi.soundindex ("taunts/lauren/taunt1.wav");
1086 gi.soundindex ("taunts/lauren/taunt2.wav");
1087 gi.soundindex ("taunts/lauren/taunt3.wav");
1088 gi.soundindex ("taunts/lauren/taunt4.wav");
1089 gi.soundindex ("taunts/lauren/taunt5.wav");
1090
1091 gi.soundindex ("taunts/martiancyborg/taunt1.wav");
1092 gi.soundindex ("taunts/martiancyborg/taunt2.wav");
1093 gi.soundindex ("taunts/martiancyborg/taunt3.wav");
1094 gi.soundindex ("taunts/martiancyborg/taunt4.wav");
1095 gi.soundindex ("taunts/martiancyborg/taunt5.wav");
1096
1097 gi.soundindex ("taunts/martianoverlord/taunt1.wav");
1098 gi.soundindex ("taunts/martianoverlord/taunt2.wav");
1099 gi.soundindex ("taunts/martianoverlord/taunt3.wav");
1100 gi.soundindex ("taunts/martianoverlord/taunt4.wav");
1101 gi.soundindex ("taunts/martianoverlord/taunt5.wav");
1102
1103 gi.soundindex ("taunts/martianwarrior/taunt1.wav");
1104 gi.soundindex ("taunts/martianwarrior/taunt2.wav");
1105 gi.soundindex ("taunts/martianwarrior/taunt3.wav");
1106 gi.soundindex ("taunts/martianwarrior/taunt4.wav");
1107 gi.soundindex ("taunts/martianwarrior/taunt5.wav");
1108
1109 //precache any gibs
1110 sm_meat_index = gi.modelindex ("models/objects/gibs/sm_meat/tris.md2");
1111 gi.modelindex ("models/objects/gibs/mart_gut/tris.md2");
1112 gi.modelindex ("models/objects/debris1/tris.md2");
1113 gi.modelindex ("models/objects/debris3/tris.md2");
1114
1115 //precache all base player models. this eliminates "stutter" when a player joins the game
1116 //this should be here for the cases of 7.45 clients and older
1117 gi.modelindex ("players/martianenforcer/tris.md2");
1118 gi.modelindex ("players/martiancyborg/tris.md2");
1119 gi.modelindex ("players/martianoverlord/tris.md2");
1120 gi.modelindex ("players/martianwarrior/tris.md2");
1121 gi.modelindex ("players/enforcer/tris.md2");
1122 gi.modelindex ("players/lauren/tris.md2");
1123 gi.modelindex ("players/slashbot/tris.md2");
1124 gi.modelindex ("players/commander/tris.md2");
1125
1126 //do the w_weps
1127 gi.modelindex ("players/martianenforcer/weapon.md2");
1128 gi.modelindex ("players/martianenforcer/w_blaster.md2");
1129 gi.modelindex ("players/martianenforcer/w_shotgun.md2");
1130 gi.modelindex ("players/martianenforcer/w_sshotgun.md2");
1131 gi.modelindex ("players/martianenforcer/w_machinegun.md2");
1132 gi.modelindex ("players/martianenforcer/w_chaingun.md2");
1133 gi.modelindex ("players/martianenforcer/w_rlauncher.md2");
1134 gi.modelindex ("players/martianenforcer/w_hyperblaster.md2");
1135 gi.modelindex ("players/martianenforcer/w_railgun.md2");
1136 gi.modelindex ("players/martianenforcer/w_bfg.md2");
1137 gi.modelindex ("players/martianenforcer/w_violator.md2");
1138 gi.modelindex ("players/martianenforcer/w_minderaser.md2");
1139
1140 gi.modelindex ("players/martiancyborg/weapon.md2");
1141 gi.modelindex ("players/martiancyborg/w_blaster.md2");
1142 gi.modelindex ("players/martiancyborg/w_shotgun.md2");
1143 gi.modelindex ("players/martiancyborg/w_sshotgun.md2");
1144 gi.modelindex ("players/martiancyborg/w_machinegun.md2");
1145 gi.modelindex ("players/martiancyborg/w_chaingun.md2");
1146 gi.modelindex ("players/martiancyborg/w_rlauncher.md2");
1147 gi.modelindex ("players/martiancyborg/w_hyperblaster.md2");
1148 gi.modelindex ("players/martiancyborg/w_railgun.md2");
1149 gi.modelindex ("players/martiancyborg/w_bfg.md2");
1150 gi.modelindex ("players/martiancyborg/w_violator.md2");
1151 gi.modelindex ("players/martiancyborg/w_minderaser.md2");
1152
1153 gi.modelindex ("players/enforcer/weapon.md2");
1154 gi.modelindex ("players/enforcer/w_blaster.md2");
1155 gi.modelindex ("players/enforcer/w_shotgun.md2");
1156 gi.modelindex ("players/enforcer/w_sshotgun.md2");
1157 gi.modelindex ("players/enforcer/w_machinegun.md2");
1158 gi.modelindex ("players/enforcer/w_chaingun.md2");
1159 gi.modelindex ("players/enforcer/w_rlauncher.md2");
1160 gi.modelindex ("players/enforcer/w_hyperblaster.md2");
1161 gi.modelindex ("players/enforcer/w_railgun.md2");
1162 gi.modelindex ("players/enforcer/w_bfg.md2");
1163 gi.modelindex ("players/enforcer/w_violator.md2");
1164 gi.modelindex ("players/enforcer/w_minderaser.md2");
1165
1166 gi.modelindex ("players/lauren/weapon.md2");
1167 gi.modelindex ("players/lauren/w_blaster.md2");
1168 gi.modelindex ("players/lauren/w_shotgun.md2");
1169 gi.modelindex ("players/lauren/w_sshotgun.md2");
1170 gi.modelindex ("players/lauren/w_machinegun.md2");
1171 gi.modelindex ("players/lauren/w_chaingun.md2");
1172 gi.modelindex ("players/lauren/w_rlauncher.md2");
1173 gi.modelindex ("players/lauren/w_hyperblaster.md2");
1174 gi.modelindex ("players/lauren/w_railgun.md2");
1175 gi.modelindex ("players/lauren/w_bfg.md2");
1176 gi.modelindex ("players/lauren/w_violator.md2");
1177 gi.modelindex ("players/lauren/w_minderaser.md2");
1178
1179 gi.modelindex ("players/slashbot/weapon.md2");
1180 gi.modelindex ("players/slashbot/w_blaster.md2");
1181 gi.modelindex ("players/slashbot/w_shotgun.md2");
1182 gi.modelindex ("players/slashbot/w_sshotgun.md2");
1183 gi.modelindex ("players/slashbot/w_machinegun.md2");
1184 gi.modelindex ("players/slashbot/w_chaingun.md2");
1185 gi.modelindex ("players/slashbot/w_rlauncher.md2");
1186 gi.modelindex ("players/slashbot/w_hyperblaster.md2");
1187 gi.modelindex ("players/slashbot/w_railgun.md2");
1188 gi.modelindex ("players/slashbot/w_bfg.md2");
1189 gi.modelindex ("players/slashbot/w_violator.md2");
1190 gi.modelindex ("players/slashbot/w_minderaser.md2");
1191
1192 gi.modelindex ("players/commander/weapon.md2");
1193 gi.modelindex ("players/commander/w_blaster.md2");
1194 gi.modelindex ("players/commander/w_shotgun.md2");
1195 gi.modelindex ("players/commander/w_sshotgun.md2");
1196 gi.modelindex ("players/commander/w_machinegun.md2");
1197 gi.modelindex ("players/commander/w_chaingun.md2");
1198 gi.modelindex ("players/commander/w_rlauncher.md2");
1199 gi.modelindex ("players/commander/w_hyperblaster.md2");
1200 gi.modelindex ("players/commander/w_railgun.md2");
1201 gi.modelindex ("players/commander/w_bfg.md2");
1202 gi.modelindex ("players/commander/w_violator.md2");
1203 gi.modelindex ("players/commander/w_minderaser.md2");
1204
1205 gi.modelindex ("players/martianoverlord/weapon.md2");
1206 gi.modelindex ("players/martianoverlord/w_blaster.md2");
1207 gi.modelindex ("players/martianoverlord/w_shotgun.md2");
1208 gi.modelindex ("players/martianoverlord/w_sshotgun.md2");
1209 gi.modelindex ("players/martianoverlord/w_machinegun.md2");
1210 gi.modelindex ("players/martianoverlord/w_chaingun.md2");
1211 gi.modelindex ("players/martianoverlord/w_rlauncher.md2");
1212 gi.modelindex ("players/martianoverlord/w_hyperblaster.md2");
1213 gi.modelindex ("players/martianoverlord/w_railgun.md2");
1214 gi.modelindex ("players/martianoverlord/w_bfg.md2");
1215 gi.modelindex ("players/martianoverlord/w_violator.md2");
1216 gi.modelindex ("players/martianoverlord/w_minderaser.md2");
1217
1218 gi.modelindex ("players/martianwarrior/weapon.md2");
1219 gi.modelindex ("players/martianwarrior/w_blaster.md2");
1220 gi.modelindex ("players/martianwarrior/w_shotgun.md2");
1221 gi.modelindex ("players/martianwarrior/w_sshotgun.md2");
1222 gi.modelindex ("players/martianwarrior/w_machinegun.md2");
1223 gi.modelindex ("players/martianwarrior/w_chaingun.md2");
1224 gi.modelindex ("players/martianwarrior/w_rlauncher.md2");
1225 gi.modelindex ("players/martianwarrior/w_hyperblaster.md2");
1226 gi.modelindex ("players/martianwarrior/w_railgun.md2");
1227 gi.modelindex ("players/martianwarrior/w_bfg.md2");
1228 gi.modelindex ("players/martianwarrior/w_violator.md2");
1229 gi.modelindex ("players/martianwarrior/w_minderaser.md2");
1230
1231 //weapon models that aren't placed in levels
1232 gi.modelindex ("models/weapons/v_minderaser/tris.md2");
1233 gi.modelindex ("models/weapons/g_minderaser/tris.md2");
1234 gi.modelindex ("models/objects/spud/tris.md2");
1235 gi.modelindex ("models/weapons/v_blast/tris.md2");
1236 gi.modelindex ("models/weapons/v_violator/tris.md2");
1237 }
1238
1239 //these are needed for custom player models for when they enter a game
1240 gi.modelindex ("#w_blaster.md2");
1241 gi.modelindex ("#w_shotgun.md2");
1242 gi.modelindex ("#w_sshotgun.md2");
1243 gi.modelindex ("#w_machinegun.md2");
1244 gi.modelindex ("#w_chaingun.md2");
1245 gi.modelindex ("#a_grenades.md2");
1246 gi.modelindex ("#w_glauncher.md2");
1247 gi.modelindex ("#w_rlauncher.md2");
1248 gi.modelindex ("#w_hyperblaster.md2");
1249 gi.modelindex ("#w_railgun.md2");
1250 gi.modelindex ("#w_bfg.md2");
1251 gi.modelindex ("#w_violator.md2");
1252 gi.modelindex ("#w_minderaser.md2");
1253
1254 //
1255 // Setup light animation tables. 'a' is total darkness, 'z' is doublebright.
1256 //
1257
1258 // 0 normal
1259 gi.configstring(CS_LIGHTS+0, "m");
1260
1261 // 1 FLICKER (first variety)
1262 gi.configstring(CS_LIGHTS+1, "mmnmmommommnonmmonqnmmo");
1263
1264 // 2 SLOW STRONG PULSE
1265 gi.configstring(CS_LIGHTS+2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");
1266
1267 // 3 CANDLE (first variety)
1268 gi.configstring(CS_LIGHTS+3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg");
1269
1270 // 4 FAST STROBE
1271 gi.configstring(CS_LIGHTS+4, "mamamamamama");
1272
1273 // 5 GENTLE PULSE 1
1274 gi.configstring(CS_LIGHTS+5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj");
1275
1276 // 6 FLICKER (second variety)
1277 gi.configstring(CS_LIGHTS+6, "nmonqnmomnmomomno");
1278
1279 // 7 CANDLE (second variety)
1280 gi.configstring(CS_LIGHTS+7, "mmmaaaabcdefgmmmmaaaammmaamm");
1281
1282 // 8 CANDLE (third variety)
1283 gi.configstring(CS_LIGHTS+8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");
1284
1285 // 9 SLOW STROBE (fourth variety)
1286 gi.configstring(CS_LIGHTS+9, "aaaaaaaazzzzzzzz");
1287
1288 // 10 FLUORESCENT FLICKER
1289 gi.configstring(CS_LIGHTS+10, "mmamammmmammamamaaamammma");
1290
1291 // 11 SLOW PULSE NOT FADE TO BLACK
1292 gi.configstring(CS_LIGHTS+11, "abcdefghijklmnopqrrqponmlkjihgfedcba");
1293
1294 // styles 32-62 are assigned by the light program for switchable lights
1295
1296 // 63 testing
1297 gi.configstring(CS_LIGHTS+63, "a");
1298
1299 //call voting(we've started a new level, clear it)
1300 if(g_callvote->value) {
1301 playervote.called = false;
1302 playervote.yay = 0;
1303 playervote.nay = 0;
1304 playervote.command[0] = 0;
1305 }
1306 }
1307
1308