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