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 "qwsvdef.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 int type_size[8] = {1,sizeof(void *)/4,1,3,1,1,sizeof(void *)/4,sizeof(void *)/4};
35
36 ddef_t *ED_FieldAtOfs (int ofs);
37 qboolean ED_ParseEpair (void *base, ddef_t *key, char *s);
38
39 #define MAX_FIELD_LEN 64
40 #define GEFV_CACHESIZE 2
41
42 typedef struct {
43 ddef_t *pcache;
44 char field[MAX_FIELD_LEN];
45 } gefv_cache;
46
47 static gefv_cache gefvCache[GEFV_CACHESIZE] = {{NULL, ""}, {NULL, ""}};
48
49 func_t SpectatorConnect;
50 func_t SpectatorThink;
51 func_t SpectatorDisconnect;
52
53
54 /*
55 =================
56 ED_ClearEdict
57
58 Sets everything to NULL
59 =================
60 */
ED_ClearEdict(edict_t * e)61 void ED_ClearEdict (edict_t *e)
62 {
63 memset (&e->v, 0, progs->entityfields * 4);
64 e->free = false;
65 }
66
67 /*
68 =================
69 ED_Alloc
70
71 Either finds a free edict, or allocates a new one.
72 Try to avoid reusing an entity that was recently freed, because it
73 can cause the client to think the entity morphed into something else
74 instead of being removed and recreated, which can cause interpolated
75 angles and bad trails.
76 =================
77 */
ED_Alloc(void)78 edict_t *ED_Alloc (void)
79 {
80 int i;
81 edict_t *e;
82
83 for ( i=MAX_CLIENTS+1 ; i<sv.num_edicts ; i++)
84 {
85 e = EDICT_NUM(i);
86 // the first couple seconds of server time can involve a lot of
87 // freeing and allocating, so relax the replacement policy
88 if (e->free && ( e->freetime < 2 || sv.time - e->freetime > 0.5 ) )
89 {
90 ED_ClearEdict (e);
91 return e;
92 }
93 }
94
95 if (i == MAX_EDICTS)
96 {
97 Con_Printf ("WARNING: ED_Alloc: no free edicts\n");
98 i--; // step on whatever is the last edict
99 e = EDICT_NUM(i);
100 SV_UnlinkEdict(e);
101 }
102 else
103 sv.num_edicts++;
104 e = EDICT_NUM(i);
105 ED_ClearEdict (e);
106
107 return e;
108 }
109
110 /*
111 =================
112 ED_Free
113
114 Marks the edict as free
115 FIXME: walk all entities and NULL out references to this entity
116 =================
117 */
ED_Free(edict_t * ed)118 void ED_Free (edict_t *ed)
119 {
120 SV_UnlinkEdict (ed); // unlink from world bsp
121
122 ed->free = true;
123 ed->v.model = 0;
124 ed->v.takedamage = 0;
125 ed->v.modelindex = 0;
126 ed->v.colormap = 0;
127 ed->v.skin = 0;
128 ed->v.frame = 0;
129 VectorCopy (vec3_origin, ed->v.origin);
130 VectorCopy (vec3_origin, ed->v.angles);
131 ed->v.nextthink = -1;
132 ed->v.solid = 0;
133
134 ed->freetime = sv.time;
135 }
136
137 //===========================================================================
138
139 /*
140 ============
141 ED_GlobalAtOfs
142 ============
143 */
ED_GlobalAtOfs(int ofs)144 ddef_t *ED_GlobalAtOfs (int ofs)
145 {
146 ddef_t *def;
147 int i;
148
149 for (i=0 ; i<progs->numglobaldefs ; i++)
150 {
151 def = &pr_globaldefs[i];
152 if (def->ofs == ofs)
153 return def;
154 }
155 return NULL;
156 }
157
158 /*
159 ============
160 ED_FieldAtOfs
161 ============
162 */
ED_FieldAtOfs(int ofs)163 ddef_t *ED_FieldAtOfs (int ofs)
164 {
165 ddef_t *def;
166 int i;
167
168 for (i=0 ; i<progs->numfielddefs ; i++)
169 {
170 def = &pr_fielddefs[i];
171 if (def->ofs == ofs)
172 return def;
173 }
174 return NULL;
175 }
176
177 /*
178 ============
179 ED_FindField
180 ============
181 */
ED_FindField(char * name)182 ddef_t *ED_FindField (char *name)
183 {
184 ddef_t *def;
185 int i;
186
187 for (i=0 ; i<progs->numfielddefs ; i++)
188 {
189 def = &pr_fielddefs[i];
190 if (!strcmp(PR_GetString(def->s_name),name) )
191 return def;
192 }
193 return NULL;
194 }
195
196
197 /*
198 ============
199 ED_FindGlobal
200 ============
201 */
ED_FindGlobal(char * name)202 ddef_t *ED_FindGlobal (char *name)
203 {
204 ddef_t *def;
205 int i;
206
207 for (i=0 ; i<progs->numglobaldefs ; i++)
208 {
209 def = &pr_globaldefs[i];
210 if (!strcmp(PR_GetString(def->s_name),name) )
211 return def;
212 }
213 return NULL;
214 }
215
216
217 /*
218 ============
219 ED_FindFunction
220 ============
221 */
ED_FindFunction(char * name)222 dfunction_t *ED_FindFunction (char *name)
223 {
224 dfunction_t *func;
225 int i;
226
227 for (i=0 ; i<progs->numfunctions ; i++)
228 {
229 func = &pr_functions[i];
230 if (!strcmp(PR_GetString(func->s_name),name) )
231 return func;
232 }
233 return NULL;
234 }
235
GetEdictFieldValue(edict_t * ed,char * field)236 eval_t *GetEdictFieldValue(edict_t *ed, char *field)
237 {
238 ddef_t *def = NULL;
239 int i;
240 static int rep = 0;
241
242 for (i=0 ; i<GEFV_CACHESIZE ; i++)
243 {
244 if (!strcmp(field, gefvCache[i].field))
245 {
246 def = gefvCache[i].pcache;
247 goto Done;
248 }
249 }
250
251 def = ED_FindField (field);
252
253 if (strlen(field) < MAX_FIELD_LEN)
254 {
255 gefvCache[rep].pcache = def;
256 strcpy (gefvCache[rep].field, field);
257 rep ^= 1;
258 }
259
260 Done:
261 if (!def)
262 return NULL;
263
264 return (eval_t *)((char *)&ed->v + def->ofs*4);
265 }
266
267 /*
268 ============
269 PR_ValueString
270
271 Returns a string describing *data in a type specific manner
272 =============
273 */
PR_ValueString(etype_t type,eval_t * val)274 char *PR_ValueString (etype_t type, eval_t *val)
275 {
276 static char line[256];
277 ddef_t *def;
278 dfunction_t *f;
279
280 type &= ~DEF_SAVEGLOBAL;
281
282 switch (type)
283 {
284 case ev_string:
285 sprintf (line, "%s", PR_GetString(val->string));
286 break;
287 case ev_entity:
288 sprintf (line, "entity %i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)) );
289 break;
290 case ev_function:
291 f = pr_functions + val->function;
292 sprintf (line, "%s()", PR_GetString(f->s_name));
293 break;
294 case ev_field:
295 def = ED_FieldAtOfs ( val->_int );
296 sprintf (line, ".%s", PR_GetString(def->s_name));
297 break;
298 case ev_void:
299 sprintf (line, "void");
300 break;
301 case ev_float:
302 sprintf (line, "%5.1f", val->_float);
303 break;
304 case ev_vector:
305 sprintf (line, "'%5.1f %5.1f %5.1f'", val->vector[0], val->vector[1], val->vector[2]);
306 break;
307 case ev_pointer:
308 sprintf (line, "pointer");
309 break;
310 default:
311 sprintf (line, "bad type %i", type);
312 break;
313 }
314
315 return line;
316 }
317
318 /*
319 ============
320 PR_UglyValueString
321
322 Returns a string describing *data in a type specific manner
323 Easier to parse than PR_ValueString
324 =============
325 */
PR_UglyValueString(etype_t type,eval_t * val)326 char *PR_UglyValueString (etype_t type, eval_t *val)
327 {
328 static char line[256];
329 ddef_t *def;
330 dfunction_t *f;
331
332 type &= ~DEF_SAVEGLOBAL;
333
334 switch (type)
335 {
336 case ev_string:
337 sprintf (line, "%s", PR_GetString(val->string));
338 break;
339 case ev_entity:
340 sprintf (line, "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
341 break;
342 case ev_function:
343 f = pr_functions + val->function;
344 sprintf (line, "%s", PR_GetString(f->s_name));
345 break;
346 case ev_field:
347 def = ED_FieldAtOfs ( val->_int );
348 sprintf (line, "%s", PR_GetString(def->s_name));
349 break;
350 case ev_void:
351 sprintf (line, "void");
352 break;
353 case ev_float:
354 sprintf (line, "%f", val->_float);
355 break;
356 case ev_vector:
357 sprintf (line, "%f %f %f", val->vector[0], val->vector[1], val->vector[2]);
358 break;
359 default:
360 sprintf (line, "bad type %i", type);
361 break;
362 }
363
364 return line;
365 }
366
367 /*
368 ============
369 PR_GlobalString
370
371 Returns a string with a description and the contents of a global,
372 padded to 20 field width
373 ============
374 */
PR_GlobalString(int ofs)375 char *PR_GlobalString (int ofs)
376 {
377 char *s;
378 int i;
379 ddef_t *def;
380 void *val;
381 static char line[128];
382
383 val = (void *)&pr_globals[ofs];
384 def = ED_GlobalAtOfs(ofs);
385 if (!def)
386 sprintf (line,"%i(???)", ofs);
387 else
388 {
389 s = PR_ValueString (def->type, val);
390 sprintf (line,"%i(%s)%s", ofs, PR_GetString(def->s_name), s);
391 }
392
393 i = strlen(line);
394 for ( ; i<20 ; i++)
395 strcat (line," ");
396 strcat (line," ");
397
398 return line;
399 }
400
PR_GlobalStringNoContents(int ofs)401 char *PR_GlobalStringNoContents (int ofs)
402 {
403 int i;
404 ddef_t *def;
405 static char line[128];
406
407 def = ED_GlobalAtOfs(ofs);
408 if (!def)
409 sprintf (line,"%i(???)", ofs);
410 else
411 sprintf (line,"%i(%s)", ofs, PR_GetString(def->s_name));
412
413 i = strlen(line);
414 for ( ; i<20 ; i++)
415 strcat (line," ");
416 strcat (line," ");
417
418 return line;
419 }
420
421
422 /*
423 =============
424 ED_Print
425
426 For debugging
427 =============
428 */
ED_Print(edict_t * ed)429 void ED_Print (edict_t *ed)
430 {
431 int l;
432 ddef_t *d;
433 int *v;
434 int i, j;
435 char *name;
436 int type;
437
438 if (ed->free)
439 {
440 Con_Printf ("FREE\n");
441 return;
442 }
443
444 for (i=1 ; i<progs->numfielddefs ; i++)
445 {
446 d = &pr_fielddefs[i];
447 name = PR_GetString(d->s_name);
448 if (name[strlen(name)-2] == '_')
449 continue; // skip _x, _y, _z vars
450
451 v = (int *)((char *)&ed->v + d->ofs*4);
452
453 // if the value is still all 0, skip the field
454 type = d->type & ~DEF_SAVEGLOBAL;
455
456 for (j=0 ; j<type_size[type] ; j++)
457 if (v[j])
458 break;
459 if (j == type_size[type])
460 continue;
461
462 Con_Printf ("%s",name);
463 l = strlen (name);
464 while (l++ < 15)
465 Con_Printf (" ");
466
467 Con_Printf ("%s\n", PR_ValueString(d->type, (eval_t *)v));
468 }
469 }
470
471 /*
472 =============
473 ED_Write
474
475 For savegames
476 =============
477 */
ED_Write(FILE * f,edict_t * ed)478 void ED_Write (FILE *f, edict_t *ed)
479 {
480 ddef_t *d;
481 int *v;
482 int i, j;
483 char *name;
484 int type;
485
486 fprintf (f, "{\n");
487
488 if (ed->free)
489 {
490 fprintf (f, "}\n");
491 return;
492 }
493
494 for (i=1 ; i<progs->numfielddefs ; i++)
495 {
496 d = &pr_fielddefs[i];
497 name = PR_GetString(d->s_name);
498 if (name[strlen(name)-2] == '_')
499 continue; // skip _x, _y, _z vars
500
501 v = (int *)((char *)&ed->v + d->ofs*4);
502
503 // if the value is still all 0, skip the field
504 type = d->type & ~DEF_SAVEGLOBAL;
505 for (j=0 ; j<type_size[type] ; j++)
506 if (v[j])
507 break;
508 if (j == type_size[type])
509 continue;
510
511 fprintf (f,"\"%s\" ",name);
512 fprintf (f,"\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v));
513 }
514
515 fprintf (f, "}\n");
516 }
517
ED_PrintNum(int ent)518 void ED_PrintNum (int ent)
519 {
520 ED_Print (EDICT_NUM(ent));
521 }
522
523 /*
524 =============
525 ED_PrintEdicts
526
527 For debugging, prints all the entities in the current server
528 =============
529 */
ED_PrintEdicts(void)530 void ED_PrintEdicts (void)
531 {
532 int i;
533
534 Con_Printf ("%i entities\n", sv.num_edicts);
535 for (i=0 ; i<sv.num_edicts ; i++)
536 {
537 Con_Printf ("\nEDICT %i:\n",i);
538 ED_PrintNum (i);
539 }
540 }
541
542 /*
543 =============
544 ED_PrintEdict_f
545
546 For debugging, prints a single edicy
547 =============
548 */
ED_PrintEdict_f(void)549 void ED_PrintEdict_f (void)
550 {
551 int i;
552
553 i = Q_atoi (Cmd_Argv(1));
554 Con_Printf ("\n EDICT %i:\n",i);
555 ED_PrintNum (i);
556 }
557
558 /*
559 =============
560 ED_Count
561
562 For debugging
563 =============
564 */
ED_Count(void)565 void ED_Count (void)
566 {
567 int i;
568 edict_t *ent;
569 int active, models, solid, step;
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->free)
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 Con_Printf ("num_edicts:%3i\n", sv.num_edicts);
587 Con_Printf ("active :%3i\n", active);
588 Con_Printf ("view :%3i\n", models);
589 Con_Printf ("touch :%3i\n", solid);
590 Con_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 */
ED_WriteGlobals(FILE * f)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 */
ED_ParseGlobals(char * data)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 SV_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 SV_Error ("ED_ParseEntity: EOF without closing brace");
661
662 if (com_token[0] == '}')
663 SV_Error ("ED_ParseEntity: closing brace without data");
664
665 key = ED_FindGlobal (keyname);
666 if (!key)
667 {
668 Con_Printf ("%s is not a global\n", keyname);
669 continue;
670 }
671
672 if (!ED_ParseEpair ((void *)pr_globals, key, com_token))
673 SV_Error ("ED_ParseGlobals: parse error");
674 }
675 }
676
677 //============================================================================
678
679
680 /*
681 =============
682 ED_NewString
683 =============
684 */
ED_NewString(char * string)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 */
ED_ParseEpair(void * base,ddef_t * key,char * s)720 qboolean 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 Con_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 Con_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 */
ED_ParseEdict(char * data,edict_t * ent)794 char *ED_ParseEdict (char *data, edict_t *ent)
795 {
796 ddef_t *key;
797 qboolean anglehack;
798 qboolean 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 SV_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 SV_Error ("ED_ParseEntity: EOF without closing brace");
837
838 if (com_token[0] == '}')
839 SV_Error ("ED_ParseEntity: closing brace without data");
840
841 init = true;
842
843 // keynames with a leading underscore are used for utility comments,
844 // and are immediately discarded by quake
845 if (keyname[0] == '_')
846 continue;
847
848 key = ED_FindField (keyname);
849 if (!key)
850 {
851 Con_Printf ("%s is not a field\n", keyname);
852 continue;
853 }
854
855 if (anglehack)
856 {
857 char temp[32];
858 strcpy (temp, com_token);
859 sprintf (com_token, "0 %s 0", temp);
860 }
861
862 if (!ED_ParseEpair ((void *)&ent->v, key, com_token))
863 SV_Error ("ED_ParseEdict: parse error");
864 }
865
866 if (!init)
867 ent->free = true;
868
869 return data;
870 }
871
872
873 /*
874 ================
875 ED_LoadFromFile
876
877 The entities are directly placed in the array, rather than allocated with
878 ED_Alloc, because otherwise an error loading the map would have entity
879 number references out of order.
880
881 Creates a server's entity / program execution context by
882 parsing textual entity definitions out of an ent file.
883
884 Used for both fresh maps and savegame loads. A fresh map would also need
885 to call ED_CallSpawnFunctions () to let the objects initialize themselves.
886 ================
887 */
ED_LoadFromFile(char * data)888 void ED_LoadFromFile (char *data)
889 {
890 edict_t *ent;
891 int inhibit;
892 dfunction_t *func;
893
894 ent = NULL;
895 inhibit = 0;
896 pr_global_struct->time = sv.time;
897
898 // parse ents
899 while (1)
900 {
901 // parse the opening brace
902 data = COM_Parse (data);
903 if (!data)
904 break;
905 if (com_token[0] != '{')
906 SV_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
907
908 if (!ent)
909 ent = EDICT_NUM(0);
910 else
911 ent = ED_Alloc ();
912 data = ED_ParseEdict (data, ent);
913
914 // remove things from different skill levels or deathmatch
915 if (((int)ent->v.spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
916 {
917 ED_Free (ent);
918 inhibit++;
919 continue;
920 }
921
922 //
923 // immediately call spawn function
924 //
925 if (!ent->v.classname)
926 {
927 Con_Printf ("No classname for:\n");
928 ED_Print (ent);
929 ED_Free (ent);
930 continue;
931 }
932
933 // look for the spawn function
934 func = ED_FindFunction ( PR_GetString(ent->v.classname) );
935
936 if (!func)
937 {
938 Con_Printf ("No spawn function for:\n");
939 ED_Print (ent);
940 ED_Free (ent);
941 continue;
942 }
943
944 pr_global_struct->self = EDICT_TO_PROG(ent);
945 PR_ExecuteProgram (func - pr_functions);
946 SV_FlushSignon();
947 }
948
949 Con_DPrintf ("%i entities inhibited\n", inhibit);
950 }
951
952
953 /*
954 ===============
955 PR_LoadProgs
956 ===============
957 */
PR_LoadProgs(void)958 void PR_LoadProgs (void)
959 {
960 int i;
961 char num[32];
962 dfunction_t *f;
963
964 // flush the non-C variable lookup cache
965 for (i=0 ; i<GEFV_CACHESIZE ; i++)
966 gefvCache[i].field[0] = 0;
967
968 progs = (dprograms_t *)COM_LoadHunkFile ("qwprogs.dat");
969 if (!progs)
970 progs = (dprograms_t *)COM_LoadHunkFile ("progs.dat");
971 if (!progs)
972 SV_Error ("PR_LoadProgs: couldn't load progs.dat");
973 Con_DPrintf ("Programs occupy %iK.\n", com_filesize/1024);
974
975 // add prog crc to the serverinfo
976 sprintf (num, "%i", CRC_Block ((byte *)progs, com_filesize));
977 Info_SetValueForStarKey (svs.info, "*progs", num, MAX_SERVERINFO_STRING);
978
979 // byte swap the header
980 for (i=0 ; i<sizeof(*progs)/4 ; i++)
981 ((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );
982
983 if (progs->version != PROG_VERSION)
984 SV_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
985 if (progs->crc != PROGHEADER_CRC)
986 SV_Error ("You must have the progs.dat from QuakeWorld installed");
987
988 pr_functions = (dfunction_t *)((byte *)progs + progs->ofs_functions);
989 pr_strings = (char *)progs + progs->ofs_strings;
990 pr_globaldefs = (ddef_t *)((byte *)progs + progs->ofs_globaldefs);
991 pr_fielddefs = (ddef_t *)((byte *)progs + progs->ofs_fielddefs);
992 pr_statements = (dstatement_t *)((byte *)progs + progs->ofs_statements);
993
994 num_prstr = 0;
995
996 pr_global_struct = (globalvars_t *)((byte *)progs + progs->ofs_globals);
997 pr_globals = (float *)pr_global_struct;
998
999 pr_edict_size = progs->entityfields * 4 + sizeof (edict_t) - sizeof(entvars_t);
1000
1001 // byte swap the lumps
1002 for (i=0 ; i<progs->numstatements ; i++)
1003 {
1004 pr_statements[i].op = LittleShort(pr_statements[i].op);
1005 pr_statements[i].a = LittleShort(pr_statements[i].a);
1006 pr_statements[i].b = LittleShort(pr_statements[i].b);
1007 pr_statements[i].c = LittleShort(pr_statements[i].c);
1008 }
1009
1010 for (i=0 ; i<progs->numfunctions; i++)
1011 {
1012 pr_functions[i].first_statement = LittleLong (pr_functions[i].first_statement);
1013 pr_functions[i].parm_start = LittleLong (pr_functions[i].parm_start);
1014 pr_functions[i].s_name = LittleLong (pr_functions[i].s_name);
1015 pr_functions[i].s_file = LittleLong (pr_functions[i].s_file);
1016 pr_functions[i].numparms = LittleLong (pr_functions[i].numparms);
1017 pr_functions[i].locals = LittleLong (pr_functions[i].locals);
1018 }
1019
1020 for (i=0 ; i<progs->numglobaldefs ; i++)
1021 {
1022 pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type);
1023 pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs);
1024 pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name);
1025 }
1026
1027 for (i=0 ; i<progs->numfielddefs ; i++)
1028 {
1029 pr_fielddefs[i].type = LittleShort (pr_fielddefs[i].type);
1030 if (pr_fielddefs[i].type & DEF_SAVEGLOBAL)
1031 SV_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
1032 pr_fielddefs[i].ofs = LittleShort (pr_fielddefs[i].ofs);
1033 pr_fielddefs[i].s_name = LittleLong (pr_fielddefs[i].s_name);
1034 }
1035
1036 for (i=0 ; i<progs->numglobals ; i++)
1037 ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
1038
1039 // Zoid, find the spectator functions
1040 SpectatorConnect = SpectatorThink = SpectatorDisconnect = 0;
1041
1042 if ((f = ED_FindFunction ("SpectatorConnect")) != NULL)
1043 SpectatorConnect = (func_t)(f - pr_functions);
1044 if ((f = ED_FindFunction ("SpectatorThink")) != NULL)
1045 SpectatorThink = (func_t)(f - pr_functions);
1046 if ((f = ED_FindFunction ("SpectatorDisconnect")) != NULL)
1047 SpectatorDisconnect = (func_t)(f - pr_functions);
1048 }
1049
1050
1051 /*
1052 ===============
1053 PR_Init
1054 ===============
1055 */
PR_Init(void)1056 void PR_Init (void)
1057 {
1058 Cmd_AddCommand ("edict", ED_PrintEdict_f);
1059 Cmd_AddCommand ("edicts", ED_PrintEdicts);
1060 Cmd_AddCommand ("edictcount", ED_Count);
1061 Cmd_AddCommand ("profile", PR_Profile_f);
1062 }
1063
1064
1065
EDICT_NUM(int n)1066 edict_t *EDICT_NUM(int n)
1067 {
1068 if (n < 0 || n >= MAX_EDICTS)
1069 SV_Error ("EDICT_NUM: bad number %i", n);
1070 return (edict_t *)((byte *)sv.edicts+ (n)*pr_edict_size);
1071 }
1072
NUM_FOR_EDICT(edict_t * e)1073 int NUM_FOR_EDICT(edict_t *e)
1074 {
1075 int b;
1076
1077 b = (byte *)e - (byte *)sv.edicts;
1078 b = b / pr_edict_size;
1079
1080 if (b < 0 || b >= sv.num_edicts)
1081 SV_Error ("NUM_FOR_EDICT: bad pointer");
1082 return b;
1083 }
1084
1085
1086