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