codemp/cgame/cg_saga.c

Go to the documentation of this file.
00001 // Copyright (C) 2000-2002 Raven Software, Inc.
00002 //
00003 /*****************************************************************************
00004  * name:                cg_siege.c
00005  *
00006  * desc:                Clientgame-side module for Siege gametype.
00007  *
00008  * $Author: osman $ 
00009  * $Revision: 1.5 $
00010  *
00011  *****************************************************************************/
00012 #include "cg_local.h"
00013 #include "bg_saga.h"
00014 
00015 int cgSiegeRoundState = 0;
00016 int cgSiegeRoundTime = 0;
00017 
00018 static char             team1[512];
00019 static char             team2[512];
00020 
00021 int                     team1Timed = 0;
00022 int                     team2Timed = 0;
00023 
00024 int                     cgSiegeTeam1PlShader = 0;
00025 int                     cgSiegeTeam2PlShader = 0;
00026 
00027 static char cgParseObjectives[MAX_SIEGE_INFO_SIZE];
00028 
00029 extern void CG_LoadCISounds(clientInfo_t *ci, qboolean modelloaded); //cg_players.c
00030 
00031 void CG_DrawSiegeMessage( const char *str, int objectiveScreen );
00032 void CG_DrawSiegeMessageNonMenu( const char *str );
00033 void CG_SiegeBriefingDisplay(int team, int dontshow);
00034 
00035 void CG_PrecacheSiegeObjectiveAssetsForTeam(int myTeam)
00036 {
00037         char                    teamstr[64];
00038         char                    objstr[256];
00039         char                    foundobjective[MAX_SIEGE_INFO_SIZE];
00040 
00041         if (!siege_valid)
00042         {
00043                 CG_Error("Siege data does not exist on client!\n");
00044                 return;
00045         }
00046 
00047         if (myTeam == SIEGETEAM_TEAM1)
00048         {
00049                 Com_sprintf(teamstr, sizeof(teamstr), team1);
00050         }
00051         else
00052         {
00053                 Com_sprintf(teamstr, sizeof(teamstr), team2);
00054         }
00055 
00056         if (BG_SiegeGetValueGroup(siege_info, teamstr, cgParseObjectives))
00057         {
00058                 int i = 1;
00059                 while (i < 32)
00060                 { //eh, just try 32 I guess
00061                         Com_sprintf(objstr, sizeof(objstr), "Objective%i", i);
00062 
00063                         if (BG_SiegeGetValueGroup(cgParseObjectives, objstr, foundobjective))
00064                         {
00065                                 char str[MAX_QPATH];
00066 
00067                                 if (BG_SiegeGetPairedValue(foundobjective, "sound_team1", str))
00068                                 {
00069                                         trap_S_RegisterSound(str);
00070                                 }
00071                                 if (BG_SiegeGetPairedValue(foundobjective, "sound_team2", str))
00072                                 {
00073                                         trap_S_RegisterSound(str);
00074                                 }
00075                                 if (BG_SiegeGetPairedValue(foundobjective, "objgfx", str))
00076                                 {
00077                                         trap_R_RegisterShaderNoMip(str);
00078                                 }
00079                                 if (BG_SiegeGetPairedValue(foundobjective, "mapicon", str))
00080                                 {
00081                                         trap_R_RegisterShaderNoMip(str);
00082                                 }
00083                                 if (BG_SiegeGetPairedValue(foundobjective, "litmapicon", str))
00084                                 {
00085                                         trap_R_RegisterShaderNoMip(str);
00086                                 }
00087                                 if (BG_SiegeGetPairedValue(foundobjective, "donemapicon", str))
00088                                 {
00089                                         trap_R_RegisterShaderNoMip(str);
00090                                 }
00091                         }
00092                         else
00093                         { //no more
00094                                 break;
00095                         }
00096                         i++;
00097                 }
00098         }
00099 }
00100 
00101 void CG_PrecachePlayersForSiegeTeam(int team)
00102 {
00103         siegeTeam_t *stm;
00104         int i = 0;
00105 
00106         stm = BG_SiegeFindThemeForTeam(team);
00107 
00108         if (!stm)
00109         { //invalid team/no theme for team?
00110                 return;
00111         }
00112 
00113         while (i < stm->numClasses)
00114         {
00115                 siegeClass_t *scl = stm->classes[i];
00116 
00117                 if (scl->forcedModel[0])
00118                 {
00119                         clientInfo_t fake;
00120 
00121                         memset(&fake, 0, sizeof(fake));
00122                         strcpy(fake.modelName, scl->forcedModel);
00123 
00124                         trap_R_RegisterModel(va("models/players/%s/model.glm", scl->forcedModel));
00125                         if (scl->forcedSkin[0])
00126                         {
00127                                 trap_R_RegisterSkin(va("models/players/%s/model_%s.skin", scl->forcedModel, scl->forcedSkin));
00128                                 strcpy(fake.skinName, scl->forcedSkin);
00129                         }
00130                         else
00131                         {
00132                                 strcpy(fake.skinName, "default");
00133                         }
00134 
00135                         //precache the sounds for the model...
00136                         CG_LoadCISounds(&fake, qtrue);
00137                 }
00138 
00139                 i++;
00140         }
00141 }
00142 
00143 void CG_InitSiegeMode(void)
00144 {
00145         char                    levelname[MAX_QPATH];
00146         char                    btime[1024];
00147         char                    teams[2048];
00148         char                    teamInfo[MAX_SIEGE_INFO_SIZE];
00149         int                             len = 0;
00150         int                             i = 0;
00151         int                             j = 0;
00152         siegeClass_t            *cl;
00153         siegeTeam_t             *sTeam;
00154         fileHandle_t    f;
00155         char                    teamIcon[128];
00156 
00157         if (cgs.gametype != GT_SIEGE)
00158         {
00159                 goto failure;
00160         }
00161 
00162         Com_sprintf(levelname, sizeof(levelname), "%s\0", cgs.mapname);
00163 
00164         i = strlen(levelname)-1;
00165 
00166         while (i > 0 && levelname[i] && levelname[i] != '.')
00167         {
00168                 i--;
00169         }
00170 
00171         if (!i)
00172         {
00173                 goto failure;
00174         }
00175 
00176         levelname[i] = '\0'; //kill the ".bsp"
00177 
00178         Com_sprintf(levelname, sizeof(levelname), "%s.siege\0", levelname); 
00179 
00180         if (!levelname || !levelname[0])
00181         {
00182                 goto failure;
00183         }
00184 
00185         len = trap_FS_FOpenFile(levelname, &f, FS_READ);
00186 
00187         if (!f || len >= MAX_SIEGE_INFO_SIZE)
00188         {
00189                 goto failure;
00190         }
00191 
00192         trap_FS_Read(siege_info, len, f);
00193 
00194         trap_FS_FCloseFile(f);
00195 
00196         siege_valid = 1;
00197 
00198         if (BG_SiegeGetValueGroup(siege_info, "Teams", teams))
00199         {
00200                 char buf[1024];
00201 
00202                 trap_Cvar_VariableStringBuffer("cg_siegeTeam1", buf, 1024);
00203                 if (buf[0] && Q_stricmp(buf, "none"))
00204                 {
00205                         strcpy(team1, buf);
00206                 }
00207                 else
00208                 {
00209                         BG_SiegeGetPairedValue(teams, "team1", team1);
00210                 }
00211 
00212                 if (team1[0] == '@')
00213                 { //it's a damn stringed reference.
00214                         char b[256];
00215                         trap_SP_GetStringTextString(team1+1, b, 256);
00216                         trap_Cvar_Set("cg_siegeTeam1Name", b);
00217                 }
00218                 else
00219                 {
00220                         trap_Cvar_Set("cg_siegeTeam1Name", team1);
00221                 }
00222 
00223                 trap_Cvar_VariableStringBuffer("cg_siegeTeam2", buf, 1024);
00224                 if (buf[0] && Q_stricmp(buf, "none"))
00225                 {
00226                         strcpy(team2, buf);
00227                 }
00228                 else
00229                 {
00230                         BG_SiegeGetPairedValue(teams, "team2", team2);
00231                 }
00232 
00233                 if (team2[0] == '@')
00234                 { //it's a damn stringed reference.
00235                         char b[256];
00236                         trap_SP_GetStringTextString(team2+1, b, 256);
00237                         trap_Cvar_Set("cg_siegeTeam2Name", b);
00238                 }
00239                 else
00240                 {
00241                         trap_Cvar_Set("cg_siegeTeam2Name", team2);
00242                 }
00243         }
00244         else
00245         {
00246                 CG_Error("Siege teams not defined");
00247         }
00248 
00249         if (BG_SiegeGetValueGroup(siege_info, team1, teamInfo))
00250         {
00251                 if (BG_SiegeGetPairedValue(teamInfo, "TeamIcon", teamIcon))
00252                 {
00253                         trap_Cvar_Set( "team1_icon", teamIcon);
00254                 }
00255 
00256                 if (BG_SiegeGetPairedValue(teamInfo, "Timed", btime))
00257                 {
00258                         team1Timed = atoi(btime)*1000;
00259                         CG_SetSiegeTimerCvar ( team1Timed );
00260                 }
00261                 else
00262                 {
00263                         team1Timed = 0;
00264                 }
00265         }
00266         else
00267         {
00268                 CG_Error("No team entry for '%s'\n", team1);
00269         }
00270 
00271         if (BG_SiegeGetPairedValue(siege_info, "mapgraphic", teamInfo))
00272         {
00273                 trap_Cvar_Set("siege_mapgraphic", teamInfo);
00274         }
00275         else
00276         {
00277                 trap_Cvar_Set("siege_mapgraphic", "gfx/mplevels/siege1_hoth");
00278         }
00279 
00280         if (BG_SiegeGetPairedValue(siege_info, "missionname", teamInfo))
00281         {
00282                 trap_Cvar_Set("siege_missionname", teamInfo);
00283         }
00284         else
00285         {
00286                 trap_Cvar_Set("siege_missionname", " ");
00287         }
00288 
00289         if (BG_SiegeGetValueGroup(siege_info, team2, teamInfo))
00290         {
00291                 if (BG_SiegeGetPairedValue(teamInfo, "TeamIcon", teamIcon))
00292                 {
00293                         trap_Cvar_Set( "team2_icon", teamIcon);
00294                 }
00295 
00296                 if (BG_SiegeGetPairedValue(teamInfo, "Timed", btime))
00297                 {
00298                         team2Timed = atoi(btime)*1000;
00299                         CG_SetSiegeTimerCvar ( team2Timed );
00300                 }
00301                 else
00302                 {
00303                         team2Timed = 0;
00304                 }
00305         }
00306         else
00307         {
00308                 CG_Error("No team entry for '%s'\n", team2);
00309         }
00310 
00311         //Load the player class types
00312         BG_SiegeLoadClasses(NULL);
00313 
00314         if (!bgNumSiegeClasses)
00315         { //We didn't find any?!
00316                 CG_Error("Couldn't find any player classes for Siege");
00317         }
00318 
00319         //Now load the teams since we have class data.
00320         BG_SiegeLoadTeams();
00321 
00322         if (!bgNumSiegeTeams)
00323         { //React same as with classes.
00324                 CG_Error("Couldn't find any player teams for Siege");
00325         }
00326 
00327         //Get and set the team themes for each team. This will control which classes can be
00328         //used on each team.
00329         if (BG_SiegeGetValueGroup(siege_info, team1, teamInfo))
00330         {
00331                 if (BG_SiegeGetPairedValue(teamInfo, "UseTeam", btime))
00332                 {
00333                         BG_SiegeSetTeamTheme(SIEGETEAM_TEAM1, btime);
00334                 }
00335                 if (BG_SiegeGetPairedValue(teamInfo, "FriendlyShader", btime))
00336                 {
00337                         cgSiegeTeam1PlShader = trap_R_RegisterShaderNoMip(btime);
00338                 }
00339                 else
00340                 {
00341                         cgSiegeTeam1PlShader = 0;
00342                 }
00343         }
00344         if (BG_SiegeGetValueGroup(siege_info, team2, teamInfo))
00345         {
00346                 if (BG_SiegeGetPairedValue(teamInfo, "UseTeam", btime))
00347                 {
00348                         BG_SiegeSetTeamTheme(SIEGETEAM_TEAM2, btime);
00349                 }
00350                 if (BG_SiegeGetPairedValue(teamInfo, "FriendlyShader", btime))
00351                 {
00352                         cgSiegeTeam2PlShader = trap_R_RegisterShaderNoMip(btime);
00353                 }
00354                 else
00355                 {
00356                         cgSiegeTeam2PlShader = 0;
00357                 }
00358         }
00359 
00360         //Now go through the classes used by the loaded teams and try to precache
00361         //any forced models or forced skins.
00362         i = SIEGETEAM_TEAM1;
00363 
00364         while (i <= SIEGETEAM_TEAM2)
00365         {
00366                 j = 0;
00367                 sTeam = BG_SiegeFindThemeForTeam(i);
00368 
00369                 if (!sTeam)
00370                 {
00371                         i++;
00372                         continue;
00373                 }
00374 
00375                 //Get custom team shaders while we're at it.
00376                 if (i == SIEGETEAM_TEAM1)
00377                 {
00378                         cgSiegeTeam1PlShader = sTeam->friendlyShader;
00379                 }
00380                 else if (i == SIEGETEAM_TEAM2)
00381                 {
00382                         cgSiegeTeam2PlShader = sTeam->friendlyShader;
00383                 }
00384 
00385                 while (j < sTeam->numClasses)
00386                 {
00387                         cl = sTeam->classes[j];
00388 
00389                         if (cl->forcedModel[0])
00390                         { //This class has a forced model, so precache it.
00391                                 trap_R_RegisterModel(va("models/players/%s/model.glm", cl->forcedModel));
00392 
00393                                 if (cl->forcedSkin[0])
00394                                 { //also has a forced skin, precache it.
00395                                         char *useSkinName;
00396 
00397                                         if (strchr(cl->forcedSkin, '|'))
00398                                         {//three part skin
00399                                                 useSkinName = va("models/players/%s/|%s", cl->forcedModel, cl->forcedSkin);
00400                                         }
00401                                         else
00402                                         {
00403                                                 useSkinName = va("models/players/%s/model_%s.skin", cl->forcedModel, cl->forcedSkin);
00404                                         }
00405 
00406                                         trap_R_RegisterSkin(useSkinName);
00407                                 }
00408                         }
00409                         
00410                         j++;
00411                 }
00412                 i++;
00413         }
00414 
00415         //precache saber data for classes that use sabers on both teams
00416         BG_PrecacheSabersForSiegeTeam(SIEGETEAM_TEAM1);
00417         BG_PrecacheSabersForSiegeTeam(SIEGETEAM_TEAM2);
00418 
00419         CG_PrecachePlayersForSiegeTeam(SIEGETEAM_TEAM1);
00420         CG_PrecachePlayersForSiegeTeam(SIEGETEAM_TEAM2);
00421 
00422         CG_PrecachePlayersForSiegeTeam(SIEGETEAM_TEAM1);
00423         CG_PrecachePlayersForSiegeTeam(SIEGETEAM_TEAM2);
00424 
00425         CG_PrecacheSiegeObjectiveAssetsForTeam(SIEGETEAM_TEAM1);
00426         CG_PrecacheSiegeObjectiveAssetsForTeam(SIEGETEAM_TEAM2);
00427 
00428         return;
00429 failure:
00430         siege_valid = 0;
00431 }
00432 
00433 static char CGAME_INLINE *CG_SiegeObjectiveBuffer(int team, int objective)
00434 {
00435         static char buf[8192];
00436         char teamstr[1024];
00437 
00438         if (team == SIEGETEAM_TEAM1)
00439         {
00440                 Com_sprintf(teamstr, sizeof(teamstr), team1);
00441         }
00442         else
00443         {
00444                 Com_sprintf(teamstr, sizeof(teamstr), team2);
00445         }
00446 
00447         if (BG_SiegeGetValueGroup(siege_info, teamstr, cgParseObjectives))
00448         { //found the team group
00449                 if (BG_SiegeGetValueGroup(cgParseObjectives, va("Objective%i", objective), buf))
00450                 { //found the objective group
00451                         return buf;
00452                 }
00453         }
00454 
00455         return NULL;
00456 }
00457 
00458 void CG_ParseSiegeObjectiveStatus(const char *str)
00459 {
00460         int i = 0;
00461         int     team = SIEGETEAM_TEAM1;
00462         char *cvarName;
00463         char *s;
00464         int objectiveNum = 0;
00465 
00466         if (!str || !str[0])
00467         {
00468                 return;
00469         }
00470 
00471         while (str[i])
00472         {
00473                 if (str[i] == '|')
00474                 { //switch over to team2, this is the next section
00475             team = SIEGETEAM_TEAM2;
00476                         objectiveNum = 0;
00477                 }
00478                 else if (str[i] == '-')
00479                 {
00480                         objectiveNum++;
00481                         i++;
00482 
00483                         cvarName = va("team%i_objective%i", team, objectiveNum);
00484                         if (str[i] == '1')
00485                         { //it's completed
00486                                 trap_Cvar_Set(cvarName, "1");
00487                         }
00488                         else
00489                         { //otherwise assume it is not
00490                                 trap_Cvar_Set(cvarName, "0");
00491                         }
00492 
00493                         s = CG_SiegeObjectiveBuffer(team, objectiveNum);
00494                         if (s && s[0])
00495                         { //now set the description and graphic cvars to by read by the menu
00496                                 char buffer[8192];
00497 
00498                                 cvarName = va("team%i_objective%i_longdesc", team, objectiveNum);
00499                                 if (BG_SiegeGetPairedValue(s, "objdesc", buffer))
00500                                 {
00501                                         trap_Cvar_Set(cvarName, buffer);
00502                                 }
00503                                 else
00504                                 {
00505                                         trap_Cvar_Set(cvarName, "UNSPECIFIED");
00506                                 }
00507 
00508                                 cvarName = va("team%i_objective%i_gfx", team, objectiveNum);
00509                                 if (BG_SiegeGetPairedValue(s, "objgfx", buffer))
00510                                 {
00511                                         trap_Cvar_Set(cvarName, buffer);
00512                                 }
00513                                 else
00514                                 {
00515                                         trap_Cvar_Set(cvarName, "UNSPECIFIED");
00516                                 }
00517 
00518                                 cvarName = va("team%i_objective%i_mapicon", team, objectiveNum);
00519                                 if (BG_SiegeGetPairedValue(s, "mapicon", buffer))
00520                                 {
00521                                         trap_Cvar_Set(cvarName, buffer);
00522                                 }
00523                                 else
00524                                 {
00525                                         trap_Cvar_Set(cvarName, "UNSPECIFIED");
00526                                 }
00527 
00528                                 cvarName = va("team%i_objective%i_litmapicon", team, objectiveNum);
00529                                 if (BG_SiegeGetPairedValue(s, "litmapicon", buffer))
00530                                 {
00531                                         trap_Cvar_Set(cvarName, buffer);
00532                                 }
00533                                 else
00534                                 {
00535                                         trap_Cvar_Set(cvarName, "UNSPECIFIED");
00536                                 }
00537 
00538                                 cvarName = va("team%i_objective%i_donemapicon", team, objectiveNum);
00539                                 if (BG_SiegeGetPairedValue(s, "donemapicon", buffer))
00540                                 {
00541                                         trap_Cvar_Set(cvarName, buffer);
00542                                 }
00543                                 else
00544                                 {
00545                                         trap_Cvar_Set(cvarName, "UNSPECIFIED");
00546                                 }
00547 
00548                                 cvarName = va("team%i_objective%i_mappos", team, objectiveNum);
00549                                 if (BG_SiegeGetPairedValue(s, "mappos", buffer))
00550                                 {
00551                                         trap_Cvar_Set(cvarName, buffer);
00552                                 }
00553                                 else
00554                                 {
00555                                         trap_Cvar_Set(cvarName, "0 0 32 32");
00556                                 }
00557                         }
00558                 }
00559                 i++;
00560         }
00561 
00562         if (cg.predictedPlayerState.persistant[PERS_TEAM] != TEAM_SPECTATOR)
00563         { //update menu cvars
00564                 CG_SiegeBriefingDisplay(cg.predictedPlayerState.persistant[PERS_TEAM], 1);
00565         }
00566 }
00567 
00568 void CG_SiegeRoundOver(centity_t *ent, int won)
00569 {
00570         int                             myTeam;
00571         char                    teamstr[64];
00572         char                    appstring[1024];
00573         char                    soundstr[1024];
00574         int                             success = 0;
00575         playerState_t   *ps = NULL;
00576 
00577         if (!siege_valid)
00578         {
00579                 CG_Error("ERROR: Siege data does not exist on client!\n");
00580                 return;
00581         }
00582 
00583         if (cg.snap)
00584         { //this should always be true, if it isn't though use the predicted ps as a fallback
00585                 ps = &cg.snap->ps;
00586         }
00587         else
00588         {
00589                 ps = &cg.predictedPlayerState;
00590         }
00591 
00592         if (!ps)
00593         {
00594                 assert(0);
00595                 return;
00596         }
00597 
00598         myTeam = ps->persistant[PERS_TEAM];
00599 
00600         if (myTeam == TEAM_SPECTATOR)
00601         {
00602                 return;
00603         }
00604 
00605         if (myTeam == SIEGETEAM_TEAM1)
00606         {
00607                 Com_sprintf(teamstr, sizeof(teamstr), team1);
00608         }
00609         else
00610         {
00611                 Com_sprintf(teamstr, sizeof(teamstr), team2);
00612         }
00613 
00614         if (BG_SiegeGetValueGroup(siege_info, teamstr, cgParseObjectives))
00615         {
00616                 if (won == myTeam)
00617                 {
00618                         success = BG_SiegeGetPairedValue(cgParseObjectives, "wonround", appstring);
00619                 }
00620                 else
00621                 {
00622                         success = BG_SiegeGetPairedValue(cgParseObjectives, "lostround", appstring);
00623                 }
00624 
00625                 if (success)
00626                 {
00627                         CG_DrawSiegeMessage(appstring, 0);
00628                 }
00629 
00630                 appstring[0] = 0;
00631                 soundstr[0] = 0;
00632 
00633                 if (myTeam == won)
00634                 {
00635                         Com_sprintf(teamstr, sizeof(teamstr), "roundover_sound_wewon");
00636                 }
00637                 else
00638                 {
00639                         Com_sprintf(teamstr, sizeof(teamstr), "roundover_sound_welost");
00640                 }
00641 
00642                 if (BG_SiegeGetPairedValue(cgParseObjectives, teamstr, appstring))
00643                 {
00644                         Com_sprintf(soundstr, sizeof(soundstr), appstring);
00645                 }
00646                 /*
00647                 else
00648                 {
00649                         if (myTeam != won)
00650                         {
00651                                 Com_sprintf(soundstr, sizeof(soundstr), DEFAULT_LOSE_ROUND);
00652                         }
00653                         else
00654                         {
00655                                 Com_sprintf(soundstr, sizeof(soundstr), DEFAULT_WIN_ROUND);
00656                         }
00657                 }
00658                 */
00659 
00660                 if (soundstr[0])
00661                 {
00662                         trap_S_StartLocalSound(trap_S_RegisterSound(soundstr), CHAN_ANNOUNCER);
00663                 }
00664         }
00665 }
00666 
00667 void CG_SiegeGetObjectiveDescription(int team, int objective, char *buffer)
00668 {
00669         char teamstr[1024];
00670         char objectiveStr[8192];
00671 
00672         buffer[0] = 0; //set to 0 ahead of time in case we fail to find the objective group/name
00673 
00674         if (team == SIEGETEAM_TEAM1)
00675         {
00676                 Com_sprintf(teamstr, sizeof(teamstr), team1);
00677         }
00678         else
00679         {
00680                 Com_sprintf(teamstr, sizeof(teamstr), team2);
00681         }
00682 
00683         if (BG_SiegeGetValueGroup(siege_info, teamstr, cgParseObjectives))
00684         { //found the team group
00685                 if (BG_SiegeGetValueGroup(cgParseObjectives, va("Objective%i", objective), objectiveStr))
00686                 { //found the objective group
00687                         //Parse the name right into the buffer.
00688                         BG_SiegeGetPairedValue(objectiveStr, "goalname", buffer);
00689                 }
00690         }
00691 }
00692 
00693 int CG_SiegeGetObjectiveFinal(int team, int objective )
00694 {
00695         char finalStr[64];
00696         char teamstr[1024];
00697         char objectiveStr[8192];
00698 
00699         if (team == SIEGETEAM_TEAM1)
00700         {
00701                 Com_sprintf(teamstr, sizeof(teamstr), team1);
00702         }
00703         else
00704         {
00705                 Com_sprintf(teamstr, sizeof(teamstr), team2);
00706         }
00707 
00708         if (BG_SiegeGetValueGroup(siege_info, teamstr, cgParseObjectives))
00709         { //found the team group
00710                 if (BG_SiegeGetValueGroup(cgParseObjectives, va("Objective%i", objective), objectiveStr))
00711                 { //found the objective group
00712                         //Parse the name right into the buffer.
00713                         BG_SiegeGetPairedValue(objectiveStr, "final", finalStr);
00714                         return (atoi( finalStr ));
00715                 }
00716         }
00717         return 0;
00718 }
00719 
00720 void CG_SiegeBriefingDisplay(int team, int dontshow)
00721 {
00722         char                    teamstr[64];
00723         char                    briefing[8192];
00724         char                    properValue[1024];
00725         char                    objectiveDesc[1024];
00726         int                             i = 1;
00727         int                             useTeam = team;
00728         qboolean                primary = qfalse;
00729 
00730         if (!siege_valid)
00731         {
00732                 return;
00733         }
00734 
00735         if (team == TEAM_SPECTATOR)
00736         {
00737                 return;
00738         }
00739 
00740         if (team == SIEGETEAM_TEAM1)
00741         {
00742                 Com_sprintf(teamstr, sizeof(teamstr), team1);
00743         }
00744         else
00745         {
00746                 Com_sprintf(teamstr, sizeof(teamstr), team2);
00747         }
00748 
00749         if (useTeam != SIEGETEAM_TEAM1 && useTeam != SIEGETEAM_TEAM2)
00750         { //This shouldn't be happening. But just fall back to team 2 anyway.
00751                 useTeam = SIEGETEAM_TEAM2;
00752         }
00753 
00754         trap_Cvar_Set(va("siege_primobj_inuse"), "0");
00755 
00756         while (i < 16)
00757         { //do up to 16 objectives I suppose
00758                 //Get the value for this objective on this team
00759                 //Now set the cvar for the menu to display.
00760                 
00761                 //primary = (CG_SiegeGetObjectiveFinal(useTeam, i)>-1)?qtrue:qfalse;
00762                 primary = (CG_SiegeGetObjectiveFinal(useTeam, i)>0)?qtrue:qfalse;
00763 
00764                 properValue[0] = 0;
00765                 trap_Cvar_VariableStringBuffer(va("team%i_objective%i", useTeam, i), properValue, 1024);
00766                 if (primary)
00767                 {
00768                         trap_Cvar_Set(va("siege_primobj"), properValue);
00769                 }
00770                 else
00771                 {
00772                         trap_Cvar_Set(va("siege_objective%i", i), properValue);
00773                 }
00774 
00775                 //Now set the long desc cvar for the menu to display.
00776                 properValue[0] = 0;
00777                 trap_Cvar_VariableStringBuffer(va("team%i_objective%i_longdesc", useTeam, i), properValue, 1024);
00778                 if (primary)
00779                 {
00780                         trap_Cvar_Set(va("siege_primobj_longdesc"), properValue);
00781                 }
00782                 else
00783                 {
00784                         trap_Cvar_Set(va("siege_objective%i_longdesc", i), properValue);
00785                 }
00786 
00787                 //Now set the gfx cvar for the menu to display.
00788                 properValue[0] = 0;
00789                 trap_Cvar_VariableStringBuffer(va("team%i_objective%i_gfx", useTeam, i), properValue, 1024);
00790                 if (primary)
00791                 {
00792                         trap_Cvar_Set(va("siege_primobj_gfx"), properValue);
00793                 }
00794                 else
00795                 {
00796                         trap_Cvar_Set(va("siege_objective%i_gfx", i), properValue);
00797                 }
00798 
00799                 //Now set the mapicon cvar for the menu to display.
00800                 properValue[0] = 0;
00801                 trap_Cvar_VariableStringBuffer(va("team%i_objective%i_mapicon", useTeam, i), properValue, 1024);
00802                 if (primary)
00803                 {
00804                         trap_Cvar_Set(va("siege_primobj_mapicon"), properValue);
00805                 }
00806                 else
00807                 {
00808                         trap_Cvar_Set(va("siege_objective%i_mapicon", i), properValue);
00809                 }
00810 
00811                 //Now set the mappos cvar for the menu to display.
00812                 properValue[0] = 0;
00813                 trap_Cvar_VariableStringBuffer(va("team%i_objective%i_mappos", useTeam, i), properValue, 1024);
00814                 if (primary)
00815                 {
00816                         trap_Cvar_Set(va("siege_primobj_mappos"), properValue);
00817                 }
00818                 else
00819                 {
00820                         trap_Cvar_Set(va("siege_objective%i_mappos", i), properValue);
00821                 }
00822 
00823                 //Now set the description cvar for the objective
00824                 CG_SiegeGetObjectiveDescription(useTeam, i, objectiveDesc);
00825 
00826                 if (objectiveDesc[0])
00827                 { //found a valid objective description
00828                         if ( primary )
00829                         {
00830                                 trap_Cvar_Set(va("siege_primobj_desc"), objectiveDesc);
00831                                 //this one is marked not in use because it gets primobj
00832                                 trap_Cvar_Set(va("siege_objective%i_inuse", i), "0");
00833                                 trap_Cvar_Set(va("siege_primobj_inuse"), "1");
00834 
00835                                 trap_Cvar_Set(va("team%i_objective%i_inuse", useTeam, i), "1");
00836 
00837                         }
00838                         else
00839                         {
00840                                 trap_Cvar_Set(va("siege_objective%i_desc", i), objectiveDesc);
00841                                 trap_Cvar_Set(va("siege_objective%i_inuse", i), "2");
00842                                 trap_Cvar_Set(va("team%i_objective%i_inuse", useTeam, i), "2");
00843 
00844                         }
00845                 }
00846                 else
00847                 { //didn't find one, so set the "inuse" cvar to 0 for the objective and mark it non-complete.
00848                         trap_Cvar_Set(va("siege_objective%i_inuse", i), "0");
00849                         trap_Cvar_Set(va("siege_objective%i", i), "0");
00850                         trap_Cvar_Set(va("team%i_objective%i_inuse", useTeam, i), "0");
00851                         trap_Cvar_Set(va("team%i_objective%i", useTeam, i), "0");
00852 
00853                         trap_Cvar_Set(va("siege_objective%i_mappos", i), "");
00854                         trap_Cvar_Set(va("team%i_objective%i_mappos", useTeam, i), "");
00855                         trap_Cvar_Set(va("siege_objective%i_gfx", i), "");
00856                         trap_Cvar_Set(va("team%i_objective%i_gfx", useTeam, i), "");
00857                         trap_Cvar_Set(va("siege_objective%i_mapicon", i), "");
00858                         trap_Cvar_Set(va("team%i_objective%i_mapicon", useTeam, i), "");
00859                 }
00860 
00861                 i++;
00862         }
00863 
00864         if (dontshow)
00865         {
00866                 return;
00867         }
00868 
00869         if (BG_SiegeGetValueGroup(siege_info, teamstr, cgParseObjectives))
00870         {
00871                 if (BG_SiegeGetPairedValue(cgParseObjectives, "briefing", briefing))
00872                 {
00873                         CG_DrawSiegeMessage(briefing, 1);
00874                 }
00875         }
00876 }
00877 
00878 void CG_SiegeObjectiveCompleted(centity_t *ent, int won, int objectivenum)
00879 {
00880         int                             myTeam;
00881         char                    teamstr[64];
00882         char                    objstr[256];
00883         char                    foundobjective[MAX_SIEGE_INFO_SIZE];
00884         char                    appstring[1024];
00885         char                    soundstr[1024];
00886         int                             success = 0;
00887         playerState_t   *ps = NULL;
00888 
00889         if (!siege_valid)
00890         {
00891                 CG_Error("Siege data does not exist on client!\n");
00892                 return;
00893         }
00894 
00895         if (cg.snap)
00896         { //this should always be true, if it isn't though use the predicted ps as a fallback
00897                 ps = &cg.snap->ps;
00898         }
00899         else
00900         {
00901                 ps = &cg.predictedPlayerState;
00902         }
00903 
00904         if (!ps)
00905         {
00906                 assert(0);
00907                 return;
00908         }
00909 
00910         myTeam = ps->persistant[PERS_TEAM];
00911 
00912         if (myTeam == TEAM_SPECTATOR)
00913         {
00914                 return;
00915         }
00916 
00917         if (won == SIEGETEAM_TEAM1)
00918         {
00919                 Com_sprintf(teamstr, sizeof(teamstr), team1);
00920         }
00921         else
00922         {
00923                 Com_sprintf(teamstr, sizeof(teamstr), team2);
00924         }
00925 
00926         if (BG_SiegeGetValueGroup(siege_info, teamstr, cgParseObjectives))
00927         {
00928                 Com_sprintf(objstr, sizeof(objstr), "Objective%i", objectivenum);
00929 
00930                 if (BG_SiegeGetValueGroup(cgParseObjectives, objstr, foundobjective))
00931                 {
00932                         if (myTeam == SIEGETEAM_TEAM1)
00933                         {
00934                                 success = BG_SiegeGetPairedValue(foundobjective, "message_team1", appstring);
00935                         }
00936                         else
00937                         {
00938                                 success = BG_SiegeGetPairedValue(foundobjective, "message_team2", appstring);
00939                         }
00940 
00941                         if (success)
00942                         {
00943                                 CG_DrawSiegeMessageNonMenu(appstring);
00944                         }
00945 
00946                         appstring[0] = 0;
00947                         soundstr[0] = 0;
00948 
00949                         if (myTeam == SIEGETEAM_TEAM1)
00950                         {
00951                                 Com_sprintf(teamstr, sizeof(teamstr), "sound_team1");
00952                         }
00953                         else
00954                         {
00955                                 Com_sprintf(teamstr, sizeof(teamstr), "sound_team2");
00956                         }
00957 
00958                         if (BG_SiegeGetPairedValue(foundobjective, teamstr, appstring))
00959                         {
00960                                 Com_sprintf(soundstr, sizeof(soundstr), appstring);
00961                         }
00962                         /*
00963                         else
00964                         {
00965                                 if (myTeam != won)
00966                                 {
00967                                         Com_sprintf(soundstr, sizeof(soundstr), DEFAULT_LOSE_OBJECTIVE);
00968                                 }
00969                                 else
00970                                 {
00971                                         Com_sprintf(soundstr, sizeof(soundstr), DEFAULT_WIN_OBJECTIVE);
00972                                 }
00973                         }
00974                         */
00975 
00976                         if (soundstr[0])
00977                         {
00978                                 trap_S_StartLocalSound(trap_S_RegisterSound(soundstr), CHAN_ANNOUNCER);
00979                         }
00980                 }
00981         }
00982 }
00983 
00984 siegeExtended_t cg_siegeExtendedData[MAX_CLIENTS];
00985 
00986 //parse a single extended siege data entry
00987 void CG_ParseSiegeExtendedDataEntry(const char *conStr)
00988 {
00989         char s[MAX_STRING_CHARS];
00990         char *str = (char *)conStr;
00991         int argParses = 0;
00992         int i;
00993         int maxAmmo = 0, clNum = -1, health = 1, maxhealth = 1, ammo = 1;
00994         centity_t *cent;
00995 
00996         if (!conStr || !conStr[0])
00997         {
00998                 return;
00999         }
01000 
01001         while (*str && argParses < 4)
01002         {
01003                 i = 0;
01004         while (*str && *str != '|')
01005                 {
01006                         s[i] = *str;
01007                         i++;
01008                         *str++;
01009                 }
01010                 s[i] = 0;
01011         switch (argParses)
01012                 {
01013                 case 0:
01014                         clNum = atoi(s);
01015                         break;
01016                 case 1:
01017                         health = atoi(s);
01018                         break;
01019                 case 2:
01020                         maxhealth = atoi(s);
01021                         break;
01022                 case 3:
01023                         ammo = atoi(s);
01024                         break;
01025                 default:
01026                         break;
01027                 }
01028                 argParses++;
01029                 str++;
01030         }
01031 
01032         if (clNum < 0 || clNum >= MAX_CLIENTS)
01033         {
01034                 return;
01035         }
01036 
01037         cg_siegeExtendedData[clNum].health = health;
01038         cg_siegeExtendedData[clNum].maxhealth = maxhealth;
01039         cg_siegeExtendedData[clNum].ammo = ammo;
01040 
01041         cent = &cg_entities[clNum];
01042 
01043         maxAmmo = ammoData[weaponData[cent->currentState.weapon].ammoIndex].max;
01044         if ( (cent->currentState.eFlags & EF_DOUBLE_AMMO) )
01045         {
01046                 maxAmmo *= 2.0f;
01047         }
01048         if (ammo >= 0 && ammo <= maxAmmo )
01049         { //assure the weapon number is valid and not over max
01050                 //keep the weapon so if it changes before our next ext data update we'll know
01051                 //that the ammo is not applicable.
01052                 cg_siegeExtendedData[clNum].weapon = cent->currentState.weapon;
01053         }
01054         else
01055         { //not valid? Oh well, just invalidate the weapon too then so we don't display ammo
01056                 cg_siegeExtendedData[clNum].weapon = -1;
01057         }
01058 
01059         cg_siegeExtendedData[clNum].lastUpdated = cg.time;
01060 }
01061 
01062 //parse incoming siege data, see counterpart in g_saga.c
01063 void CG_ParseSiegeExtendedData(void)
01064 {
01065         int numEntries = trap_Argc();
01066         int i = 0;
01067 
01068         if (numEntries < 1)
01069         {
01070                 assert(!"Bad numEntries for sxd");
01071                 return;
01072         }
01073 
01074         while (i < numEntries)
01075         {
01076                 CG_ParseSiegeExtendedDataEntry(CG_Argv(i+1));
01077                 i++;
01078         }
01079 }
01080 
01081 void CG_SetSiegeTimerCvar ( int msec )
01082 {
01083         int seconds;
01084         int mins;
01085         int tens;
01086 
01087         seconds = msec / 1000;
01088         mins = seconds / 60;
01089         seconds -= mins * 60;
01090         tens = seconds / 10;
01091         seconds -= tens * 10;
01092 
01093         trap_Cvar_Set("ui_siegeTimer", va( "%i:%i%i", mins, tens, seconds ) );
01094 }