g_save.c 17 KB

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