void NetServer::GenerateDriversForXML() { assert(m_strRaceXMLFile!=""); void *params = GfParmReadFileLocal(m_strRaceXMLFile.c_str(),GFPARM_RMODE_STD); assert(params); const char *pName =GfParmGetStr(params, RM_SECT_HEADER, RM_ATTR_NAME, ""); int nCars = GfParmGetEltNb(params, RM_SECT_DRIVERS); //Gather vector of all non human drivers std::vector<NetDriver> vecRDrivers; for (int i=1;i<=nCars;i++) { NetDriver driver; ReadDriverData(driver,i,params); if (strcmp(driver.module,NETWORKROBOT) && strcmp(driver.module,HUMANROBOT)) vecRDrivers.push_back(driver); } //Recreate drivers section robots first char drvSec[256]; GfParmListClean(params, RM_SECT_DRIVERS); for (int i=0;i<(int)vecRDrivers.size();i++) { int index = i+1; sprintf(drvSec, "%s/%d", RM_SECT_DRIVERS, index); GfParmSetNum(params, drvSec, RM_ATTR_IDX, (char*)NULL, (tdble)vecRDrivers[i].idx); GfParmSetStr(params, drvSec, RM_ATTR_MODULE, vecRDrivers[i].module); } //And then add the networkhuman drivers NetServerMutexData *pSData = LockServerData(); for (int i=0;i<(int)pSData->m_vecNetworkPlayers.size();i++) { int index = i+1+vecRDrivers.size(); sprintf(drvSec, "%s/%d", RM_SECT_DRIVERS, index); GfParmSetNum(params, drvSec, RM_ATTR_IDX, (char*)NULL,(tdble) pSData->m_vecNetworkPlayers[i].idx); GfParmSetStr(params, drvSec, RM_ATTR_MODULE, pSData->m_vecNetworkPlayers[i].module); } UnlockServerData(); //Save our changes GfParmWriteFileLocal(m_strRaceXMLFile.c_str(), params, pName); }
static void rmdsSelect(void * /* dummy */) { char *name; tDrvElt *curDrv; int index; sprintf(buf, "%s", RM_SECT_DRIVERS); GfParmListClean(ds->param, buf); name = GfuiScrollListExtractElement(scrHandle, selectedScrollList, 0, (void**)&curDrv); index = 1; while (name != NULL) { sprintf(buf, "%s/%d", RM_SECT_DRIVERS, index); GfParmSetNum(ds->param, buf, RM_ATTR_IDX, (char*)NULL, curDrv->index); GfParmSetStr(ds->param, buf, RM_ATTR_MODULE, curDrv->dname); index++; name = GfuiScrollListExtractElement(scrHandle, selectedScrollList, 0, (void**)&curDrv); } rmdsDeactivate(ds->nextScreen); }
bool RobotXml::CreateRobotFile(const char*pRobotName,std::vector<NetDriver> &vecDrivers) { char buf[255]; sprintf(buf,"drivers/%s/%s.xml",pRobotName,pRobotName); void *params = GfParmReadFileLocal(buf,GFPARM_RMODE_CREAT); //Erase existing robots GfParmListClean(params, "Robots"); char path2[256]; for (int i=0;i<(int)vecDrivers.size();i++) { sprintf(path2, "Robots/index/%d",i+1); GfParmSetStr(params, path2, "name",vecDrivers[i].name); GfParmSetStr(params, path2, "car name",vecDrivers[i].car); GfParmSetNum(params, path2, "race number", (char*)NULL,(tdble) vecDrivers[i].racenumber); GfParmSetNum(params, path2, "red", (char*)NULL, vecDrivers[i].red); GfParmSetNum(params, path2, "green", (char*)NULL, vecDrivers[i].green); GfParmSetNum(params, path2, "blue", (char*)NULL, vecDrivers[i].blue); GfParmSetStr(params, path2, "type",vecDrivers[i].type); GfParmSetStr(params, path2, "skill level",vecDrivers[i].skilllevel); GfParmSetStr(params, path2, "networkrace","yes"); if (vecDrivers[i].client) GfParmSetStr(params, path2, "client","yes"); else GfParmSetStr(params, path2, "client","no"); char hostName[256]; enet_address_get_host_ip (&vecDrivers[i].address,hostName,256); GfParmSetStr(params, path2, "host",hostName); GfParmSetNum(params, path2, "port",(char*)NULL, vecDrivers[i].address.port); } //Save our changes GfParmWriteFileLocal(buf, params, pRobotName); GfParmReleaseHandle(params); return true; }
int RePreRace(void) { tdble dist; void *params = ReInfo->params; void *results = ReInfo->results; const int BUFSIZE = 1024; char path[BUFSIZE]; const char* raceName = ReInfo->_reRaceName = ReGetCurrentRaceName(); if (!raceName) { return RM_QUIT; } dist = GfParmGetNum(params, raceName, RM_ATTR_DISTANCE, NULL, 0); if (dist < 0.001) { ReInfo->s->_totLaps = (int)GfParmGetNum(params, raceName, RM_ATTR_LAPS, NULL, 30); } else { ReInfo->s->_totLaps = ((int)(dist / ReInfo->track->length)) + 1; } ReInfo->s->_maxDammage = (int)GfParmGetNum(params, raceName, RM_ATTR_MAX_DMG, NULL, 10000); const char* raceType = GfParmGetStr(params, raceName, RM_ATTR_TYPE, RM_VAL_RACE); if (!strcmp(raceType, RM_VAL_RACE)) { ReInfo->s->_raceType = RM_TYPE_RACE; } else if (!strcmp(raceType, RM_VAL_QUALIF)) { ReInfo->s->_raceType = RM_TYPE_QUALIF; } else if (!strcmp(raceType, RM_VAL_PRACTICE)) { ReInfo->s->_raceType = RM_TYPE_PRACTICE; } ReInfo->s->_raceState = 0; /* Cleanup results */ snprintf(path, BUFSIZE, "%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, raceName); GfParmListClean(results, path); return RM_SYNC | RM_NEXT_STEP; }
/* return state mode */ int ReRaceStart(void) { char path[128]; char path2[128]; const char *sessionName = ReInfo->_reRaceName; void *params = ReInfo->params; void *results = ReInfo->results; int mode = 0; // Trace race session identification (more to say for the Carer mode). char pszSessionId[128]; if (!strcmp(GfParmGetStr(ReInfo->mainParams, RM_SECT_SUBFILES, RM_ATTR_HASSUBFILES, RM_VAL_NO), RM_VAL_YES)) { const char* pszGroup = GfParmGetStr(params, RM_SECT_HEADER, RM_ATTR_NAME, "<no group>"); snprintf(pszSessionId, sizeof(pszSessionId), "%s %s %s", ReInfo->_reName, pszGroup, sessionName); } else snprintf(pszSessionId, sizeof(pszSessionId), "%s %s", ReInfo->_reName, sessionName); GfLogInfo("Starting %s session at %s\n", pszSessionId, ReInfo->track->name); // Reallocate and reset car info for the race. FREEZ(ReInfo->_reCarInfo); ReInfo->_reCarInfo = (tReCarInfo*)calloc(GfParmGetEltNb(params, RM_SECT_DRIVERS), sizeof(tReCarInfo)); ReUI().onRaceInitializing(); // Drivers starting order int nCars = GfParmGetEltNb(params, RM_SECT_DRIVERS); GfParmListClean(params, RM_SECT_DRIVERS_RACING); if (nCars == 0) { // This may happen, when playing with the text-only mode, // and forgetting that human are automatically excluded then, // or when getting back to the GUI mode, and not reconfiguring the competitors list. GfLogError("No competitor in this race : cancelled.\n"); mode = RM_ERROR; } else if ((ReInfo->s->_raceType == RM_TYPE_QUALIF || ReInfo->s->_raceType == RM_TYPE_PRACTICE) && ReInfo->s->_totTime < 0.0f /* Timed session? */) //Checks if there is only one driver per session allowed, so practice, qualification without timed session. { // non-timed Qualification or Practice session => 1 driver at a time = the "current" one. int nCurrDrvInd = (int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_DRIVER, NULL, 1); if (nCurrDrvInd == -1) return RM_ERROR; // Propagate competitor drivers info to the real race starting grid snprintf(path, sizeof(path), "%s/%d", RM_SECT_DRIVERS, nCurrDrvInd); snprintf(path2, sizeof(path2), "%s/%d", RM_SECT_DRIVERS_RACING, 1); GfParmSetStr(params, path2, RM_ATTR_MODULE, GfParmGetStr(params, path, RM_ATTR_MODULE, "")); GfParmSetNum(params, path2, RM_ATTR_IDX, NULL, GfParmGetNum(params, path, RM_ATTR_IDX, NULL, 0)); GfParmSetNum(params, path2, RM_ATTR_EXTENDED, NULL, GfParmGetNum(params, path, RM_ATTR_EXTENDED, NULL, 0)); GfParmSetNum(params, path2, RM_ATTR_SKINTARGETS, NULL, GfParmGetNum(params, path, RM_ATTR_SKINTARGETS, NULL, 0)); if (GfParmGetStr(params, path, RM_ATTR_SKINNAME, 0)) GfParmSetStr(params, path2, RM_ATTR_SKINNAME, GfParmGetStr(params, path, RM_ATTR_SKINNAME, "")); } else { // For a race, add cars to the starting grid in the order stored in ReStartingOrderIdx. ReUI().addLoadingMessage("Preparing Starting Grid ..."); int maxCars = (int)GfParmGetNum(params, sessionName, RM_ATTR_MAX_DRV, NULL, 100); nCars = MIN(nCars, maxCars); int currDriver = -1; int aCars = 0; for (int i = 1; i < nCars + 1; i++) { currDriver = ReStartingOrderIdx[i-1]; if (currDriver == -1) continue; aCars++; snprintf(path, sizeof(path), "%s/%d", RM_SECT_DRIVERS, currDriver); snprintf(path2, sizeof(path2), "%s/%d", RM_SECT_DRIVERS_RACING, i); GfParmSetStr(params, path2, RM_ATTR_MODULE, GfParmGetStr(params, path, RE_ATTR_MODULE, "")); GfParmSetNum(params, path2, RM_ATTR_IDX, NULL, GfParmGetNum(params, path, RE_ATTR_IDX, NULL, 0)); GfParmSetNum(params, path2, RM_ATTR_EXTENDED, NULL, GfParmGetNum(params, path, RM_ATTR_EXTENDED, NULL, 0)); GfParmSetNum(params, path2, RM_ATTR_SKINTARGETS, NULL, GfParmGetNum(params, path, RM_ATTR_SKINTARGETS, NULL, 0)); if (GfParmGetStr(params, path, RM_ATTR_SKINNAME, 0)) GfParmSetStr(params, path2, RM_ATTR_SKINNAME, GfParmGetStr(params, path, RM_ATTR_SKINNAME, "")); } //no valid drivers present in the list if (aCars == 0) { GfLogError("No competitor in this race : cancelled.\n"); mode = RM_ERROR; } } //ReTrackUpdate(); if (!(mode & RM_ERROR)) { // According to what the UI answers, start the race right now or not. mode = RM_ASYNC | RM_NEXT_STEP; const bool bGoOn = ReUI().onRaceStarting(); if (bGoOn) mode = ReRaceRealStart(); } return mode; }
int RePreRace(void) { char path[128]; const char *raceName; const char *raceType; void *params = ReInfo->params; void *results = ReInfo->results; int curRaceIdx; int timedLapsReplacement = 0; char *prevRaceName; raceName = ReInfo->_reRaceName = ReGetCurrentRaceName(); GfParmRemoveVariable (params, "/", "humanInGroup"); GfParmRemoveVariable (params, "/", "eventNb"); GfParmSetVariable (params, "/", "humanInGroup", ReHumanInGroup() ? 1.0f : 0.0f); GfParmSetVariable (params, "/", "eventNb", GfParmGetNum (ReInfo->results, RE_SECT_CURRENT, RE_ATTR_CUR_TRACK, NULL, 1.0 ) ); if (!raceName) { return RM_ERROR; } if (strcmp(GfParmGetStr(params, raceName, RM_ATTR_ENABLED, RM_VAL_YES), RM_VAL_NO) == 0) { GfLogTrace( "Race %s disabled\n", raceName); curRaceIdx = (int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_RACE, NULL, 1); if (curRaceIdx < GfParmGetEltNb(params, RM_SECT_RACES)) { curRaceIdx++; GfLogTrace( "Race %s is not the last one, but the #%d\n", raceName, curRaceIdx); GfParmSetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_RACE, NULL, (tdble)curRaceIdx); return RM_SYNC | RM_NEXT_RACE; } GfParmSetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_RACE, NULL, 1); return RM_SYNC | RM_NEXT_RACE | RM_NEXT_STEP; } // Get session max dammages. ReInfo->s->_maxDammage = (int)GfParmGetNum(params, raceName, RM_ATTR_MAX_DMG, NULL, 10000); // Get session type (race, qualification or practice). raceType = GfParmGetStr(params, raceName, RM_ATTR_TYPE, RM_VAL_RACE); if (!strcmp(raceType, RM_VAL_RACE)) { ReInfo->s->_raceType = RM_TYPE_RACE; } else if (!strcmp(raceType, RM_VAL_QUALIF)) { ReInfo->s->_raceType = RM_TYPE_QUALIF; } else if (!strcmp(raceType, RM_VAL_PRACTICE)) { ReInfo->s->_raceType = RM_TYPE_PRACTICE; } // Get session duration (defaults to "All sessions" one, or else -60). ReInfo->s->_totTime = GfParmGetNum(params, raceName, RM_ATTR_SESSIONTIME, NULL, -1); if (ReInfo->s->_totTime < 0) ReInfo->s->_totTime = GfParmGetNum(params, RM_VAL_ANYRACE, RM_ATTR_SESSIONTIME, NULL, -60.0f); // Determine the actual session duration and/or number of laps. ReInfo->s->_extraLaps = 0; // TODO: Does this is ever needed ? ReInfo->s->_totLaps = 0; // Make sure it is initialized if (ReInfo->s->_totTime > 0 && !(ReInfo->s->_features & RM_FEATURE_TIMEDSESSION)) { // Timed session not supported: add 1 km for every minute in parctise or qualifying, // and 150 km for every hour (2.5 km for every minute) in race if (ReInfo->s->_raceType == RM_TYPE_RACE) { ReInfo->s->_totLaps = (int)floor(ReInfo->s->_totTime * 2500.0f / 60.0f / ReInfo->track->length + 0.5f); } else { ReInfo->s->_totLaps = (int)floor(ReInfo->s->_totTime * 1000.0f / 60.0f / ReInfo->track->length + 0.5f); } timedLapsReplacement = ReInfo->s->_totLaps; ReInfo->s->_totTime = -60.0f; } // Timed session doesn't exclude additional laps after the time finishes // Make sure that if no time set, we set far below zero if(ReInfo->s->_totTime <= 0.0f ) ReInfo->s->_totTime = -60.0f; // Get session distance (defaults to "All sessions" one, or else 0). tdble dist = GfParmGetNum(params, raceName, RM_ATTR_DISTANCE, NULL, -1); if (dist < 0) dist = GfParmGetNum(params, RM_VAL_ANYRACE, RM_ATTR_DISTANCE, NULL, 0); // If a (> 0) session distance was specified, deduce the number of laps // in case the race settings don't specify it, and it is not a timed race. if ( (dist >= 0.001) && (ReInfo->s->_totTime < 0.0f) ) { // Why not 'if (dist > 0)' ??? ReInfo->s->_totLaps = (int)(dist / ReInfo->track->length) + 1; ReInfo->s->_extraLaps = ReInfo->s->_totLaps; // Extralaps are used to find out how many laps there are after the time is up in timed sessions } else {dist = -1;} // Get the number of laps (defaults to "All sessions" one, // or else the already computed one from the session distance, or 0). int laps = (int)GfParmGetNum(params, raceName, RM_ATTR_LAPS, NULL, -1); if (laps < 0) laps = (int)GfParmGetNum(params, RM_VAL_ANYRACE, RM_ATTR_LAPS, NULL, 0); // Use lap number only when race distance is not in use. if ( (laps > 0) && (dist <= 0.0) && (timedLapsReplacement <= 0) ) { ReInfo->s->_totLaps = laps; ReInfo->s->_extraLaps = ReInfo->s->_totLaps; //Extralaps are used to find out how many laps there are after the time is up in timed sessions } // Make sure we have at least 1 lap race length. if ( (laps <= 0) && (dist <=0) && (ReInfo->s->_totTime < 0) ) { ReInfo->s->_totLaps = 1; ReInfo->s->_extraLaps = ReInfo->s->_totLaps; //Extralaps are used to find out how many laps there are after the time is up in timed sessions } // Correct extra laps (possible laps run after the winner arrived ?) : // during timed practice or qualification, there are none. if (ReInfo->s->_raceType != RM_TYPE_RACE && ReInfo->s->_totTime > 0) { ReInfo->s->_extraLaps = 0; //Extralaps are used to find out how many laps there are after the time is up in timed sessions ReInfo->s->_totLaps = 0; } GfLogInfo("Race length : time=%.0fs, laps=%d (extra=%d)\n", ReInfo->s->_totTime, ReInfo->s->_totLaps, ReInfo->s->_extraLaps); // Initialize race state. ReInfo->s->_raceState = 0; // Cleanup results snprintf(path, sizeof(path), "%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, raceName); GfParmListClean(results, path); // Drivers starting order // The starting order is decided here, // then car indexes are stored in ReStartingOrderIdx, in the starting order. // The actual grid is assembled in ReRaceStart(). // In case of a race, when all cars start at the same time, // cars are simply added to the starting list in the order stored in ReStartingOrderIdx. // If only one car is at the track at a time (not timed session qualifying or practice), // the race is divided into many sub-races. // For a sub-race, only the car pointed by results/RE_ATTR_CUR_DRIVER // is added to the starting grid. // RE_ATTR_CUR_DRIVER is refreshed after every sub-race in ReRaceEnd(). ReCurrDriverNr = 0; int nCars = GfParmGetEltNb(params, RM_SECT_DRIVERS); GfParmListClean(params, RM_SECT_DRIVERS_RACING); if (nCars == 0) { // This may happen, when playing with the text-only mode, // and forgetting that human are automatically excluded then, // or when getting back to the GUI mode, and not reconfiguring the competitors list. GfLogError("No competitor in this race : cancelled.\n"); return RM_ERROR; } else { ReUI().addLoadingMessage("Determining Starting Order ..."); const char* gridType = GfParmGetStr(params, raceName, RM_ATTR_START_ORDER, RM_VAL_DRV_LIST_ORDER); int maxCars = (int)GfParmGetNum(params, raceName, RM_ATTR_MAX_DRV, NULL, 100); nCars = MIN(nCars, maxCars); tReGridPart *GridList = NULL; int nGridList = 0; // Initialize the array of car indexes for starting order if (ReStartingOrderIdx != NULL) { delete[] ReStartingOrderIdx; ReStartingOrderIdx = NULL; } ReStartingOrderIdx = new int[nCars]; for (int i = 0; i < nCars; i++) { ReStartingOrderIdx[i] = -1; } // Starting grid in the arrival order of the previous race (or qualification session) if (!strcmp(gridType, RM_VAL_LAST_RACE_ORDER)) { GfLogTrace("Starting grid in the order of the last race\n"); prevRaceName = ReGetPrevRaceName(/* bLoop = */false); if (!prevRaceName) { return RM_ERROR; } for (int i = 1; i < nCars + 1; i++) { snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, prevRaceName, RE_SECT_RANK, i); ReStartingOrderIdx[i-1] = ReFindDriverIdx (GfParmGetStr(results, path, RE_ATTR_MODULE, ""), (int)GfParmGetNum(results, path, RE_ATTR_IDX, NULL, 0)); } } // Starting grid in the reversed arrival order of the previous race else if (!strcmp(gridType, RM_VAL_LAST_RACE_RORDER)) { GfLogTrace("Starting grid in the reverse order of the last race\n"); prevRaceName = ReGetPrevRaceName(/* bLoop = */false); if (!prevRaceName) { return RM_ERROR; } for (int i = 1; i < nCars + 1; i++) { snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, prevRaceName, RE_SECT_RANK, nCars - i + 1); ReStartingOrderIdx[i-1] = ReFindDriverIdx (GfParmGetStr(results, path, RE_ATTR_MODULE, ""), (int)GfParmGetNum(results, path, RE_ATTR_IDX, NULL, 0)); } } // Starting grid as a mix from the results of earlier sessions else if (ReParseStartingOrder(gridType, &GridList, nCars, nGridList)) { GfLogTrace("Starting grid as a mix from the results of earlier sessions\n"); int idx; int gridpos = 1; int carnr; const char *modulename; for (int i = 0; i < nGridList; i++) { if (gridpos > nCars) {break;} if (GridList[i].diffpos == -1) {//reversed for ( int j = GridList[i].startpos; j >= GridList[i].endpos; j--) { if (gridpos > nCars) {break;} snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, GridList[i].racename, RE_SECT_RANK, j); idx = (int)GfParmGetNum(results, path, RE_ATTR_IDX, NULL, 0); modulename = GfParmGetStr(results, path, RE_ATTR_MODULE, ""); carnr = ReFindDriverIdx(modulename, idx); for (int k = 0; k < gridpos-1; k++) { if ( carnr == ReStartingOrderIdx[k] ) { //oops: same car twice GfLogWarning("The same car appears twice in the advanced grid!\n"); carnr = -1; break; } } //adding car to the list if (carnr != -1) { ReStartingOrderIdx[gridpos-1] = carnr; gridpos++; } } } else if (GridList[i].diffpos == 1){//straight order for ( int j = GridList[i].startpos; j <= GridList[i].endpos; j++) { if (gridpos > nCars) {break;} snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, GridList[i].racename, RE_SECT_RANK, j); idx = (int)GfParmGetNum(results, path, RE_ATTR_IDX, NULL, 0); modulename = GfParmGetStr(results, path, RE_ATTR_MODULE, ""); carnr = ReFindDriverIdx(modulename, idx); for (int k = 0; k < gridpos-1; k++) { if ( carnr == ReStartingOrderIdx[k] ) { //oops: same car twice GfLogWarning("The same car appears twice in the advanced grid!\n"); carnr = -1; break; } } //adding car to the list if (carnr != -1) { ReStartingOrderIdx[gridpos-1] = carnr; gridpos++; } } } } //cleaning up memory if (nGridList > 0){delete[] GridList;} } // Starting grid in the drivers list order else { GfLogTrace("Starting grid in the order of the driver list\n"); for (int i = 1; i < nCars + 1; i++) { snprintf(path, sizeof(path), "%s/%d", RM_SECT_DRIVERS, i); ReStartingOrderIdx[i-1] = ReFindDriverIdx (GfParmGetStr(params, path, RE_ATTR_MODULE, ""), (int)GfParmGetNum(params, path, RE_ATTR_IDX, NULL, 0)); } } } ReCurrDriverNr = 0; GfParmSetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_DRIVER, NULL, (tdble)ReStartingOrderIdx[ReCurrDriverNr]); return RM_SYNC | RM_NEXT_STEP; }
int ReRaceEventShutdown(void) { char buf[64]; int curTrkIdx; void *params = ReInfo->params; int nbTrk; void *results = ReInfo->results; int curRaceIdx; bool careerMode = false; bool first = true; // Notify the UI that the race event is finishing now. ReUI().onRaceEventFinishing(); // Shutdown track-physics-related stuff. ReTrackShutdown(); // Determine the track of the next event to come, if not the last one // and, if Career mode, prepare race params / results for the next event or season. do { nbTrk = GfParmGetEltNb(params, RM_SECT_TRACKS); curRaceIdx =(int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_RACE, NULL, 1); curTrkIdx = (int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_TRACK, NULL, 1); if (curRaceIdx == 1) { if (curTrkIdx < nbTrk) { // Next track. curTrkIdx++; } else if (curTrkIdx >= nbTrk) { // Back to the beginning. curTrkIdx = 1; } } GfParmSetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_TRACK, NULL, (tdble)curTrkIdx); // Career mode. if (!strcmp(GfParmGetStr(ReInfo->mainParams, RM_SECT_SUBFILES, RM_ATTR_HASSUBFILES, RM_VAL_NO), RM_VAL_YES)) { careerMode = true; const bool lastRaceOfRound = strcmp(GfParmGetStr(params, RM_SECT_SUBFILES, RM_ATTR_LASTSUBFILE, RM_VAL_YES), RM_VAL_YES) == 0; // Previous file <= Current file. GfParmSetStr(ReInfo->mainResults, RE_SECT_CURRENT, RE_ATTR_PREV_FILE, GfParmGetStr(ReInfo->mainResults, RE_SECT_CURRENT, RE_ATTR_CUR_FILE, "")); // Current file <= Next file. GfParmSetStr(ReInfo->mainResults, RE_SECT_CURRENT, RE_ATTR_CUR_FILE, GfParmGetStr(params, RM_SECT_SUBFILES, RM_ATTR_NEXTSUBFILE, "")); GfParmWriteFile(NULL, ReInfo->mainResults, NULL); /* Check if the next competition has a free weekend */ if( !first ) { /* Close old params */ GfParmWriteFile( NULL, results, NULL ); GfParmReleaseHandle( results ); GfParmReleaseHandle( params ); }//if !first /* Open params of next race */ params = GfParmReadFile( GfParmGetStr(ReInfo->mainResults, RE_SECT_CURRENT, RE_ATTR_CUR_FILE, "" ), GFPARM_RMODE_STD ); if( !params ) break; results = GfParmReadFile( GfParmGetStr(params, RM_SECT_SUBFILES, RM_ATTR_RESULTSUBFILE, ""), GFPARM_RMODE_STD ); if( !results ) { GfParmReleaseHandle( results ); break; } if (lastRaceOfRound && curTrkIdx == 1) { ReCareerNextSeason(); } if ((int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_TRACK, NULL, 1) == 1) { GfParmListClean(results, RE_SECT_STANDINGS); GfParmWriteFile(NULL, results, NULL); } /* Check if it is free */ snprintf( buf, sizeof(buf), "%s/%d", RM_SECT_TRACKS, (int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_TRACK, NULL, 1) ); if( !strcmp(GfParmGetStr(params, buf, RM_ATTR_NAME, "free"), "free") == 0) { /* Not a free weekend */ GfParmReleaseHandle( results ); GfParmReleaseHandle( params ); break; } first = false; } else { // Normal mode (no subfiles, so free weekends possible, so nothing to check) break; } } while( true ); // Determine new race state automaton mode. int mode = (curTrkIdx != 1 || careerMode) ? RM_NEXT_RACE : RM_NEXT_STEP; bool careerNonHumanGroup = careerMode && !ReHumanInGroup(); mode |= ReUI().onRaceEventFinished(nbTrk != 1, careerNonHumanGroup) ? RM_SYNC : RM_ASYNC;; if (mode & RM_NEXT_STEP) FREEZ(ReInfo->_reCarInfo); return mode; }
void ReUpdateStandings(void) { int maxDrv; int curDrv; int runDrv; char *modName; int drvIdx; int points; int i, j; int found; tReStandings *standings = 0; void *results = ReInfo->results; const int BUFSIZE = 1024; char str1[BUFSIZE], str2[BUFSIZE], path[BUFSIZE], path2[BUFSIZE]; snprintf(path, BUFSIZE, "%s/%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, ReInfo->_reRaceName, RE_SECT_RANK); runDrv = GfParmGetEltNb(results, path); curDrv = GfParmGetEltNb(results, RE_SECT_STANDINGS); maxDrv = curDrv + runDrv; standings = (tReStandings *)calloc(maxDrv, sizeof(tReStandings)); /* Read the current standings */ for (i = 0; i < curDrv; i++) { snprintf(path2, BUFSIZE, "%s/%d", RE_SECT_STANDINGS, i + 1); standings[i].carName = strdup(GfParmGetStr(results, path2, RE_ATTR_NAME, 0)); standings[i].modName = strdup(GfParmGetStr(results, path2, RE_ATTR_MODULE, 0)); standings[i].drvIdx = (int)GfParmGetNum(results, path2, RE_ATTR_IDX, NULL, 0); standings[i].points = (int)GfParmGetNum(results, path2, RE_ATTR_POINTS, NULL, 0); } GfParmListClean(results, RE_SECT_STANDINGS); for (i = 0; i < runDrv; i++) { /* Search the driver in the standings */ found = 0; snprintf(path, BUFSIZE, "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, ReInfo->_reRaceName, RE_SECT_RANK, i + 1); const char* carName = GfParmGetStr(results, path, RE_ATTR_NAME, 0); for (j = 0; j < curDrv; j++) { if (!strcmp(carName, standings[j].carName)) { found = 1; break; } } if (!found) { /* Add the new driver */ curDrv++; standings[j].carName = strdup(carName); standings[j].modName = strdup(GfParmGetStr(results, path, RE_ATTR_MODULE, 0)); standings[j].drvIdx = (int)GfParmGetNum(results, path, RE_ATTR_IDX, NULL, 0); standings[j].points = (int)GfParmGetNum(results, path, RE_ATTR_POINTS, NULL, 0); } else { /* Add the new points */ standings[j].points += (int)GfParmGetNum(results, path, RE_ATTR_POINTS, NULL, 0); } /* bubble sort... */ while (j > 0) { if (standings[j - 1].points >= standings[j].points) { break; } /* Swap with preceeding */ carName = standings[j].carName; modName = standings[j].modName; drvIdx = standings[j].drvIdx; points = standings[j].points; standings[j].carName = standings[j - 1].carName; standings[j].modName = standings[j - 1].modName; standings[j].drvIdx = standings[j - 1].drvIdx; standings[j].points = standings[j - 1].points; standings[j - 1].carName = carName; standings[j - 1].modName = modName; standings[j - 1].drvIdx = drvIdx; standings[j - 1].points = points; j--; } } /* Store the standing back */ for (i = 0; i < curDrv; i++) { snprintf(path, BUFSIZE, "%s/%d", RE_SECT_STANDINGS, i + 1); GfParmSetStr(results, path, RE_ATTR_NAME, standings[i].carName); //free(standings[i].carName); GfParmSetStr(results, path, RE_ATTR_MODULE, standings[i].modName); free(standings[i].modName); GfParmSetNum(results, path, RE_ATTR_IDX, NULL, standings[i].drvIdx); GfParmSetNum(results, path, RE_ATTR_POINTS, NULL, standings[i].points); } free(standings); snprintf(str1, BUFSIZE, "%sconfig/params.dtd", GetDataDir()); snprintf(str2, BUFSIZE, "<?xml-stylesheet type=\"text/xsl\" href=\"file:///%sconfig/style.xsl\"?>", GetDataDir()); GfParmSetDTD (results, str1, str2); GfParmWriteFile(0, results, "Results"); }
void ReStoreRaceResults(const char *race) { int i; int nCars; tCarElt *car; tSituation *s = ReInfo->s; char *carName; void *carparam; void *results = ReInfo->results; void *params = ReInfo->params; const int BUFSIZE = 1024; char buf[BUFSIZE], path[BUFSIZE], path2[BUFSIZE]; /* Store the number of laps of the race */ switch (ReInfo->s->_raceType) { case RM_TYPE_RACE: car = s->cars[0]; if (car->_laps > s->_totLaps) car->_laps = s->_totLaps + 1; snprintf(path, BUFSIZE, "%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race); GfParmListClean(results, path); GfParmSetNum(results, path, RE_ATTR_LAPS, NULL, car->_laps - 1); for (i = 0; i < s->_ncars; i++) { snprintf(path, BUFSIZE, "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1); car = s->cars[i]; if (car->_laps > s->_totLaps) car->_laps = s->_totLaps + 1; GfParmSetStr(results, path, RE_ATTR_NAME, car->_name); snprintf(buf, BUFSIZE, "cars/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = GfParmGetName(carparam); GfParmSetStr(results, path, RE_ATTR_CAR, carName); GfParmSetNum(results, path, RE_ATTR_INDEX, NULL, car->index); GfParmSetNum(results, path, RE_ATTR_LAPS, NULL, car->_laps - 1); GfParmSetNum(results, path, RE_ATTR_TIME, NULL, car->_curTime); GfParmSetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, car->_bestLapTime); GfParmSetNum(results, path, RE_ATTR_TOP_SPEED, NULL, car->_topSpeed); GfParmSetNum(results, path, RE_ATTR_DAMMAGES, NULL, car->_dammage); GfParmSetNum(results, path, RE_ATTR_NB_PIT_STOPS, NULL, car->_nbPitStops); GfParmSetStr(results, path, RE_ATTR_MODULE, car->_modName); GfParmSetNum(results, path, RE_ATTR_IDX, NULL, car->_driverIndex); snprintf(path2, BUFSIZE, "%s/%s/%d", race, RM_SECT_POINTS, i + 1); GfParmSetNum(results, path, RE_ATTR_POINTS, NULL, (int)GfParmGetNum(params, path2, RE_ATTR_POINTS, NULL, 0)); GfParmReleaseHandle(carparam); } break; case RM_TYPE_PRACTICE: car = s->cars[0]; snprintf(path, BUFSIZE, "%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race); GfParmSetStr(results, path, RM_ATTR_DRVNAME, car->_name); break; case RM_TYPE_QUALIF: car = s->cars[0]; snprintf(path, BUFSIZE, "%s/%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK); nCars = GfParmGetEltNb(results, path); for (i = nCars; i > 0; i--) { snprintf(path, BUFSIZE, "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i); float opponentBestLapTime = GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0); if ( (car->_bestLapTime != 0.0) && ((car->_bestLapTime < opponentBestLapTime) || (opponentBestLapTime == 0.0)) ) { /* shift */ snprintf(path2, BUFSIZE, "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1); GfParmSetStr(results, path2, RE_ATTR_NAME, GfParmGetStr(results, path, RE_ATTR_NAME, "")); GfParmSetStr(results, path2, RE_ATTR_CAR, GfParmGetStr(results, path, RE_ATTR_CAR, "")); GfParmSetNum(results, path2, RE_ATTR_BEST_LAP_TIME, NULL, GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0)); GfParmSetStr(results, path2, RE_ATTR_MODULE, GfParmGetStr(results, path, RM_ATTR_MODULE, "")); GfParmSetNum(results, path2, RE_ATTR_IDX, NULL, GfParmGetNum(results, path, RM_ATTR_IDX, NULL, 0)); snprintf(path, BUFSIZE, "%s/%s/%d", race, RM_SECT_POINTS, i + 1); GfParmSetNum(results, path2, RE_ATTR_POINTS, NULL, (int)GfParmGetNum(params, path, RE_ATTR_POINTS, NULL, 0)); } else { break; } } /* insert after */ snprintf(path, BUFSIZE, "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1); GfParmSetStr(results, path, RE_ATTR_NAME, car->_name); snprintf(buf, BUFSIZE, "cars/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = GfParmGetName(carparam); GfParmSetStr(results, path, RE_ATTR_CAR, carName); GfParmSetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, car->_bestLapTime); GfParmSetStr(results, path, RE_ATTR_MODULE, car->_modName); GfParmSetNum(results, path, RE_ATTR_IDX, NULL, car->_driverIndex); snprintf(path2, BUFSIZE, "%s/%s/%d", race, RM_SECT_POINTS, i + 1); GfParmSetNum(results, path, RE_ATTR_POINTS, NULL, (int)GfParmGetNum(params, path2, RE_ATTR_POINTS, NULL, 0)); GfParmReleaseHandle(carparam); break; } }
void ReStoreRaceResults(const char *race) { int i; int nCars; tCarElt *car; tSituation *s = ReInfo->s; char *carName; void *carparam; void *results = ReInfo->results; void *params = ReInfo->params; /* Store the number of laps of the race */ switch (ReInfo->s->_raceType) { case RM_TYPE_RACE: car = s->cars[0]; if (car->_laps > s->_totLaps) car->_laps = s->_totLaps + 1; snprintf(path, sizeof(path), "%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race); GfParmListClean(results, path); GfParmSetNum(results, path, RE_ATTR_LAPS, NULL, (tdble)(car->_laps - 1)); for (i = 0; i < s->_ncars; i++) { snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1); car = s->cars[i]; if (car->_laps > s->_totLaps) car->_laps = s->_totLaps + 1; GfParmSetStr(results, path, RE_ATTR_NAME, car->_name); snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = GfParmGetName(carparam); GfParmSetStr(results, path, RE_ATTR_CAR, carName); GfParmSetNum(results, path, RE_ATTR_INDEX, NULL, (tdble)car->index); GfParmSetNum(results, path, RE_ATTR_LAPS, NULL, (tdble)(car->_laps - 1)); GfParmSetNum(results, path, RE_ATTR_TIME, NULL, (tdble)car->_curTime); GfParmSetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, (tdble)car->_bestLapTime); GfParmSetNum(results, path, RE_ATTR_TOP_SPEED, NULL, car->_topSpeed); GfParmSetNum(results, path, RE_ATTR_DAMMAGES, NULL, (tdble)car->_dammage); GfParmSetNum(results, path, RE_ATTR_NB_PIT_STOPS, NULL, (tdble)car->_nbPitStops); GfParmSetStr(results, path, RE_ATTR_MODULE, car->_modName); GfParmSetNum(results, path, RE_ATTR_IDX, NULL, (tdble)car->_moduleIndex); snprintf(path2, sizeof(path2), "%s/%d", RM_SECT_DRIVERS_RACING, car->index + 1 ); GfParmSetNum(results, path, RM_ATTR_EXTENDED, NULL, GfParmGetNum(params, path2, RM_ATTR_EXTENDED, NULL, 0)); GfParmSetStr(results, path, ROB_ATTR_CAR, car->_carName); snprintf(path2, sizeof(path2), "%s/%s/%d", race, RM_SECT_POINTS, i + 1); GfParmSetNum(results, path, RE_ATTR_POINTS, NULL, GfParmGetNum(params, path2, RE_ATTR_POINTS, NULL, 0)); if (strlen(car->_skinName) > 0) GfParmSetStr(results, path, RM_ATTR_SKINNAME, car->_skinName); GfParmSetNum(results, path, RM_ATTR_SKINTARGETS, NULL, (tdble)car->_skinTargets); GfParmReleaseHandle(carparam); } break; case RM_TYPE_PRACTICE: if (s->_ncars == 1) { car = s->cars[0]; snprintf(path, sizeof(path), "%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race); GfParmSetStr(results, path, RM_ATTR_DRVNAME, car->_name); snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = GfParmGetName(carparam); GfParmSetStr(results, path, RE_ATTR_CAR, carName); GfParmReleaseHandle(carparam); break; } /* Otherwise, fall through */ case RM_TYPE_QUALIF: if (s->_ncars == 1) { car = s->cars[0]; snprintf(path, sizeof(path), "%s/%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK); nCars = GfParmGetEltNb(results, path); for (i = nCars; i > 0; i--) { snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i); float opponentBestLapTime = GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0); if (car->_bestLapTime != 0.0 && (car->_bestLapTime < opponentBestLapTime || opponentBestLapTime == 0.0)) { /* shift */ snprintf(path2, sizeof(path2), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1); GfParmSetStr(results, path2, RE_ATTR_NAME, GfParmGetStr(results, path, RE_ATTR_NAME, "")); GfParmSetStr(results, path2, RE_ATTR_CAR, GfParmGetStr(results, path, RE_ATTR_CAR, "")); GfParmSetNum(results, path2, RE_ATTR_BEST_LAP_TIME, NULL, GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0)); GfParmSetStr(results, path2, RE_ATTR_MODULE, GfParmGetStr(results, path, RM_ATTR_MODULE, "")); GfParmSetNum(results, path2, RE_ATTR_IDX, NULL, GfParmGetNum(results, path, RM_ATTR_IDX, NULL, 0)); GfParmSetNum(results, path2, RM_ATTR_EXTENDED, NULL, GfParmGetNum(results, path, RM_ATTR_EXTENDED, NULL, 0)); GfParmSetStr(results, path2, ROB_ATTR_CAR, GfParmGetStr(results, path, ROB_ATTR_CAR, "")); GfParmSetStr(results, path2, ROB_ATTR_NAME, GfParmGetStr(results, path, ROB_ATTR_NAME, "")); snprintf(path, sizeof(path), "%s/%s/%d", race, RM_SECT_POINTS, i + 1); GfParmSetNum(results, path2, RE_ATTR_POINTS, NULL, GfParmGetNum(params, path, RE_ATTR_POINTS, NULL, 0)); if (GfParmGetStr(results, path, RM_ATTR_SKINNAME, 0)) GfParmSetStr(results, path2, RM_ATTR_SKINNAME, GfParmGetStr(results, path, RM_ATTR_SKINNAME, 0)); GfParmSetNum(results, path2, RM_ATTR_SKINTARGETS, NULL, GfParmGetNum(results, path, RM_ATTR_SKINTARGETS, NULL, 0)); } else { break; } } /* insert after */ snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1); GfParmSetStr(results, path, RE_ATTR_NAME, car->_name); snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = GfParmGetName(carparam); GfParmSetStr(results, path, RE_ATTR_CAR, carName); GfParmSetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, (tdble)car->_bestLapTime); GfParmSetStr(results, path, RE_ATTR_MODULE, car->_modName); GfParmSetNum(results, path, RE_ATTR_IDX, NULL, (tdble)car->_moduleIndex); GfParmSetStr(results, path, ROB_ATTR_CAR, car->_carName); GfParmSetStr(results, path, ROB_ATTR_NAME, car->_name); snprintf(path2, sizeof(path2), "%s/%d", RM_SECT_DRIVERS_RACING, car->index + 1 ); GfParmSetNum(results, path, RM_ATTR_EXTENDED, NULL, GfParmGetNum(params, path2, RM_ATTR_EXTENDED, NULL, 0)); snprintf(path2, sizeof(path2), "%s/%s/%d", race, RM_SECT_POINTS, i + 1); GfParmSetNum(results, path, RE_ATTR_POINTS, NULL, GfParmGetNum(params, path2, RE_ATTR_POINTS, NULL, 0)); if (strlen(car->_skinName) > 0) GfParmSetStr(results, path, RM_ATTR_SKINNAME, car->_skinName); GfParmSetNum(results, path, RM_ATTR_SKINTARGETS, NULL, (tdble)car->_skinTargets); GfParmReleaseHandle(carparam); break; } else { car = s->cars[0]; if (s->_totTime < 0.0f) GfLogWarning("Saving results of multicar non-race session, but it was not timed!\n" ); snprintf(path, sizeof(path), "%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race); GfParmListClean(results, path); GfParmSetNum(results, path, RE_ATTR_SESSIONTIME, NULL, (tdble)s->_totTime); for (i = 0; i < s->_ncars; i++) { snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1); car = s->cars[i]; GfParmSetStr(results, path, RE_ATTR_NAME, car->_name); snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = GfParmGetName(carparam); GfParmSetStr(results, path, RE_ATTR_CAR, carName); GfParmSetNum(results, path, RE_ATTR_INDEX, NULL, (tdble)car->index); GfParmSetNum(results, path, RE_ATTR_LAPS, NULL, (tdble)(car->_laps - 1)); GfParmSetNum(results, path, RE_ATTR_TIME, NULL, (tdble)car->_curTime); GfParmSetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, (tdble)car->_bestLapTime); GfParmSetNum(results, path, RE_ATTR_TOP_SPEED, NULL, car->_topSpeed); GfParmSetNum(results, path, RE_ATTR_DAMMAGES, NULL, (tdble)car->_dammage); GfParmSetNum(results, path, RE_ATTR_NB_PIT_STOPS, NULL, (tdble)car->_nbPitStops); GfParmSetStr(results, path, RE_ATTR_MODULE, car->_modName); GfParmSetNum(results, path, RE_ATTR_IDX, NULL, (tdble)car->_moduleIndex); snprintf(path2, sizeof(path2), "%s/%d", RM_SECT_DRIVERS_RACING, car->index + 1 ); GfParmSetNum(results, path, RM_ATTR_EXTENDED, NULL, GfParmGetNum(params, path2, RM_ATTR_EXTENDED, NULL, 0)); GfParmSetStr(results, path, ROB_ATTR_CAR, car->_carName); snprintf(path2, sizeof(path2), "%s/%s/%d", race, RM_SECT_POINTS, i + 1); GfParmSetNum(results, path, RE_ATTR_POINTS, NULL, GfParmGetNum(params, path2, RE_ATTR_POINTS, NULL, 0)); if (strlen(car->_skinName) > 0) GfParmSetStr(results, path, RM_ATTR_SKINNAME, car->_skinName); GfParmSetNum(results, path, RM_ATTR_SKINTARGETS, NULL, (tdble)car->_skinTargets); GfParmReleaseHandle(carparam); } break; } } }
void ReUpdateStandings(void) { tReStandings st; std::string drvName; std::vector<tReStandings> *standings; std::vector<tReStandings>::iterator found; std::vector<tReStandings>::iterator it; int runDrv, curDrv; int i; void *results = ReInfo->results; snprintf(path, sizeof(path), "%s/%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, ReInfo->_reRaceName, RE_SECT_RANK); runDrv = GfParmGetEltNb(results, path); curDrv = GfParmGetEltNb(results, RE_SECT_STANDINGS); standings = new std::vector<tReStandings>; standings->reserve(curDrv); /* Read the current standings */ for (i = 0; i < curDrv; i++) { snprintf(path2, sizeof(path2), "%s/%d", RE_SECT_STANDINGS, i + 1); st.drvName = GfParmGetStr(results, path2, RE_ATTR_NAME, 0); st.modName = GfParmGetStr(results, path2, RE_ATTR_MODULE, 0); st.carName = GfParmGetStr(results, path2, RE_ATTR_CAR, 0); st.extended = (int)GfParmGetNum(results, path2, RM_ATTR_EXTENDED, NULL, 0); st.drvIdx = (int)GfParmGetNum(results, path2, RE_ATTR_IDX, NULL, 0); st.points = (int)GfParmGetNum(results, path2, RE_ATTR_POINTS, NULL, 0); standings->push_back(st); }//for i //Void the stored results GfParmListClean(results, RE_SECT_STANDINGS); //Check last races' drivers and search their name in the results. //If found there, adds recent points. //If not found, adds the driver for (i = 0; i < runDrv; i++) { //Search the driver name in the standings snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, ReInfo->_reRaceName, RE_SECT_RANK, i + 1); drvName = GfParmGetStr(results, path, RE_ATTR_NAME, 0); found = std::find(standings->begin(), standings->end(), drvName); if(found == standings->end()) { //No such driver in the standings, let's add it st.drvName = drvName; st.modName = GfParmGetStr(results, path, RE_ATTR_MODULE, 0); st.carName = GfParmGetStr(results, path, RE_ATTR_CAR, 0); st.extended = (int)GfParmGetNum(results, path, RM_ATTR_EXTENDED, NULL, 0); st.drvIdx = (int)GfParmGetNum(results, path, RE_ATTR_IDX, NULL, 0); st.points = (int)GfParmGetNum(results, path, RE_ATTR_POINTS, NULL, 0); standings->push_back(st); } else { //Driver found, add recent points found->points += (int)GfParmGetNum(results, path, RE_ATTR_POINTS, NULL, 0); }//if found }//for i //sort standings by score std::sort(standings->begin(), standings->end(), sortByScore); //Store the standing back for(it = standings->begin(), i = 0; it != standings->end(); ++it, ++i) { snprintf(path, sizeof(path), "%s/%d", RE_SECT_STANDINGS, i + 1); GfParmSetStr(results, path, RE_ATTR_NAME, it->drvName.c_str()); GfParmSetStr(results, path, RE_ATTR_MODULE, it->modName.c_str()); GfParmSetStr(results, path, RE_ATTR_CAR, it->carName.c_str()); GfParmSetNum(results, path, RE_ATTR_IDX, NULL, (tdble)it->drvIdx); GfParmSetNum(results, path, RE_ATTR_POINTS, NULL, (tdble)it->points); }//for it delete standings; char str1[512], str2[512]; snprintf(str1, sizeof(str1), "%sconfig/params.dtd", GfDataDir()); snprintf(str2, sizeof(str2), "<?xml-stylesheet type=\"text/xsl\" href=\"file:///%sconfig/raceresults.xsl\"?>", GfDataDir()); GfParmSetDTD (results, str1, str2); GfParmWriteFile(0, results, "Results"); }//ReUpdateStandings
/* return state mode */ int ReRaceStart(void) { int i; int nCars; int maxCars; const char *raceName = ReInfo->_reRaceName; void *params = ReInfo->params; void *results = ReInfo->results; const int BUFSIZE = 1024; char path[BUFSIZE], path2[BUFSIZE]; FREEZ(ReInfo->_reCarInfo); ReInfo->_reCarInfo = (tReCarInfo*)calloc(GfParmGetEltNb(params, RM_SECT_DRIVERS), sizeof(tReCarInfo)); /* Drivers starting order */ GfParmListClean(params, RM_SECT_DRIVERS_RACING); if (ReInfo->s->_raceType == RM_TYPE_QUALIF) { i = (int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_DRIVER, NULL, 1); if (i == 1) { RmLoadingScreenStart(ReInfo->_reName, "data/img/splash-qrloading.png"); RmLoadingScreenSetText("Preparing Starting Grid..."); } else { RmShutdownLoadingScreen(); } snprintf(path, BUFSIZE, "%s/%d", RM_SECT_DRIVERS, i); snprintf(path2, BUFSIZE, "%s/%d", RM_SECT_DRIVERS_RACING, 1); GfParmSetStr(params, path2, RM_ATTR_MODULE, GfParmGetStr(params, path, RM_ATTR_MODULE, "")); GfParmSetNum(params, path2, RM_ATTR_IDX, NULL, GfParmGetNum(params, path, RM_ATTR_IDX, NULL, 0)); } else { RmLoadingScreenStart(ReInfo->_reName, "data/img/splash-qrloading.png"); RmLoadingScreenSetText("Preparing Starting Grid..."); const char* gridType = GfParmGetStr(params, raceName, RM_ATTR_START_ORDER, RM_VAL_DRV_LIST_ORDER); if (!strcmp(gridType, RM_VAL_LAST_RACE_ORDER)) { /* Starting grid in the arrival of the previous race */ nCars = GfParmGetEltNb(params, RM_SECT_DRIVERS); maxCars = (int)GfParmGetNum(params, raceName, RM_ATTR_MAX_DRV, NULL, 100); nCars = MIN(nCars, maxCars); const char* prevRaceName = ReGetPrevRaceName(); if (!prevRaceName) { return RM_QUIT; } for (i = 1; i < nCars + 1; i++) { snprintf(path, BUFSIZE, "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, prevRaceName, RE_SECT_RANK, i); snprintf(path2, BUFSIZE, "%s/%d", RM_SECT_DRIVERS_RACING, i); GfParmSetStr(params, path2, RM_ATTR_MODULE, GfParmGetStr(results, path, RE_ATTR_MODULE, "")); GfParmSetNum(params, path2, RM_ATTR_IDX, NULL, GfParmGetNum(results, path, RE_ATTR_IDX, NULL, 0)); } } else if (!strcmp(gridType, RM_VAL_LAST_RACE_RORDER)) { /* Starting grid in the reversed arrival order of the previous race */ nCars = GfParmGetEltNb(params, RM_SECT_DRIVERS); maxCars = (int)GfParmGetNum(params, raceName, RM_ATTR_MAX_DRV, NULL, 100); nCars = MIN(nCars, maxCars); const char* prevRaceName = ReGetPrevRaceName(); if (!prevRaceName) { return RM_QUIT; } for (i = 1; i < nCars + 1; i++) { snprintf(path, BUFSIZE, "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, prevRaceName, RE_SECT_RANK, nCars - i + 1); snprintf(path2, BUFSIZE, "%s/%d", RM_SECT_DRIVERS_RACING, i); GfParmSetStr(params, path2, RM_ATTR_MODULE, GfParmGetStr(results, path, RE_ATTR_MODULE, "")); GfParmSetNum(params, path2, RM_ATTR_IDX, NULL, GfParmGetNum(results, path, RE_ATTR_IDX, NULL, 0)); } } else { /* Starting grid in the drivers list order */ nCars = GfParmGetEltNb(params, RM_SECT_DRIVERS); maxCars = (int)GfParmGetNum(params, raceName, RM_ATTR_MAX_DRV, NULL, 100); nCars = MIN(nCars, maxCars); for (i = 1; i < nCars + 1; i++) { snprintf(path, BUFSIZE, "%s/%d", RM_SECT_DRIVERS, i); snprintf(path2, BUFSIZE, "%s/%d", RM_SECT_DRIVERS_RACING, i); GfParmSetStr(params, path2, RM_ATTR_MODULE, GfParmGetStr(params, path, RM_ATTR_MODULE, "")); GfParmSetNum(params, path2, RM_ATTR_IDX, NULL, GfParmGetNum(params, path, RM_ATTR_IDX, NULL, 0)); } } } if (ReInfo->_displayMode != RM_DISP_MODE_CONSOLE) { if (!strcmp(GfParmGetStr(params, ReInfo->_reRaceName, RM_ATTR_SPLASH_MENU, RM_VAL_NO), RM_VAL_YES)) { RmShutdownLoadingScreen(); RmDisplayStartRace(ReInfo, StartRaceHookInit(), AbandonRaceHookInit()); return RM_ASYNC | RM_NEXT_STEP; } } return reRaceRealStart(); }