Quake-2

Quake 2 GPL Source Release
Log | Files | Refs

g_spawn.c (23662B)


      1 /*
      2 Copyright (C) 1997-2001 Id Software, Inc.
      3 
      4 This program is free software; you can redistribute it and/or
      5 modify it under the terms of the GNU General Public License
      6 as published by the Free Software Foundation; either version 2
      7 of the License, or (at your option) any later version.
      8 
      9 This program is distributed in the hope that it will be useful,
     10 but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
     12 
     13 See the GNU General Public License for more details.
     14 
     15 You should have received a copy of the GNU General Public License
     16 along with this program; if not, write to the Free Software
     17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     18 
     19 */
     20 
     21 #include "g_local.h"
     22 
     23 typedef struct
     24 {
     25 	char	*name;
     26 	void	(*spawn)(edict_t *ent);
     27 } spawn_t;
     28 
     29 
     30 void SP_item_health (edict_t *self);
     31 void SP_item_health_small (edict_t *self);
     32 void SP_item_health_large (edict_t *self);
     33 void SP_item_health_mega (edict_t *self);
     34 
     35 void SP_info_player_start (edict_t *ent);
     36 void SP_info_player_deathmatch (edict_t *ent);
     37 void SP_info_player_coop (edict_t *ent);
     38 void SP_info_player_intermission (edict_t *ent);
     39 
     40 void SP_func_plat (edict_t *ent);
     41 void SP_func_rotating (edict_t *ent);
     42 void SP_func_button (edict_t *ent);
     43 void SP_func_door (edict_t *ent);
     44 void SP_func_door_secret (edict_t *ent);
     45 void SP_func_door_rotating (edict_t *ent);
     46 void SP_func_water (edict_t *ent);
     47 void SP_func_train (edict_t *ent);
     48 void SP_func_conveyor (edict_t *self);
     49 void SP_func_wall (edict_t *self);
     50 void SP_func_object (edict_t *self);
     51 void SP_func_explosive (edict_t *self);
     52 void SP_func_timer (edict_t *self);
     53 void SP_func_areaportal (edict_t *ent);
     54 void SP_func_clock (edict_t *ent);
     55 void SP_func_killbox (edict_t *ent);
     56 
     57 void SP_trigger_always (edict_t *ent);
     58 void SP_trigger_once (edict_t *ent);
     59 void SP_trigger_multiple (edict_t *ent);
     60 void SP_trigger_relay (edict_t *ent);
     61 void SP_trigger_push (edict_t *ent);
     62 void SP_trigger_hurt (edict_t *ent);
     63 void SP_trigger_key (edict_t *ent);
     64 void SP_trigger_counter (edict_t *ent);
     65 void SP_trigger_elevator (edict_t *ent);
     66 void SP_trigger_gravity (edict_t *ent);
     67 void SP_trigger_monsterjump (edict_t *ent);
     68 
     69 void SP_target_temp_entity (edict_t *ent);
     70 void SP_target_speaker (edict_t *ent);
     71 void SP_target_explosion (edict_t *ent);
     72 void SP_target_changelevel (edict_t *ent);
     73 void SP_target_secret (edict_t *ent);
     74 void SP_target_goal (edict_t *ent);
     75 void SP_target_splash (edict_t *ent);
     76 void SP_target_spawner (edict_t *ent);
     77 void SP_target_blaster (edict_t *ent);
     78 void SP_target_crosslevel_trigger (edict_t *ent);
     79 void SP_target_crosslevel_target (edict_t *ent);
     80 void SP_target_laser (edict_t *self);
     81 void SP_target_help (edict_t *ent);
     82 void SP_target_actor (edict_t *ent);
     83 void SP_target_lightramp (edict_t *self);
     84 void SP_target_earthquake (edict_t *ent);
     85 void SP_target_character (edict_t *ent);
     86 void SP_target_string (edict_t *ent);
     87 
     88 void SP_worldspawn (edict_t *ent);
     89 void SP_viewthing (edict_t *ent);
     90 
     91 void SP_light (edict_t *self);
     92 void SP_light_mine1 (edict_t *ent);
     93 void SP_light_mine2 (edict_t *ent);
     94 void SP_info_null (edict_t *self);
     95 void SP_info_notnull (edict_t *self);
     96 void SP_path_corner (edict_t *self);
     97 void SP_point_combat (edict_t *self);
     98 
     99 void SP_misc_explobox (edict_t *self);
    100 void SP_misc_banner (edict_t *self);
    101 void SP_misc_satellite_dish (edict_t *self);
    102 void SP_misc_actor (edict_t *self);
    103 void SP_misc_gib_arm (edict_t *self);
    104 void SP_misc_gib_leg (edict_t *self);
    105 void SP_misc_gib_head (edict_t *self);
    106 void SP_misc_insane (edict_t *self);
    107 void SP_misc_deadsoldier (edict_t *self);
    108 void SP_misc_viper (edict_t *self);
    109 void SP_misc_viper_bomb (edict_t *self);
    110 void SP_misc_bigviper (edict_t *self);
    111 void SP_misc_strogg_ship (edict_t *self);
    112 void SP_misc_teleporter (edict_t *self);
    113 void SP_misc_teleporter_dest (edict_t *self);
    114 void SP_misc_blackhole (edict_t *self);
    115 void SP_misc_eastertank (edict_t *self);
    116 void SP_misc_easterchick (edict_t *self);
    117 void SP_misc_easterchick2 (edict_t *self);
    118 
    119 void SP_monster_berserk (edict_t *self);
    120 void SP_monster_gladiator (edict_t *self);
    121 void SP_monster_gunner (edict_t *self);
    122 void SP_monster_infantry (edict_t *self);
    123 void SP_monster_soldier_light (edict_t *self);
    124 void SP_monster_soldier (edict_t *self);
    125 void SP_monster_soldier_ss (edict_t *self);
    126 void SP_monster_tank (edict_t *self);
    127 void SP_monster_medic (edict_t *self);
    128 void SP_monster_flipper (edict_t *self);
    129 void SP_monster_chick (edict_t *self);
    130 void SP_monster_parasite (edict_t *self);
    131 void SP_monster_flyer (edict_t *self);
    132 void SP_monster_brain (edict_t *self);
    133 void SP_monster_floater (edict_t *self);
    134 void SP_monster_hover (edict_t *self);
    135 void SP_monster_mutant (edict_t *self);
    136 void SP_monster_supertank (edict_t *self);
    137 void SP_monster_boss2 (edict_t *self);
    138 void SP_monster_jorg (edict_t *self);
    139 void SP_monster_boss3_stand (edict_t *self);
    140 
    141 void SP_monster_commander_body (edict_t *self);
    142 
    143 void SP_turret_breach (edict_t *self);
    144 void SP_turret_base (edict_t *self);
    145 void SP_turret_driver (edict_t *self);
    146 
    147 
    148 spawn_t	spawns[] = {
    149 	{"item_health", SP_item_health},
    150 	{"item_health_small", SP_item_health_small},
    151 	{"item_health_large", SP_item_health_large},
    152 	{"item_health_mega", SP_item_health_mega},
    153 
    154 	{"info_player_start", SP_info_player_start},
    155 	{"info_player_deathmatch", SP_info_player_deathmatch},
    156 	{"info_player_coop", SP_info_player_coop},
    157 	{"info_player_intermission", SP_info_player_intermission},
    158 
    159 	{"func_plat", SP_func_plat},
    160 	{"func_button", SP_func_button},
    161 	{"func_door", SP_func_door},
    162 	{"func_door_secret", SP_func_door_secret},
    163 	{"func_door_rotating", SP_func_door_rotating},
    164 	{"func_rotating", SP_func_rotating},
    165 	{"func_train", SP_func_train},
    166 	{"func_water", SP_func_water},
    167 	{"func_conveyor", SP_func_conveyor},
    168 	{"func_areaportal", SP_func_areaportal},
    169 	{"func_clock", SP_func_clock},
    170 	{"func_wall", SP_func_wall},
    171 	{"func_object", SP_func_object},
    172 	{"func_timer", SP_func_timer},
    173 	{"func_explosive", SP_func_explosive},
    174 	{"func_killbox", SP_func_killbox},
    175 
    176 	{"trigger_always", SP_trigger_always},
    177 	{"trigger_once", SP_trigger_once},
    178 	{"trigger_multiple", SP_trigger_multiple},
    179 	{"trigger_relay", SP_trigger_relay},
    180 	{"trigger_push", SP_trigger_push},
    181 	{"trigger_hurt", SP_trigger_hurt},
    182 	{"trigger_key", SP_trigger_key},
    183 	{"trigger_counter", SP_trigger_counter},
    184 	{"trigger_elevator", SP_trigger_elevator},
    185 	{"trigger_gravity", SP_trigger_gravity},
    186 	{"trigger_monsterjump", SP_trigger_monsterjump},
    187 
    188 	{"target_temp_entity", SP_target_temp_entity},
    189 	{"target_speaker", SP_target_speaker},
    190 	{"target_explosion", SP_target_explosion},
    191 	{"target_changelevel", SP_target_changelevel},
    192 	{"target_secret", SP_target_secret},
    193 	{"target_goal", SP_target_goal},
    194 	{"target_splash", SP_target_splash},
    195 	{"target_spawner", SP_target_spawner},
    196 	{"target_blaster", SP_target_blaster},
    197 	{"target_crosslevel_trigger", SP_target_crosslevel_trigger},
    198 	{"target_crosslevel_target", SP_target_crosslevel_target},
    199 	{"target_laser", SP_target_laser},
    200 	{"target_help", SP_target_help},
    201 	{"target_actor", SP_target_actor},
    202 	{"target_lightramp", SP_target_lightramp},
    203 	{"target_earthquake", SP_target_earthquake},
    204 	{"target_character", SP_target_character},
    205 	{"target_string", SP_target_string},
    206 
    207 	{"worldspawn", SP_worldspawn},
    208 	{"viewthing", SP_viewthing},
    209 
    210 	{"light", SP_light},
    211 	{"light_mine1", SP_light_mine1},
    212 	{"light_mine2", SP_light_mine2},
    213 	{"info_null", SP_info_null},
    214 	{"func_group", SP_info_null},
    215 	{"info_notnull", SP_info_notnull},
    216 	{"path_corner", SP_path_corner},
    217 	{"point_combat", SP_point_combat},
    218 
    219 	{"misc_explobox", SP_misc_explobox},
    220 	{"misc_banner", SP_misc_banner},
    221 	{"misc_satellite_dish", SP_misc_satellite_dish},
    222 	{"misc_actor", SP_misc_actor},
    223 	{"misc_gib_arm", SP_misc_gib_arm},
    224 	{"misc_gib_leg", SP_misc_gib_leg},
    225 	{"misc_gib_head", SP_misc_gib_head},
    226 	{"misc_insane", SP_misc_insane},
    227 	{"misc_deadsoldier", SP_misc_deadsoldier},
    228 	{"misc_viper", SP_misc_viper},
    229 	{"misc_viper_bomb", SP_misc_viper_bomb},
    230 	{"misc_bigviper", SP_misc_bigviper},
    231 	{"misc_strogg_ship", SP_misc_strogg_ship},
    232 	{"misc_teleporter", SP_misc_teleporter},
    233 	{"misc_teleporter_dest", SP_misc_teleporter_dest},
    234 	{"misc_blackhole", SP_misc_blackhole},
    235 	{"misc_eastertank", SP_misc_eastertank},
    236 	{"misc_easterchick", SP_misc_easterchick},
    237 	{"misc_easterchick2", SP_misc_easterchick2},
    238 
    239 	{"monster_berserk", SP_monster_berserk},
    240 	{"monster_gladiator", SP_monster_gladiator},
    241 	{"monster_gunner", SP_monster_gunner},
    242 	{"monster_infantry", SP_monster_infantry},
    243 	{"monster_soldier_light", SP_monster_soldier_light},
    244 	{"monster_soldier", SP_monster_soldier},
    245 	{"monster_soldier_ss", SP_monster_soldier_ss},
    246 	{"monster_tank", SP_monster_tank},
    247 	{"monster_tank_commander", SP_monster_tank},
    248 	{"monster_medic", SP_monster_medic},
    249 	{"monster_flipper", SP_monster_flipper},
    250 	{"monster_chick", SP_monster_chick},
    251 	{"monster_parasite", SP_monster_parasite},
    252 	{"monster_flyer", SP_monster_flyer},
    253 	{"monster_brain", SP_monster_brain},
    254 	{"monster_floater", SP_monster_floater},
    255 	{"monster_hover", SP_monster_hover},
    256 	{"monster_mutant", SP_monster_mutant},
    257 	{"monster_supertank", SP_monster_supertank},
    258 	{"monster_boss2", SP_monster_boss2},
    259 	{"monster_boss3_stand", SP_monster_boss3_stand},
    260 	{"monster_jorg", SP_monster_jorg},
    261 
    262 	{"monster_commander_body", SP_monster_commander_body},
    263 
    264 	{"turret_breach", SP_turret_breach},
    265 	{"turret_base", SP_turret_base},
    266 	{"turret_driver", SP_turret_driver},
    267 
    268 	{NULL, NULL}
    269 };
    270 
    271 /*
    272 ===============
    273 ED_CallSpawn
    274 
    275 Finds the spawn function for the entity and calls it
    276 ===============
    277 */
    278 void ED_CallSpawn (edict_t *ent)
    279 {
    280 	spawn_t	*s;
    281 	gitem_t	*item;
    282 	int		i;
    283 
    284 	if (!ent->classname)
    285 	{
    286 		gi.dprintf ("ED_CallSpawn: NULL classname\n");
    287 		return;
    288 	}
    289 
    290 	// check item spawn functions
    291 	for (i=0,item=itemlist ; i<game.num_items ; i++,item++)
    292 	{
    293 		if (!item->classname)
    294 			continue;
    295 		if (!strcmp(item->classname, ent->classname))
    296 		{	// found it
    297 			SpawnItem (ent, item);
    298 			return;
    299 		}
    300 	}
    301 
    302 	// check normal spawn functions
    303 	for (s=spawns ; s->name ; s++)
    304 	{
    305 		if (!strcmp(s->name, ent->classname))
    306 		{	// found it
    307 			s->spawn (ent);
    308 			return;
    309 		}
    310 	}
    311 	gi.dprintf ("%s doesn't have a spawn function\n", ent->classname);
    312 }
    313 
    314 /*
    315 =============
    316 ED_NewString
    317 =============
    318 */
    319 char *ED_NewString (char *string)
    320 {
    321 	char	*newb, *new_p;
    322 	int		i,l;
    323 	
    324 	l = strlen(string) + 1;
    325 
    326 	newb = gi.TagMalloc (l, TAG_LEVEL);
    327 
    328 	new_p = newb;
    329 
    330 	for (i=0 ; i< l ; i++)
    331 	{
    332 		if (string[i] == '\\' && i < l-1)
    333 		{
    334 			i++;
    335 			if (string[i] == 'n')
    336 				*new_p++ = '\n';
    337 			else
    338 				*new_p++ = '\\';
    339 		}
    340 		else
    341 			*new_p++ = string[i];
    342 	}
    343 	
    344 	return newb;
    345 }
    346 
    347 
    348 
    349 
    350 /*
    351 ===============
    352 ED_ParseField
    353 
    354 Takes a key/value pair and sets the binary values
    355 in an edict
    356 ===============
    357 */
    358 void ED_ParseField (char *key, char *value, edict_t *ent)
    359 {
    360 	field_t	*f;
    361 	byte	*b;
    362 	float	v;
    363 	vec3_t	vec;
    364 
    365 	for (f=fields ; f->name ; f++)
    366 	{
    367 		if (!(f->flags & FFL_NOSPAWN) && !Q_stricmp(f->name, key))
    368 		{	// found it
    369 			if (f->flags & FFL_SPAWNTEMP)
    370 				b = (byte *)&st;
    371 			else
    372 				b = (byte *)ent;
    373 
    374 			switch (f->type)
    375 			{
    376 			case F_LSTRING:
    377 				*(char **)(b+f->ofs) = ED_NewString (value);
    378 				break;
    379 			case F_VECTOR:
    380 				sscanf (value, "%f %f %f", &vec[0], &vec[1], &vec[2]);
    381 				((float *)(b+f->ofs))[0] = vec[0];
    382 				((float *)(b+f->ofs))[1] = vec[1];
    383 				((float *)(b+f->ofs))[2] = vec[2];
    384 				break;
    385 			case F_INT:
    386 				*(int *)(b+f->ofs) = atoi(value);
    387 				break;
    388 			case F_FLOAT:
    389 				*(float *)(b+f->ofs) = atof(value);
    390 				break;
    391 			case F_ANGLEHACK:
    392 				v = atof(value);
    393 				((float *)(b+f->ofs))[0] = 0;
    394 				((float *)(b+f->ofs))[1] = v;
    395 				((float *)(b+f->ofs))[2] = 0;
    396 				break;
    397 			case F_IGNORE:
    398 				break;
    399 			}
    400 			return;
    401 		}
    402 	}
    403 	gi.dprintf ("%s is not a field\n", key);
    404 }
    405 
    406 /*
    407 ====================
    408 ED_ParseEdict
    409 
    410 Parses an edict out of the given string, returning the new position
    411 ed should be a properly initialized empty edict.
    412 ====================
    413 */
    414 char *ED_ParseEdict (char *data, edict_t *ent)
    415 {
    416 	qboolean	init;
    417 	char		keyname[256];
    418 	char		*com_token;
    419 
    420 	init = false;
    421 	memset (&st, 0, sizeof(st));
    422 
    423 // go through all the dictionary pairs
    424 	while (1)
    425 	{	
    426 	// parse key
    427 		com_token = COM_Parse (&data);
    428 		if (com_token[0] == '}')
    429 			break;
    430 		if (!data)
    431 			gi.error ("ED_ParseEntity: EOF without closing brace");
    432 
    433 		strncpy (keyname, com_token, sizeof(keyname)-1);
    434 		
    435 	// parse value	
    436 		com_token = COM_Parse (&data);
    437 		if (!data)
    438 			gi.error ("ED_ParseEntity: EOF without closing brace");
    439 
    440 		if (com_token[0] == '}')
    441 			gi.error ("ED_ParseEntity: closing brace without data");
    442 
    443 		init = true;	
    444 
    445 	// keynames with a leading underscore are used for utility comments,
    446 	// and are immediately discarded by quake
    447 		if (keyname[0] == '_')
    448 			continue;
    449 
    450 		ED_ParseField (keyname, com_token, ent);
    451 	}
    452 
    453 	if (!init)
    454 		memset (ent, 0, sizeof(*ent));
    455 
    456 	return data;
    457 }
    458 
    459 
    460 /*
    461 ================
    462 G_FindTeams
    463 
    464 Chain together all entities with a matching team field.
    465 
    466 All but the first will have the FL_TEAMSLAVE flag set.
    467 All but the last will have the teamchain field set to the next one
    468 ================
    469 */
    470 void G_FindTeams (void)
    471 {
    472 	edict_t	*e, *e2, *chain;
    473 	int		i, j;
    474 	int		c, c2;
    475 
    476 	c = 0;
    477 	c2 = 0;
    478 	for (i=1, e=g_edicts+i ; i < globals.num_edicts ; i++,e++)
    479 	{
    480 		if (!e->inuse)
    481 			continue;
    482 		if (!e->team)
    483 			continue;
    484 		if (e->flags & FL_TEAMSLAVE)
    485 			continue;
    486 		chain = e;
    487 		e->teammaster = e;
    488 		c++;
    489 		c2++;
    490 		for (j=i+1, e2=e+1 ; j < globals.num_edicts ; j++,e2++)
    491 		{
    492 			if (!e2->inuse)
    493 				continue;
    494 			if (!e2->team)
    495 				continue;
    496 			if (e2->flags & FL_TEAMSLAVE)
    497 				continue;
    498 			if (!strcmp(e->team, e2->team))
    499 			{
    500 				c2++;
    501 				chain->teamchain = e2;
    502 				e2->teammaster = e;
    503 				chain = e2;
    504 				e2->flags |= FL_TEAMSLAVE;
    505 			}
    506 		}
    507 	}
    508 
    509 	gi.dprintf ("%i teams with %i entities\n", c, c2);
    510 }
    511 
    512 /*
    513 ==============
    514 SpawnEntities
    515 
    516 Creates a server's entity / program execution context by
    517 parsing textual entity definitions out of an ent file.
    518 ==============
    519 */
    520 void SpawnEntities (char *mapname, char *entities, char *spawnpoint)
    521 {
    522 	edict_t		*ent;
    523 	int			inhibit;
    524 	char		*com_token;
    525 	int			i;
    526 	float		skill_level;
    527 
    528 	skill_level = floor (skill->value);
    529 	if (skill_level < 0)
    530 		skill_level = 0;
    531 	if (skill_level > 3)
    532 		skill_level = 3;
    533 	if (skill->value != skill_level)
    534 		gi.cvar_forceset("skill", va("%f", skill_level));
    535 
    536 	SaveClientData ();
    537 
    538 	gi.FreeTags (TAG_LEVEL);
    539 
    540 	memset (&level, 0, sizeof(level));
    541 	memset (g_edicts, 0, game.maxentities * sizeof (g_edicts[0]));
    542 
    543 	strncpy (level.mapname, mapname, sizeof(level.mapname)-1);
    544 	strncpy (game.spawnpoint, spawnpoint, sizeof(game.spawnpoint)-1);
    545 
    546 	// set client fields on player ents
    547 	for (i=0 ; i<game.maxclients ; i++)
    548 		g_edicts[i+1].client = game.clients + i;
    549 
    550 	ent = NULL;
    551 	inhibit = 0;
    552 
    553 // parse ents
    554 	while (1)
    555 	{
    556 		// parse the opening brace	
    557 		com_token = COM_Parse (&entities);
    558 		if (!entities)
    559 			break;
    560 		if (com_token[0] != '{')
    561 			gi.error ("ED_LoadFromFile: found %s when expecting {",com_token);
    562 
    563 		if (!ent)
    564 			ent = g_edicts;
    565 		else
    566 			ent = G_Spawn ();
    567 		entities = ED_ParseEdict (entities, ent);
    568 
    569 		// yet another map hack
    570 		if (!Q_stricmp(level.mapname, "command") && !Q_stricmp(ent->classname, "trigger_once") && !Q_stricmp(ent->model, "*27"))
    571 			ent->spawnflags &= ~SPAWNFLAG_NOT_HARD;
    572 
    573 		// remove things (except the world) from different skill levels or deathmatch
    574 		if (ent != g_edicts)
    575 		{
    576 			if (deathmatch->value)
    577 			{
    578 				if ( ent->spawnflags & SPAWNFLAG_NOT_DEATHMATCH )
    579 				{
    580 					G_FreeEdict (ent);	
    581 					inhibit++;
    582 					continue;
    583 				}
    584 			}
    585 			else
    586 			{
    587 				if ( /* ((coop->value) && (ent->spawnflags & SPAWNFLAG_NOT_COOP)) || */
    588 					((skill->value == 0) && (ent->spawnflags & SPAWNFLAG_NOT_EASY)) ||
    589 					((skill->value == 1) && (ent->spawnflags & SPAWNFLAG_NOT_MEDIUM)) ||
    590 					(((skill->value == 2) || (skill->value == 3)) && (ent->spawnflags & SPAWNFLAG_NOT_HARD))
    591 					)
    592 					{
    593 						G_FreeEdict (ent);	
    594 						inhibit++;
    595 						continue;
    596 					}
    597 			}
    598 
    599 			ent->spawnflags &= ~(SPAWNFLAG_NOT_EASY|SPAWNFLAG_NOT_MEDIUM|SPAWNFLAG_NOT_HARD|SPAWNFLAG_NOT_COOP|SPAWNFLAG_NOT_DEATHMATCH);
    600 		}
    601 
    602 		ED_CallSpawn (ent);
    603 	}	
    604 
    605 	gi.dprintf ("%i entities inhibited\n", inhibit);
    606 
    607 #ifdef DEBUG
    608 	i = 1;
    609 	ent = EDICT_NUM(i);
    610 	while (i < globals.num_edicts) {
    611 		if (ent->inuse != 0 || ent->inuse != 1)
    612 			Com_DPrintf("Invalid entity %d\n", i);
    613 		i++, ent++;
    614 	}
    615 #endif
    616 
    617 	G_FindTeams ();
    618 
    619 	PlayerTrail_Init ();
    620 }
    621 
    622 
    623 //===================================================================
    624 
    625 #if 0
    626 	// cursor positioning
    627 	xl <value>
    628 	xr <value>
    629 	yb <value>
    630 	yt <value>
    631 	xv <value>
    632 	yv <value>
    633 
    634 	// drawing
    635 	statpic <name>
    636 	pic <stat>
    637 	num <fieldwidth> <stat>
    638 	string <stat>
    639 
    640 	// control
    641 	if <stat>
    642 	ifeq <stat> <value>
    643 	ifbit <stat> <value>
    644 	endif
    645 
    646 #endif
    647 
    648 char *single_statusbar = 
    649 "yb	-24 "
    650 
    651 // health
    652 "xv	0 "
    653 "hnum "
    654 "xv	50 "
    655 "pic 0 "
    656 
    657 // ammo
    658 "if 2 "
    659 "	xv	100 "
    660 "	anum "
    661 "	xv	150 "
    662 "	pic 2 "
    663 "endif "
    664 
    665 // armor
    666 "if 4 "
    667 "	xv	200 "
    668 "	rnum "
    669 "	xv	250 "
    670 "	pic 4 "
    671 "endif "
    672 
    673 // selected item
    674 "if 6 "
    675 "	xv	296 "
    676 "	pic 6 "
    677 "endif "
    678 
    679 "yb	-50 "
    680 
    681 // picked up item
    682 "if 7 "
    683 "	xv	0 "
    684 "	pic 7 "
    685 "	xv	26 "
    686 "	yb	-42 "
    687 "	stat_string 8 "
    688 "	yb	-50 "
    689 "endif "
    690 
    691 // timer
    692 "if 9 "
    693 "	xv	262 "
    694 "	num	2	10 "
    695 "	xv	296 "
    696 "	pic	9 "
    697 "endif "
    698 
    699 //  help / weapon icon 
    700 "if 11 "
    701 "	xv	148 "
    702 "	pic	11 "
    703 "endif "
    704 ;
    705 
    706 char *dm_statusbar =
    707 "yb	-24 "
    708 
    709 // health
    710 "xv	0 "
    711 "hnum "
    712 "xv	50 "
    713 "pic 0 "
    714 
    715 // ammo
    716 "if 2 "
    717 "	xv	100 "
    718 "	anum "
    719 "	xv	150 "
    720 "	pic 2 "
    721 "endif "
    722 
    723 // armor
    724 "if 4 "
    725 "	xv	200 "
    726 "	rnum "
    727 "	xv	250 "
    728 "	pic 4 "
    729 "endif "
    730 
    731 // selected item
    732 "if 6 "
    733 "	xv	296 "
    734 "	pic 6 "
    735 "endif "
    736 
    737 "yb	-50 "
    738 
    739 // picked up item
    740 "if 7 "
    741 "	xv	0 "
    742 "	pic 7 "
    743 "	xv	26 "
    744 "	yb	-42 "
    745 "	stat_string 8 "
    746 "	yb	-50 "
    747 "endif "
    748 
    749 // timer
    750 "if 9 "
    751 "	xv	246 "
    752 "	num	2	10 "
    753 "	xv	296 "
    754 "	pic	9 "
    755 "endif "
    756 
    757 //  help / weapon icon 
    758 "if 11 "
    759 "	xv	148 "
    760 "	pic	11 "
    761 "endif "
    762 
    763 //  frags
    764 "xr	-50 "
    765 "yt 2 "
    766 "num 3 14 "
    767 
    768 // spectator
    769 "if 17 "
    770   "xv 0 "
    771   "yb -58 "
    772   "string2 \"SPECTATOR MODE\" "
    773 "endif "
    774 
    775 // chase camera
    776 "if 16 "
    777   "xv 0 "
    778   "yb -68 "
    779   "string \"Chasing\" "
    780   "xv 64 "
    781   "stat_string 16 "
    782 "endif "
    783 ;
    784 
    785 
    786 /*QUAKED worldspawn (0 0 0) ?
    787 
    788 Only used for the world.
    789 "sky"	environment map name
    790 "skyaxis"	vector axis for rotating sky
    791 "skyrotate"	speed of rotation in degrees/second
    792 "sounds"	music cd track number
    793 "gravity"	800 is default gravity
    794 "message"	text to print at user logon
    795 */
    796 void SP_worldspawn (edict_t *ent)
    797 {
    798 	ent->movetype = MOVETYPE_PUSH;
    799 	ent->solid = SOLID_BSP;
    800 	ent->inuse = true;			// since the world doesn't use G_Spawn()
    801 	ent->s.modelindex = 1;		// world model is always index 1
    802 
    803 	//---------------
    804 
    805 	// reserve some spots for dead player bodies for coop / deathmatch
    806 	InitBodyQue ();
    807 
    808 	// set configstrings for items
    809 	SetItemNames ();
    810 
    811 	if (st.nextmap)
    812 		strcpy (level.nextmap, st.nextmap);
    813 
    814 	// make some data visible to the server
    815 
    816 	if (ent->message && ent->message[0])
    817 	{
    818 		gi.configstring (CS_NAME, ent->message);
    819 		strncpy (level.level_name, ent->message, sizeof(level.level_name));
    820 	}
    821 	else
    822 		strncpy (level.level_name, level.mapname, sizeof(level.level_name));
    823 
    824 	if (st.sky && st.sky[0])
    825 		gi.configstring (CS_SKY, st.sky);
    826 	else
    827 		gi.configstring (CS_SKY, "unit1_");
    828 
    829 	gi.configstring (CS_SKYROTATE, va("%f", st.skyrotate) );
    830 
    831 	gi.configstring (CS_SKYAXIS, va("%f %f %f",
    832 		st.skyaxis[0], st.skyaxis[1], st.skyaxis[2]) );
    833 
    834 	gi.configstring (CS_CDTRACK, va("%i", ent->sounds) );
    835 
    836 	gi.configstring (CS_MAXCLIENTS, va("%i", (int)(maxclients->value) ) );
    837 
    838 	// status bar program
    839 	if (deathmatch->value)
    840 		gi.configstring (CS_STATUSBAR, dm_statusbar);
    841 	else
    842 		gi.configstring (CS_STATUSBAR, single_statusbar);
    843 
    844 	//---------------
    845 
    846 
    847 	// help icon for statusbar
    848 	gi.imageindex ("i_help");
    849 	level.pic_health = gi.imageindex ("i_health");
    850 	gi.imageindex ("help");
    851 	gi.imageindex ("field_3");
    852 
    853 	if (!st.gravity)
    854 		gi.cvar_set("sv_gravity", "800");
    855 	else
    856 		gi.cvar_set("sv_gravity", st.gravity);
    857 
    858 	snd_fry = gi.soundindex ("player/fry.wav");	// standing in lava / slime
    859 
    860 	PrecacheItem (FindItem ("Blaster"));
    861 
    862 	gi.soundindex ("player/lava1.wav");
    863 	gi.soundindex ("player/lava2.wav");
    864 
    865 	gi.soundindex ("misc/pc_up.wav");
    866 	gi.soundindex ("misc/talk1.wav");
    867 
    868 	gi.soundindex ("misc/udeath.wav");
    869 
    870 	// gibs
    871 	gi.soundindex ("items/respawn1.wav");
    872 
    873 	// sexed sounds
    874 	gi.soundindex ("*death1.wav");
    875 	gi.soundindex ("*death2.wav");
    876 	gi.soundindex ("*death3.wav");
    877 	gi.soundindex ("*death4.wav");
    878 	gi.soundindex ("*fall1.wav");
    879 	gi.soundindex ("*fall2.wav");	
    880 	gi.soundindex ("*gurp1.wav");		// drowning damage
    881 	gi.soundindex ("*gurp2.wav");	
    882 	gi.soundindex ("*jump1.wav");		// player jump
    883 	gi.soundindex ("*pain25_1.wav");
    884 	gi.soundindex ("*pain25_2.wav");
    885 	gi.soundindex ("*pain50_1.wav");
    886 	gi.soundindex ("*pain50_2.wav");
    887 	gi.soundindex ("*pain75_1.wav");
    888 	gi.soundindex ("*pain75_2.wav");
    889 	gi.soundindex ("*pain100_1.wav");
    890 	gi.soundindex ("*pain100_2.wav");
    891 
    892 	// sexed models
    893 	// THIS ORDER MUST MATCH THE DEFINES IN g_local.h
    894 	// you can add more, max 15
    895 	gi.modelindex ("#w_blaster.md2");
    896 	gi.modelindex ("#w_shotgun.md2");
    897 	gi.modelindex ("#w_sshotgun.md2");
    898 	gi.modelindex ("#w_machinegun.md2");
    899 	gi.modelindex ("#w_chaingun.md2");
    900 	gi.modelindex ("#a_grenades.md2");
    901 	gi.modelindex ("#w_glauncher.md2");
    902 	gi.modelindex ("#w_rlauncher.md2");
    903 	gi.modelindex ("#w_hyperblaster.md2");
    904 	gi.modelindex ("#w_railgun.md2");
    905 	gi.modelindex ("#w_bfg.md2");
    906 
    907 	//-------------------
    908 
    909 	gi.soundindex ("player/gasp1.wav");		// gasping for air
    910 	gi.soundindex ("player/gasp2.wav");		// head breaking surface, not gasping
    911 
    912 	gi.soundindex ("player/watr_in.wav");	// feet hitting water
    913 	gi.soundindex ("player/watr_out.wav");	// feet leaving water
    914 
    915 	gi.soundindex ("player/watr_un.wav");	// head going underwater
    916 	
    917 	gi.soundindex ("player/u_breath1.wav");
    918 	gi.soundindex ("player/u_breath2.wav");
    919 
    920 	gi.soundindex ("items/pkup.wav");		// bonus item pickup
    921 	gi.soundindex ("world/land.wav");		// landing thud
    922 	gi.soundindex ("misc/h2ohit1.wav");		// landing splash
    923 
    924 	gi.soundindex ("items/damage.wav");
    925 	gi.soundindex ("items/protect.wav");
    926 	gi.soundindex ("items/protect4.wav");
    927 	gi.soundindex ("weapons/noammo.wav");
    928 
    929 	gi.soundindex ("infantry/inflies1.wav");
    930 
    931 	sm_meat_index = gi.modelindex ("models/objects/gibs/sm_meat/tris.md2");
    932 	gi.modelindex ("models/objects/gibs/arm/tris.md2");
    933 	gi.modelindex ("models/objects/gibs/bone/tris.md2");
    934 	gi.modelindex ("models/objects/gibs/bone2/tris.md2");
    935 	gi.modelindex ("models/objects/gibs/chest/tris.md2");
    936 	gi.modelindex ("models/objects/gibs/skull/tris.md2");
    937 	gi.modelindex ("models/objects/gibs/head2/tris.md2");
    938 
    939 //
    940 // Setup light animation tables. 'a' is total darkness, 'z' is doublebright.
    941 //
    942 
    943 	// 0 normal
    944 	gi.configstring(CS_LIGHTS+0, "m");
    945 	
    946 	// 1 FLICKER (first variety)
    947 	gi.configstring(CS_LIGHTS+1, "mmnmmommommnonmmonqnmmo");
    948 	
    949 	// 2 SLOW STRONG PULSE
    950 	gi.configstring(CS_LIGHTS+2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");
    951 	
    952 	// 3 CANDLE (first variety)
    953 	gi.configstring(CS_LIGHTS+3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg");
    954 	
    955 	// 4 FAST STROBE
    956 	gi.configstring(CS_LIGHTS+4, "mamamamamama");
    957 	
    958 	// 5 GENTLE PULSE 1
    959 	gi.configstring(CS_LIGHTS+5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj");
    960 	
    961 	// 6 FLICKER (second variety)
    962 	gi.configstring(CS_LIGHTS+6, "nmonqnmomnmomomno");
    963 	
    964 	// 7 CANDLE (second variety)
    965 	gi.configstring(CS_LIGHTS+7, "mmmaaaabcdefgmmmmaaaammmaamm");
    966 	
    967 	// 8 CANDLE (third variety)
    968 	gi.configstring(CS_LIGHTS+8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");
    969 	
    970 	// 9 SLOW STROBE (fourth variety)
    971 	gi.configstring(CS_LIGHTS+9, "aaaaaaaazzzzzzzz");
    972 	
    973 	// 10 FLUORESCENT FLICKER
    974 	gi.configstring(CS_LIGHTS+10, "mmamammmmammamamaaamammma");
    975 
    976 	// 11 SLOW PULSE NOT FADE TO BLACK
    977 	gi.configstring(CS_LIGHTS+11, "abcdefghijklmnopqrrqponmlkjihgfedcba");
    978 	
    979 	// styles 32-62 are assigned by the light program for switchable lights
    980 
    981 	// 63 testing
    982 	gi.configstring(CS_LIGHTS+63, "a");
    983 }
    984