void CASW_Campaign_Save::UpdateLastCommanders() { // save which marines the players have selected // add which marines he has selected CASW_Game_Resource *pGameResource = ASWGameResource(); if ( !pGameResource ) return; // first check there were some marines selected (i.e. we're not in the campaign lobby map) int iNumMarineResources = 0; for (int i=0;i<pGameResource->GetMaxMarineResources();i++) { if (pGameResource->GetMarineResource(i)) iNumMarineResources++; } if ( iNumMarineResources <= 0 ) return; char buffer[256]; for (int i=0;i<ASW_NUM_MARINE_PROFILES;i++) { // look for a marine info for this marine bool bFound = false; for (int k=0;k<pGameResource->GetMaxMarineResources();k++) { CASW_Marine_Resource *pMR = pGameResource->GetMarineResource(k); if (pMR && pMR->GetProfileIndex() == i && pMR->GetCommander()) { CASW_Player *pPlayer = pMR->GetCommander(); if (pPlayer) { // store the commander who has this marine Q_snprintf(buffer, sizeof(buffer), "%s%s",pPlayer->GetPlayerName(), pPlayer->GetASWNetworkID()); m_LastCommanders[i] = AllocPooledString(buffer); m_LastMarineResourceSlot[i] = k; m_LastPrimaryMarines[i] = pPlayer->IsPrimaryMarine(i); bFound = true; break; } } } if (!bFound) { m_LastCommanders[i] = AllocPooledString(""); m_LastMarineResourceSlot[i] = 0; } } }
// saves current save data to a keyvalues file bool CASW_Campaign_Save::SaveGameToFile(const char *szFileName) { // make sure the path and extension are correct char szFullFileName[256]; char tempbuffer[256]; if (szFileName==NULL) { if (m_CurrentSaveFileName == NULL_STRING) { Msg("Error: Couldn't save game to file as we have no name already and you didn't supply one.\n"); return false; } Q_snprintf(szFullFileName, sizeof(szFullFileName), "%s", STRING(m_CurrentSaveFileName)); } else { Q_snprintf(tempbuffer, sizeof(tempbuffer), "%s", szFileName); Q_SetExtension( tempbuffer, ".campaignsave", sizeof(tempbuffer) ); const char *pszNoPathName = Q_UnqualifiedFileName(tempbuffer); Q_snprintf(szFullFileName, sizeof(szFullFileName), "save/%s", pszNoPathName); } // before saving, check if this is actually a completed campaign if (ASWGameRules()) { int iLeft = ASWGameRules()->CampaignMissionsLeft(); if (iLeft <= 0) { Msg("Deleting completed campaign %s", szFullFileName); filesystem->RemoveFile( szFullFileName, "GAME" ); // notify the local mission source that a save has been deleted if (missionchooser && missionchooser->LocalMissionSource()) { const char *pszNoPathName = Q_UnqualifiedFileName(szFullFileName); missionchooser->LocalMissionSource()->NotifySaveDeleted(pszNoPathName); } return true; } } // we don't want completed campaigns lingering on disk KeyValues *pSaveKeyValues = new KeyValues( "CAMPAIGNSAVE" ); pSaveKeyValues->SetInt("Version", m_iVersion); pSaveKeyValues->SetInt("SkillLevel", m_iLowestSkillLevelPlayed); pSaveKeyValues->SetString("CampaignName", m_CampaignName.Get()); pSaveKeyValues->SetInt("CurrentPosition", m_iCurrentPosition); pSaveKeyValues->SetInt("NumMissionsComplete", m_iNumMissionsComplete); pSaveKeyValues->SetInt("InitialNumMissionsComplete", m_iInitialNumMissionsComplete); pSaveKeyValues->SetInt("Multiplayer", m_bMultiplayerGame ? 1 : 0); pSaveKeyValues->SetInt( "NumDeaths", m_iNumDeaths ); pSaveKeyValues->SetBool( "FixedSkillPoints", m_bFixedSkillPoints ); // update date int year, month, dayOfWeek, day, hour, minute, second; missionchooser->GetCurrentTimeAndDate(&year, &month, &dayOfWeek, &day, &hour, &minute, &second); //year = month = dayOfWeek = day = hour = minute = second = 0; Q_snprintf(m_DateTime.GetForModify(), 255, "%02d/%02d/%d %02d:%02d", month, day, year, hour, minute); pSaveKeyValues->SetString("DateTime", m_DateTime.Get()); // write out each mission's status KeyValues *pSubSection; for (int i=0; i<ASW_MAX_MISSIONS_PER_CAMPAIGN; i++) { pSubSection = new KeyValues("MISSION"); pSubSection->SetInt("MissionID", i); pSubSection->SetInt("MissionComplete", m_MissionComplete[i]); pSubSection->SetInt("NumRetries", m_NumRetries[i]); pSaveKeyValues->AddSubKey(pSubSection); } // write out each marine's stats for (int MarineID=0; MarineID<ASW_NUM_MARINE_PROFILES; MarineID++) { pSubSection = new KeyValues("MARINE"); pSubSection->SetInt("MarineID", MarineID); pSubSection->SetInt("SkillSlot0", m_iMarineSkill[MarineID][ASW_SKILL_SLOT_0]); pSubSection->SetInt("SkillSlot1", m_iMarineSkill[MarineID][ASW_SKILL_SLOT_1]); pSubSection->SetInt("SkillSlot2", m_iMarineSkill[MarineID][ASW_SKILL_SLOT_2]); pSubSection->SetInt("SkillSlot3", m_iMarineSkill[MarineID][ASW_SKILL_SLOT_3]); pSubSection->SetInt("SkillSlot4", m_iMarineSkill[MarineID][ASW_SKILL_SLOT_4]); pSubSection->SetInt("SkillSlotSpare", m_iMarineSkill[MarineID][ASW_SKILL_SLOT_SPARE]); pSubSection->SetInt("UndoSkillSlot0", m_iPreviousMarineSkill[MarineID][ASW_SKILL_SLOT_0]); pSubSection->SetInt("UndoSkillSlot1", m_iPreviousMarineSkill[MarineID][ASW_SKILL_SLOT_1]); pSubSection->SetInt("UndoSkillSlot2", m_iPreviousMarineSkill[MarineID][ASW_SKILL_SLOT_2]); pSubSection->SetInt("UndoSkillSlot3", m_iPreviousMarineSkill[MarineID][ASW_SKILL_SLOT_3]); pSubSection->SetInt("UndoSkillSlot4", m_iPreviousMarineSkill[MarineID][ASW_SKILL_SLOT_4]); pSubSection->SetInt("UndoSkillSlotSpare", m_iPreviousMarineSkill[MarineID][ASW_SKILL_SLOT_SPARE]); pSubSection->SetInt("ParasitesKilled", m_iParasitesKilled[MarineID]); pSubSection->SetString("MissionsCompleted", STRING(m_MissionsCompleteNames[MarineID])); pSubSection->SetString("Medals", STRING(m_Medals[MarineID])); int iWound = IsMarineWounded(MarineID) ? 1 : 0; pSubSection->SetInt("Wounded", iWound); int iDead = IsMarineAlive(MarineID) ? 0 : 1; pSubSection->SetInt("Dead", iDead); pSaveKeyValues->AddSubKey(pSubSection); } // check for any new players to add to our list for ( int i = 1; i <= gpGlobals->maxClients; i++ ) { CASW_Player* pPlayer = dynamic_cast<CASW_Player*>(UTIL_PlayerByIndex(i)); if ( pPlayer ) { // first check his network ID const char *pszNetworkID = pPlayer->GetASWNetworkID(); // check if it's in our list bool bFound = false; for (int k=0;k<m_PlayerIDs.Count();k++) { const char *p = STRING(m_PlayerIDs[k]); if (!Q_strcmp(p, pszNetworkID)) bFound = true; } if (!bFound) { // add it to the list string_t stringID = AllocPooledString(pszNetworkID); m_PlayerIDs.AddToTail(stringID); } // then check player name const char *pszPlayerName = pPlayer->GetPlayerName(); bFound = false; for (int k=0;k<m_PlayerNames.Count();k++) { const char *p = STRING(m_PlayerNames[k]); if (!Q_strcmp(p, pszPlayerName)) bFound = true; } if (!bFound) { // add it to the list string_t stringName = AllocPooledString(pszPlayerName); m_PlayerNames.AddToTail(stringName); } } } pSaveKeyValues->SetInt("NumPlayers", m_PlayerNames.Count()); // write out player names for (int i=0; i<m_PlayerNames.Count(); i++) { pSubSection = new KeyValues("PLAYER"); pSubSection->SetString("PlayerName", STRING(m_PlayerNames[i])); pSaveKeyValues->AddSubKey(pSubSection); } // write out player IDs for (int i=0; i<m_PlayerIDs.Count(); i++) { pSubSection = new KeyValues("DATA"); pSubSection->SetString("DataBlock", STRING(m_PlayerIDs[i])); pSaveKeyValues->AddSubKey(pSubSection); } // write out last commanders section pSubSection = new KeyValues("COMM"); for (int i=0;i<ASW_NUM_MARINE_PROFILES;i++) { char buffer[16]; Q_snprintf(buffer, sizeof(buffer), "Comm%d", i); pSubSection->SetString(buffer, STRING(m_LastCommanders[i])); Q_snprintf(buffer, sizeof(buffer), "Slot%d", i); pSubSection->SetInt( buffer, m_LastMarineResourceSlot[i] ); //Ch1ckensCoop: Record which marine was primary for reservations. Q_snprintf(buffer, sizeof(buffer), "Primary%d", i); pSubSection->SetBool( buffer, m_LastPrimaryMarines[i] ); } pSaveKeyValues->AddSubKey(pSubSection); if (pSaveKeyValues->SaveToFile(filesystem, szFullFileName)) { if (missionchooser && missionchooser->LocalMissionSource()) { const char *pszNoPathName = Q_UnqualifiedFileName(szFullFileName); missionchooser->LocalMissionSource()->OnSaveUpdated(pszNoPathName); } return true; } return false; }