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 #define Function(f) {#f, f}
24 
25 mmove_t mmove_reloc;
26 
27 field_t fields[] = {
28 	{"classname", FOFS(classname), F_LSTRING},
29 	{"model", FOFS(model), F_LSTRING},
30 	{"spawnflags", FOFS(spawnflags), F_INT},
31 	{"speed", FOFS(speed), F_FLOAT},
32 	{"accel", FOFS(accel), F_FLOAT},
33 	{"decel", FOFS(decel), F_FLOAT},
34 	{"target", FOFS(target), F_LSTRING},
35 	{"targetname", FOFS(targetname), F_LSTRING},
36 	{"pathtarget", FOFS(pathtarget), F_LSTRING},
37 	{"deathtarget", FOFS(deathtarget), F_LSTRING},
38 	{"killtarget", FOFS(killtarget), F_LSTRING},
39 	{"combattarget", FOFS(combattarget), F_LSTRING},
40 	{"message", FOFS(message), F_LSTRING},
41 	{"team", FOFS(team), F_LSTRING},
42 	{"wait", FOFS(wait), F_FLOAT},
43 	{"delay", FOFS(delay), F_FLOAT},
44 	{"random", FOFS(random), F_FLOAT},
45 	{"move_origin", FOFS(move_origin), F_VECTOR},
46 	{"move_angles", FOFS(move_angles), F_VECTOR},
47 	{"style", FOFS(style), F_INT},
48 	{"count", FOFS(count), F_INT},
49 	{"health", FOFS(health), F_INT},
50 	{"sounds", FOFS(sounds), F_INT},
51 	{"light", 0, F_IGNORE},
52 	{"dmg", FOFS(dmg), F_INT},
53 	{"mass", FOFS(mass), F_INT},
54 	{"volume", FOFS(volume), F_FLOAT},
55 	{"attenuation", FOFS(attenuation), F_FLOAT},
56 	{"map", FOFS(map), F_LSTRING},
57 	{"origin", FOFS(s.origin), F_VECTOR},
58 	{"angles", FOFS(s.angles), F_VECTOR},
59 	{"angle", FOFS(s.angles), F_ANGLEHACK},
60 
61 	{"goalentity", FOFS(goalentity), F_EDICT, FFL_NOSPAWN},
62 	{"movetarget", FOFS(movetarget), F_EDICT, FFL_NOSPAWN},
63 	{"enemy", FOFS(enemy), F_EDICT, FFL_NOSPAWN},
64 	{"oldenemy", FOFS(oldenemy), F_EDICT, FFL_NOSPAWN},
65 	{"activator", FOFS(activator), F_EDICT, FFL_NOSPAWN},
66 	{"groundentity", FOFS(groundentity), F_EDICT, FFL_NOSPAWN},
67 	{"teamchain", FOFS(teamchain), F_EDICT, FFL_NOSPAWN},
68 	{"teammaster", FOFS(teammaster), F_EDICT, FFL_NOSPAWN},
69 	{"owner", FOFS(owner), F_EDICT, FFL_NOSPAWN},
70 	{"mynoise", FOFS(mynoise), F_EDICT, FFL_NOSPAWN},
71 	{"mynoise2", FOFS(mynoise2), F_EDICT, FFL_NOSPAWN},
72 	{"target_ent", FOFS(target_ent), F_EDICT, FFL_NOSPAWN},
73 	{"chain", FOFS(chain), F_EDICT, FFL_NOSPAWN},
74 
75 	{"prethink", FOFS(prethink), F_FUNCTION, FFL_NOSPAWN},
76 	{"think", FOFS(think), F_FUNCTION, FFL_NOSPAWN},
77 	{"blocked", FOFS(blocked), F_FUNCTION, FFL_NOSPAWN},
78 	{"touch", FOFS(touch), F_FUNCTION, FFL_NOSPAWN},
79 	{"use", FOFS(use), F_FUNCTION, FFL_NOSPAWN},
80 	{"pain", FOFS(pain), F_FUNCTION, FFL_NOSPAWN},
81 	{"die", FOFS(die), F_FUNCTION, FFL_NOSPAWN},
82 
83 	{"stand", FOFS(monsterinfo.stand), F_FUNCTION, FFL_NOSPAWN},
84 	{"idle", FOFS(monsterinfo.idle), F_FUNCTION, FFL_NOSPAWN},
85 	{"search", FOFS(monsterinfo.search), F_FUNCTION, FFL_NOSPAWN},
86 	{"walk", FOFS(monsterinfo.walk), F_FUNCTION, FFL_NOSPAWN},
87 	{"run", FOFS(monsterinfo.run), F_FUNCTION, FFL_NOSPAWN},
88 	{"dodge", FOFS(monsterinfo.dodge), F_FUNCTION, FFL_NOSPAWN},
89 	{"attack", FOFS(monsterinfo.attack), F_FUNCTION, FFL_NOSPAWN},
90 	{"melee", FOFS(monsterinfo.melee), F_FUNCTION, FFL_NOSPAWN},
91 	{"sight", FOFS(monsterinfo.sight), F_FUNCTION, FFL_NOSPAWN},
92 	{"checkattack", FOFS(monsterinfo.checkattack), F_FUNCTION, FFL_NOSPAWN},
93 	{"currentmove", FOFS(monsterinfo.currentmove), F_MMOVE, FFL_NOSPAWN},
94 
95 	{"endfunc", FOFS(moveinfo.endfunc), F_FUNCTION, FFL_NOSPAWN},
96 
97 	// temp spawn vars -- only valid when the spawn function is called
98 	{"lip", STOFS(lip), F_INT, FFL_SPAWNTEMP},
99 	{"distance", STOFS(distance), F_INT, FFL_SPAWNTEMP},
100 	{"height", STOFS(height), F_INT, FFL_SPAWNTEMP},
101 	{"noise", STOFS(noise), F_LSTRING, FFL_SPAWNTEMP},
102 	{"pausetime", STOFS(pausetime), F_FLOAT, FFL_SPAWNTEMP},
103 	{"item", STOFS(item), F_LSTRING, FFL_SPAWNTEMP},
104 
105 //need for item field in edict struct, FFL_SPAWNTEMP item will be skipped on saves
106 	{"item", FOFS(item), F_ITEM},
107 
108 	{"gravity", STOFS(gravity), F_LSTRING, FFL_SPAWNTEMP},
109 	{"sky", STOFS(sky), F_LSTRING, FFL_SPAWNTEMP},
110 	{"skyrotate", STOFS(skyrotate), F_FLOAT, FFL_SPAWNTEMP},
111 	{"skyaxis", STOFS(skyaxis), F_VECTOR, FFL_SPAWNTEMP},
112 	{"minyaw", STOFS(minyaw), F_FLOAT, FFL_SPAWNTEMP},
113 	{"maxyaw", STOFS(maxyaw), F_FLOAT, FFL_SPAWNTEMP},
114 	{"minpitch", STOFS(minpitch), F_FLOAT, FFL_SPAWNTEMP},
115 	{"maxpitch", STOFS(maxpitch), F_FLOAT, FFL_SPAWNTEMP},
116 	{"nextmap", STOFS(nextmap), F_LSTRING, FFL_SPAWNTEMP},
117 
118 	{0, 0, 0, 0}
119 
120 };
121 
122 field_t		levelfields[] =
123 {
124 	{"changemap", LLOFS(changemap), F_LSTRING},
125 
126 	{"sight_client", LLOFS(sight_client), F_EDICT},
127 	{"sight_entity", LLOFS(sight_entity), F_EDICT},
128 	{"sound_entity", LLOFS(sound_entity), F_EDICT},
129 	{"sound2_entity", LLOFS(sound2_entity), F_EDICT},
130 
131 	{NULL, 0, F_INT}
132 };
133 
134 field_t		clientfields[] =
135 {
136 	{"pers.weapon", CLOFS(pers.weapon), F_ITEM},
137 	{"pers.lastweapon", CLOFS(pers.lastweapon), F_ITEM},
138 	{"newweapon", CLOFS(newweapon), F_ITEM},
139 
140 	{NULL, 0, F_INT}
141 };
142 
143 /*
144 ============
145 InitGame
146 
147 This will be called when the dll is first loaded, which
148 only happens when a new game is started or a save game
149 is loaded.
150 ============
151 */
InitGame(void)152 void InitGame (void)
153 {
154 	gi.dprintf ("==== InitGame ====\n");
155 
156 	gun_x = gi.cvar ("gun_x", "0", 0);
157 	gun_y = gi.cvar ("gun_y", "0", 0);
158 	gun_z = gi.cvar ("gun_z", "0", 0);
159 
160 	//FIXME: sv_ prefix is wrong for these
161 	sv_rollspeed = gi.cvar ("sv_rollspeed", "200", 0);
162 	sv_rollangle = gi.cvar ("sv_rollangle", "2", 0);
163 	sv_maxvelocity = gi.cvar ("sv_maxvelocity", "2000", 0);
164 	sv_gravity = gi.cvar ("sv_gravity", "800", 0);
165 
166 	// noset vars
167 	dedicated = gi.cvar ("dedicated", "0", CVAR_NOSET);
168 
169 	// latched vars
170 	sv_cheats = gi.cvar ("cheats", "0", CVAR_SERVERINFO|CVAR_LATCH);
171 	gi.cvar ("gamename", GAMEVERSION , CVAR_SERVERINFO | CVAR_LATCH);
172 	gi.cvar ("gamedate", __DATE__ , CVAR_SERVERINFO | CVAR_LATCH);
173 
174 	maxclients = gi.cvar ("maxclients", "4", CVAR_SERVERINFO | CVAR_LATCH);
175 	maxspectators = gi.cvar ("maxspectators", "4", CVAR_SERVERINFO);
176 	deathmatch = gi.cvar ("deathmatch", "0", CVAR_LATCH);
177 	coop = gi.cvar ("coop", "0", CVAR_LATCH);
178 	skill = gi.cvar ("skill", "1", CVAR_LATCH);
179 	maxentities = gi.cvar ("maxentities", "1024", CVAR_LATCH);
180 
181 	// change anytime vars
182 	dmflags = gi.cvar ("dmflags", "0", CVAR_SERVERINFO);
183 	fraglimit = gi.cvar ("fraglimit", "0", CVAR_SERVERINFO);
184 	timelimit = gi.cvar ("timelimit", "0", CVAR_SERVERINFO);
185 	password = gi.cvar ("password", "", CVAR_USERINFO);
186 	spectator_password = gi.cvar ("spectator_password", "", CVAR_USERINFO);
187 	needpass = gi.cvar ("needpass", "0", CVAR_SERVERINFO);
188 	filterban = gi.cvar ("filterban", "1", 0);
189 
190 	g_select_empty = gi.cvar ("g_select_empty", "0", CVAR_ARCHIVE);
191 
192 	run_pitch = gi.cvar ("run_pitch", "0.002", 0);
193 	run_roll = gi.cvar ("run_roll", "0.005", 0);
194 	bob_up  = gi.cvar ("bob_up", "0.005", 0);
195 	bob_pitch = gi.cvar ("bob_pitch", "0.002", 0);
196 	bob_roll = gi.cvar ("bob_roll", "0.002", 0);
197 
198 	// flood control
199 	flood_msgs = gi.cvar ("flood_msgs", "4", 0);
200 	flood_persecond = gi.cvar ("flood_persecond", "4", 0);
201 	flood_waitdelay = gi.cvar ("flood_waitdelay", "10", 0);
202 
203 	// dm map list
204 	sv_maplist = gi.cvar ("sv_maplist", "", 0);
205 
206 	// items
207 	InitItems ();
208 
209 	Com_sprintf (game.helpmessage1, sizeof(game.helpmessage1), "");
210 
211 	Com_sprintf (game.helpmessage2, sizeof(game.helpmessage2), "");
212 
213 	// initialize all entities for this game
214 	game.maxentities = maxentities->value;
215 	g_edicts =  gi.TagMalloc (game.maxentities * sizeof(g_edicts[0]), TAG_GAME);
216 	globals.edicts = g_edicts;
217 	globals.max_edicts = game.maxentities;
218 
219 	// initialize all clients for this game
220 	game.maxclients = maxclients->value;
221 	game.clients = gi.TagMalloc (game.maxclients * sizeof(game.clients[0]), TAG_GAME);
222 	globals.num_edicts = game.maxclients+1;
223 }
224 
225 //=========================================================
226 
WriteField1(FILE * f,field_t * field,byte * base)227 void WriteField1 (FILE *f, field_t *field, byte *base)
228 {
229 	void		*p;
230 	int			len;
231 	int			index;
232 
233 	if (field->flags & FFL_SPAWNTEMP)
234 		return;
235 
236 	p = (void *)(base + field->ofs);
237 	switch (field->type)
238 	{
239 	case F_INT:
240 	case F_FLOAT:
241 	case F_ANGLEHACK:
242 	case F_VECTOR:
243 	case F_IGNORE:
244 		break;
245 
246 	case F_LSTRING:
247 	case F_GSTRING:
248 		if ( *(char **)p )
249 			len = strlen(*(char **)p) + 1;
250 		else
251 			len = 0;
252 		*(int *)p = len;
253 		break;
254 	case F_EDICT:
255 		if ( *(edict_t **)p == NULL)
256 			index = -1;
257 		else
258 			index = *(edict_t **)p - g_edicts;
259 		*(int *)p = index;
260 		break;
261 	case F_CLIENT:
262 		if ( *(gclient_t **)p == NULL)
263 			index = -1;
264 		else
265 			index = *(gclient_t **)p - game.clients;
266 		*(int *)p = index;
267 		break;
268 	case F_ITEM:
269 		if ( *(edict_t **)p == NULL)
270 			index = -1;
271 		else
272 			index = *(gitem_t **)p - itemlist;
273 		*(int *)p = index;
274 		break;
275 
276 	//relative to code segment
277 	case F_FUNCTION:
278 		if (*(byte **)p == NULL)
279 			index = 0;
280 		else
281 			index = *(byte **)p - ((byte *)InitGame);
282 		*(int *)p = index;
283 		break;
284 
285 	//relative to data segment
286 	case F_MMOVE:
287 		if (*(byte **)p == NULL)
288 			index = 0;
289 		else
290 			index = *(byte **)p - (byte *)&mmove_reloc;
291 		*(int *)p = index;
292 		break;
293 
294 	default:
295 		gi.error ("WriteEdict: unknown field type");
296 	}
297 }
298 
299 
WriteField2(FILE * f,field_t * field,byte * base)300 void WriteField2 (FILE *f, field_t *field, byte *base)
301 {
302 	int			len;
303 	void		*p;
304 
305 	if (field->flags & FFL_SPAWNTEMP)
306 		return;
307 
308 	p = (void *)(base + field->ofs);
309 	switch (field->type)
310 	{
311 	case F_LSTRING:
312 		if ( *(char **)p )
313 		{
314 			len = strlen(*(char **)p) + 1;
315 			fwrite (*(char **)p, len, 1, f);
316 		}
317 		break;
318 	default:
319 		break;
320 	}
321 }
322 
ReadField(FILE * f,field_t * field,byte * base)323 void ReadField (FILE *f, field_t *field, byte *base)
324 {
325 	void		*p;
326 	int			len;
327 	int			index;
328 
329 	if (field->flags & FFL_SPAWNTEMP)
330 		return;
331 
332 	p = (void *)(base + field->ofs);
333 	switch (field->type)
334 	{
335 	case F_INT:
336 	case F_FLOAT:
337 	case F_ANGLEHACK:
338 	case F_VECTOR:
339 	case F_IGNORE:
340 		break;
341 
342 	case F_LSTRING:
343 		len = *(int *)p;
344 		if (!len)
345 			*(char **)p = NULL;
346 		else
347 		{
348 			*(char **)p = gi.TagMalloc (len, TAG_LEVEL);
349 			fread (*(char **)p, len, 1, f);
350 		}
351 		break;
352 	case F_EDICT:
353 		index = *(int *)p;
354 		if ( index == -1 )
355 			*(edict_t **)p = NULL;
356 		else
357 			*(edict_t **)p = &g_edicts[index];
358 		break;
359 	case F_CLIENT:
360 		index = *(int *)p;
361 		if ( index == -1 )
362 			*(gclient_t **)p = NULL;
363 		else
364 			*(gclient_t **)p = &game.clients[index];
365 		break;
366 	case F_ITEM:
367 		index = *(int *)p;
368 		if ( index == -1 )
369 			*(gitem_t **)p = NULL;
370 		else
371 			*(gitem_t **)p = &itemlist[index];
372 		break;
373 
374 	//relative to code segment
375 	case F_FUNCTION:
376 		index = *(int *)p;
377 		if ( index == 0 )
378 			*(byte **)p = NULL;
379 		else
380 			*(byte **)p = ((byte *)InitGame) + index;
381 		break;
382 
383 	//relative to data segment
384 	case F_MMOVE:
385 		index = *(int *)p;
386 		if (index == 0)
387 			*(byte **)p = NULL;
388 		else
389 			*(byte **)p = (byte *)&mmove_reloc + index;
390 		break;
391 
392 	default:
393 		gi.error ("ReadEdict: unknown field type");
394 	}
395 }
396 
397 //=========================================================
398 
399 /*
400 ==============
401 WriteClient
402 
403 All pointer variables (except function pointers) must be handled specially.
404 ==============
405 */
WriteClient(FILE * f,gclient_t * client)406 void WriteClient (FILE *f, gclient_t *client)
407 {
408 	field_t		*field;
409 	gclient_t	temp;
410 
411 	// all of the ints, floats, and vectors stay as they are
412 	temp = *client;
413 
414 	// change the pointers to lengths or indexes
415 	for (field=clientfields ; field->name ; field++)
416 	{
417 		WriteField1 (f, field, (byte *)&temp);
418 	}
419 
420 	// write the block
421 	fwrite (&temp, sizeof(temp), 1, f);
422 
423 	// now write any allocated data following the edict
424 	for (field=clientfields ; field->name ; field++)
425 	{
426 		WriteField2 (f, field, (byte *)client);
427 	}
428 }
429 
430 /*
431 ==============
432 ReadClient
433 
434 All pointer variables (except function pointers) must be handled specially.
435 ==============
436 */
ReadClient(FILE * f,gclient_t * client)437 void ReadClient (FILE *f, gclient_t *client)
438 {
439 	field_t		*field;
440 
441 	fread (client, sizeof(*client), 1, f);
442 
443 	for (field=clientfields ; field->name ; field++)
444 	{
445 		ReadField (f, field, (byte *)client);
446 	}
447 }
448 
449 /*
450 ============
451 WriteGame
452 
453 This will be called whenever the game goes to a new level,
454 and when the user explicitly saves the game.
455 
456 Game information include cross level data, like multi level
457 triggers, help computer info, and all client states.
458 
459 A single player death will automatically restore from the
460 last save position.
461 ============
462 */
WriteGame(char * filename,qboolean autosave)463 void WriteGame (char *filename, qboolean autosave)
464 {
465 	FILE	*f;
466 	int		i;
467 	char	str[16];
468 
469 	if (!autosave)
470 		SaveClientData ();
471 
472 	f = fopen (filename, "wb");
473 	if (!f)
474 		gi.error ("Couldn't open %s", filename);
475 
476 	memset (str, 0, sizeof(str));
477 	strcpy (str, __DATE__);
478 	fwrite (str, sizeof(str), 1, f);
479 
480 	game.autosaved = autosave;
481 	fwrite (&game, sizeof(game), 1, f);
482 	game.autosaved = false;
483 
484 	for (i=0 ; i<game.maxclients ; i++)
485 		WriteClient (f, &game.clients[i]);
486 
487 	fclose (f);
488 }
489 
ReadGame(char * filename)490 void ReadGame (char *filename)
491 {
492 	FILE	*f;
493 	int		i;
494 	char	str[16];
495 
496 	gi.FreeTags (TAG_GAME);
497 
498 	f = fopen (filename, "rb");
499 	if (!f)
500 		gi.error ("Couldn't open %s", filename);
501 
502 	fread (str, sizeof(str), 1, f);
503 	if (strcmp (str, __DATE__))
504 	{
505 		fclose (f);
506 		gi.error ("Savegame from an older version.\n");
507 	}
508 
509 	g_edicts =  gi.TagMalloc (game.maxentities * sizeof(g_edicts[0]), TAG_GAME);
510 	globals.edicts = g_edicts;
511 
512 	fread (&game, sizeof(game), 1, f);
513 	game.clients = gi.TagMalloc (game.maxclients * sizeof(game.clients[0]), TAG_GAME);
514 	for (i=0 ; i<game.maxclients ; i++)
515 		ReadClient (f, &game.clients[i]);
516 
517 	fclose (f);
518 }
519 
520 //==========================================================
521 
522 
523 /*
524 ==============
525 WriteEdict
526 
527 All pointer variables (except function pointers) must be handled specially.
528 ==============
529 */
WriteEdict(FILE * f,edict_t * ent)530 void WriteEdict (FILE *f, edict_t *ent)
531 {
532 	field_t		*field;
533 	edict_t		temp;
534 
535 	// all of the ints, floats, and vectors stay as they are
536 	temp = *ent;
537 
538 	// change the pointers to lengths or indexes
539 	for (field=fields ; field->name ; field++)
540 	{
541 		WriteField1 (f, field, (byte *)&temp);
542 	}
543 
544 	// write the block
545 	fwrite (&temp, sizeof(temp), 1, f);
546 
547 	// now write any allocated data following the edict
548 	for (field=fields ; field->name ; field++)
549 	{
550 		WriteField2 (f, field, (byte *)ent);
551 	}
552 
553 }
554 
555 /*
556 ==============
557 WriteLevelLocals
558 
559 All pointer variables (except function pointers) must be handled specially.
560 ==============
561 */
WriteLevelLocals(FILE * f)562 void WriteLevelLocals (FILE *f)
563 {
564 	field_t		*field;
565 	level_locals_t		temp;
566 
567 	// all of the ints, floats, and vectors stay as they are
568 	temp = level;
569 
570 	// change the pointers to lengths or indexes
571 	for (field=levelfields ; field->name ; field++)
572 	{
573 		WriteField1 (f, field, (byte *)&temp);
574 	}
575 
576 	// write the block
577 	fwrite (&temp, sizeof(temp), 1, f);
578 
579 	// now write any allocated data following the edict
580 	for (field=levelfields ; field->name ; field++)
581 	{
582 		WriteField2 (f, field, (byte *)&level);
583 	}
584 }
585 
586 
587 /*
588 ==============
589 ReadEdict
590 
591 All pointer variables (except function pointers) must be handled specially.
592 ==============
593 */
ReadEdict(FILE * f,edict_t * ent)594 void ReadEdict (FILE *f, edict_t *ent)
595 {
596 	field_t		*field;
597 
598 	fread (ent, sizeof(*ent), 1, f);
599 
600 	for (field=fields ; field->name ; field++)
601 	{
602 		ReadField (f, field, (byte *)ent);
603 	}
604 }
605 
606 /*
607 ==============
608 ReadLevelLocals
609 
610 All pointer variables (except function pointers) must be handled specially.
611 ==============
612 */
ReadLevelLocals(FILE * f)613 void ReadLevelLocals (FILE *f)
614 {
615 	field_t		*field;
616 
617 	fread (&level, sizeof(level), 1, f);
618 
619 	for (field=levelfields ; field->name ; field++)
620 	{
621 		ReadField (f, field, (byte *)&level);
622 	}
623 }
624 
625 /*
626 =================
627 WriteLevel
628 
629 =================
630 */
WriteLevel(char * filename)631 void WriteLevel (char *filename)
632 {
633 	int		i;
634 	edict_t	*ent;
635 	FILE	*f;
636 	void	*base;
637 
638 	f = fopen (filename, "wb");
639 	if (!f)
640 		gi.error ("Couldn't open %s", filename);
641 
642 	// write out edict size for checking
643 	i = sizeof(edict_t);
644 	fwrite (&i, sizeof(i), 1, f);
645 
646 	// write out a function pointer for checking
647 	base = (void *)InitGame;
648 	fwrite (&base, sizeof(base), 1, f);
649 
650 	// write out level_locals_t
651 	WriteLevelLocals (f);
652 
653 	// write out all the entities
654 	for (i=0 ; i<globals.num_edicts ; i++)
655 	{
656 		ent = &g_edicts[i];
657 		if (!ent->inuse)
658 			continue;
659 		fwrite (&i, sizeof(i), 1, f);
660 		WriteEdict (f, ent);
661 	}
662 	i = -1;
663 	fwrite (&i, sizeof(i), 1, f);
664 
665 	fclose (f);
666 }
667 
668 
669 /*
670 =================
671 ReadLevel
672 
673 SpawnEntities will allready have been called on the
674 level the same way it was when the level was saved.
675 
676 That is necessary to get the baselines
677 set up identically.
678 
679 The server will have cleared all of the world links before
680 calling ReadLevel.
681 
682 No clients are connected yet.
683 =================
684 */
ReadLevel(char * filename)685 void ReadLevel (char *filename)
686 {
687 	int		entnum;
688 	FILE	*f;
689 	int		i;
690 	void	*base;
691 	edict_t	*ent;
692 
693 	f = fopen (filename, "rb");
694 	if (!f)
695 		gi.error ("Couldn't open %s", filename);
696 
697 	// free any dynamic memory allocated by loading the level
698 	// base state
699 	gi.FreeTags (TAG_LEVEL);
700 
701 	// wipe all the entities
702 	memset (g_edicts, 0, game.maxentities*sizeof(g_edicts[0]));
703 	globals.num_edicts = maxclients->value+1;
704 
705 	// check edict size
706 	fread (&i, sizeof(i), 1, f);
707 	if (i != sizeof(edict_t))
708 	{
709 		fclose (f);
710 		gi.error ("ReadLevel: mismatched edict size");
711 	}
712 
713 	// check function pointer base address
714 	fread (&base, sizeof(base), 1, f);
715 #ifdef _WIN32
716 	if (base != (void *)InitGame)
717 	{
718 		fclose (f);
719 		gi.error ("ReadLevel: function pointers have moved");
720 	}
721 #else
722 	gi.dprintf("Function offsets %d\n", ((byte *)base) - ((byte *)InitGame));
723 #endif
724 
725 	// load the level locals
726 	ReadLevelLocals (f);
727 
728 	// load all the entities
729 	while (1)
730 	{
731 		if (fread (&entnum, sizeof(entnum), 1, f) != 1)
732 		{
733 			fclose (f);
734 			gi.error ("ReadLevel: failed to read entnum");
735 		}
736 		if (entnum == -1)
737 			break;
738 		if (entnum >= globals.num_edicts)
739 			globals.num_edicts = entnum+1;
740 
741 		ent = &g_edicts[entnum];
742 		ReadEdict (f, ent);
743 
744 		// let the server rebuild world links for this ent
745 		memset (&ent->area, 0, sizeof(ent->area));
746 		gi.linkentity (ent);
747 	}
748 
749 	fclose (f);
750 
751 	// mark all clients as unconnected
752 	for (i=0 ; i<maxclients->value ; i++)
753 	{
754 		ent = &g_edicts[i+1];
755 		ent->client = game.clients + i;
756 		ent->client->pers.connected = false;
757 	}
758 
759 	// do any load time things at this point
760 	for (i=0 ; i<globals.num_edicts ; i++)
761 	{
762 		ent = &g_edicts[i];
763 
764 		if (!ent->inuse)
765 			continue;
766 
767 		// fire any cross-level triggers
768 		if (ent->classname)
769 			if (strcmp(ent->classname, "target_crosslevel_target") == 0)
770 				ent->nextthink = level.time + ent->delay;
771 	}
772 }
773