Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5131 clevermous 1
/*
2
Copyright (C) 1996-1997 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
// sv_edict.c -- entity dictionary
21
 
22
#include "quakedef.h"
23
 
24
dprograms_t		*progs;
25
dfunction_t		*pr_functions;
26
char			*pr_strings;
27
ddef_t			*pr_fielddefs;
28
ddef_t			*pr_globaldefs;
29
dstatement_t	*pr_statements;
30
globalvars_t	*pr_global_struct;
31
float			*pr_globals;			// same as pr_global_struct
32
int				pr_edict_size;	// in bytes
33
 
34
unsigned short		pr_crc;
35
 
36
int		type_size[8] = {1,sizeof(string_t)/4,1,3,1,1,sizeof(func_t)/4,sizeof(void *)/4};
37
 
38
ddef_t *ED_FieldAtOfs (int ofs);
39
qboolean	ED_ParseEpair (void *base, ddef_t *key, char *s);
40
 
41
cvar_t	nomonsters = {"nomonsters", "0"};
42
cvar_t	gamecfg = {"gamecfg", "0"};
43
cvar_t	scratch1 = {"scratch1", "0"};
44
cvar_t	scratch2 = {"scratch2", "0"};
45
cvar_t	scratch3 = {"scratch3", "0"};
46
cvar_t	scratch4 = {"scratch4", "0"};
47
cvar_t	savedgamecfg = {"savedgamecfg", "0", true};
48
cvar_t	saved1 = {"saved1", "0", true};
49
cvar_t	saved2 = {"saved2", "0", true};
50
cvar_t	saved3 = {"saved3", "0", true};
51
cvar_t	saved4 = {"saved4", "0", true};
52
 
53
#define	MAX_FIELD_LEN	64
54
#define GEFV_CACHESIZE	2
55
 
56
typedef struct {
57
	ddef_t	*pcache;
58
	char	field[MAX_FIELD_LEN];
59
} gefv_cache;
60
 
61
static gefv_cache	gefvCache[GEFV_CACHESIZE] = {{NULL, ""}, {NULL, ""}};
62
 
63
/*
64
=================
65
ED_ClearEdict
66
 
67
Sets everything to NULL
68
=================
69
*/
70
void ED_ClearEdict (edict_t *e)
71
{
72
	memset (&e->v, 0, progs->entityfields * 4);
73
	e->free = false;
74
}
75
 
76
/*
77
=================
78
ED_Alloc
79
 
80
Either finds a free edict, or allocates a new one.
81
Try to avoid reusing an entity that was recently freed, because it
82
can cause the client to think the entity morphed into something else
83
instead of being removed and recreated, which can cause interpolated
84
angles and bad trails.
85
=================
86
*/
87
edict_t *ED_Alloc (void)
88
{
89
	int			i;
90
	edict_t		*e;
91
 
92
	for ( i=svs.maxclients+1 ; i
93
	{
94
		e = EDICT_NUM(i);
95
		// the first couple seconds of server time can involve a lot of
96
		// freeing and allocating, so relax the replacement policy
97
		if (e->free && ( e->freetime < 2 || sv.time - e->freetime > 0.5 ) )
98
		{
99
			ED_ClearEdict (e);
100
			return e;
101
		}
102
	}
103
 
104
	if (i == MAX_EDICTS)
105
		Sys_Error ("ED_Alloc: no free edicts");
106
 
107
	sv.num_edicts++;
108
	e = EDICT_NUM(i);
109
	ED_ClearEdict (e);
110
 
111
	return e;
112
}
113
 
114
/*
115
=================
116
ED_Free
117
 
118
Marks the edict as free
119
FIXME: walk all entities and NULL out references to this entity
120
=================
121
*/
122
void ED_Free (edict_t *ed)
123
{
124
	SV_UnlinkEdict (ed);		// unlink from world bsp
125
 
126
	ed->free = true;
127
	ed->v.model = 0;
128
	ed->v.takedamage = 0;
129
	ed->v.modelindex = 0;
130
	ed->v.colormap = 0;
131
	ed->v.skin = 0;
132
	ed->v.frame = 0;
133
	VectorCopy (vec3_origin, ed->v.origin);
134
	VectorCopy (vec3_origin, ed->v.angles);
135
	ed->v.nextthink = -1;
136
	ed->v.solid = 0;
137
 
138
	ed->freetime = sv.time;
139
}
140
 
141
//===========================================================================
142
 
143
/*
144
============
145
ED_GlobalAtOfs
146
============
147
*/
148
ddef_t *ED_GlobalAtOfs (int ofs)
149
{
150
	ddef_t		*def;
151
	int			i;
152
 
153
	for (i=0 ; inumglobaldefs ; i++)
154
	{
155
		def = &pr_globaldefs[i];
156
		if (def->ofs == ofs)
157
			return def;
158
	}
159
	return NULL;
160
}
161
 
162
/*
163
============
164
ED_FieldAtOfs
165
============
166
*/
167
ddef_t *ED_FieldAtOfs (int ofs)
168
{
169
	ddef_t		*def;
170
	int			i;
171
 
172
	for (i=0 ; inumfielddefs ; i++)
173
	{
174
		def = &pr_fielddefs[i];
175
		if (def->ofs == ofs)
176
			return def;
177
	}
178
	return NULL;
179
}
180
 
181
/*
182
============
183
ED_FindField
184
============
185
*/
186
ddef_t *ED_FindField (char *name)
187
{
188
	ddef_t		*def;
189
	int			i;
190
 
191
	for (i=0 ; inumfielddefs ; i++)
192
	{
193
		def = &pr_fielddefs[i];
194
		if (!strcmp(pr_strings + def->s_name,name) )
195
			return def;
196
	}
197
	return NULL;
198
}
199
 
200
 
201
/*
202
============
203
ED_FindGlobal
204
============
205
*/
206
ddef_t *ED_FindGlobal (char *name)
207
{
208
	ddef_t		*def;
209
	int			i;
210
 
211
	for (i=0 ; inumglobaldefs ; i++)
212
	{
213
		def = &pr_globaldefs[i];
214
		if (!strcmp(pr_strings + def->s_name,name) )
215
			return def;
216
	}
217
	return NULL;
218
}
219
 
220
 
221
/*
222
============
223
ED_FindFunction
224
============
225
*/
226
dfunction_t *ED_FindFunction (char *name)
227
{
228
	dfunction_t		*func;
229
	int				i;
230
 
231
	for (i=0 ; inumfunctions ; i++)
232
	{
233
		func = &pr_functions[i];
234
		if (!strcmp(pr_strings + func->s_name,name) )
235
			return func;
236
	}
237
	return NULL;
238
}
239
 
240
 
241
eval_t *GetEdictFieldValue(edict_t *ed, char *field)
242
{
243
	ddef_t			*def = NULL;
244
	int				i;
245
	static int		rep = 0;
246
 
247
	for (i=0 ; i
248
	{
249
		if (!strcmp(field, gefvCache[i].field))
250
		{
251
			def = gefvCache[i].pcache;
252
			goto Done;
253
		}
254
	}
255
 
256
	def = ED_FindField (field);
257
 
258
	if (strlen(field) < MAX_FIELD_LEN)
259
	{
260
		gefvCache[rep].pcache = def;
261
		strcpy (gefvCache[rep].field, field);
262
		rep ^= 1;
263
	}
264
 
265
Done:
266
	if (!def)
267
		return NULL;
268
 
269
	return (eval_t *)((char *)&ed->v + def->ofs*4);
270
}
271
 
272
 
273
/*
274
============
275
PR_ValueString
276
 
277
Returns a string describing *data in a type specific manner
278
=============
279
*/
280
char *PR_ValueString (etype_t type, eval_t *val)
281
{
282
	static char	line[256];
283
	ddef_t		*def;
284
	dfunction_t	*f;
285
 
286
	type &= ~DEF_SAVEGLOBAL;
287
 
288
	switch (type)
289
	{
290
	case ev_string:
291
		sprintf (line, "%s", pr_strings + val->string);
292
		break;
293
	case ev_entity:
294
		sprintf (line, "entity %i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)) );
295
		break;
296
	case ev_function:
297
		f = pr_functions + val->function;
298
		sprintf (line, "%s()", pr_strings + f->s_name);
299
		break;
300
	case ev_field:
301
		def = ED_FieldAtOfs ( val->_int );
302
		sprintf (line, ".%s", pr_strings + def->s_name);
303
		break;
304
	case ev_void:
305
		sprintf (line, "void");
306
		break;
307
	case ev_float:
308
		sprintf (line, "%5.1f", val->_float);
309
		break;
310
	case ev_vector:
311
		sprintf (line, "'%5.1f %5.1f %5.1f'", val->vector[0], val->vector[1], val->vector[2]);
312
		break;
313
	case ev_pointer:
314
		sprintf (line, "pointer");
315
		break;
316
	default:
317
		sprintf (line, "bad type %i", type);
318
		break;
319
	}
320
 
321
	return line;
322
}
323
 
324
/*
325
============
326
PR_UglyValueString
327
 
328
Returns a string describing *data in a type specific manner
329
Easier to parse than PR_ValueString
330
=============
331
*/
332
char *PR_UglyValueString (etype_t type, eval_t *val)
333
{
334
	static char	line[256];
335
	ddef_t		*def;
336
	dfunction_t	*f;
337
 
338
	type &= ~DEF_SAVEGLOBAL;
339
 
340
	switch (type)
341
	{
342
	case ev_string:
343
		sprintf (line, "%s", pr_strings + val->string);
344
		break;
345
	case ev_entity:
346
		sprintf (line, "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
347
		break;
348
	case ev_function:
349
		f = pr_functions + val->function;
350
		sprintf (line, "%s", pr_strings + f->s_name);
351
		break;
352
	case ev_field:
353
		def = ED_FieldAtOfs ( val->_int );
354
		sprintf (line, "%s", pr_strings + def->s_name);
355
		break;
356
	case ev_void:
357
		sprintf (line, "void");
358
		break;
359
	case ev_float:
360
		sprintf (line, "%f", val->_float);
361
		break;
362
	case ev_vector:
363
		sprintf (line, "%f %f %f", val->vector[0], val->vector[1], val->vector[2]);
364
		break;
365
	default:
366
		sprintf (line, "bad type %i", type);
367
		break;
368
	}
369
 
370
	return line;
371
}
372
 
373
/*
374
============
375
PR_GlobalString
376
 
377
Returns a string with a description and the contents of a global,
378
padded to 20 field width
379
============
380
*/
381
char *PR_GlobalString (int ofs)
382
{
383
	char	*s;
384
	int		i;
385
	ddef_t	*def;
386
	void	*val;
387
	static char	line[128];
388
 
389
	val = (void *)&pr_globals[ofs];
390
	def = ED_GlobalAtOfs(ofs);
391
	if (!def)
392
		sprintf (line,"%i(???)", ofs);
393
	else
394
	{
395
		s = PR_ValueString (def->type, val);
396
		sprintf (line,"%i(%s)%s", ofs, pr_strings + def->s_name, s);
397
	}
398
 
399
	i = strlen(line);
400
	for ( ; i<20 ; i++)
401
		strcat (line," ");
402
	strcat (line," ");
403
 
404
	return line;
405
}
406
 
407
char *PR_GlobalStringNoContents (int ofs)
408
{
409
	int		i;
410
	ddef_t	*def;
411
	static char	line[128];
412
 
413
	def = ED_GlobalAtOfs(ofs);
414
	if (!def)
415
		sprintf (line,"%i(???)", ofs);
416
	else
417
		sprintf (line,"%i(%s)", ofs, pr_strings + def->s_name);
418
 
419
	i = strlen(line);
420
	for ( ; i<20 ; i++)
421
		strcat (line," ");
422
	strcat (line," ");
423
 
424
	return line;
425
}
426
 
427
 
428
/*
429
=============
430
ED_Print
431
 
432
For debugging
433
=============
434
*/
435
void ED_Print (edict_t *ed)
436
{
437
	int		l;
438
	ddef_t	*d;
439
	int		*v;
440
	int		i, j;
441
	char	*name;
442
	int		type;
443
 
444
	if (ed->free)
445
	{
446
		Con_Printf ("FREE\n");
447
		return;
448
	}
449
 
450
	Con_Printf("\nEDICT %i:\n", NUM_FOR_EDICT(ed));
451
	for (i=1 ; inumfielddefs ; i++)
452
	{
453
		d = &pr_fielddefs[i];
454
		name = pr_strings + d->s_name;
455
		if (name[strlen(name)-2] == '_')
456
			continue;	// skip _x, _y, _z vars
457
 
458
		v = (int *)((char *)&ed->v + d->ofs*4);
459
 
460
	// if the value is still all 0, skip the field
461
		type = d->type & ~DEF_SAVEGLOBAL;
462
 
463
		for (j=0 ; j
464
			if (v[j])
465
				break;
466
		if (j == type_size[type])
467
			continue;
468
 
469
		Con_Printf ("%s",name);
470
		l = strlen (name);
471
		while (l++ < 15)
472
			Con_Printf (" ");
473
 
474
		Con_Printf ("%s\n", PR_ValueString(d->type, (eval_t *)v));
475
	}
476
}
477
 
478
/*
479
=============
480
ED_Write
481
 
482
For savegames
483
=============
484
*/
485
void ED_Write (FILE *f, edict_t *ed)
486
{
487
	ddef_t	*d;
488
	int		*v;
489
	int		i, j;
490
	char	*name;
491
	int		type;
492
 
493
	fprintf (f, "{\n");
494
 
495
	if (ed->free)
496
	{
497
		fprintf (f, "}\n");
498
		return;
499
	}
500
 
501
	for (i=1 ; inumfielddefs ; i++)
502
	{
503
		d = &pr_fielddefs[i];
504
		name = pr_strings + d->s_name;
505
		if (name[strlen(name)-2] == '_')
506
			continue;	// skip _x, _y, _z vars
507
 
508
		v = (int *)((char *)&ed->v + d->ofs*4);
509
 
510
	// if the value is still all 0, skip the field
511
		type = d->type & ~DEF_SAVEGLOBAL;
512
		for (j=0 ; j
513
			if (v[j])
514
				break;
515
		if (j == type_size[type])
516
			continue;
517
 
518
		fprintf (f,"\"%s\" ",name);
519
		fprintf (f,"\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v));
520
	}
521
 
522
	fprintf (f, "}\n");
523
}
524
 
525
void ED_PrintNum (int ent)
526
{
527
	ED_Print (EDICT_NUM(ent));
528
}
529
 
530
/*
531
=============
532
ED_PrintEdicts
533
 
534
For debugging, prints all the entities in the current server
535
=============
536
*/
537
void ED_PrintEdicts (void)
538
{
539
	int		i;
540
 
541
	Con_Printf ("%i entities\n", sv.num_edicts);
542
	for (i=0 ; i
543
		ED_PrintNum (i);
544
}
545
 
546
/*
547
=============
548
ED_PrintEdict_f
549
 
550
For debugging, prints a single edicy
551
=============
552
*/
553
void ED_PrintEdict_f (void)
554
{
555
	int		i;
556
 
557
	i = Q_atoi (Cmd_Argv(1));
558
	if (i >= sv.num_edicts)
559
	{
560
		Con_Printf("Bad edict number\n");
561
		return;
562
	}
563
	ED_PrintNum (i);
564
}
565
 
566
/*
567
=============
568
ED_Count
569
 
570
For debugging
571
=============
572
*/
573
void ED_Count (void)
574
{
575
	int		i;
576
	edict_t	*ent;
577
	int		active, models, solid, step;
578
 
579
	active = models = solid = step = 0;
580
	for (i=0 ; i
581
	{
582
		ent = EDICT_NUM(i);
583
		if (ent->free)
584
			continue;
585
		active++;
586
		if (ent->v.solid)
587
			solid++;
588
		if (ent->v.model)
589
			models++;
590
		if (ent->v.movetype == MOVETYPE_STEP)
591
			step++;
592
	}
593
 
594
	Con_Printf ("num_edicts:%3i\n", sv.num_edicts);
595
	Con_Printf ("active    :%3i\n", active);
596
	Con_Printf ("view      :%3i\n", models);
597
	Con_Printf ("touch     :%3i\n", solid);
598
	Con_Printf ("step      :%3i\n", step);
599
 
600
}
601
 
602
/*
603
==============================================================================
604
 
605
					ARCHIVING GLOBALS
606
 
607
FIXME: need to tag constants, doesn't really work
608
==============================================================================
609
*/
610
 
611
/*
612
=============
613
ED_WriteGlobals
614
=============
615
*/
616
void ED_WriteGlobals (FILE *f)
617
{
618
	ddef_t		*def;
619
	int			i;
620
	char		*name;
621
	int			type;
622
 
623
	fprintf (f,"{\n");
624
	for (i=0 ; inumglobaldefs ; i++)
625
	{
626
		def = &pr_globaldefs[i];
627
		type = def->type;
628
		if ( !(def->type & DEF_SAVEGLOBAL) )
629
			continue;
630
		type &= ~DEF_SAVEGLOBAL;
631
 
632
		if (type != ev_string
633
		&& type != ev_float
634
		&& type != ev_entity)
635
			continue;
636
 
637
		name = pr_strings + def->s_name;
638
		fprintf (f,"\"%s\" ", name);
639
		fprintf (f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs]));
640
	}
641
	fprintf (f,"}\n");
642
}
643
 
644
/*
645
=============
646
ED_ParseGlobals
647
=============
648
*/
649
void ED_ParseGlobals (char *data)
650
{
651
	char	keyname[64];
652
	ddef_t	*key;
653
 
654
	while (1)
655
	{
656
	// parse key
657
		data = COM_Parse (data);
658
		if (com_token[0] == '}')
659
			break;
660
		if (!data)
661
			Sys_Error ("ED_ParseEntity: EOF without closing brace");
662
 
663
		strcpy (keyname, com_token);
664
 
665
	// parse value
666
		data = COM_Parse (data);
667
		if (!data)
668
			Sys_Error ("ED_ParseEntity: EOF without closing brace");
669
 
670
		if (com_token[0] == '}')
671
			Sys_Error ("ED_ParseEntity: closing brace without data");
672
 
673
		key = ED_FindGlobal (keyname);
674
		if (!key)
675
		{
676
			Con_Printf ("'%s' is not a global\n", keyname);
677
			continue;
678
		}
679
 
680
		if (!ED_ParseEpair ((void *)pr_globals, key, com_token))
681
			Host_Error ("ED_ParseGlobals: parse error");
682
	}
683
}
684
 
685
//============================================================================
686
 
687
 
688
/*
689
=============
690
ED_NewString
691
=============
692
*/
693
char *ED_NewString (char *string)
694
{
695
	char	*new, *new_p;
696
	int		i,l;
697
 
698
	l = strlen(string) + 1;
699
	new = Hunk_Alloc (l);
700
	new_p = new;
701
 
702
	for (i=0 ; i< l ; i++)
703
	{
704
		if (string[i] == '\\' && i < l-1)
705
		{
706
			i++;
707
			if (string[i] == 'n')
708
				*new_p++ = '\n';
709
			else
710
				*new_p++ = '\\';
711
		}
712
		else
713
			*new_p++ = string[i];
714
	}
715
 
716
	return new;
717
}
718
 
719
 
720
/*
721
=============
722
ED_ParseEval
723
 
724
Can parse either fields or globals
725
returns false if error
726
=============
727
*/
728
qboolean	ED_ParseEpair (void *base, ddef_t *key, char *s)
729
{
730
	int		i;
731
	char	string[128];
732
	ddef_t	*def;
733
	char	*v, *w;
734
	void	*d;
735
	dfunction_t	*func;
736
 
737
	d = (void *)((int *)base + key->ofs);
738
 
739
	switch (key->type & ~DEF_SAVEGLOBAL)
740
	{
741
	case ev_string:
742
		*(string_t *)d = ED_NewString (s) - pr_strings;
743
		break;
744
 
745
	case ev_float:
746
		*(float *)d = atof (s);
747
		break;
748
 
749
	case ev_vector:
750
		strcpy (string, s);
751
		v = string;
752
		w = string;
753
		for (i=0 ; i<3 ; i++)
754
		{
755
			while (*v && *v != ' ')
756
				v++;
757
			*v = 0;
758
			((float *)d)[i] = atof (w);
759
			w = v = v+1;
760
		}
761
		break;
762
 
763
	case ev_entity:
764
		*(int *)d = EDICT_TO_PROG(EDICT_NUM(atoi (s)));
765
		break;
766
 
767
	case ev_field:
768
		def = ED_FindField (s);
769
		if (!def)
770
		{
771
			Con_Printf ("Can't find field %s\n", s);
772
			return false;
773
		}
774
		*(int *)d = G_INT(def->ofs);
775
		break;
776
 
777
	case ev_function:
778
		func = ED_FindFunction (s);
779
		if (!func)
780
		{
781
			Con_Printf ("Can't find function %s\n", s);
782
			return false;
783
		}
784
		*(func_t *)d = func - pr_functions;
785
		break;
786
 
787
	default:
788
		break;
789
	}
790
	return true;
791
}
792
 
793
/*
794
====================
795
ED_ParseEdict
796
 
797
Parses an edict out of the given string, returning the new position
798
ed should be a properly initialized empty edict.
799
Used for initial level load and for savegames.
800
====================
801
*/
802
char *ED_ParseEdict (char *data, edict_t *ent)
803
{
804
	ddef_t		*key;
805
	qboolean	anglehack;
806
	qboolean	init;
807
	char		keyname[256];
808
	int			n;
809
 
810
	init = false;
811
 
812
// clear it
813
	if (ent != sv.edicts)	// hack
814
		memset (&ent->v, 0, progs->entityfields * 4);
815
 
816
// go through all the dictionary pairs
817
	while (1)
818
	{
819
	// parse key
820
		data = COM_Parse (data);
821
		if (com_token[0] == '}')
822
			break;
823
		if (!data)
824
			Sys_Error ("ED_ParseEntity: EOF without closing brace");
825
 
826
// anglehack is to allow QuakeEd to write single scalar angles
827
// and allow them to be turned into vectors. (FIXME...)
828
if (!strcmp(com_token, "angle"))
829
{
830
	strcpy (com_token, "angles");
831
	anglehack = true;
832
}
833
else
834
	anglehack = false;
835
 
836
// FIXME: change light to _light to get rid of this hack
837
if (!strcmp(com_token, "light"))
838
	strcpy (com_token, "light_lev");	// hack for single light def
839
 
840
		strcpy (keyname, com_token);
841
 
842
		// another hack to fix heynames with trailing spaces
843
		n = strlen(keyname);
844
		while (n && keyname[n-1] == ' ')
845
		{
846
			keyname[n-1] = 0;
847
			n--;
848
		}
849
 
850
	// parse value
851
		data = COM_Parse (data);
852
		if (!data)
853
			Sys_Error ("ED_ParseEntity: EOF without closing brace");
854
 
855
		if (com_token[0] == '}')
856
			Sys_Error ("ED_ParseEntity: closing brace without data");
857
 
858
		init = true;
859
 
860
// keynames with a leading underscore are used for utility comments,
861
// and are immediately discarded by quake
862
		if (keyname[0] == '_')
863
			continue;
864
 
865
		key = ED_FindField (keyname);
866
		if (!key)
867
		{
868
			Con_Printf ("'%s' is not a field\n", keyname);
869
			continue;
870
		}
871
 
872
if (anglehack)
873
{
874
char	temp[32];
875
strcpy (temp, com_token);
876
sprintf (com_token, "0 %s 0", temp);
877
}
878
 
879
		if (!ED_ParseEpair ((void *)&ent->v, key, com_token))
880
			Host_Error ("ED_ParseEdict: parse error");
881
	}
882
 
883
	if (!init)
884
		ent->free = true;
885
 
886
	return data;
887
}
888
 
889
 
890
/*
891
================
892
ED_LoadFromFile
893
 
894
The entities are directly placed in the array, rather than allocated with
895
ED_Alloc, because otherwise an error loading the map would have entity
896
number references out of order.
897
 
898
Creates a server's entity / program execution context by
899
parsing textual entity definitions out of an ent file.
900
 
901
Used for both fresh maps and savegame loads.  A fresh map would also need
902
to call ED_CallSpawnFunctions () to let the objects initialize themselves.
903
================
904
*/
905
void ED_LoadFromFile (char *data)
906
{
907
	edict_t		*ent;
908
	int			inhibit;
909
	dfunction_t	*func;
910
 
911
	ent = NULL;
912
	inhibit = 0;
913
	pr_global_struct->time = sv.time;
914
 
915
// parse ents
916
	while (1)
917
	{
918
// parse the opening brace
919
		data = COM_Parse (data);
920
		if (!data)
921
			break;
922
		if (com_token[0] != '{')
923
			Sys_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
924
 
925
		if (!ent)
926
			ent = EDICT_NUM(0);
927
		else
928
			ent = ED_Alloc ();
929
		data = ED_ParseEdict (data, ent);
930
 
931
// remove things from different skill levels or deathmatch
932
		if (deathmatch.value)
933
		{
934
			if (((int)ent->v.spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
935
			{
936
				ED_Free (ent);
937
				inhibit++;
938
				continue;
939
			}
940
		}
941
		else if ((current_skill == 0 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_EASY))
942
				|| (current_skill == 1 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_MEDIUM))
943
				|| (current_skill >= 2 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_HARD)) )
944
		{
945
			ED_Free (ent);
946
			inhibit++;
947
			continue;
948
		}
949
 
950
//
951
// immediately call spawn function
952
//
953
		if (!ent->v.classname)
954
		{
955
			Con_Printf ("No classname for:\n");
956
			ED_Print (ent);
957
			ED_Free (ent);
958
			continue;
959
		}
960
 
961
	// look for the spawn function
962
		func = ED_FindFunction ( pr_strings + ent->v.classname );
963
 
964
		if (!func)
965
		{
966
			Con_Printf ("No spawn function for:\n");
967
			ED_Print (ent);
968
			ED_Free (ent);
969
			continue;
970
		}
971
 
972
		pr_global_struct->self = EDICT_TO_PROG(ent);
973
		PR_ExecuteProgram (func - pr_functions);
974
	}
975
 
976
	Con_DPrintf ("%i entities inhibited\n", inhibit);
977
}
978
 
979
 
980
/*
981
===============
982
PR_LoadProgs
983
===============
984
*/
985
void PR_LoadProgs (void)
986
{
987
	int		i;
988
 
989
// flush the non-C variable lookup cache
990
	for (i=0 ; i
991
		gefvCache[i].field[0] = 0;
992
 
993
	CRC_Init (&pr_crc);
994
 
995
	progs = (dprograms_t *)COM_LoadHunkFile ("progs.dat");
996
	if (!progs)
997
		Sys_Error ("PR_LoadProgs: couldn't load progs.dat");
998
	Con_DPrintf ("Programs occupy %iK.\n", com_filesize/1024);
999
 
1000
	for (i=0 ; i
1001
		CRC_ProcessByte (&pr_crc, ((byte *)progs)[i]);
1002
 
1003
// byte swap the header
1004
	for (i=0 ; i
1005
		((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );
1006
 
1007
	if (progs->version != PROG_VERSION)
1008
		Sys_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
1009
	if (progs->crc != PROGHEADER_CRC)
1010
		Sys_Error ("progs.dat system vars have been modified, progdefs.h is out of date");
1011
 
1012
	pr_functions = (dfunction_t *)((byte *)progs + progs->ofs_functions);
1013
	pr_strings = (char *)progs + progs->ofs_strings;
1014
	pr_globaldefs = (ddef_t *)((byte *)progs + progs->ofs_globaldefs);
1015
	pr_fielddefs = (ddef_t *)((byte *)progs + progs->ofs_fielddefs);
1016
	pr_statements = (dstatement_t *)((byte *)progs + progs->ofs_statements);
1017
 
1018
	pr_global_struct = (globalvars_t *)((byte *)progs + progs->ofs_globals);
1019
	pr_globals = (float *)pr_global_struct;
1020
 
1021
	pr_edict_size = progs->entityfields * 4 + sizeof (edict_t) - sizeof(entvars_t);
1022
 
1023
// byte swap the lumps
1024
	for (i=0 ; inumstatements ; i++)
1025
	{
1026
		pr_statements[i].op = LittleShort(pr_statements[i].op);
1027
		pr_statements[i].a = LittleShort(pr_statements[i].a);
1028
		pr_statements[i].b = LittleShort(pr_statements[i].b);
1029
		pr_statements[i].c = LittleShort(pr_statements[i].c);
1030
	}
1031
 
1032
	for (i=0 ; inumfunctions; i++)
1033
	{
1034
	pr_functions[i].first_statement = LittleLong (pr_functions[i].first_statement);
1035
	pr_functions[i].parm_start = LittleLong (pr_functions[i].parm_start);
1036
	pr_functions[i].s_name = LittleLong (pr_functions[i].s_name);
1037
	pr_functions[i].s_file = LittleLong (pr_functions[i].s_file);
1038
	pr_functions[i].numparms = LittleLong (pr_functions[i].numparms);
1039
	pr_functions[i].locals = LittleLong (pr_functions[i].locals);
1040
	}
1041
 
1042
	for (i=0 ; inumglobaldefs ; i++)
1043
	{
1044
		pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type);
1045
		pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs);
1046
		pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name);
1047
	}
1048
 
1049
	for (i=0 ; inumfielddefs ; i++)
1050
	{
1051
		pr_fielddefs[i].type = LittleShort (pr_fielddefs[i].type);
1052
		if (pr_fielddefs[i].type & DEF_SAVEGLOBAL)
1053
			Sys_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
1054
		pr_fielddefs[i].ofs = LittleShort (pr_fielddefs[i].ofs);
1055
		pr_fielddefs[i].s_name = LittleLong (pr_fielddefs[i].s_name);
1056
	}
1057
 
1058
	for (i=0 ; inumglobals ; i++)
1059
		((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
1060
}
1061
 
1062
 
1063
/*
1064
===============
1065
PR_Init
1066
===============
1067
*/
1068
void PR_Init (void)
1069
{
1070
	Cmd_AddCommand ("edict", ED_PrintEdict_f);
1071
	Cmd_AddCommand ("edicts", ED_PrintEdicts);
1072
	Cmd_AddCommand ("edictcount", ED_Count);
1073
	Cmd_AddCommand ("profile", PR_Profile_f);
1074
	Cvar_RegisterVariable (&nomonsters);
1075
	Cvar_RegisterVariable (&gamecfg);
1076
	Cvar_RegisterVariable (&scratch1);
1077
	Cvar_RegisterVariable (&scratch2);
1078
	Cvar_RegisterVariable (&scratch3);
1079
	Cvar_RegisterVariable (&scratch4);
1080
	Cvar_RegisterVariable (&savedgamecfg);
1081
	Cvar_RegisterVariable (&saved1);
1082
	Cvar_RegisterVariable (&saved2);
1083
	Cvar_RegisterVariable (&saved3);
1084
	Cvar_RegisterVariable (&saved4);
1085
}
1086
 
1087
 
1088
 
1089
edict_t *EDICT_NUM(int n)
1090
{
1091
	if (n < 0 || n >= sv.max_edicts)
1092
		Sys_Error ("EDICT_NUM: bad number %i", n);
1093
	return (edict_t *)((byte *)sv.edicts+ (n)*pr_edict_size);
1094
}
1095
 
1096
int NUM_FOR_EDICT(edict_t *e)
1097
{
1098
	int		b;
1099
 
1100
	b = (byte *)e - (byte *)sv.edicts;
1101
	b = b / pr_edict_size;
1102
 
1103
	if (b < 0 || b >= sv.num_edicts)
1104
		Sys_Error ("NUM_FOR_EDICT: bad pointer");
1105
	return b;
1106
}