432 lines
7.8 KiB
C
432 lines
7.8 KiB
C
#include "cg_local.h"
|
|
#include "bg_saga.h"
|
|
|
|
#define DEFAULT_WIN_OBJECTIVE "sound/chars/kyle/prototype/personal.mp3"
|
|
#define DEFAULT_LOSE_OBJECTIVE "sound/chars/kyle/prototype/isntworking.mp3"
|
|
|
|
#define DEFAULT_WIN_ROUND "sound/chars/kyle/prototype/personal.mp3"
|
|
#define DEFAULT_LOSE_ROUND "sound/chars/kyle/prototype/isntworking.mp3"
|
|
|
|
char cg_saga_info[MAX_SAGA_INFO_SIZE];
|
|
int cg_saga_valid;
|
|
|
|
//The following two functions are very cheap parsing functions
|
|
int CGSagaGetValueGroup(char *buf, char *group, char *outbuf)
|
|
{
|
|
char *place, *placesecond;
|
|
int iplace;
|
|
int failure;
|
|
int i;
|
|
int startpoint, startletter;
|
|
int subg = 0;
|
|
|
|
i = 0;
|
|
|
|
iplace = 0;
|
|
|
|
place = strstr(buf, group);
|
|
|
|
if (!place)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
startpoint = place - buf + strlen(group) + 1;
|
|
startletter = (place - buf) - 1;
|
|
|
|
failure = 0;
|
|
|
|
while (buf[startpoint+1] != '{' || buf[startletter] != '\n')
|
|
{
|
|
placesecond = strstr(place+1, group);
|
|
|
|
if (placesecond)
|
|
{
|
|
startpoint += (placesecond - place);
|
|
startletter += (placesecond - place);
|
|
place = placesecond;
|
|
}
|
|
else
|
|
{
|
|
failure = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (failure)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
//we have found the proper group name if we made it here, so find the opening brace and read into the outbuf
|
|
//until hitting the end brace
|
|
|
|
while (buf[startpoint] != '{')
|
|
{
|
|
startpoint++;
|
|
}
|
|
|
|
startpoint++;
|
|
|
|
while (buf[startpoint] != '}' || subg)
|
|
{
|
|
if (buf[startpoint] == '{')
|
|
{
|
|
subg++;
|
|
}
|
|
else if (buf[startpoint] == '}')
|
|
{
|
|
subg--;
|
|
}
|
|
outbuf[i] = buf[startpoint];
|
|
i++;
|
|
startpoint++;
|
|
}
|
|
outbuf[i] = '\0';
|
|
|
|
return 1;
|
|
}
|
|
|
|
int CGSagaGetPairedValue(char *buf, char *key, char *outbuf, int inquotes)
|
|
{
|
|
char *place, *placesecond;
|
|
int startpoint, startletter;
|
|
int i, found;
|
|
|
|
if (!buf || !key || !outbuf)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
i = 0;
|
|
|
|
while (buf[i] && buf[i] != '\0')
|
|
{
|
|
if (buf[i] == '/')
|
|
{
|
|
if (buf[i+1] && buf[i+1] != '\0' && buf[i+1] == '/')
|
|
{
|
|
while (buf[i] != '\n')
|
|
{
|
|
buf[i] = '/';
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
i++;
|
|
}
|
|
|
|
place = strstr(buf, key);
|
|
|
|
if (!place)
|
|
{
|
|
return 0;
|
|
}
|
|
//tab == 9
|
|
startpoint = place - buf + strlen(key);
|
|
startletter = (place - buf) - 1;
|
|
|
|
found = 0;
|
|
|
|
while (!found)
|
|
{
|
|
if (startletter == 0 || !buf[startletter] || buf[startletter] == '\0' || buf[startletter] == 9 || buf[startletter] == ' ' || buf[startletter] == '\n')
|
|
{
|
|
if (buf[startpoint] == '\0' || buf[startpoint] == 9 || buf[startpoint] == ' ' || buf[startpoint] == '\n')
|
|
{
|
|
found = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
placesecond = strstr(place+1, key);
|
|
|
|
if (placesecond)
|
|
{
|
|
startpoint += placesecond - place;
|
|
startletter += placesecond - place;
|
|
place = placesecond;
|
|
}
|
|
else
|
|
{
|
|
place = NULL;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
if (!found || !place || !buf[startpoint] || buf[startpoint] == '\0')
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
while (buf[startpoint] == ' ' || buf[startpoint] == 9 || buf[startpoint] == '\n')
|
|
{
|
|
startpoint++;
|
|
}
|
|
|
|
i = 0;
|
|
|
|
if (inquotes)
|
|
{
|
|
while (buf[startpoint] && buf[startpoint] != '\"')
|
|
{
|
|
startpoint++;
|
|
}
|
|
|
|
startpoint++;
|
|
}
|
|
|
|
while (buf[startpoint] && buf[startpoint] != '\0' && buf[startpoint] != '\n')
|
|
{
|
|
outbuf[i] = buf[startpoint];
|
|
i++;
|
|
startpoint++;
|
|
|
|
if (inquotes && buf[startpoint] == '\"')
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
outbuf[i] = '\0';
|
|
|
|
return 1;
|
|
}
|
|
|
|
void CG_InitSagaMode(void)
|
|
{
|
|
char levelname[512];
|
|
int len = 0;
|
|
int i = 0;
|
|
fileHandle_t f;
|
|
|
|
if (cgs.gametype != GT_SAGA)
|
|
{
|
|
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.saga\0", levelname);
|
|
|
|
if (!levelname || !levelname[0])
|
|
{
|
|
goto failure;
|
|
}
|
|
|
|
len = trap_FS_FOpenFile(levelname, &f, FS_READ);
|
|
|
|
if (!f || len >= MAX_SAGA_INFO_SIZE)
|
|
{
|
|
goto failure;
|
|
}
|
|
|
|
trap_FS_Read(cg_saga_info, len, f);
|
|
|
|
cg_saga_valid = 1;
|
|
|
|
return;
|
|
|
|
failure:
|
|
cg_saga_valid = 0;
|
|
}
|
|
|
|
void CG_SagaRoundOver(centity_t *ent, int won)
|
|
{
|
|
int myTeam;
|
|
char teamstr[64];
|
|
char objectives[MAX_SAGA_INFO_SIZE];
|
|
char appstring[1024];
|
|
char soundstr[1024];
|
|
int success = 0;
|
|
|
|
if (!cg_saga_valid)
|
|
{
|
|
Com_Printf("ERROR: Saga data does not exist on client!\n");
|
|
return;
|
|
}
|
|
|
|
if (!cg.snap)
|
|
{
|
|
return; //yikes
|
|
}
|
|
|
|
myTeam = cg.snap->ps.persistant[PERS_TEAM];
|
|
|
|
if (myTeam == TEAM_SPECTATOR)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (myTeam == SAGATEAM_IMPERIAL)
|
|
{
|
|
Com_sprintf(teamstr, sizeof(teamstr), "Imperial");
|
|
}
|
|
else
|
|
{
|
|
Com_sprintf(teamstr, sizeof(teamstr), "Rebel");
|
|
}
|
|
|
|
if (CGSagaGetValueGroup(cg_saga_info, teamstr, objectives))
|
|
{
|
|
if (won == myTeam)
|
|
{
|
|
success = CGSagaGetPairedValue(objectives, "wonround", appstring, 1);
|
|
}
|
|
else
|
|
{
|
|
success = CGSagaGetPairedValue(objectives, "lostround", appstring, 1);
|
|
}
|
|
|
|
if (success)
|
|
{
|
|
Com_Printf("%s\n", appstring);
|
|
}
|
|
|
|
if (myTeam == won)
|
|
{
|
|
Com_sprintf(teamstr, sizeof(teamstr), "roundover_sound_wewon");
|
|
}
|
|
else
|
|
{
|
|
Com_sprintf(teamstr, sizeof(teamstr), "roundover_sound_welost");
|
|
}
|
|
|
|
if (CGSagaGetPairedValue(objectives, teamstr, appstring, 1))
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
|
|
trap_S_StartLocalSound(trap_S_RegisterSound(soundstr), CHAN_ANNOUNCER);
|
|
//Com_Printf("Play sound: %s\n", soundstr);
|
|
}
|
|
}
|
|
|
|
void CG_SagaObjectiveCompleted(centity_t *ent, int won, int objectivenum)
|
|
{
|
|
int myTeam;
|
|
char teamstr[64];
|
|
char objstr[256];
|
|
char objectives[MAX_SAGA_INFO_SIZE];
|
|
char foundobjective[MAX_SAGA_INFO_SIZE];
|
|
char appstring[1024];
|
|
char soundstr[1024];
|
|
int success = 0;
|
|
int i = 0;
|
|
int i_r = 0;
|
|
|
|
if (!cg_saga_valid)
|
|
{
|
|
Com_Printf("ERROR: Saga data does not exist on client!\n");
|
|
return;
|
|
}
|
|
|
|
if (!cg.snap)
|
|
{
|
|
return; //yikes
|
|
}
|
|
|
|
myTeam = cg.snap->ps.persistant[PERS_TEAM];
|
|
|
|
if (myTeam == TEAM_SPECTATOR)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (won == SAGATEAM_IMPERIAL)
|
|
{
|
|
Com_sprintf(teamstr, sizeof(teamstr), "Imperial");
|
|
}
|
|
else
|
|
{
|
|
Com_sprintf(teamstr, sizeof(teamstr), "Rebel");
|
|
}
|
|
|
|
if (CGSagaGetValueGroup(cg_saga_info, teamstr, objectives))
|
|
{
|
|
Com_sprintf(objstr, sizeof(objstr), "Objective%i", objectivenum);
|
|
|
|
while (objectives[i])
|
|
{
|
|
if (objectives[i] != 9)
|
|
{
|
|
objectives[i_r] = objectives[i];
|
|
i_r++;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
objectives[i_r] = '\0';
|
|
|
|
if (CGSagaGetValueGroup(objectives, objstr, foundobjective))
|
|
{
|
|
if (myTeam == SAGATEAM_IMPERIAL)
|
|
{
|
|
success = CGSagaGetPairedValue(foundobjective, "message_imperial", appstring, 1);
|
|
}
|
|
else
|
|
{
|
|
success = CGSagaGetPairedValue(foundobjective, "message_rebel", appstring, 1);
|
|
}
|
|
|
|
if (success)
|
|
{
|
|
Com_Printf("%s\n", appstring);
|
|
}
|
|
|
|
if (myTeam == SAGATEAM_IMPERIAL)
|
|
{
|
|
Com_sprintf(teamstr, sizeof(teamstr), "sound_imperial");
|
|
}
|
|
else
|
|
{
|
|
Com_sprintf(teamstr, sizeof(teamstr), "sound_rebel");
|
|
}
|
|
|
|
if (CGSagaGetPairedValue(foundobjective, teamstr, appstring, 1))
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
|
|
trap_S_StartLocalSound(trap_S_RegisterSound(soundstr), CHAN_ANNOUNCER);
|
|
//Com_Printf("Play sound: %s\n", soundstr);
|
|
}
|
|
}
|
|
}
|