g_save.c 18 KB

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