|
|
1.1 ! root 1: ! 2: #include "g_local.h" ! 3: ! 4: game_locals_t game; ! 5: level_locals_t level; ! 6: game_import_t gi; ! 7: game_export_t globals; ! 8: spawn_temp_t st; ! 9: ! 10: int sm_meat_index; ! 11: int snd_fry; ! 12: int meansOfDeath; ! 13: ! 14: edict_t *g_edicts; ! 15: ! 16: cvar_t *deathmatch; ! 17: cvar_t *coop; ! 18: cvar_t *dmflags; ! 19: cvar_t *skill; ! 20: cvar_t *fraglimit; ! 21: cvar_t *timelimit; ! 22: //ZOID ! 23: cvar_t *capturelimit; ! 24: cvar_t *instantweap; ! 25: //ZOID ! 26: cvar_t *password; ! 27: cvar_t *maxclients; ! 28: cvar_t *maxentities; ! 29: cvar_t *g_select_empty; ! 30: cvar_t *dedicated; ! 31: ! 32: cvar_t *sv_maxvelocity; ! 33: cvar_t *sv_gravity; ! 34: ! 35: cvar_t *sv_rollspeed; ! 36: cvar_t *sv_rollangle; ! 37: cvar_t *gun_x; ! 38: cvar_t *gun_y; ! 39: cvar_t *gun_z; ! 40: ! 41: cvar_t *run_pitch; ! 42: cvar_t *run_roll; ! 43: cvar_t *bob_up; ! 44: cvar_t *bob_pitch; ! 45: cvar_t *bob_roll; ! 46: ! 47: cvar_t *sv_cheats; ! 48: ! 49: cvar_t *flood_msgs; ! 50: cvar_t *flood_persecond; ! 51: cvar_t *flood_waitdelay; ! 52: ! 53: cvar_t *sv_maplist; ! 54: ! 55: void SpawnEntities (char *mapname, char *entities, char *spawnpoint); ! 56: void ClientThink (edict_t *ent, usercmd_t *cmd); ! 57: qboolean ClientConnect (edict_t *ent, char *userinfo); ! 58: void ClientUserinfoChanged (edict_t *ent, char *userinfo); ! 59: void ClientDisconnect (edict_t *ent); ! 60: void ClientBegin (edict_t *ent); ! 61: void ClientCommand (edict_t *ent); ! 62: void RunEntity (edict_t *ent); ! 63: void WriteGame (char *filename, qboolean autosave); ! 64: void ReadGame (char *filename); ! 65: void WriteLevel (char *filename); ! 66: void ReadLevel (char *filename); ! 67: void InitGame (void); ! 68: void G_RunFrame (void); ! 69: ! 70: ! 71: //=================================================================== ! 72: ! 73: ! 74: void ShutdownGame (void) ! 75: { ! 76: gi.dprintf ("==== ShutdownGame ====\n"); ! 77: ! 78: gi.FreeTags (TAG_LEVEL); ! 79: gi.FreeTags (TAG_GAME); ! 80: } ! 81: ! 82: ! 83: /* ! 84: ================= ! 85: GetGameAPI ! 86: ! 87: Returns a pointer to the structure with all entry points ! 88: and global variables ! 89: ================= ! 90: */ ! 91: game_export_t *GetGameAPI (game_import_t *import) ! 92: { ! 93: gi = *import; ! 94: ! 95: globals.apiversion = GAME_API_VERSION; ! 96: globals.Init = InitGame; ! 97: globals.Shutdown = ShutdownGame; ! 98: globals.SpawnEntities = SpawnEntities; ! 99: ! 100: globals.WriteGame = WriteGame; ! 101: globals.ReadGame = ReadGame; ! 102: globals.WriteLevel = WriteLevel; ! 103: globals.ReadLevel = ReadLevel; ! 104: ! 105: globals.ClientThink = ClientThink; ! 106: globals.ClientConnect = ClientConnect; ! 107: globals.ClientUserinfoChanged = ClientUserinfoChanged; ! 108: globals.ClientDisconnect = ClientDisconnect; ! 109: globals.ClientBegin = ClientBegin; ! 110: globals.ClientCommand = ClientCommand; ! 111: ! 112: globals.RunFrame = G_RunFrame; ! 113: ! 114: globals.ServerCommand = ServerCommand; ! 115: ! 116: globals.edict_size = sizeof(edict_t); ! 117: ! 118: return &globals; ! 119: } ! 120: ! 121: #ifndef GAME_HARD_LINKED ! 122: // this is only here so the functions in q_shared.c and q_shwin.c can link ! 123: void Sys_Error (char *error, ...) ! 124: { ! 125: va_list argptr; ! 126: char text[1024]; ! 127: ! 128: va_start (argptr, error); ! 129: vsprintf (text, error, argptr); ! 130: va_end (argptr); ! 131: ! 132: gi.error (ERR_FATAL, "%s", text); ! 133: } ! 134: ! 135: void Com_Printf (char *msg, ...) ! 136: { ! 137: va_list argptr; ! 138: char text[1024]; ! 139: ! 140: va_start (argptr, msg); ! 141: vsprintf (text, msg, argptr); ! 142: va_end (argptr); ! 143: ! 144: gi.dprintf ("%s", text); ! 145: } ! 146: ! 147: #endif ! 148: ! 149: //====================================================================== ! 150: ! 151: ! 152: /* ! 153: ================= ! 154: ClientEndServerFrames ! 155: ================= ! 156: */ ! 157: void ClientEndServerFrames (void) ! 158: { ! 159: int i; ! 160: edict_t *ent; ! 161: ! 162: // calc the player views now that all pushing ! 163: // and damage has been added ! 164: for (i=0 ; i<maxclients->value ; i++) ! 165: { ! 166: ent = g_edicts + 1 + i; ! 167: if (!ent->inuse || !ent->client) ! 168: continue; ! 169: ClientEndServerFrame (ent); ! 170: } ! 171: ! 172: } ! 173: ! 174: /* ! 175: ================= ! 176: CreateTargetChangeLevel ! 177: ! 178: Returns the created target changelevel ! 179: ================= ! 180: */ ! 181: edict_t *CreateTargetChangeLevel(char *map) ! 182: { ! 183: edict_t *ent; ! 184: ! 185: ent = G_Spawn (); ! 186: ent->classname = "target_changelevel"; ! 187: Com_sprintf(level.nextmap, sizeof(level.nextmap), "%s", map); ! 188: ent->map = level.nextmap; ! 189: return ent; ! 190: } ! 191: ! 192: /* ! 193: ================= ! 194: EndDMLevel ! 195: ! 196: The timelimit or fraglimit has been exceeded ! 197: ================= ! 198: */ ! 199: void EndDMLevel (void) ! 200: { ! 201: edict_t *ent; ! 202: char *s, *t, *f; ! 203: static const char *seps = " ,\n\r"; ! 204: ! 205: // stay on same level flag ! 206: if ((int)dmflags->value & DF_SAME_LEVEL) ! 207: { ! 208: BeginIntermission (CreateTargetChangeLevel (level.mapname) ); ! 209: return; ! 210: } ! 211: ! 212: if (*level.forcemap) { ! 213: BeginIntermission (CreateTargetChangeLevel (level.forcemap) ); ! 214: return; ! 215: } ! 216: ! 217: // see if it's in the map list ! 218: if (*sv_maplist->string) { ! 219: s = strdup(sv_maplist->string); ! 220: f = NULL; ! 221: t = strtok(s, seps); ! 222: while (t != NULL) { ! 223: if (Q_stricmp(t, level.mapname) == 0) { ! 224: // it's in the list, go to the next one ! 225: t = strtok(NULL, seps); ! 226: if (t == NULL) { // end of list, go to first one ! 227: if (f == NULL) // there isn't a first one, same level ! 228: BeginIntermission (CreateTargetChangeLevel (level.mapname) ); ! 229: else ! 230: BeginIntermission (CreateTargetChangeLevel (f) ); ! 231: } else ! 232: BeginIntermission (CreateTargetChangeLevel (t) ); ! 233: free(s); ! 234: return; ! 235: } ! 236: if (!f) ! 237: f = t; ! 238: t = strtok(NULL, seps); ! 239: } ! 240: free(s); ! 241: } ! 242: ! 243: if (level.nextmap[0]) // go to a specific map ! 244: BeginIntermission (CreateTargetChangeLevel (level.nextmap) ); ! 245: else { // search for a changelevel ! 246: ent = G_Find (NULL, FOFS(classname), "target_changelevel"); ! 247: if (!ent) ! 248: { // the map designer didn't include a changelevel, ! 249: // so create a fake ent that goes back to the same level ! 250: BeginIntermission (CreateTargetChangeLevel (level.mapname) ); ! 251: return; ! 252: } ! 253: BeginIntermission (ent); ! 254: } ! 255: } ! 256: ! 257: /* ! 258: ================= ! 259: CheckDMRules ! 260: ================= ! 261: */ ! 262: void CheckDMRules (void) ! 263: { ! 264: int i; ! 265: gclient_t *cl; ! 266: ! 267: if (level.intermissiontime) ! 268: return; ! 269: ! 270: if (!deathmatch->value) ! 271: return; ! 272: ! 273: //ZOID ! 274: if (ctf->value && CTFCheckRules()) { ! 275: EndDMLevel (); ! 276: return; ! 277: } ! 278: if (CTFInMatch()) ! 279: return; // no checking in match mode ! 280: //ZOID ! 281: ! 282: if (timelimit->value) ! 283: { ! 284: if (level.time >= timelimit->value*60) ! 285: { ! 286: gi.bprintf (PRINT_HIGH, "Timelimit hit.\n"); ! 287: EndDMLevel (); ! 288: return; ! 289: } ! 290: } ! 291: ! 292: if (fraglimit->value) ! 293: for (i=0 ; i<maxclients->value ; i++) ! 294: { ! 295: cl = game.clients + i; ! 296: if (!g_edicts[i+1].inuse) ! 297: continue; ! 298: ! 299: if (cl->resp.score >= fraglimit->value) ! 300: { ! 301: gi.bprintf (PRINT_HIGH, "Fraglimit hit.\n"); ! 302: EndDMLevel (); ! 303: return; ! 304: } ! 305: } ! 306: } ! 307: ! 308: ! 309: /* ! 310: ============= ! 311: ExitLevel ! 312: ============= ! 313: */ ! 314: void ExitLevel (void) ! 315: { ! 316: int i; ! 317: edict_t *ent; ! 318: char command [256]; ! 319: ! 320: level.exitintermission = 0; ! 321: level.intermissiontime = 0; ! 322: ! 323: if (CTFNextMap()) ! 324: return; ! 325: ! 326: Com_sprintf (command, sizeof(command), "gamemap \"%s\"\n", level.changemap); ! 327: gi.AddCommandString (command); ! 328: ClientEndServerFrames (); ! 329: ! 330: level.changemap = NULL; ! 331: ! 332: // clear some things before going to next level ! 333: for (i=0 ; i<maxclients->value ; i++) ! 334: { ! 335: ent = g_edicts + 1 + i; ! 336: if (!ent->inuse) ! 337: continue; ! 338: if (ent->health > ent->client->pers.max_health) ! 339: ent->health = ent->client->pers.max_health; ! 340: } ! 341: } ! 342: ! 343: /* ! 344: ================ ! 345: G_RunFrame ! 346: ! 347: Advances the world by 0.1 seconds ! 348: ================ ! 349: */ ! 350: void G_RunFrame (void) ! 351: { ! 352: int i; ! 353: edict_t *ent; ! 354: ! 355: level.framenum++; ! 356: level.time = level.framenum*FRAMETIME; ! 357: ! 358: // choose a client for monsters to target this frame ! 359: AI_SetSightClient (); ! 360: ! 361: // exit intermissions ! 362: ! 363: if (level.exitintermission) ! 364: { ! 365: ExitLevel (); ! 366: return; ! 367: } ! 368: ! 369: // ! 370: // treat each object in turn ! 371: // even the world gets a chance to think ! 372: // ! 373: ent = &g_edicts[0]; ! 374: for (i=0 ; i<globals.num_edicts ; i++, ent++) ! 375: { ! 376: if (!ent->inuse) ! 377: continue; ! 378: ! 379: level.current_entity = ent; ! 380: ! 381: VectorCopy (ent->s.origin, ent->s.old_origin); ! 382: ! 383: // if the ground entity moved, make sure we are still on it ! 384: if ((ent->groundentity) && (ent->groundentity->linkcount != ent->groundentity_linkcount)) ! 385: { ! 386: ent->groundentity = NULL; ! 387: if ( !(ent->flags & (FL_SWIM|FL_FLY)) && (ent->svflags & SVF_MONSTER) ) ! 388: { ! 389: M_CheckGround (ent); ! 390: } ! 391: } ! 392: ! 393: if (i > 0 && i <= maxclients->value) ! 394: { ! 395: ClientBeginServerFrame (ent); ! 396: continue; ! 397: } ! 398: ! 399: G_RunEntity (ent); ! 400: } ! 401: ! 402: // see if it is time to end a deathmatch ! 403: CheckDMRules (); ! 404: ! 405: // build the playerstate_t structures for all players ! 406: ClientEndServerFrames (); ! 407: } ! 408:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.