Annotation of quake2/ctf/g_main.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.