--- quake2/game/g_main.c 2018/04/24 17:59:09 1.1.1.2 +++ quake2/game/g_main.c 2018/04/24 18:03:16 1.1.1.4 @@ -1,3 +1,22 @@ +/* +Copyright (C) 1997-2001 Id Software, Inc. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ #include "g_local.h" @@ -20,7 +39,10 @@ cvar_t *skill; cvar_t *fraglimit; cvar_t *timelimit; cvar_t *password; +cvar_t *spectator_password; +cvar_t *needpass; cvar_t *maxclients; +cvar_t *maxspectators; cvar_t *maxentities; cvar_t *g_select_empty; cvar_t *dedicated; @@ -48,6 +70,8 @@ cvar_t *flood_msgs; cvar_t *flood_persecond; cvar_t *flood_waitdelay; +cvar_t *sv_maplist; + void SpawnEntities (char *mapname, char *entities, char *spawnpoint); void ClientThink (edict_t *ent, usercmd_t *cmd); qboolean ClientConnect (edict_t *ent, char *userinfo); @@ -169,6 +193,24 @@ void ClientEndServerFrames (void) /* ================= +CreateTargetChangeLevel + +Returns the created target changelevel +================= +*/ +edict_t *CreateTargetChangeLevel(char *map) +{ + edict_t *ent; + + ent = G_Spawn (); + ent->classname = "target_changelevel"; + Com_sprintf(level.nextmap, sizeof(level.nextmap), "%s", map); + ent->map = level.nextmap; + return ent; +} + +/* +================= EndDMLevel The timelimit or fraglimit has been exceeded @@ -177,33 +219,81 @@ The timelimit or fraglimit has been exce void EndDMLevel (void) { edict_t *ent; + char *s, *t, *f; + static const char *seps = " ,\n\r"; // stay on same level flag if ((int)dmflags->value & DF_SAME_LEVEL) { - ent = G_Spawn (); - ent->classname = "target_changelevel"; - ent->map = level.mapname; + BeginIntermission (CreateTargetChangeLevel (level.mapname) ); + return; } - else if (level.nextmap[0]) - { // go to a specific map - ent = G_Spawn (); - ent->classname = "target_changelevel"; - ent->map = level.nextmap; + + // see if it's in the map list + if (*sv_maplist->string) { + s = strdup(sv_maplist->string); + f = NULL; + t = strtok(s, seps); + while (t != NULL) { + if (Q_stricmp(t, level.mapname) == 0) { + // it's in the list, go to the next one + t = strtok(NULL, seps); + if (t == NULL) { // end of list, go to first one + if (f == NULL) // there isn't a first one, same level + BeginIntermission (CreateTargetChangeLevel (level.mapname) ); + else + BeginIntermission (CreateTargetChangeLevel (f) ); + } else + BeginIntermission (CreateTargetChangeLevel (t) ); + free(s); + return; + } + if (!f) + f = t; + t = strtok(NULL, seps); + } + free(s); } - else - { // search for a changeleve + + if (level.nextmap[0]) // go to a specific map + BeginIntermission (CreateTargetChangeLevel (level.nextmap) ); + else { // search for a changelevel ent = G_Find (NULL, FOFS(classname), "target_changelevel"); if (!ent) { // the map designer didn't include a changelevel, // so create a fake ent that goes back to the same level - ent = G_Spawn (); - ent->classname = "target_changelevel"; - ent->map = level.mapname; + BeginIntermission (CreateTargetChangeLevel (level.mapname) ); + return; } + BeginIntermission (ent); } +} + - BeginIntermission (ent); +/* +================= +CheckNeedPass +================= +*/ +void CheckNeedPass (void) +{ + int need; + + // if password or spectator_password has changed, update needpass + // as needed + if (password->modified || spectator_password->modified) + { + password->modified = spectator_password->modified = false; + + need = 0; + + if (*password->string && Q_stricmp(password->string, "none")) + need |= 1; + if (*spectator_password->string && Q_stricmp(spectator_password->string, "none")) + need |= 2; + + gi.cvar_set("needpass", va("%d", need)); + } } /* @@ -343,6 +433,9 @@ void G_RunFrame (void) // see if it is time to end a deathmatch CheckDMRules (); + // see if needpass needs updated + CheckNeedPass (); + // build the playerstate_t structures for all players ClientEndServerFrames (); }