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