~agrip-hackers/sns/trunk

« back to all changes in this revision

Viewing changes to zq-repo/zquake/source/pr_edict.c

  • Committer: Matthew Tylee Atkinson
  • Date: 2008-03-07 20:15:20 UTC
  • Revision ID: mta@agrip.org.uk-20080307201520-uj9sa2jrytx91b2t
Remove non-SNS components.

Show diffs side-by-side

added added

removed removed

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