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