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[0]) { goto failure; } len = trap->FS_Open(levelname, &f, FS_READ); if (!f || len >= MAX_SIEGE_INFO_SIZE) { goto failure; } trap->FS_Read(siege_info, len, f); trap->FS_Close(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->SE_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->SE_GetStringTextString(team2+1, b, 256); trap->Cvar_Set("cg_siegeTeam2Name", b); } else { trap->Cvar_Set("cg_siegeTeam2Name", team2); } } else { trap->Error( ERR_DROP, "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 { trap->Error( ERR_DROP, "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 { trap->Error( ERR_DROP, "No team entry for '%s'\n", team2); } //Load the player class types BG_SiegeLoadClasses(NULL); if (!bgNumSiegeClasses) { //We didn't find any?! trap->Error( ERR_DROP, "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. trap->Error( ERR_DROP, "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; }
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) { trap->Error( ERR_DROP, "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); } } } }
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) { trap->Error( ERR_DROP, "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_PrecacheSiegeObjectiveAssetsForTeam(int myTeam) { char teamstr[64]; char objstr[256]; char foundobjective[MAX_SIEGE_INFO_SIZE]; if (!siege_valid) { trap->Error( ERR_DROP, "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 BG_SiegeParseClassFile( const char *filename, siegeClassDesc_t *descBuffer ) { fileHandle_t f; int len; int i; char classInfo[4096]; char parseBuf[4096]; len = trap->FS_Open( filename, &f, FS_READ ); if ( !f || len >= 4096 ) { return; } trap->FS_Read( classInfo, len, f ); trap->FS_Close( f ); classInfo[len] = 0; //first get the description if we have a buffer for it if ( descBuffer ) { if ( !BG_SiegeGetPairedValue( classInfo, "description", descBuffer->desc ) ) { strcpy( descBuffer->desc, "DESCRIPTION UNAVAILABLE" ); } //Hit this assert? Memory has already been trashed. Increase //SIEGE_CLASS_DESC_LEN. assert( strlen( descBuffer->desc ) < SIEGE_CLASS_DESC_LEN ); } BG_SiegeGetValueGroup( classInfo, "ClassInfo", classInfo ); //Parse name if ( BG_SiegeGetPairedValue( classInfo, "name", parseBuf ) ) { strcpy( bgSiegeClasses[bgNumSiegeClasses].name, parseBuf ); } else { Com_Error( ERR_DROP, "Siege class without name entry" ); } //Parse forced model if ( BG_SiegeGetPairedValue( classInfo, "model", parseBuf ) ) { strcpy( bgSiegeClasses[bgNumSiegeClasses].forcedModel, parseBuf ); } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].forcedModel[0] = 0; } //Parse forced skin if ( BG_SiegeGetPairedValue( classInfo, "skin", parseBuf ) ) { strcpy( bgSiegeClasses[bgNumSiegeClasses].forcedSkin, parseBuf ); } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].forcedSkin[0] = 0; } //Parse first saber if ( BG_SiegeGetPairedValue( classInfo, "saber1", parseBuf ) ) { strcpy( bgSiegeClasses[bgNumSiegeClasses].saber1, parseBuf ); } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].saber1[0] = 0; } //Parse second saber if ( BG_SiegeGetPairedValue( classInfo, "saber2", parseBuf ) ) { strcpy( bgSiegeClasses[bgNumSiegeClasses].saber2, parseBuf ); } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].saber2[0] = 0; } //Parse forced saber stance if ( BG_SiegeGetPairedValue( classInfo, "saberstyle", parseBuf ) ) { bgSiegeClasses[bgNumSiegeClasses].saberStance = BG_SiegeTranslateGenericTable( parseBuf, StanceTable, qtrue ); } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].saberStance = 0; } //Parse forced saber color if ( BG_SiegeGetPairedValue( classInfo, "sabercolor", parseBuf ) ) { bgSiegeClasses[bgNumSiegeClasses].forcedSaberColor = atoi( parseBuf ); bgSiegeClasses[bgNumSiegeClasses].hasForcedSaberColor = qtrue; } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].hasForcedSaberColor = qfalse; } //Parse forced saber2 color if ( BG_SiegeGetPairedValue( classInfo, "saber2color", parseBuf ) ) { bgSiegeClasses[bgNumSiegeClasses].forcedSaber2Color = atoi( parseBuf ); bgSiegeClasses[bgNumSiegeClasses].hasForcedSaber2Color = qtrue; } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].hasForcedSaber2Color = qfalse; } //Parse weapons if ( BG_SiegeGetPairedValue( classInfo, "weapons", parseBuf ) ) { bgSiegeClasses[bgNumSiegeClasses].weapons = BG_SiegeTranslateGenericTable( parseBuf, WPTable, qtrue ); } else { Com_Error( ERR_DROP, "Siege class without weapons entry" ); } if ( !(bgSiegeClasses[bgNumSiegeClasses].weapons & (1 << WP_SABER)) ) { //make sure it has melee if there's no saber bgSiegeClasses[bgNumSiegeClasses].weapons |= (1 << WP_MELEE); //always give them this too if they are not a saber user //bgSiegeClasses[bgNumSiegeClasses].weapons |= (1 << WP_BRYAR_PISTOL); } //Parse forcepowers if ( BG_SiegeGetPairedValue( classInfo, "forcepowers", parseBuf ) ) { BG_SiegeTranslateForcePowers( parseBuf, &bgSiegeClasses[bgNumSiegeClasses] ); } else { //fine, clear out the powers. i = 0; while ( i < NUM_FORCE_POWERS ) { bgSiegeClasses[bgNumSiegeClasses].forcePowerLevels[i] = 0; i++; } } //Parse classflags if ( BG_SiegeGetPairedValue( classInfo, "classflags", parseBuf ) ) { bgSiegeClasses[bgNumSiegeClasses].classflags = BG_SiegeTranslateGenericTable( parseBuf, bgSiegeClassFlagNames, qtrue ); } else { //fine, we'll 0 it. bgSiegeClasses[bgNumSiegeClasses].classflags = 0; } //Parse maxhealth if ( BG_SiegeGetPairedValue( classInfo, "maxhealth", parseBuf ) ) { bgSiegeClasses[bgNumSiegeClasses].maxhealth = atoi( parseBuf ); } else { //It's alright, just default to 100 then. bgSiegeClasses[bgNumSiegeClasses].maxhealth = 100; } //Parse starthealth if ( BG_SiegeGetPairedValue( classInfo, "starthealth", parseBuf ) ) { bgSiegeClasses[bgNumSiegeClasses].starthealth = atoi( parseBuf ); } else { //It's alright, just default to 100 then. bgSiegeClasses[bgNumSiegeClasses].starthealth = bgSiegeClasses[bgNumSiegeClasses].maxhealth; } //Parse startarmor if ( BG_SiegeGetPairedValue( classInfo, "maxarmor", parseBuf ) ) { bgSiegeClasses[bgNumSiegeClasses].maxarmor = atoi( parseBuf ); } else { //It's alright, just default to 0 then. bgSiegeClasses[bgNumSiegeClasses].maxarmor = 0; } //Parse startarmor if ( BG_SiegeGetPairedValue( classInfo, "startarmor", parseBuf ) ) { bgSiegeClasses[bgNumSiegeClasses].startarmor = atoi( parseBuf ); if ( !bgSiegeClasses[bgNumSiegeClasses].maxarmor ) { //if they didn't specify a damn max armor then use this. bgSiegeClasses[bgNumSiegeClasses].maxarmor = bgSiegeClasses[bgNumSiegeClasses].startarmor; } } else { //default to maxarmor. bgSiegeClasses[bgNumSiegeClasses].startarmor = bgSiegeClasses[bgNumSiegeClasses].maxarmor; } //Parse speed (this is a multiplier value) if ( BG_SiegeGetPairedValue( classInfo, "speed", parseBuf ) ) { bgSiegeClasses[bgNumSiegeClasses].speed = atof( parseBuf ); } else { //It's alright, just default to 1 then. bgSiegeClasses[bgNumSiegeClasses].speed = 1.0f; } //Parse shader for ui to use if ( BG_SiegeGetPairedValue( classInfo, "uishader", parseBuf ) ) { #ifdef PROJECT_GAME bgSiegeClasses[bgNumSiegeClasses].uiPortraitShader = 0; memset( bgSiegeClasses[bgNumSiegeClasses].uiPortrait, 0, sizeof(bgSiegeClasses[bgNumSiegeClasses].uiPortrait) ); #elif defined PROJECT_CGAME bgSiegeClasses[bgNumSiegeClasses].uiPortraitShader = 0; memset( bgSiegeClasses[bgNumSiegeClasses].uiPortrait, 0, sizeof(bgSiegeClasses[bgNumSiegeClasses].uiPortrait) ); #else //ui bgSiegeClasses[bgNumSiegeClasses].uiPortraitShader = trap->R_RegisterShaderNoMip( parseBuf ); memcpy( bgSiegeClasses[bgNumSiegeClasses].uiPortrait, parseBuf, sizeof(bgSiegeClasses[bgNumSiegeClasses].uiPortrait) ); #endif } else { //I guess this is an essential.. we don't want to render bad shaders or anything. Com_Error( ERR_DROP, "Siege class without uishader entry" ); } //Parse shader for ui to use if ( BG_SiegeGetPairedValue( classInfo, "class_shader", parseBuf ) ) { #ifdef PROJECT_GAME bgSiegeClasses[bgNumSiegeClasses].classShader = 0; #else //cgame, ui bgSiegeClasses[bgNumSiegeClasses].classShader = trap->R_RegisterShaderNoMip( parseBuf ); assert( bgSiegeClasses[bgNumSiegeClasses].classShader ); if ( !bgSiegeClasses[bgNumSiegeClasses].classShader ) { //Com_Error( ERR_DROP, "ERROR: could not find class_shader %s for class %s\n", parseBuf, bgSiegeClasses[bgNumSiegeClasses].name ); Com_Printf( "ERROR: could not find class_shader %s for class %s\n", parseBuf, bgSiegeClasses[bgNumSiegeClasses].name ); } // A very hacky way to determine class . . . else #endif { // Find the base player class based on the icon name - very bad, I know. int titleLength, arrayTitleLength; char *holdBuf; titleLength = strlen( parseBuf ); for ( i = 0; i<SPC_MAX; i++ ) { // Back up arrayTitleLength = strlen( classTitles[i] ); if ( arrayTitleLength>titleLength ) // Too long { break; } holdBuf = parseBuf + (titleLength - arrayTitleLength); if ( !strcmp( holdBuf, classTitles[i] ) ) { bgSiegeClasses[bgNumSiegeClasses].playerClass = i; break; } } // In case the icon name doesn't match up if ( i >= SPC_MAX ) { bgSiegeClasses[bgNumSiegeClasses].playerClass = SPC_INFANTRY; } } } else { //No entry! Bad bad bad //Com_Error( ERR_DROP, "ERROR: no class_shader defined for class %s\n", bgSiegeClasses[bgNumSiegeClasses].name ); Com_Printf( "ERROR: no class_shader defined for class %s\n", bgSiegeClasses[bgNumSiegeClasses].name ); } //Parse holdable items to use if ( BG_SiegeGetPairedValue( classInfo, "holdables", parseBuf ) ) { bgSiegeClasses[bgNumSiegeClasses].invenItems = BG_SiegeTranslateGenericTable( parseBuf, HoldableTable, qtrue ); } else { //Just don't start out with any then. bgSiegeClasses[bgNumSiegeClasses].invenItems = 0; } //Parse powerups to use if ( BG_SiegeGetPairedValue( classInfo, "powerups", parseBuf ) ) { bgSiegeClasses[bgNumSiegeClasses].powerups = BG_SiegeTranslateGenericTable( parseBuf, PowerupTable, qtrue ); } else { //Just don't start out with any then. bgSiegeClasses[bgNumSiegeClasses].powerups = 0; } //A successful read. bgNumSiegeClasses++; }
void BG_SiegeParseTeamFile( const char *filename ) { fileHandle_t f; int len; char teamInfo[2048]; char parseBuf[1024]; char lookString[256]; int i = 1; qboolean success = qtrue; len = trap->FS_Open( filename, &f, FS_READ ); if ( !f || len >= 2048 ) { return; } trap->FS_Read( teamInfo, len, f ); trap->FS_Close( f ); teamInfo[len] = 0; if ( BG_SiegeGetPairedValue( teamInfo, "name", parseBuf ) ) { strcpy( bgSiegeTeams[bgNumSiegeTeams].name, parseBuf ); } else { Com_Error( ERR_DROP, "Siege team with no name definition" ); } //I don't entirely like doing things this way but it's the easiest way. #ifdef PROJECT_CGAME if ( BG_SiegeGetPairedValue( teamInfo, "FriendlyShader", parseBuf ) ) { bgSiegeTeams[bgNumSiegeTeams].friendlyShader = trap->R_RegisterShaderNoMip( parseBuf ); } #else bgSiegeTeams[bgNumSiegeTeams].friendlyShader = 0; #endif bgSiegeTeams[bgNumSiegeTeams].numClasses = 0; if ( BG_SiegeGetValueGroup( teamInfo, "Classes", teamInfo ) ) { while ( success && i < MAX_SIEGE_CLASSES ) { //keep checking for group values named class# up to MAX_SIEGE_CLASSES until we can't find one. strcpy( lookString, va( "class%i", i ) ); success = BG_SiegeGetPairedValue( teamInfo, lookString, parseBuf ); if ( !success ) { break; } bgSiegeTeams[bgNumSiegeTeams].classes[bgSiegeTeams[bgNumSiegeTeams].numClasses] = BG_SiegeFindClassByName( parseBuf ); if ( !bgSiegeTeams[bgNumSiegeTeams].classes[bgSiegeTeams[bgNumSiegeTeams].numClasses] ) { Com_Error( ERR_DROP, "Invalid class specified: '%s'", parseBuf ); } bgSiegeTeams[bgNumSiegeTeams].numClasses++; i++; } } if ( !bgSiegeTeams[bgNumSiegeTeams].numClasses ) { Com_Error( ERR_DROP, "Team defined with no allowable classes\n" ); } //If we get here then it was a success, so increment the team number bgNumSiegeTeams++; }
void InitSiegeMode(void) { vmCvar_t mapname; char levelname[512]; char teamIcon[128]; char goalreq[64]; char teams[2048]; static char objective[MAX_SIEGE_INFO_SIZE]; char objecStr[8192]; int len = 0; int i = 0; // int j = 0; int objectiveNumTeam1 = 0; int objectiveNumTeam2 = 0; fileHandle_t f; objective[0] = '\0'; if (level.gametype != GT_SIEGE) { goto failure; } //reset SiegeSetCompleteData(0); //get pers data in case it existed from last level if (g_siegeTeamSwitch.integer) { trap->SiegePersGet(&g_siegePersistant); if (g_siegePersistant.beatingTime) { trap->SetConfigstring(CS_SIEGE_TIMEOVERRIDE, va("%i", g_siegePersistant.lastTime)); } else { trap->SetConfigstring(CS_SIEGE_TIMEOVERRIDE, "0"); } } else { //hmm, ok, nothing. trap->SetConfigstring(CS_SIEGE_TIMEOVERRIDE, "0"); } imperial_goals_completed = 0; rebel_goals_completed = 0; trap->Cvar_Register( &mapname, "mapname", "", CVAR_SERVERINFO | CVAR_ROM ); Com_sprintf(levelname, sizeof(levelname), "maps/%s.siege\0", mapname.string); if ( !levelname[0] ) { goto failure; } len = trap->FS_Open(levelname, &f, FS_READ); if (!f) { goto failure; } if (len >= MAX_SIEGE_INFO_SIZE) { trap->FS_Close( f ); goto failure; } trap->FS_Read(siege_info, len, f); trap->FS_Close(f); siege_valid = 1; //See if players should be specs or ingame preround if (BG_SiegeGetPairedValue(siege_info, "preround_state", teams)) { if (teams[0]) { g_preroundState = atoi(teams); } } if (BG_SiegeGetValueGroup(siege_info, "Teams", teams)) { if (g_siegeTeam1.string[0] && Q_stricmp(g_siegeTeam1.string, "none")) { //check for override strcpy(team1, g_siegeTeam1.string); } else { //otherwise use level default BG_SiegeGetPairedValue(teams, "team1", team1); } if (g_siegeTeam2.string[0] && Q_stricmp(g_siegeTeam2.string, "none")) { //check for override strcpy(team2, g_siegeTeam2.string); } else { //otherwise use level default BG_SiegeGetPairedValue(teams, "team2", team2); } } else { trap->Error( ERR_DROP, "Siege teams not defined" ); } if (BG_SiegeGetValueGroup(siege_info, team2, gParseObjectives)) { if (BG_SiegeGetPairedValue(gParseObjectives, "TeamIcon", teamIcon)) { trap->Cvar_Set( "team2_icon", teamIcon); } if (BG_SiegeGetPairedValue(gParseObjectives, "RequiredObjectives", goalreq)) { rebel_goals_required = atoi(goalreq); } if (BG_SiegeGetPairedValue(gParseObjectives, "Timed", goalreq)) { rebel_time_limit = atoi(goalreq)*1000; if (g_siegeTeamSwitch.integer && g_siegePersistant.beatingTime) { gRebelCountdown = level.time + g_siegePersistant.lastTime; } else { gRebelCountdown = level.time + rebel_time_limit; } } if (BG_SiegeGetPairedValue(gParseObjectives, "attackers", goalreq)) { rebel_attackers = atoi(goalreq); } } if (BG_SiegeGetValueGroup(siege_info, team1, gParseObjectives)) { if (BG_SiegeGetPairedValue(gParseObjectives, "TeamIcon", teamIcon)) { trap->Cvar_Set( "team1_icon", teamIcon); } if (BG_SiegeGetPairedValue(gParseObjectives, "RequiredObjectives", goalreq)) { imperial_goals_required = atoi(goalreq); } if (BG_SiegeGetPairedValue(gParseObjectives, "Timed", goalreq)) { if (rebel_time_limit) { Com_Printf("Tried to set imperial time limit, but there's already a rebel time limit!\nOnly one team can have a time limit.\n"); } else { imperial_time_limit = atoi(goalreq)*1000; if (g_siegeTeamSwitch.integer && g_siegePersistant.beatingTime) { gImperialCountdown = level.time + g_siegePersistant.lastTime; } else { gImperialCountdown = level.time + imperial_time_limit; } } } if (BG_SiegeGetPairedValue(gParseObjectives, "attackers", goalreq)) { imperial_attackers = atoi(goalreq); } } //Load the player class types BG_SiegeLoadClasses(NULL); if (!bgNumSiegeClasses) { //We didn't find any?! trap->Error( ERR_DROP, "Couldn't find any player classes for Siege" ); } /* //We could probably just see what teams are used on this level, //then see what classes are used by those teams, and then precache //all weapons for said classes. However, I'm just going to do them //all for now. while (i < bgNumSiegeClasses) { cl = &bgSiegeClasses[i]; j = 0; while (j < WP_NUM_WEAPONS) { if (cl->weapons & (1 << j)) { //we use this weapon so register it. RegisterItem(BG_FindItemForWeapon(j)); } j++; } i++; } */ //Ok, I'm adding inventory item precaching now, so I'm finally going to optimize this //to only do weapons/items for the current teams used on the level. //Now load the teams since we have class data. BG_SiegeLoadTeams(); if (!bgNumSiegeTeams) { //React same as with classes. trap->Error( ERR_DROP, "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, gParseObjectives)) { if (BG_SiegeGetPairedValue(gParseObjectives, "UseTeam", goalreq)) { BG_SiegeSetTeamTheme(SIEGETEAM_TEAM1, goalreq); } //Now count up the objectives for this team. i = 1; strcpy(objecStr, va("Objective%i", i)); while (BG_SiegeGetValueGroup(gParseObjectives, objecStr, objective)) { objectiveNumTeam1++; i++; strcpy(objecStr, va("Objective%i", i)); } } if (BG_SiegeGetValueGroup(siege_info, team2, gParseObjectives)) { if (BG_SiegeGetPairedValue(gParseObjectives, "UseTeam", goalreq)) { BG_SiegeSetTeamTheme(SIEGETEAM_TEAM2, goalreq); } //Now count up the objectives for this team. i = 1; strcpy(objecStr, va("Objective%i", i)); while (BG_SiegeGetValueGroup(gParseObjectives, objecStr, objective)) { objectiveNumTeam2++; i++; strcpy(objecStr, va("Objective%i", i)); } } //Set the configstring to show status of all current objectives strcpy(gObjectiveCfgStr, "t1"); while (objectiveNumTeam1 > 0) { //mark them all as not completed since we just initialized Q_strcat(gObjectiveCfgStr, 1024, "-0"); objectiveNumTeam1--; } //Finished doing team 1's objectives, now do team 2's Q_strcat(gObjectiveCfgStr, 1024, "|t2"); while (objectiveNumTeam2 > 0) { Q_strcat(gObjectiveCfgStr, 1024, "-0"); objectiveNumTeam2--; } //And finally set the actual config string trap->SetConfigstring(CS_SIEGE_OBJECTIVES, gObjectiveCfgStr); //precache saber data for classes that use sabers on both teams BG_PrecacheSabersForSiegeTeam(SIEGETEAM_TEAM1); BG_PrecacheSabersForSiegeTeam(SIEGETEAM_TEAM2); G_SiegeRegisterWeaponsAndHoldables(SIEGETEAM_TEAM1); G_SiegeRegisterWeaponsAndHoldables(SIEGETEAM_TEAM2); return; failure: siege_valid = 0; }