jedi-academy/codemp/cgame/cg_saga.c
2013-04-23 15:21:39 +10:00

1094 lines
23 KiB
C

// Copyright (C) 2000-2002 Raven Software, Inc.
//
/*****************************************************************************
* name: cg_siege.c
*
* desc: Clientgame-side module for Siege gametype.
*
* $Author: osman $
* $Revision: 1.5 $
*
*****************************************************************************/
#include "cg_local.h"
#include "bg_saga.h"
int cgSiegeRoundState = 0;
int cgSiegeRoundTime = 0;
static char team1[512];
static char team2[512];
int team1Timed = 0;
int team2Timed = 0;
int cgSiegeTeam1PlShader = 0;
int cgSiegeTeam2PlShader = 0;
static char cgParseObjectives[MAX_SIEGE_INFO_SIZE];
extern void CG_LoadCISounds(clientInfo_t *ci, qboolean modelloaded); //cg_players.c
void CG_DrawSiegeMessage( const char *str, int objectiveScreen );
void CG_DrawSiegeMessageNonMenu( const char *str );
void CG_SiegeBriefingDisplay(int team, int dontshow);
void CG_PrecacheSiegeObjectiveAssetsForTeam(int myTeam)
{
char teamstr[64];
char objstr[256];
char foundobjective[MAX_SIEGE_INFO_SIZE];
if (!siege_valid)
{
CG_Error("Siege data does not exist on client!\n");
return;
}
if (myTeam == SIEGETEAM_TEAM1)
{
Com_sprintf(teamstr, sizeof(teamstr), team1);
}
else
{
Com_sprintf(teamstr, sizeof(teamstr), team2);
}
if (BG_SiegeGetValueGroup(siege_info, teamstr, cgParseObjectives))
{
int i = 1;
while (i < 32)
{ //eh, just try 32 I guess
Com_sprintf(objstr, sizeof(objstr), "Objective%i", i);
if (BG_SiegeGetValueGroup(cgParseObjectives, objstr, foundobjective))
{
char str[MAX_QPATH];
if (BG_SiegeGetPairedValue(foundobjective, "sound_team1", str))
{
trap_S_RegisterSound(str);
}
if (BG_SiegeGetPairedValue(foundobjective, "sound_team2", str))
{
trap_S_RegisterSound(str);
}
if (BG_SiegeGetPairedValue(foundobjective, "objgfx", str))
{
trap_R_RegisterShaderNoMip(str);
}
if (BG_SiegeGetPairedValue(foundobjective, "mapicon", str))
{
trap_R_RegisterShaderNoMip(str);
}
if (BG_SiegeGetPairedValue(foundobjective, "litmapicon", str))
{
trap_R_RegisterShaderNoMip(str);
}
if (BG_SiegeGetPairedValue(foundobjective, "donemapicon", str))
{
trap_R_RegisterShaderNoMip(str);
}
}
else
{ //no more
break;
}
i++;
}
}
}
void CG_PrecachePlayersForSiegeTeam(int team)
{
siegeTeam_t *stm;
int i = 0;
stm = BG_SiegeFindThemeForTeam(team);
if (!stm)
{ //invalid team/no theme for team?
return;
}
while (i < stm->numClasses)
{
siegeClass_t *scl = stm->classes[i];
if (scl->forcedModel[0])
{
clientInfo_t fake;
memset(&fake, 0, sizeof(fake));
strcpy(fake.modelName, scl->forcedModel);
trap_R_RegisterModel(va("models/players/%s/model.glm", scl->forcedModel));
if (scl->forcedSkin[0])
{
trap_R_RegisterSkin(va("models/players/%s/model_%s.skin", scl->forcedModel, scl->forcedSkin));
strcpy(fake.skinName, scl->forcedSkin);
}
else
{
strcpy(fake.skinName, "default");
}
//precache the sounds for the model...
CG_LoadCISounds(&fake, qtrue);
}
i++;
}
}
void CG_InitSiegeMode(void)
{
char levelname[MAX_QPATH];
char btime[1024];
char teams[2048];
char teamInfo[MAX_SIEGE_INFO_SIZE];
int len = 0;
int i = 0;
int j = 0;
siegeClass_t *cl;
siegeTeam_t *sTeam;
fileHandle_t f;
char teamIcon[128];
if (cgs.gametype != GT_SIEGE)
{
goto failure;
}
Com_sprintf(levelname, sizeof(levelname), "%s\0", cgs.mapname);
i = strlen(levelname)-1;
while (i > 0 && levelname[i] && levelname[i] != '.')
{
i--;
}
if (!i)
{
goto failure;
}
levelname[i] = '\0'; //kill the ".bsp"
Com_sprintf(levelname, sizeof(levelname), "%s.siege\0", levelname);
if (!levelname || !levelname[0])
{
goto failure;
}
len = trap_FS_FOpenFile(levelname, &f, FS_READ);
if (!f || len >= MAX_SIEGE_INFO_SIZE)
{
goto failure;
}
trap_FS_Read(siege_info, len, f);
trap_FS_FCloseFile(f);
siege_valid = 1;
if (BG_SiegeGetValueGroup(siege_info, "Teams", teams))
{
char buf[1024];
trap_Cvar_VariableStringBuffer("cg_siegeTeam1", buf, 1024);
if (buf[0] && Q_stricmp(buf, "none"))
{
strcpy(team1, buf);
}
else
{
BG_SiegeGetPairedValue(teams, "team1", team1);
}
if (team1[0] == '@')
{ //it's a damn stringed reference.
char b[256];
trap_SP_GetStringTextString(team1+1, b, 256);
trap_Cvar_Set("cg_siegeTeam1Name", b);
}
else
{
trap_Cvar_Set("cg_siegeTeam1Name", team1);
}
trap_Cvar_VariableStringBuffer("cg_siegeTeam2", buf, 1024);
if (buf[0] && Q_stricmp(buf, "none"))
{
strcpy(team2, buf);
}
else
{
BG_SiegeGetPairedValue(teams, "team2", team2);
}
if (team2[0] == '@')
{ //it's a damn stringed reference.
char b[256];
trap_SP_GetStringTextString(team2+1, b, 256);
trap_Cvar_Set("cg_siegeTeam2Name", b);
}
else
{
trap_Cvar_Set("cg_siegeTeam2Name", team2);
}
}
else
{
CG_Error("Siege teams not defined");
}
if (BG_SiegeGetValueGroup(siege_info, team1, teamInfo))
{
if (BG_SiegeGetPairedValue(teamInfo, "TeamIcon", teamIcon))
{
trap_Cvar_Set( "team1_icon", teamIcon);
}
if (BG_SiegeGetPairedValue(teamInfo, "Timed", btime))
{
team1Timed = atoi(btime)*1000;
CG_SetSiegeTimerCvar ( team1Timed );
}
else
{
team1Timed = 0;
}
}
else
{
CG_Error("No team entry for '%s'\n", team1);
}
if (BG_SiegeGetPairedValue(siege_info, "mapgraphic", teamInfo))
{
trap_Cvar_Set("siege_mapgraphic", teamInfo);
}
else
{
trap_Cvar_Set("siege_mapgraphic", "gfx/mplevels/siege1_hoth");
}
if (BG_SiegeGetPairedValue(siege_info, "missionname", teamInfo))
{
trap_Cvar_Set("siege_missionname", teamInfo);
}
else
{
trap_Cvar_Set("siege_missionname", " ");
}
if (BG_SiegeGetValueGroup(siege_info, team2, teamInfo))
{
if (BG_SiegeGetPairedValue(teamInfo, "TeamIcon", teamIcon))
{
trap_Cvar_Set( "team2_icon", teamIcon);
}
if (BG_SiegeGetPairedValue(teamInfo, "Timed", btime))
{
team2Timed = atoi(btime)*1000;
CG_SetSiegeTimerCvar ( team2Timed );
}
else
{
team2Timed = 0;
}
}
else
{
CG_Error("No team entry for '%s'\n", team2);
}
//Load the player class types
BG_SiegeLoadClasses(NULL);
if (!bgNumSiegeClasses)
{ //We didn't find any?!
CG_Error("Couldn't find any player classes for Siege");
}
//Now load the teams since we have class data.
BG_SiegeLoadTeams();
if (!bgNumSiegeTeams)
{ //React same as with classes.
CG_Error("Couldn't find any player teams for Siege");
}
//Get and set the team themes for each team. This will control which classes can be
//used on each team.
if (BG_SiegeGetValueGroup(siege_info, team1, teamInfo))
{
if (BG_SiegeGetPairedValue(teamInfo, "UseTeam", btime))
{
BG_SiegeSetTeamTheme(SIEGETEAM_TEAM1, btime);
}
if (BG_SiegeGetPairedValue(teamInfo, "FriendlyShader", btime))
{
cgSiegeTeam1PlShader = trap_R_RegisterShaderNoMip(btime);
}
else
{
cgSiegeTeam1PlShader = 0;
}
}
if (BG_SiegeGetValueGroup(siege_info, team2, teamInfo))
{
if (BG_SiegeGetPairedValue(teamInfo, "UseTeam", btime))
{
BG_SiegeSetTeamTheme(SIEGETEAM_TEAM2, btime);
}
if (BG_SiegeGetPairedValue(teamInfo, "FriendlyShader", btime))
{
cgSiegeTeam2PlShader = trap_R_RegisterShaderNoMip(btime);
}
else
{
cgSiegeTeam2PlShader = 0;
}
}
//Now go through the classes used by the loaded teams and try to precache
//any forced models or forced skins.
i = SIEGETEAM_TEAM1;
while (i <= SIEGETEAM_TEAM2)
{
j = 0;
sTeam = BG_SiegeFindThemeForTeam(i);
if (!sTeam)
{
i++;
continue;
}
//Get custom team shaders while we're at it.
if (i == SIEGETEAM_TEAM1)
{
cgSiegeTeam1PlShader = sTeam->friendlyShader;
}
else if (i == SIEGETEAM_TEAM2)
{
cgSiegeTeam2PlShader = sTeam->friendlyShader;
}
while (j < sTeam->numClasses)
{
cl = sTeam->classes[j];
if (cl->forcedModel[0])
{ //This class has a forced model, so precache it.
trap_R_RegisterModel(va("models/players/%s/model.glm", cl->forcedModel));
if (cl->forcedSkin[0])
{ //also has a forced skin, precache it.
char *useSkinName;
if (strchr(cl->forcedSkin, '|'))
{//three part skin
useSkinName = va("models/players/%s/|%s", cl->forcedModel, cl->forcedSkin);
}
else
{
useSkinName = va("models/players/%s/model_%s.skin", cl->forcedModel, cl->forcedSkin);
}
trap_R_RegisterSkin(useSkinName);
}
}
j++;
}
i++;
}
//precache saber data for classes that use sabers on both teams
BG_PrecacheSabersForSiegeTeam(SIEGETEAM_TEAM1);
BG_PrecacheSabersForSiegeTeam(SIEGETEAM_TEAM2);
CG_PrecachePlayersForSiegeTeam(SIEGETEAM_TEAM1);
CG_PrecachePlayersForSiegeTeam(SIEGETEAM_TEAM2);
CG_PrecachePlayersForSiegeTeam(SIEGETEAM_TEAM1);
CG_PrecachePlayersForSiegeTeam(SIEGETEAM_TEAM2);
CG_PrecacheSiegeObjectiveAssetsForTeam(SIEGETEAM_TEAM1);
CG_PrecacheSiegeObjectiveAssetsForTeam(SIEGETEAM_TEAM2);
return;
failure:
siege_valid = 0;
}
static char CGAME_INLINE *CG_SiegeObjectiveBuffer(int team, int objective)
{
static char buf[8192];
char teamstr[1024];
if (team == SIEGETEAM_TEAM1)
{
Com_sprintf(teamstr, sizeof(teamstr), team1);
}
else
{
Com_sprintf(teamstr, sizeof(teamstr), team2);
}
if (BG_SiegeGetValueGroup(siege_info, teamstr, cgParseObjectives))
{ //found the team group
if (BG_SiegeGetValueGroup(cgParseObjectives, va("Objective%i", objective), buf))
{ //found the objective group
return buf;
}
}
return NULL;
}
void CG_ParseSiegeObjectiveStatus(const char *str)
{
int i = 0;
int team = SIEGETEAM_TEAM1;
char *cvarName;
char *s;
int objectiveNum = 0;
if (!str || !str[0])
{
return;
}
while (str[i])
{
if (str[i] == '|')
{ //switch over to team2, this is the next section
team = SIEGETEAM_TEAM2;
objectiveNum = 0;
}
else if (str[i] == '-')
{
objectiveNum++;
i++;
cvarName = va("team%i_objective%i", team, objectiveNum);
if (str[i] == '1')
{ //it's completed
trap_Cvar_Set(cvarName, "1");
}
else
{ //otherwise assume it is not
trap_Cvar_Set(cvarName, "0");
}
s = CG_SiegeObjectiveBuffer(team, objectiveNum);
if (s && s[0])
{ //now set the description and graphic cvars to by read by the menu
char buffer[8192];
cvarName = va("team%i_objective%i_longdesc", team, objectiveNum);
if (BG_SiegeGetPairedValue(s, "objdesc", buffer))
{
trap_Cvar_Set(cvarName, buffer);
}
else
{
trap_Cvar_Set(cvarName, "UNSPECIFIED");
}
cvarName = va("team%i_objective%i_gfx", team, objectiveNum);
if (BG_SiegeGetPairedValue(s, "objgfx", buffer))
{
trap_Cvar_Set(cvarName, buffer);
}
else
{
trap_Cvar_Set(cvarName, "UNSPECIFIED");
}
cvarName = va("team%i_objective%i_mapicon", team, objectiveNum);
if (BG_SiegeGetPairedValue(s, "mapicon", buffer))
{
trap_Cvar_Set(cvarName, buffer);
}
else
{
trap_Cvar_Set(cvarName, "UNSPECIFIED");
}
cvarName = va("team%i_objective%i_litmapicon", team, objectiveNum);
if (BG_SiegeGetPairedValue(s, "litmapicon", buffer))
{
trap_Cvar_Set(cvarName, buffer);
}
else
{
trap_Cvar_Set(cvarName, "UNSPECIFIED");
}
cvarName = va("team%i_objective%i_donemapicon", team, objectiveNum);
if (BG_SiegeGetPairedValue(s, "donemapicon", buffer))
{
trap_Cvar_Set(cvarName, buffer);
}
else
{
trap_Cvar_Set(cvarName, "UNSPECIFIED");
}
cvarName = va("team%i_objective%i_mappos", team, objectiveNum);
if (BG_SiegeGetPairedValue(s, "mappos", buffer))
{
trap_Cvar_Set(cvarName, buffer);
}
else
{
trap_Cvar_Set(cvarName, "0 0 32 32");
}
}
}
i++;
}
if (cg.predictedPlayerState.persistant[PERS_TEAM] != TEAM_SPECTATOR)
{ //update menu cvars
CG_SiegeBriefingDisplay(cg.predictedPlayerState.persistant[PERS_TEAM], 1);
}
}
void CG_SiegeRoundOver(centity_t *ent, int won)
{
int myTeam;
char teamstr[64];
char appstring[1024];
char soundstr[1024];
int success = 0;
playerState_t *ps = NULL;
if (!siege_valid)
{
CG_Error("ERROR: Siege data does not exist on client!\n");
return;
}
if (cg.snap)
{ //this should always be true, if it isn't though use the predicted ps as a fallback
ps = &cg.snap->ps;
}
else
{
ps = &cg.predictedPlayerState;
}
if (!ps)
{
assert(0);
return;
}
myTeam = ps->persistant[PERS_TEAM];
if (myTeam == TEAM_SPECTATOR)
{
return;
}
if (myTeam == SIEGETEAM_TEAM1)
{
Com_sprintf(teamstr, sizeof(teamstr), team1);
}
else
{
Com_sprintf(teamstr, sizeof(teamstr), team2);
}
if (BG_SiegeGetValueGroup(siege_info, teamstr, cgParseObjectives))
{
if (won == myTeam)
{
success = BG_SiegeGetPairedValue(cgParseObjectives, "wonround", appstring);
}
else
{
success = BG_SiegeGetPairedValue(cgParseObjectives, "lostround", appstring);
}
if (success)
{
CG_DrawSiegeMessage(appstring, 0);
}
appstring[0] = 0;
soundstr[0] = 0;
if (myTeam == won)
{
Com_sprintf(teamstr, sizeof(teamstr), "roundover_sound_wewon");
}
else
{
Com_sprintf(teamstr, sizeof(teamstr), "roundover_sound_welost");
}
if (BG_SiegeGetPairedValue(cgParseObjectives, teamstr, appstring))
{
Com_sprintf(soundstr, sizeof(soundstr), appstring);
}
/*
else
{
if (myTeam != won)
{
Com_sprintf(soundstr, sizeof(soundstr), DEFAULT_LOSE_ROUND);
}
else
{
Com_sprintf(soundstr, sizeof(soundstr), DEFAULT_WIN_ROUND);
}
}
*/
if (soundstr[0])
{
trap_S_StartLocalSound(trap_S_RegisterSound(soundstr), CHAN_ANNOUNCER);
}
}
}
void CG_SiegeGetObjectiveDescription(int team, int objective, char *buffer)
{
char teamstr[1024];
char objectiveStr[8192];
buffer[0] = 0; //set to 0 ahead of time in case we fail to find the objective group/name
if (team == SIEGETEAM_TEAM1)
{
Com_sprintf(teamstr, sizeof(teamstr), team1);
}
else
{
Com_sprintf(teamstr, sizeof(teamstr), team2);
}
if (BG_SiegeGetValueGroup(siege_info, teamstr, cgParseObjectives))
{ //found the team group
if (BG_SiegeGetValueGroup(cgParseObjectives, va("Objective%i", objective), objectiveStr))
{ //found the objective group
//Parse the name right into the buffer.
BG_SiegeGetPairedValue(objectiveStr, "goalname", buffer);
}
}
}
int CG_SiegeGetObjectiveFinal(int team, int objective )
{
char finalStr[64];
char teamstr[1024];
char objectiveStr[8192];
if (team == SIEGETEAM_TEAM1)
{
Com_sprintf(teamstr, sizeof(teamstr), team1);
}
else
{
Com_sprintf(teamstr, sizeof(teamstr), team2);
}
if (BG_SiegeGetValueGroup(siege_info, teamstr, cgParseObjectives))
{ //found the team group
if (BG_SiegeGetValueGroup(cgParseObjectives, va("Objective%i", objective), objectiveStr))
{ //found the objective group
//Parse the name right into the buffer.
BG_SiegeGetPairedValue(objectiveStr, "final", finalStr);
return (atoi( finalStr ));
}
}
return 0;
}
void CG_SiegeBriefingDisplay(int team, int dontshow)
{
char teamstr[64];
char briefing[8192];
char properValue[1024];
char objectiveDesc[1024];
int i = 1;
int useTeam = team;
qboolean primary = qfalse;
if (!siege_valid)
{
return;
}
if (team == TEAM_SPECTATOR)
{
return;
}
if (team == SIEGETEAM_TEAM1)
{
Com_sprintf(teamstr, sizeof(teamstr), team1);
}
else
{
Com_sprintf(teamstr, sizeof(teamstr), team2);
}
if (useTeam != SIEGETEAM_TEAM1 && useTeam != SIEGETEAM_TEAM2)
{ //This shouldn't be happening. But just fall back to team 2 anyway.
useTeam = SIEGETEAM_TEAM2;
}
trap_Cvar_Set(va("siege_primobj_inuse"), "0");
while (i < 16)
{ //do up to 16 objectives I suppose
//Get the value for this objective on this team
//Now set the cvar for the menu to display.
//primary = (CG_SiegeGetObjectiveFinal(useTeam, i)>-1)?qtrue:qfalse;
primary = (CG_SiegeGetObjectiveFinal(useTeam, i)>0)?qtrue:qfalse;
properValue[0] = 0;
trap_Cvar_VariableStringBuffer(va("team%i_objective%i", useTeam, i), properValue, 1024);
if (primary)
{
trap_Cvar_Set(va("siege_primobj"), properValue);
}
else
{
trap_Cvar_Set(va("siege_objective%i", i), properValue);
}
//Now set the long desc cvar for the menu to display.
properValue[0] = 0;
trap_Cvar_VariableStringBuffer(va("team%i_objective%i_longdesc", useTeam, i), properValue, 1024);
if (primary)
{
trap_Cvar_Set(va("siege_primobj_longdesc"), properValue);
}
else
{
trap_Cvar_Set(va("siege_objective%i_longdesc", i), properValue);
}
//Now set the gfx cvar for the menu to display.
properValue[0] = 0;
trap_Cvar_VariableStringBuffer(va("team%i_objective%i_gfx", useTeam, i), properValue, 1024);
if (primary)
{
trap_Cvar_Set(va("siege_primobj_gfx"), properValue);
}
else
{
trap_Cvar_Set(va("siege_objective%i_gfx", i), properValue);
}
//Now set the mapicon cvar for the menu to display.
properValue[0] = 0;
trap_Cvar_VariableStringBuffer(va("team%i_objective%i_mapicon", useTeam, i), properValue, 1024);
if (primary)
{
trap_Cvar_Set(va("siege_primobj_mapicon"), properValue);
}
else
{
trap_Cvar_Set(va("siege_objective%i_mapicon", i), properValue);
}
//Now set the mappos cvar for the menu to display.
properValue[0] = 0;
trap_Cvar_VariableStringBuffer(va("team%i_objective%i_mappos", useTeam, i), properValue, 1024);
if (primary)
{
trap_Cvar_Set(va("siege_primobj_mappos"), properValue);
}
else
{
trap_Cvar_Set(va("siege_objective%i_mappos", i), properValue);
}
//Now set the description cvar for the objective
CG_SiegeGetObjectiveDescription(useTeam, i, objectiveDesc);
if (objectiveDesc[0])
{ //found a valid objective description
if ( primary )
{
trap_Cvar_Set(va("siege_primobj_desc"), objectiveDesc);
//this one is marked not in use because it gets primobj
trap_Cvar_Set(va("siege_objective%i_inuse", i), "0");
trap_Cvar_Set(va("siege_primobj_inuse"), "1");
trap_Cvar_Set(va("team%i_objective%i_inuse", useTeam, i), "1");
}
else
{
trap_Cvar_Set(va("siege_objective%i_desc", i), objectiveDesc);
trap_Cvar_Set(va("siege_objective%i_inuse", i), "2");
trap_Cvar_Set(va("team%i_objective%i_inuse", useTeam, i), "2");
}
}
else
{ //didn't find one, so set the "inuse" cvar to 0 for the objective and mark it non-complete.
trap_Cvar_Set(va("siege_objective%i_inuse", i), "0");
trap_Cvar_Set(va("siege_objective%i", i), "0");
trap_Cvar_Set(va("team%i_objective%i_inuse", useTeam, i), "0");
trap_Cvar_Set(va("team%i_objective%i", useTeam, i), "0");
trap_Cvar_Set(va("siege_objective%i_mappos", i), "");
trap_Cvar_Set(va("team%i_objective%i_mappos", useTeam, i), "");
trap_Cvar_Set(va("siege_objective%i_gfx", i), "");
trap_Cvar_Set(va("team%i_objective%i_gfx", useTeam, i), "");
trap_Cvar_Set(va("siege_objective%i_mapicon", i), "");
trap_Cvar_Set(va("team%i_objective%i_mapicon", useTeam, i), "");
}
i++;
}
if (dontshow)
{
return;
}
if (BG_SiegeGetValueGroup(siege_info, teamstr, cgParseObjectives))
{
if (BG_SiegeGetPairedValue(cgParseObjectives, "briefing", briefing))
{
CG_DrawSiegeMessage(briefing, 1);
}
}
}
void CG_SiegeObjectiveCompleted(centity_t *ent, int won, int objectivenum)
{
int myTeam;
char teamstr[64];
char objstr[256];
char foundobjective[MAX_SIEGE_INFO_SIZE];
char appstring[1024];
char soundstr[1024];
int success = 0;
playerState_t *ps = NULL;
if (!siege_valid)
{
CG_Error("Siege data does not exist on client!\n");
return;
}
if (cg.snap)
{ //this should always be true, if it isn't though use the predicted ps as a fallback
ps = &cg.snap->ps;
}
else
{
ps = &cg.predictedPlayerState;
}
if (!ps)
{
assert(0);
return;
}
myTeam = ps->persistant[PERS_TEAM];
if (myTeam == TEAM_SPECTATOR)
{
return;
}
if (won == SIEGETEAM_TEAM1)
{
Com_sprintf(teamstr, sizeof(teamstr), team1);
}
else
{
Com_sprintf(teamstr, sizeof(teamstr), team2);
}
if (BG_SiegeGetValueGroup(siege_info, teamstr, cgParseObjectives))
{
Com_sprintf(objstr, sizeof(objstr), "Objective%i", objectivenum);
if (BG_SiegeGetValueGroup(cgParseObjectives, objstr, foundobjective))
{
if (myTeam == SIEGETEAM_TEAM1)
{
success = BG_SiegeGetPairedValue(foundobjective, "message_team1", appstring);
}
else
{
success = BG_SiegeGetPairedValue(foundobjective, "message_team2", appstring);
}
if (success)
{
CG_DrawSiegeMessageNonMenu(appstring);
}
appstring[0] = 0;
soundstr[0] = 0;
if (myTeam == SIEGETEAM_TEAM1)
{
Com_sprintf(teamstr, sizeof(teamstr), "sound_team1");
}
else
{
Com_sprintf(teamstr, sizeof(teamstr), "sound_team2");
}
if (BG_SiegeGetPairedValue(foundobjective, teamstr, appstring))
{
Com_sprintf(soundstr, sizeof(soundstr), appstring);
}
/*
else
{
if (myTeam != won)
{
Com_sprintf(soundstr, sizeof(soundstr), DEFAULT_LOSE_OBJECTIVE);
}
else
{
Com_sprintf(soundstr, sizeof(soundstr), DEFAULT_WIN_OBJECTIVE);
}
}
*/
if (soundstr[0])
{
trap_S_StartLocalSound(trap_S_RegisterSound(soundstr), CHAN_ANNOUNCER);
}
}
}
}
siegeExtended_t cg_siegeExtendedData[MAX_CLIENTS];
//parse a single extended siege data entry
void CG_ParseSiegeExtendedDataEntry(const char *conStr)
{
char s[MAX_STRING_CHARS];
char *str = (char *)conStr;
int argParses = 0;
int i;
int maxAmmo = 0, clNum = -1, health = 1, maxhealth = 1, ammo = 1;
centity_t *cent;
if (!conStr || !conStr[0])
{
return;
}
while (*str && argParses < 4)
{
i = 0;
while (*str && *str != '|')
{
s[i] = *str;
i++;
*str++;
}
s[i] = 0;
switch (argParses)
{
case 0:
clNum = atoi(s);
break;
case 1:
health = atoi(s);
break;
case 2:
maxhealth = atoi(s);
break;
case 3:
ammo = atoi(s);
break;
default:
break;
}
argParses++;
str++;
}
if (clNum < 0 || clNum >= MAX_CLIENTS)
{
return;
}
cg_siegeExtendedData[clNum].health = health;
cg_siegeExtendedData[clNum].maxhealth = maxhealth;
cg_siegeExtendedData[clNum].ammo = ammo;
cent = &cg_entities[clNum];
maxAmmo = ammoData[weaponData[cent->currentState.weapon].ammoIndex].max;
if ( (cent->currentState.eFlags & EF_DOUBLE_AMMO) )
{
maxAmmo *= 2.0f;
}
if (ammo >= 0 && ammo <= maxAmmo )
{ //assure the weapon number is valid and not over max
//keep the weapon so if it changes before our next ext data update we'll know
//that the ammo is not applicable.
cg_siegeExtendedData[clNum].weapon = cent->currentState.weapon;
}
else
{ //not valid? Oh well, just invalidate the weapon too then so we don't display ammo
cg_siegeExtendedData[clNum].weapon = -1;
}
cg_siegeExtendedData[clNum].lastUpdated = cg.time;
}
//parse incoming siege data, see counterpart in g_saga.c
void CG_ParseSiegeExtendedData(void)
{
int numEntries = trap_Argc();
int i = 0;
if (numEntries < 1)
{
assert(!"Bad numEntries for sxd");
return;
}
while (i < numEntries)
{
CG_ParseSiegeExtendedDataEntry(CG_Argv(i+1));
i++;
}
}
void CG_SetSiegeTimerCvar ( int msec )
{
int seconds;
int mins;
int tens;
seconds = msec / 1000;
mins = seconds / 60;
seconds -= mins * 60;
tens = seconds / 10;
seconds -= tens * 10;
trap_Cvar_Set("ui_siegeTimer", va( "%i:%i%i", mins, tens, seconds ) );
}