jedioutcast/CODE-mp/game/g_saga.c
2013-04-04 13:01:17 -05:00

380 lines
8 KiB
C

#include "g_local.h"
#include "bg_saga.h"
char saga_info[MAX_SAGA_INFO_SIZE];
int saga_valid;
int saga_round_over;
int imperial_goals_required;
int imperial_goals_completed;
int rebel_goals_required;
int rebel_goals_completed;
int rebel_attackers;
int imperial_attackers;
void LogExit( const char *string );
int GetValueGroup(char *buf, char *group, char *outbuf);
int GetPairedValue(char *buf, char *key, char *outbuf);
//Using the bot parsing functions on saga ini's, at least for now.
void InitSagaMode(void)
{
vmCvar_t mapname;
char levelname[512];
char goalreq[64];
char objectives[MAX_SAGA_INFO_SIZE];
int len = 0;
fileHandle_t f;
if (g_gametype.integer != GT_SAGA)
{
goto failure;
}
imperial_goals_completed = 0;
rebel_goals_completed = 0;
saga_round_over = 0;
trap_Cvar_Register( &mapname, "mapname", "", CVAR_SERVERINFO | CVAR_ROM );
Com_sprintf(levelname, sizeof(levelname), "maps/%s.saga\0", mapname.string);
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(saga_info, len, f);
saga_valid = 1;
if (GetValueGroup(saga_info, "Rebel", objectives))
{
if (GetPairedValue(objectives, "RequiredObjectives", goalreq))
{
rebel_goals_required = atoi(goalreq);
}
if (GetPairedValue(objectives, "attackers", goalreq))
{
rebel_attackers = atoi(goalreq);
}
}
if (GetValueGroup(saga_info, "Imperial", objectives))
{
if (GetPairedValue(objectives, "RequiredObjectives", goalreq))
{
imperial_goals_required = atoi(goalreq);
}
if (GetPairedValue(objectives, "attackers", goalreq))
{
imperial_attackers = atoi(goalreq);
}
}
return;
failure:
saga_valid = 0;
}
void UseSagaTarget(gentity_t *other, gentity_t *en, char *target)
{ //actually use the player which triggered the object which triggered the saga objective to trigger the target
gentity_t *t;
gentity_t *ent;
if ( !en || !en->client )
{ //looks like we don't have access to a player, so just use the activating entity
ent = other;
}
else
{
ent = en;
}
if (!en)
{
return;
}
if ( !target )
{
return;
}
t = NULL;
while ( (t = G_Find (t, FOFS(targetname), target)) != NULL )
{
if ( t == ent )
{
G_Printf ("WARNING: Entity used itself.\n");
}
else
{
if ( t->use )
{
t->use (t, ent, ent);
}
}
if ( !ent->inuse )
{
G_Printf("entity was removed while using targets\n");
return;
}
}
}
void SagaBroadcast_OBJECTIVECOMPLETE(int team, int client, int objective)
{
gentity_t *te;
vec3_t nomatter;
VectorClear(nomatter);
te = G_TempEntity( nomatter, EV_SAGA_OBJECTIVECOMPLETE );
te->r.svFlags |= SVF_BROADCAST;
te->s.eventParm = team;
te->s.weapon = client;
te->s.trickedentindex = objective;
}
void SagaBroadcast_ROUNDOVER(int winningteam, int winningclient)
{
gentity_t *te;
vec3_t nomatter;
VectorClear(nomatter);
te = G_TempEntity( nomatter, EV_SAGA_ROUNDOVER );
te->r.svFlags |= SVF_BROADCAST;
te->s.eventParm = winningteam;
te->s.weapon = winningclient;
}
void BroadcastObjectiveCompletion(int team, int objective, int final, int client)
{
if (client != ENTITYNUM_NONE && g_entities[client].client && g_entities[client].client->sess.sessionTeam == team)
{ //guy who completed this objective gets points, providing he's on the opposing team
AddScore(&g_entities[client], g_entities[client].client->ps.origin, SAGA_POINTS_OBJECTIVECOMPLETED);
}
SagaBroadcast_OBJECTIVECOMPLETE(team, client, objective);
//G_Printf("Broadcast goal completion team %i objective %i final %i\n", team, objective, final);
}
void AddSagaWinningTeamPoints(int team, int winner)
{
int i = 0;
gentity_t *ent;
while (i < MAX_CLIENTS)
{
ent = &g_entities[i];
if (ent && ent->client && ent->client->sess.sessionTeam == team)
{
if (i == winner)
{
AddScore(ent, ent->client->ps.origin, SAGA_POINTS_TEAMWONROUND+SAGA_POINTS_FINALOBJECTIVECOMPLETED);
}
else
{
AddScore(ent, ent->client->ps.origin, SAGA_POINTS_TEAMWONROUND);
}
}
i++;
}
}
void SagaRoundComplete(int winningteam, int winningclient)
{
vec3_t nomatter;
saga_round_over = 1;
//G_Printf("Team %i won\n", winningteam);
if (winningclient != ENTITYNUM_NONE && g_entities[winningclient].client &&
g_entities[winningclient].client->sess.sessionTeam != winningteam)
{ //this person just won the round for the other team..
winningclient = ENTITYNUM_NONE;
}
VectorClear(nomatter);
SagaBroadcast_ROUNDOVER(winningteam, winningclient);
AddSagaWinningTeamPoints(winningteam, winningclient);
if (winningteam == SAGATEAM_IMPERIAL)
{
LogExit( "The Imperials completed their final objective." );
}
else
{
LogExit( "The Rebels completed their final objective." );
}
}
void SagaObjectiveCompleted(int team, int objective, int final, int client)
{
int goals_completed, goals_required;
if (saga_round_over)
{
return;
}
if (final != -1)
{
if (team == SAGATEAM_IMPERIAL)
{
imperial_goals_completed++;
}
else
{
rebel_goals_completed++;
}
}
if (team == SAGATEAM_IMPERIAL)
{
goals_completed = imperial_goals_completed;
goals_required = imperial_goals_required;
}
else
{
goals_completed = rebel_goals_completed;
goals_required = rebel_goals_required;
}
if (final == 1 || goals_completed >= goals_required)
{
SagaRoundComplete(team, client);
}
else
{
BroadcastObjectiveCompletion(team, objective, final, client);
}
}
void StripTabs(char *buf)
{
int i = 0;
int i_r = 0;
while (buf[i])
{
if (buf[i] != 9)
{
buf[i_r] = buf[i];
i_r++;
}
i++;
}
buf[i_r] = '\0';
}
void sagaTriggerUse(gentity_t *ent, gentity_t *other, gentity_t *activator)
{
char teamstr[64];
char objectivestr[64];
char objectives[MAX_SAGA_INFO_SIZE];
char desiredobjective[MAX_SAGA_INFO_SIZE];
int clUser = ENTITYNUM_NONE;
int final = 0;
int i = 0;
if (!saga_valid)
{
return;
}
if (activator && activator->client)
{ //activator will hopefully be the person who triggered this event
clUser = activator->s.number;
}
if (ent->side == SAGATEAM_IMPERIAL)
{
Com_sprintf(teamstr, sizeof(teamstr), "Imperial");
}
else
{
Com_sprintf(teamstr, sizeof(teamstr), "Rebel");
}
if (GetValueGroup(saga_info, teamstr, objectives))
{
Com_sprintf(objectivestr, sizeof(objectivestr), "Objective%i", ent->objective);
StripTabs(objectives); //tabs confuse the parsing function
if (GetValueGroup(objectives, objectivestr, desiredobjective))
{
if (GetPairedValue(desiredobjective, "final", teamstr))
{
final = atoi(teamstr);
}
if (GetPairedValue(desiredobjective, "target", teamstr))
{
while (teamstr[i])
{
if (teamstr[i] == '\r' ||
teamstr[i] == '\n')
{
teamstr[i] = '\0';
}
i++;
}
UseSagaTarget(other, activator, teamstr);
}
if (ent->target && ent->target[0])
{ //use this too
UseSagaTarget(other, activator, ent->target);
}
SagaObjectiveCompleted(ent->side, ent->objective, final, clUser);
}
}
}
/*QUAKED info_saga_objective (1 0 1) (-16 -16 -24) (16 16 32)
"objective" - specifies the objective to complete upon activation
"side" - set to 1 to specify an imperial goal, 2 to specify rebels
*/
void SP_info_saga_objective (gentity_t *ent)
{
if (!saga_valid || g_gametype.integer != GT_SAGA)
{
G_FreeEntity(ent);
return;
}
ent->use = sagaTriggerUse;
G_SpawnInt( "objective", "0", &ent->objective);
G_SpawnInt( "side", "0", &ent->side);
if (!ent->objective || !ent->side)
{ //j00 fux0red something up
G_FreeEntity(ent);
G_Printf("ERROR: info_saga_objective without an objective or side value\n");
return;
}
}