00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00057 if (cl.pnum == playerNum) {
00058
00059 Com_sprintf(buf, sizeof(buf), _("You've ended your round\n"));
00060 } else {
00061 const char *playerName = CL_PlayerGetName(playerNum);
00062
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
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
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
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
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
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 = >s[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
00307
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 }