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