cl_game_multiplayer.c

Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2002-2010 UFO: Alien Invasion.
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018 See the GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00023 
00024 */
00025 
00026 #include "client.h"
00027 #include "cl_game.h"
00028 #include "cl_team.h"
00029 #include "cl_inventory.h"
00030 #include "multiplayer/mp_callbacks.h"
00031 #include "multiplayer/mp_serverlist.h"
00032 #include "multiplayer/mp_team.h"
00033 #include "ui/ui_main.h"
00034 #include "ui/ui_popup.h"
00035 #include "battlescape/cl_hud.h"
00036 #include "battlescape/cl_parse.h"
00037 
00038 void GAME_MP_AutoTeam (void)
00039 {
00040     const equipDef_t *ed = INV_GetEquipmentDefinitionByID("multiplayer_initial");
00041     const char *teamDefID = GAME_GetTeamDef();
00042 
00043     GAME_GenerateTeam(teamDefID, ed, GAME_GetCharacterArraySize());
00044 }
00045 
00046 void GAME_MP_StartBattlescape (qboolean isTeamPlay)
00047 {
00048     UI_ExecuteConfunc("multiplayer_setTeamplay %i", isTeamPlay);
00049     UI_InitStack("multiplayer_wait", NULL, qtrue, qtrue);
00050 }
00051 
00052 void GAME_MP_EndRoundAnnounce (int playerNum, int team)
00053 {
00054     char buf[128];
00055 
00056     /* it was our own round */
00057     if (cl.pnum == playerNum) {
00058         /* add translated message to chat buffer */
00059         Com_sprintf(buf, sizeof(buf), _("You've ended your round\n"));
00060     } else {
00061         const char *playerName = CL_PlayerGetName(playerNum);
00062         /* add translated message to chat buffer */
00063         Com_sprintf(buf, sizeof(buf), _("%s ended his round (team %i)\n"), playerName, team);
00064     }
00065     HUD_DisplayMessage(buf);
00066 }
00067 
00072 static void GAME_MP_StartServer_f (void)
00073 {
00074     char map[MAX_VAR];
00075     mapDef_t *md;
00076 
00077     if (!sv_dedicated->integer && !chrDisplayList.num)
00078         GAME_MP_AutoTeam();
00079 
00080     if (Cvar_GetInteger("sv_teamplay")
00081      && Cvar_GetValue("sv_maxsoldiersperplayer") > Cvar_GetValue("sv_maxsoldiersperteam")) {
00082         UI_Popup(_("Settings doesn't make sense"), _("Set soldiers per player lower than soldiers per team"));
00083         return;
00084     }
00085 
00086     md = Com_GetMapDefByIDX(cls.currentSelectedMap);
00087     if (!md || !md->multiplayer)
00088         return;
00089     assert(md->map);
00090 
00091     Com_sprintf(map, sizeof(map), "map %s %s %s", Cvar_GetInteger("mn_serverday") ? "day" : "night", md->map, md->param ? md->param : "");
00092 
00093     /* let the (local) server know which map we are running right now */
00094     cls.currentMD = md;
00095 
00097     Cvar_Set("rm_drop", "");
00098     Cvar_Set("rm_ufo", "");
00099 
00100     if (md->hurtAliens)
00101         Cvar_Set("sv_hurtaliens", "1");
00102     else
00103         Cvar_Set("sv_hurtaliens", "0");
00104 
00105     if (md->teams)
00106         Cvar_SetValue("sv_maxteams", md->teams);
00107     else
00108         Cvar_SetValue("sv_maxteams", 2);
00109 
00110     Cmd_ExecuteString(map);
00111 
00112     UI_InitStack("multiplayer_wait", "multiplayerInGame", qfalse, qtrue);
00113 }
00114 
00118 static void GAME_MP_UpdateGametype_f (void)
00119 {
00120     Com_SetGameType();
00121 }
00122 
00127 static void GAME_MP_ChangeGametype_f (void)
00128 {
00129     const mapDef_t *md;
00130     const char *newGameTypeID = NULL;
00131     qboolean next = qtrue;
00132 
00133     /* no types defined or parsed */
00134     if (numGTs == 0)
00135         return;
00136 
00137     md = Com_GetMapDefByIDX(cls.currentSelectedMap);
00138     if (!md || !md->multiplayer) {
00139         Com_Printf("UI_ChangeGametype_f: No mapdef for the map\n");
00140         return;
00141     }
00142 
00143     /* previous? */
00144     if (!strcmp(Cmd_Argv(0), "mp_prevgametype")) {
00145         next = qfalse;
00146     }
00147 
00148     if (md->gameTypes) {
00149         linkedList_t *list = md->gameTypes;
00150         linkedList_t *old = NULL;
00151         while (list) {
00152             if (!strcmp((const char*)list->data, sv_gametype->string)) {
00153                 if (next) {
00154                     if (list->next)
00155                         newGameTypeID = (const char *)list->next->data;
00156                     else
00157                         newGameTypeID = (const char *)md->gameTypes->data;
00158                 } else {
00159                     /* only one or the first entry */
00160                     if (old) {
00161                         newGameTypeID = (const char *)old->data;
00162                     } else {
00163                         while (list->next)
00164                             list = list->next;
00165                         newGameTypeID = (const char *)list->data;
00166                     }
00167                 }
00168                 break;
00169             }
00170             old = list;
00171             list = list->next;
00172         }
00173         /* current value is not valid for this map, set to first valid gametype */
00174         if (!list)
00175             newGameTypeID = (const char *)md->gameTypes->data;
00176     } else {
00177         int i;
00178         for (i = 0; i < numGTs; i++) {
00179             const gametype_t *gt = &gts[i];
00180             if (!strcmp(gt->id, sv_gametype->string)) {
00181                 int newType;
00182                 if (next) {
00183                     newType = (i + 1);
00184                     if (newType >= numGTs)
00185                         newType = 0;
00186                 } else {
00187                     newType = (i - 1);
00188                     if (newType < 0)
00189                         newType = numGTs - 1;
00190                 }
00191 
00192                 newGameTypeID = gts[newType].id;
00193                 break;
00194             }
00195         }
00196     }
00197     if (newGameTypeID) {
00198         Cvar_Set("sv_gametype", newGameTypeID);
00199         Com_SetGameType();
00200     }
00201 }
00202 
00214 void GAME_MP_Results (struct dbuffer *msg, int winner, int *numSpawned, int *numAlive, int numKilled[][MAX_TEAMS], int numStunned[][MAX_TEAMS])
00215 {
00216     char resultText[UI_MAX_SMALLTEXTLEN];
00217     int their_killed, their_stunned;
00218     int i;
00219 
00220     CL_Drop();
00221 
00222     if (winner == 0) {
00223         UI_Popup(_("Game Drawn!"), _("The game was a draw!\n\nNo survivors left on any side."));
00224         return;
00225     }
00226 
00227     their_killed = their_stunned = 0;
00228     for (i = 0; i < MAX_TEAMS; i++) {
00229         if (i != cls.team) {
00230             their_killed += numKilled[cls.team][i];
00231             their_stunned += numStunned[cls.team][i];
00232         }
00233     }
00234 
00235     Com_sprintf(resultText, sizeof(resultText), _("\n\nEnemies killed:  %i\nTeam survivors:  %i"), their_killed + their_stunned, numAlive[cls.team]);
00236     if (winner == cls.team) {
00237         Com_sprintf(popupText, lengthof(popupText), "%s%s", _("You won the game!"), resultText);
00238         UI_Popup(_("Congratulations"), popupText);
00239     } else {
00240         Com_sprintf(popupText, lengthof(popupText), "%s%s", _("You've lost the game!"), resultText);
00241         UI_Popup(_("Better luck next time"), popupText);
00242     }
00243 }
00244 
00245 const mapDef_t* GAME_MP_MapInfo (int step)
00246 {
00247     const mapDef_t *md;
00248     int i = 0;
00249 
00250     while (!Com_GetMapDefByIDX(cls.currentSelectedMap)->multiplayer) {
00251         i++;
00252         cls.currentSelectedMap += (step ? step : 1);
00253         if (cls.currentSelectedMap < 0)
00254             cls.currentSelectedMap = cls.numMDs - 1;
00255         cls.currentSelectedMap %= cls.numMDs;
00256         if (i >= cls.numMDs)
00257             Com_Error(ERR_DROP, "GAME_MP_MapInfo: There is no multiplayer map in any mapdef");
00258     }
00259 
00260     md = Com_GetMapDefByIDX(cls.currentSelectedMap);
00261 
00262     if (md->gameTypes) {
00263         const linkedList_t *list = md->gameTypes;
00264         char buf[256] = "";
00265         while (list) {
00266             Q_strcat(buf, va("%s ", (const char *)list->data), sizeof(buf));
00267             list = list->next;
00268         }
00269         Cvar_Set("mn_mapgametypes", buf);
00270         list = LIST_ContainsString(md->gameTypes, sv_gametype->string);
00271     } else {
00272         Cvar_Set("mn_mapgametypes", _("all"));
00273     }
00274 
00275     return md;
00276 }
00277 
00278 int GAME_MP_GetTeam (void)
00279 {
00280     return cl_team->integer;
00281 }
00282 
00283 static equipDef_t equipDefMultiplayer;
00284 
00285 equipDef_t *GAME_MP_GetEquipmentDefinition (void)
00286 {
00287     return &equipDefMultiplayer;
00288 }
00289 
00290 void GAME_MP_InitStartup (void)
00291 {
00292     const char *max_s = Cvar_VariableStringOld("sv_maxsoldiersperteam");
00293     const char *max_spp = Cvar_VariableStringOld("sv_maxsoldiersperplayer");
00294 
00295     chrDisplayList.num = 0;
00296 
00297     Cvar_ForceSet("sv_maxclients", "2");
00298 
00299     Cmd_AddCommand("mp_startserver", GAME_MP_StartServer_f, NULL);
00300     Cmd_AddCommand("mp_updategametype", GAME_MP_UpdateGametype_f, "Update the menu values with current gametype values");
00301     Cmd_AddCommand("mp_nextgametype", GAME_MP_ChangeGametype_f, "Switch to the next multiplayer game type");
00302     Cmd_AddCommand("mp_prevgametype", GAME_MP_ChangeGametype_f, "Switch to the previous multiplayer game type");
00303     MP_CallbacksInit();
00304     MP_ServerListInit();
00305 
00306     /* restore old sv_maxsoldiersperplayer and sv_maxsoldiersperteam
00307      * cvars if values were previously set */
00308     if (max_s[0] != '\0')
00309         Cvar_Set("sv_maxsoldiersperteam", max_s);
00310     if (max_spp[0] != '\0')
00311         Cvar_Set("sv_maxsoldiersperplayer", max_spp);
00312 }
00313 
00314 void GAME_MP_Shutdown (void)
00315 {
00316     Cmd_RemoveCommand("mp_startserver");
00317     Cmd_RemoveCommand("mp_updategametype");
00318     Cmd_RemoveCommand("mp_nextgametype");
00319     Cmd_RemoveCommand("mp_prevgametype");
00320     MP_CallbacksShutdown();
00321     MP_ServerListShutdown();
00322 
00323     SV_Shutdown("Game mode shutdown", qfalse);
00324 
00325     memset(&teamData, 0, sizeof(teamData));
00326 }

Generated by  doxygen 1.6.2