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