Quake II RTX doxygen  1.0 dev
g_save.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (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. See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18 
19 #include "g_local.h"
20 #include "g_ptrs.h"
21 
22 //#define _DEBUG
23 typedef struct {
25 #ifdef _DEBUG
26  char *name;
27 #endif
28  size_t ofs;
29  size_t size;
30 } save_field_t;
31 
32 #ifdef _DEBUG
33 #define _FA(type, name, size) { type, #name, _OFS(name), size }
34 #else
35 #define _FA(type, name, size) { type, _OFS(name), size }
36 #endif
37 #define _F(type, name) _FA(type, name, 1)
38 #define SZ(name, size) _FA(F_ZSTRING, name, size)
39 #define BA(name, size) _FA(F_BYTE, name, size)
40 #define B(name) BA(name, 1)
41 #define SA(name, size) _FA(F_SHORT, name, size)
42 #define S(name) SA(name, 1)
43 #define IA(name, size) _FA(F_INT, name, size)
44 #define I(name) IA(name, 1)
45 #define FA(name, size) _FA(F_FLOAT, name, size)
46 #define F(name) FA(name, 1)
47 #define L(name) _F(F_LSTRING, name)
48 #define V(name) _F(F_VECTOR, name)
49 #define T(name) _F(F_ITEM, name)
50 #define E(name) _F(F_EDICT, name)
51 #define P(name, type) _FA(F_POINTER, name, type)
52 
53 static const save_field_t entityfields[] = {
54 #define _OFS FOFS
55  V(s.origin),
56  V(s.angles),
57  V(s.old_origin),
58  I(s.modelindex),
59  I(s.modelindex2),
60  I(s.modelindex3),
61  I(s.modelindex4),
62  I(s.frame),
63  I(s.skinnum),
64  I(s.effects),
65  I(s.renderfx),
66  I(s.solid),
67  I(s.sound),
68  I(s.event),
69 
70  // [...]
71 
72  I(svflags),
73  V(mins),
74  V(maxs),
75  V(absmin),
76  V(absmax),
77  V(size),
78  I(solid),
79  I(clipmask),
80  E(owner),
81 
82  I(movetype),
83  I(flags),
84 
85  L(model),
86  F(freetime),
87 
88  L(message),
89  L(classname),
90  I(spawnflags),
91 
92  F(timestamp),
93 
94  L(target),
95  L(targetname),
96  L(killtarget),
97  L(team),
98  L(pathtarget),
99  L(deathtarget),
100  L(combattarget),
101  E(target_ent),
102 
103  F(speed),
104  F(accel),
105  F(decel),
106  V(movedir),
107  V(pos1),
108  V(pos2),
109 
110  V(velocity),
111  V(avelocity),
112  I(mass),
113  F(air_finished),
114  F(gravity),
115 
116  E(goalentity),
117  E(movetarget),
118  F(yaw_speed),
119  F(ideal_yaw),
120 
121  F(nextthink),
122  P(prethink, P_prethink),
123  P(think, P_think),
124  P(blocked, P_blocked),
125  P(touch, P_touch),
126  P(use, P_use),
127  P(pain, P_pain),
128  P(die, P_die),
129 
130  F(touch_debounce_time),
131  F(pain_debounce_time),
132  F(damage_debounce_time),
133  F(fly_sound_debounce_time),
134  F(last_move_time),
135 
136  I(health),
137  I(max_health),
138  I(gib_health),
139  I(deadflag),
140  I(show_hostile),
141 
142  F(powerarmor_time),
143 
144  L(map),
145 
146  I(viewheight),
147  I(takedamage),
148  I(dmg),
149  I(radius_dmg),
150  F(dmg_radius),
151  I(sounds),
152  I(count),
153 
154  E(chain),
155  E(enemy),
156  E(oldenemy),
157  E(activator),
158  E(groundentity),
159  I(groundentity_linkcount),
160  E(teamchain),
161  E(teammaster),
162 
163  E(mynoise),
164  E(mynoise2),
165 
166  I(noise_index),
167  I(noise_index2),
168  F(volume),
169  F(attenuation),
170 
171  F(wait),
172  F(delay),
173  F(random),
174 
175  F(teleport_time),
176 
177  I(watertype),
178  I(waterlevel),
179 
180  V(move_origin),
181  V(move_angles),
182 
183  I(light_level),
184 
185  I(style),
186 
187  T(item),
188 
189  V(moveinfo.start_origin),
190  V(moveinfo.start_angles),
191  V(moveinfo.end_origin),
192  V(moveinfo.end_angles),
193 
194  I(moveinfo.sound_start),
195  I(moveinfo.sound_middle),
196  I(moveinfo.sound_end),
197 
198  F(moveinfo.accel),
199  F(moveinfo.speed),
200  F(moveinfo.decel),
201  F(moveinfo.distance),
202 
203  F(moveinfo.wait),
204 
205  I(moveinfo.state),
206  V(moveinfo.dir),
207  F(moveinfo.current_speed),
208  F(moveinfo.move_speed),
209  F(moveinfo.next_speed),
210  F(moveinfo.remaining_distance),
211  F(moveinfo.decel_distance),
212  P(moveinfo.endfunc, P_moveinfo_endfunc),
213 
214  P(monsterinfo.currentmove, P_monsterinfo_currentmove),
215  I(monsterinfo.aiflags),
216  I(monsterinfo.nextframe),
217  F(monsterinfo.scale),
218 
219  P(monsterinfo.stand, P_monsterinfo_stand),
220  P(monsterinfo.idle, P_monsterinfo_idle),
221  P(monsterinfo.search, P_monsterinfo_search),
222  P(monsterinfo.walk, P_monsterinfo_walk),
223  P(monsterinfo.run, P_monsterinfo_run),
224  P(monsterinfo.dodge, P_monsterinfo_dodge),
225  P(monsterinfo.attack, P_monsterinfo_attack),
226  P(monsterinfo.melee, P_monsterinfo_melee),
227  P(monsterinfo.sight, P_monsterinfo_sight),
228  P(monsterinfo.checkattack, P_monsterinfo_checkattack),
229 
230  F(monsterinfo.pausetime),
231  F(monsterinfo.attack_finished),
232 
233  V(monsterinfo.saved_goal),
234  F(monsterinfo.search_time),
235  F(monsterinfo.trail_time),
236  V(monsterinfo.last_sighting),
237  I(monsterinfo.attack_state),
238  I(monsterinfo.lefty),
239  F(monsterinfo.idle_time),
240  I(monsterinfo.linkcount),
241 
242  I(monsterinfo.power_armor_type),
243  I(monsterinfo.power_armor_power),
244 
245  {0}
246 #undef _OFS
247 };
248 
249 static const save_field_t levelfields[] = {
250 #define _OFS LLOFS
251  I(framenum),
252  F(time),
253 
254  SZ(level_name, MAX_QPATH),
255  SZ(mapname, MAX_QPATH),
256  SZ(nextmap, MAX_QPATH),
257 
258  F(intermissiontime),
259  L(changemap),
260  I(exitintermission),
261  V(intermission_origin),
262  V(intermission_angle),
263 
264  E(sight_client),
265 
266  E(sight_entity),
267  I(sight_entity_framenum),
268  E(sound_entity),
269  I(sound_entity_framenum),
270  E(sound2_entity),
271  I(sound2_entity_framenum),
272 
273  I(pic_health),
274 
275  I(total_secrets),
276  I(found_secrets),
277 
278  I(total_goals),
279  I(found_goals),
280 
281  I(total_monsters),
282  I(killed_monsters),
283 
284  I(body_que),
285 
286  I(power_cubes),
287 
288  {0}
289 #undef _OFS
290 };
291 
292 static const save_field_t clientfields[] = {
293 #define _OFS CLOFS
294  I(ps.pmove.pm_type),
295 
296  SA(ps.pmove.origin, 3),
297  SA(ps.pmove.velocity, 3),
298  B(ps.pmove.pm_flags),
299  B(ps.pmove.pm_time),
300  S(ps.pmove.gravity),
301  SA(ps.pmove.delta_angles, 3),
302 
303  V(ps.viewangles),
304  V(ps.viewoffset),
305  V(ps.kick_angles),
306 
307  V(ps.gunangles),
308  V(ps.gunoffset),
309  I(ps.gunindex),
310  I(ps.gunframe),
311 
312  FA(ps.blend, 4),
313 
314  F(ps.fov),
315 
316  I(ps.rdflags),
317 
318  SA(ps.stats, MAX_STATS),
319 
320  SZ(pers.userinfo, MAX_INFO_STRING),
321  SZ(pers.netname, 16),
322  I(pers.hand),
323 
324  I(pers.connected),
325 
326  I(pers.health),
327  I(pers.max_health),
328  I(pers.savedFlags),
329 
330  I(pers.selected_item),
331  IA(pers.inventory, MAX_ITEMS),
332 
333  I(pers.max_bullets),
334  I(pers.max_shells),
335  I(pers.max_rockets),
336  I(pers.max_grenades),
337  I(pers.max_cells),
338  I(pers.max_slugs),
339 
340  T(pers.weapon),
341  T(pers.lastweapon),
342 
343  I(pers.power_cubes),
344  I(pers.score),
345 
346  I(pers.game_helpchanged),
347  I(pers.helpchanged),
348 
349  I(pers.spectator),
350 
351  I(showscores),
352  I(showinventory),
353  I(showhelp),
354  I(showhelpicon),
355 
356  I(ammo_index),
357 
358  T(newweapon),
359 
360  I(damage_armor),
361  I(damage_parmor),
362  I(damage_blood),
363  I(damage_knockback),
364  V(damage_from),
365 
366  F(killer_yaw),
367 
368  I(weaponstate),
369 
370  V(kick_angles),
371  V(kick_origin),
372  F(v_dmg_roll),
373  F(v_dmg_pitch),
374  F(v_dmg_time),
375  F(fall_time),
376  F(fall_value),
377  F(damage_alpha),
378  F(bonus_alpha),
379  V(damage_blend),
380  V(v_angle),
381  F(bobtime),
382  V(oldviewangles),
383  V(oldvelocity),
384 
385  F(next_drown_time),
386  I(old_waterlevel),
387  I(breather_sound),
388 
389  I(machinegun_shots),
390 
391  I(anim_end),
392  I(anim_priority),
393  I(anim_duck),
394  I(anim_run),
395 
396  // powerup timers
397  I(quad_framenum),
398  I(invincible_framenum),
399  I(breather_framenum),
400  I(enviro_framenum),
401 
402  I(grenade_blew_up),
403  F(grenade_time),
404  I(silencer_shots),
405  I(weapon_sound),
406 
407  F(pickup_msg_time),
408 
409  {0}
410 #undef _OFS
411 };
412 
413 static const save_field_t gamefields[] = {
414 #define _OFS GLOFS
415  SZ(helpmessage1, 512),
416  SZ(helpmessage2, 512),
417 
418  I(maxclients),
419  I(maxentities),
420 
421  I(serverflags),
422 
423  I(num_items),
424 
425  I(autosaved),
426 
427  {0}
428 #undef _OFS
429 };
430 
431 //=========================================================
432 
433 static void write_data(void *buf, size_t len, FILE *f)
434 {
435  if (fwrite(buf, 1, len, f) != len) {
436  gi.error("%s: couldn't write %"PRIz" bytes", __func__, len);
437  }
438 }
439 
440 static void write_short(FILE *f, short v)
441 {
442  v = LittleShort(v);
443  write_data(&v, sizeof(v), f);
444 }
445 
446 static void write_int(FILE *f, int v)
447 {
448  v = LittleLong(v);
449  write_data(&v, sizeof(v), f);
450 }
451 
452 static void write_float(FILE *f, float v)
453 {
454  v = LittleFloat(v);
455  write_data(&v, sizeof(v), f);
456 }
457 
458 static void write_string(FILE *f, char *s)
459 {
460  size_t len;
461 
462  if (!s) {
463  write_int(f, -1);
464  return;
465  }
466 
467  len = strlen(s);
468  write_int(f, len);
469  write_data(s, len, f);
470 }
471 
472 static void write_vector(FILE *f, vec_t *v)
473 {
474  write_float(f, v[0]);
475  write_float(f, v[1]);
476  write_float(f, v[2]);
477 }
478 
479 static void write_index(FILE *f, void *p, size_t size, void *start, int max_index)
480 {
481  size_t diff;
482 
483  if (!p) {
484  write_int(f, -1);
485  return;
486  }
487 
488  if (p < start || (byte *)p > (byte *)start + max_index * size) {
489  gi.error("%s: pointer out of range: %p", __func__, p);
490  }
491 
492  diff = (byte *)p - (byte *)start;
493  if (diff % size) {
494  gi.error("%s: misaligned pointer: %p", __func__, p);
495  }
496  write_int(f, (int)(diff / size));
497 }
498 
499 static void write_pointer(FILE *f, void *p, ptr_type_t type)
500 {
501  const save_ptr_t *ptr;
502  int i;
503 
504  if (!p) {
505  write_int(f, -1);
506  return;
507  }
508 
509  for (i = 0, ptr = save_ptrs; i < num_save_ptrs; i++, ptr++) {
510  if (ptr->type == type && ptr->ptr == p) {
511  write_int(f, i);
512  return;
513  }
514  }
515 
516  gi.error("%s: unknown pointer: %p", __func__, p);
517 }
518 
519 static void write_field(FILE *f, const save_field_t *field, void *base)
520 {
521  void *p = (byte *)base + field->ofs;
522  int i;
523 
524  switch (field->type) {
525  case F_BYTE:
526  write_data(p, field->size, f);
527  break;
528  case F_SHORT:
529  for (i = 0; i < field->size; i++) {
530  write_short(f, ((short *)p)[i]);
531  }
532  break;
533  case F_INT:
534  for (i = 0; i < field->size; i++) {
535  write_int(f, ((int *)p)[i]);
536  }
537  break;
538  case F_FLOAT:
539  for (i = 0; i < field->size; i++) {
540  write_float(f, ((float *)p)[i]);
541  }
542  break;
543  case F_VECTOR:
544  write_vector(f, (vec_t *)p);
545  break;
546 
547  case F_ZSTRING:
548  write_string(f, (char *)p);
549  break;
550  case F_LSTRING:
551  write_string(f, *(char **)p);
552  break;
553 
554  case F_EDICT:
555  write_index(f, *(void **)p, sizeof(edict_t), g_edicts, MAX_EDICTS - 1);
556  break;
557  case F_CLIENT:
558  write_index(f, *(void **)p, sizeof(gclient_t), game.clients, game.maxclients - 1);
559  break;
560  case F_ITEM:
561  write_index(f, *(void **)p, sizeof(gitem_t), itemlist, game.num_items - 1);
562  break;
563 
564  case F_POINTER:
565  write_pointer(f, *(void **)p, field->size);
566  break;
567 
568  default:
569  gi.error("%s: unknown field type", __func__);
570  }
571 }
572 
573 static void write_fields(FILE *f, const save_field_t *fields, void *base)
574 {
575  const save_field_t *field;
576 
577  for (field = fields; field->type; field++) {
578  write_field(f, field, base);
579  }
580 }
581 
582 static void read_data(void *buf, size_t len, FILE *f)
583 {
584  if (fread(buf, 1, len, f) != len) {
585  gi.error("%s: couldn't read %"PRIz" bytes", __func__, len);
586  }
587 }
588 
589 static int read_short(FILE *f)
590 {
591  short v;
592 
593  read_data(&v, sizeof(v), f);
594  v = LittleShort(v);
595 
596  return v;
597 }
598 
599 static int read_int(FILE *f)
600 {
601  int v;
602 
603  read_data(&v, sizeof(v), f);
604  v = LittleLong(v);
605 
606  return v;
607 }
608 
609 static float read_float(FILE *f)
610 {
611  float v;
612 
613  read_data(&v, sizeof(v), f);
614  v = LittleFloat(v);
615 
616  return v;
617 }
618 
619 
620 static char *read_string(FILE *f)
621 {
622  int len;
623  char *s;
624 
625  len = read_int(f);
626  if (len == -1) {
627  return NULL;
628  }
629 
630  if (len < 0 || len > 65536) {
631  gi.error("%s: bad length", __func__);
632  }
633 
634  s = gi.TagMalloc(len + 1, TAG_LEVEL);
635  read_data(s, len, f);
636  s[len] = 0;
637 
638  return s;
639 }
640 
641 static void read_zstring(FILE *f, char *s, size_t size)
642 {
643  int len;
644 
645  len = read_int(f);
646  if (len < 0 || len >= size) {
647  gi.error("%s: bad length", __func__);
648  }
649 
650  read_data(s, len, f);
651  s[len] = 0;
652 }
653 
654 static void read_vector(FILE *f, vec_t *v)
655 {
656  v[0] = read_float(f);
657  v[1] = read_float(f);
658  v[2] = read_float(f);
659 }
660 
661 static void *read_index(FILE *f, size_t size, void *start, int max_index)
662 {
663  int index;
664  byte *p;
665 
666  index = read_int(f);
667  if (index == -1) {
668  return NULL;
669  }
670 
671  if (index < 0 || index > max_index) {
672  gi.error("%s: bad index", __func__);
673  }
674 
675  p = (byte *)start + index * size;
676  return p;
677 }
678 
679 static void *read_pointer(FILE *f, ptr_type_t type)
680 {
681  int index;
682  const save_ptr_t *ptr;
683 
684  index = read_int(f);
685  if (index == -1) {
686  return NULL;
687  }
688 
689  if (index < 0 || index >= num_save_ptrs) {
690  gi.error("%s: bad index", __func__);
691  }
692 
693  ptr = &save_ptrs[index];
694  if (ptr->type != type) {
695  gi.error("%s: type mismatch", __func__);
696  }
697 
698  return ptr->ptr;
699 }
700 
701 static void read_field(FILE *f, const save_field_t *field, void *base)
702 {
703  void *p = (byte *)base + field->ofs;
704  int i;
705 
706  switch (field->type) {
707  case F_BYTE:
708  read_data(p, field->size, f);
709  break;
710  case F_SHORT:
711  for (i = 0; i < field->size; i++) {
712  ((short *)p)[i] = read_short(f);
713  }
714  break;
715  case F_INT:
716  for (i = 0; i < field->size; i++) {
717  ((int *)p)[i] = read_int(f);
718  }
719  break;
720  case F_FLOAT:
721  for (i = 0; i < field->size; i++) {
722  ((float *)p)[i] = read_float(f);
723  }
724  break;
725  case F_VECTOR:
726  read_vector(f, (vec_t *)p);
727  break;
728 
729  case F_LSTRING:
730  *(char **)p = read_string(f);
731  break;
732  case F_ZSTRING:
733  read_zstring(f, (char *)p, field->size);
734  break;
735 
736  case F_EDICT:
737  *(edict_t **)p = read_index(f, sizeof(edict_t), g_edicts, game.maxentities - 1);
738  break;
739  case F_CLIENT:
740  *(gclient_t **)p = read_index(f, sizeof(gclient_t), game.clients, game.maxclients - 1);
741  break;
742  case F_ITEM:
743  *(gitem_t **)p = read_index(f, sizeof(gitem_t), itemlist, game.num_items - 1);
744  break;
745 
746  case F_POINTER:
747  *(void **)p = read_pointer(f, field->size);
748  break;
749 
750  default:
751  gi.error("%s: unknown field type", __func__);
752  }
753 }
754 
755 static void read_fields(FILE *f, const save_field_t *fields, void *base)
756 {
757  const save_field_t *field;
758 
759  for (field = fields; field->type; field++) {
760  read_field(f, field, base);
761  }
762 }
763 
764 //=========================================================
765 
766 #define SAVE_MAGIC1 (('1'<<24)|('V'<<16)|('S'<<8)|'S') // "SSV1"
767 #define SAVE_MAGIC2 (('1'<<24)|('V'<<16)|('A'<<8)|'S') // "SAV1"
768 #define SAVE_VERSION 2
769 
770 /*
771 ============
772 WriteGame
773 
774 This will be called whenever the game goes to a new level,
775 and when the user explicitly saves the game.
776 
777 Game information include cross level data, like multi level
778 triggers, help computer info, and all client states.
779 
780 A single player death will automatically restore from the
781 last save position.
782 ============
783 */
784 void WriteGame(const char *filename, qboolean autosave)
785 {
786  FILE *f;
787  int i;
788 
789  if (!autosave)
790  SaveClientData();
791 
792  f = fopen(filename, "wb");
793  if (!f)
794  gi.error("Couldn't open %s", filename);
795 
798 
799  game.autosaved = autosave;
801  game.autosaved = qfalse;
802 
803  for (i = 0; i < game.maxclients; i++) {
805  }
806 
807  fclose(f);
808 }
809 
810 void ReadGame(const char *filename)
811 {
812  FILE *f;
813  int i;
814 
815  gi.FreeTags(TAG_GAME);
816 
817  f = fopen(filename, "rb");
818  if (!f)
819  gi.error("Couldn't open %s", filename);
820 
821  i = read_int(f);
822  if (i != SAVE_MAGIC1) {
823  fclose(f);
824  gi.error("Not a save game");
825  }
826 
827  i = read_int(f);
828  if (i != SAVE_VERSION) {
829  fclose(f);
830  gi.error("Savegame from an older version");
831  }
832 
834 
835  // should agree with server's version
836  if (game.maxclients != (int)maxclients->value) {
837  fclose(f);
838  gi.error("Savegame has bad maxclients");
839  }
840  if (game.maxentities <= game.maxclients || game.maxentities > MAX_EDICTS) {
841  fclose(f);
842  gi.error("Savegame has bad maxentities");
843  }
844 
845  g_edicts = gi.TagMalloc(game.maxentities * sizeof(g_edicts[0]), TAG_GAME);
846  globals.edicts = g_edicts;
847  globals.max_edicts = game.maxentities;
848 
849  game.clients = gi.TagMalloc(game.maxclients * sizeof(game.clients[0]), TAG_GAME);
850  for (i = 0; i < game.maxclients; i++) {
852  }
853 
854  fclose(f);
855 }
856 
857 //==========================================================
858 
859 
860 /*
861 =================
862 WriteLevel
863 
864 =================
865 */
866 void WriteLevel(const char *filename)
867 {
868  int i;
869  edict_t *ent;
870  FILE *f;
871 
872  f = fopen(filename, "wb");
873  if (!f)
874  gi.error("Couldn't open %s", filename);
875 
878 
879  // write out level_locals_t
881 
882  // write out all the entities
883  for (i = 0; i < globals.num_edicts; i++) {
884  ent = &g_edicts[i];
885  if (!ent->inuse)
886  continue;
887  write_int(f, i);
888  write_fields(f, entityfields, ent);
889  }
890  write_int(f, -1);
891 
892  fclose(f);
893 }
894 
895 
896 /*
897 =================
898 ReadLevel
899 
900 SpawnEntities will allready have been called on the
901 level the same way it was when the level was saved.
902 
903 That is necessary to get the baselines
904 set up identically.
905 
906 The server will have cleared all of the world links before
907 calling ReadLevel.
908 
909 No clients are connected yet.
910 =================
911 */
912 void ReadLevel(const char *filename)
913 {
914  int entnum;
915  FILE *f;
916  int i;
917  edict_t *ent;
918 
919  // free any dynamic memory allocated by loading the level
920  // base state
921  gi.FreeTags(TAG_LEVEL);
922 
923  f = fopen(filename, "rb");
924  if (!f)
925  gi.error("Couldn't open %s", filename);
926 
927  // wipe all the entities
928  memset(g_edicts, 0, game.maxentities * sizeof(g_edicts[0]));
929  globals.num_edicts = maxclients->value + 1;
930 
931  i = read_int(f);
932  if (i != SAVE_MAGIC2) {
933  fclose(f);
934  gi.error("Not a save game");
935  }
936 
937  i = read_int(f);
938  if (i != SAVE_VERSION) {
939  fclose(f);
940  gi.error("Savegame from an older version");
941  }
942 
943  // load the level locals
945 
946  // load all the entities
947  while (1) {
948  entnum = read_int(f);
949  if (entnum == -1)
950  break;
951  if (entnum < 0 || entnum >= game.maxentities) {
952  gi.error("%s: bad entity number", __func__);
953  }
954  if (entnum >= globals.num_edicts)
955  globals.num_edicts = entnum + 1;
956 
957  ent = &g_edicts[entnum];
958  read_fields(f, entityfields, ent);
959  ent->inuse = qtrue;
960  ent->s.number = entnum;
961 
962  // let the server rebuild world links for this ent
963  memset(&ent->area, 0, sizeof(ent->area));
964  gi.linkentity(ent);
965  }
966 
967  fclose(f);
968 
969  // mark all clients as unconnected
970  for (i = 0 ; i < maxclients->value ; i++) {
971  ent = &g_edicts[i + 1];
972  ent->client = game.clients + i;
973  ent->client->pers.connected = qfalse;
974  }
975 
976  // do any load time things at this point
977  for (i = 0 ; i < globals.num_edicts ; i++) {
978  ent = &g_edicts[i];
979 
980  if (!ent->inuse)
981  continue;
982 
983  // fire any cross-level triggers
984  if (ent->classname)
985  if (strcmp(ent->classname, "target_crosslevel_target") == 0)
986  ent->nextthink = level.time + ent->delay;
987 
988  if (ent->think == func_clock_think || ent->use == func_clock_use) {
989  char *msg = ent->message;
990  ent->message = gi.TagMalloc(CLOCK_MESSAGE_SIZE, TAG_LEVEL);
991  if (msg) {
992  Q_strlcpy(ent->message, msg, CLOCK_MESSAGE_SIZE);
993  gi.TagFree(msg);
994  }
995  }
996  }
997 }
998 
gi
game_import_t gi
Definition: g_main.c:23
P_prethink
@ P_prethink
Definition: g_ptrs.h:4
P_monsterinfo_stand
@ P_monsterinfo_stand
Definition: g_ptrs.h:15
write_int
static void write_int(FILE *f, int v)
Definition: g_save.c:446
read_index
static void * read_index(FILE *f, size_t size, void *start, int max_index)
Definition: g_save.c:661
P_die
@ P_die
Definition: g_ptrs.h:10
save_field_t::size
size_t size
Definition: g_save.c:29
P_blocked
@ P_blocked
Definition: g_ptrs.h:6
T
#define T(name)
Definition: g_save.c:49
save_ptr_t
Definition: g_ptrs.h:27
maxclients
cvar_t * maxclients
Definition: g_main.c:42
F_ZSTRING
@ F_ZSTRING
Definition: g_local.h:573
P_monsterinfo_search
@ P_monsterinfo_search
Definition: g_ptrs.h:17
write_vector
static void write_vector(FILE *f, vec_t *v)
Definition: g_save.c:472
write_data
static void write_data(void *buf, size_t len, FILE *f)
Definition: g_save.c:433
F_VECTOR
@ F_VECTOR
Definition: g_local.h:574
write_fields
static void write_fields(FILE *f, const save_field_t *fields, void *base)
Definition: g_save.c:573
g_ptrs.h
F_BYTE
@ F_BYTE
Definition: g_local.h:567
ReadLevel
void ReadLevel(const char *filename)
Definition: g_save.c:912
write_short
static void write_short(FILE *f, short v)
Definition: g_save.c:440
WriteGame
void WriteGame(const char *filename, qboolean autosave)
Definition: g_save.c:784
E
#define E(name)
Definition: g_save.c:50
P_touch
@ P_touch
Definition: g_ptrs.h:7
P
#define P(name, type)
Definition: g_save.c:51
read_int
static int read_int(FILE *f)
Definition: g_save.c:599
write_field
static void write_field(FILE *f, const save_field_t *field, void *base)
Definition: g_save.c:519
F
#define F(name)
Definition: g_save.c:46
maxentities
cvar_t * maxentities
Definition: g_main.c:44
TAG_LEVEL
#define TAG_LEVEL
Definition: g_local.h:79
P_use
@ P_use
Definition: g_ptrs.h:8
save_ptr_t::ptr
void * ptr
Definition: g_ptrs.h:29
F_ITEM
@ F_ITEM
Definition: g_local.h:577
B
#define B(name)
Definition: g_save.c:40
g_edicts
edict_t * g_edicts
Definition: g_main.c:31
F_EDICT
@ F_EDICT
Definition: g_local.h:576
itemlist
gitem_t itemlist[]
Definition: g_items.c:1063
save_ptrs
const save_ptr_t save_ptrs[]
Definition: g_ptrs.c:619
clientfields
static const save_field_t clientfields[]
Definition: g_save.c:292
P_pain
@ P_pain
Definition: g_ptrs.h:9
F_FLOAT
@ F_FLOAT
Definition: g_local.h:570
IA
#define IA(name, size)
Definition: g_save.c:43
write_pointer
static void write_pointer(FILE *f, void *p, ptr_type_t type)
Definition: g_save.c:499
read_field
static void read_field(FILE *f, const save_field_t *field, void *base)
Definition: g_save.c:701
read_string
static char * read_string(FILE *f)
Definition: g_save.c:620
write_string
static void write_string(FILE *f, char *s)
Definition: g_save.c:458
F_CLIENT
@ F_CLIENT
Definition: g_local.h:578
CLOCK_MESSAGE_SIZE
#define CLOCK_MESSAGE_SIZE
Definition: g_local.h:692
read_zstring
static void read_zstring(FILE *f, char *s, size_t size)
Definition: g_save.c:641
SAVE_VERSION
#define SAVE_VERSION
Definition: g_save.c:768
fieldtype_t
fieldtype_t
Definition: g_local.h:565
game_locals_t::num_items
int num_items
Definition: g_local.h:287
S
#define S(name)
Definition: g_save.c:42
P_monsterinfo_melee
@ P_monsterinfo_melee
Definition: g_ptrs.h:22
ptr_type_t
ptr_type_t
Definition: g_ptrs.h:1
save_field_t::ofs
size_t ofs
Definition: g_save.c:28
game_locals_t::clients
gclient_t * clients
Definition: g_local.h:273
game
game_locals_t game
Definition: g_main.c:21
random
#define random()
Definition: g_local.h:504
I
#define I(name)
Definition: g_save.c:44
globals
game_export_t globals
Definition: g_main.c:24
write_float
static void write_float(FILE *f, float v)
Definition: g_save.c:452
Q_strlcpy
size_t Q_strlcpy(char *dst, const char *src, size_t size)
Definition: shared.c:715
save_field_t
Definition: g_save.c:23
F_SHORT
@ F_SHORT
Definition: g_local.h:568
gamefields
static const save_field_t gamefields[]
Definition: g_save.c:413
entityfields
static const save_field_t entityfields[]
Definition: g_save.c:53
P_monsterinfo_idle
@ P_monsterinfo_idle
Definition: g_ptrs.h:16
save_ptr_t::type
ptr_type_t type
Definition: g_ptrs.h:28
V
#define V(name)
Definition: g_save.c:48
P_monsterinfo_checkattack
@ P_monsterinfo_checkattack
Definition: g_ptrs.h:24
P_moveinfo_endfunc
@ P_moveinfo_endfunc
Definition: g_ptrs.h:12
game_locals_t::autosaved
qboolean autosaved
Definition: g_local.h:289
level_locals_t::time
float time
Definition: g_local.h:299
read_vector
static void read_vector(FILE *f, vec_t *v)
Definition: g_save.c:654
save_field_t::type
fieldtype_t type
Definition: g_save.c:24
ReadGame
void ReadGame(const char *filename)
Definition: g_save.c:810
P_monsterinfo_walk
@ P_monsterinfo_walk
Definition: g_ptrs.h:18
WriteLevel
void WriteLevel(const char *filename)
Definition: g_save.c:866
TAG_GAME
#define TAG_GAME
Definition: g_local.h:78
P_monsterinfo_run
@ P_monsterinfo_run
Definition: g_ptrs.h:19
level
level_locals_t level
Definition: g_main.c:22
diff
static q_noinline int diff(uint32_t A_u32, uint32_t B_u32)
Definition: hq2x.c:55
P_monsterinfo_sight
@ P_monsterinfo_sight
Definition: g_ptrs.h:23
SAVE_MAGIC2
#define SAVE_MAGIC2
Definition: g_save.c:767
num_save_ptrs
const int num_save_ptrs
Definition: g_ptrs.c:1237
L
#define L(name)
Definition: g_save.c:47
SA
#define SA(name, size)
Definition: g_save.c:41
msg
const char * msg
Definition: win.h:25
func_clock_use
void func_clock_use(edict_t *self, edict_t *other, edict_t *activator)
Definition: g_misc.c:1660
read_float
static float read_float(FILE *f)
Definition: g_save.c:609
P_monsterinfo_attack
@ P_monsterinfo_attack
Definition: g_ptrs.h:21
write_index
static void write_index(FILE *f, void *p, size_t size, void *start, int max_index)
Definition: g_save.c:479
read_data
static void read_data(void *buf, size_t len, FILE *f)
Definition: g_save.c:582
P_think
@ P_think
Definition: g_ptrs.h:5
func_clock_think
void func_clock_think(edict_t *self)
Definition: g_misc.c:1600
F_LSTRING
@ F_LSTRING
Definition: g_local.h:571
read_short
static int read_short(FILE *f)
Definition: g_save.c:589
SaveClientData
void SaveClientData(void)
Definition: p_client.c:635
game_locals_t::maxentities
int maxentities
Definition: g_local.h:281
SAVE_MAGIC1
#define SAVE_MAGIC1
Definition: g_save.c:766
F_POINTER
@ F_POINTER
Definition: g_local.h:580
levelfields
static const save_field_t levelfields[]
Definition: g_save.c:249
P_monsterinfo_dodge
@ P_monsterinfo_dodge
Definition: g_ptrs.h:20
F_INT
@ F_INT
Definition: g_local.h:569
read_pointer
static void * read_pointer(FILE *f, ptr_type_t type)
Definition: g_save.c:679
SZ
#define SZ(name, size)
Definition: g_save.c:38
FA
#define FA(name, size)
Definition: g_save.c:45
P_monsterinfo_currentmove
@ P_monsterinfo_currentmove
Definition: g_ptrs.h:14
read_fields
static void read_fields(FILE *f, const save_field_t *fields, void *base)
Definition: g_save.c:755
g_local.h
gitem_s
Definition: g_local.h:232
game_locals_t::maxclients
int maxclients
Definition: g_local.h:280