@@ -928,15 +928,11 @@ void mission_campaign_eval_next_mission()
928928 */
929929void mission_campaign_store_goals_and_events ()
930930{
931- int cur;
932- cmission *mission_obj;
933-
934931 if (!(Game_mode & GM_CAMPAIGN_MODE) || (Campaign.current_mission < 0 ))
935932 return ;
936933
937- cur = Campaign.current_mission ;
938-
939- mission_obj = &Campaign.missions [cur];
934+ int cur = Campaign.current_mission ;
935+ auto mission_obj = &Campaign.missions [cur];
940936
941937 // first we must save the status of the current missions goals in the campaign mission structure.
942938 // After that, we can determine which mission is tagged as the next mission. Finally, we
@@ -992,66 +988,49 @@ void mission_campaign_store_goals_and_events()
992988
993989void mission_campaign_store_variables (int persistence_type, bool store_red_alert)
994990{
995- int cur, i, j;
996- cmission *mission_obj;
997-
998991 if (!(Game_mode & GM_CAMPAIGN_MODE) || (Campaign.current_mission < 0 ))
999992 return ;
1000993
1001- cur = Campaign.current_mission ;
1002- mission_obj = &Campaign.missions [cur];
1003-
1004- // handle variables that are saved on mission victory -------------------------------------
994+ int cur = Campaign.current_mission ;
995+ auto mission_obj = &Campaign.missions [cur];
1005996 mission_obj->variables .clear ();
1006997
1007- int num_mission_variables = sexp_campaign_file_variable_count ();
1008-
1009- if (num_mission_variables > 0 ) {
1010-
1011- if (store_red_alert) {
1012- for (auto & current_rav : Campaign.red_alert_variables ) {
1013- Campaign.persistent_variables .push_back (current_rav);
1014- }
998+ if (store_red_alert) {
999+ for (auto & current_rav : Campaign.red_alert_variables ) {
1000+ Campaign.persistent_variables .push_back (current_rav);
10151001 }
1002+ }
10161003
1017- for (i = 0 ; i < sexp_variable_count (); i++) {
1018- if (!(Sexp_variables[i].type & SEXP_VARIABLE_SAVE_TO_PLAYER_FILE)) {
1019- if (Sexp_variables[i].type & persistence_type) {
1020- bool add_it = true ;
1021-
1022- // see if we already have a variable with this name
1023- for (j = 0 ; j < (int )Campaign.persistent_variables .size (); j++) {
1024- if (!(stricmp (Sexp_variables[i].variable_name , Campaign.persistent_variables [j].variable_name ))) {
1025- add_it = false ;
1026- Campaign.persistent_variables [j].type = Sexp_variables[i].type ;
1027- strcpy_s (Campaign.persistent_variables [j].text , Sexp_variables[i].text );
1028- break ;
1029- }
1030- }
1004+ int num_sexp_variables = sexp_variable_count ();
1005+ for (int i = 0 ; i < num_sexp_variables; i++) {
1006+ if (!(Sexp_variables[i].type & persistence_type)) {
1007+ continue ;
1008+ }
10311009
1032- // new variable
1033- if (add_it) {
1034- Campaign.persistent_variables .push_back (Sexp_variables[i]);
1035- }
1036- }
1010+ // player-persistent (aka "eternal")
1011+ if (Sexp_variables[i].type & SEXP_VARIABLE_SAVE_TO_PLAYER_FILE) {
1012+ // see if we already have a variable with this name
1013+ int j = find_item_with_string (Player->variables , &sexp_variable::variable_name, Sexp_variables[i].variable_name );
1014+ if (j >= 0 ) {
1015+ Player->variables [j].type = Sexp_variables[i].type ;
1016+ strcpy_s (Player->variables [j].text , Sexp_variables[i].text );
10371017 }
1038- // we might need to save some eternal variables
1039- else if ((persistence_type & SEXP_VARIABLE_SAVE_ON_MISSION_PROGRESS) && (Sexp_variables[i].type & persistence_type) && (Sexp_variables[i].type & SEXP_VARIABLE_SAVE_TO_PLAYER_FILE)) {
1040- bool add_it = true ;
1041-
1042- for (j = 0 ; j < (int )Player->variables .size (); j++) {
1043- if (!(stricmp (Sexp_variables[i].variable_name , Player->variables [j].variable_name ))) {
1044- Player->variables [j] = Sexp_variables[i];
1045-
1046- add_it = false ;
1047- break ;
1048- }
1049- }
1050-
1051- // if not found then add new entry
1052- if (add_it) {
1053- Player->variables .push_back (Sexp_variables[i]);
1054- }
1018+ // new variable
1019+ else {
1020+ Player->variables .push_back (Sexp_variables[i]);
1021+ }
1022+ }
1023+ // campaign-persistent
1024+ else {
1025+ // see if we already have a variable with this name
1026+ int j = find_item_with_string (Campaign.persistent_variables , &sexp_variable::variable_name, Sexp_variables[i].variable_name );
1027+ if (j >= 0 ) {
1028+ Campaign.persistent_variables [j].type = Sexp_variables[i].type ;
1029+ strcpy_s (Campaign.persistent_variables [j].text , Sexp_variables[i].text );
1030+ }
1031+ // new variable
1032+ else {
1033+ Campaign.persistent_variables .push_back (Sexp_variables[i]);
10551034 }
10561035 }
10571036 }
@@ -1063,58 +1042,57 @@ void mission_campaign_store_containers(ContainerType persistence_type, bool stor
10631042 if (!(Game_mode & GM_CAMPAIGN_MODE) || (Campaign.current_mission < 0 ))
10641043 return ;
10651044
1066- if (!sexp_container_has_persistent_non_eternal_containers ()) {
1067- // nothing to do
1068- return ;
1069- }
1070-
10711045 if (store_red_alert) {
10721046 for (const auto & current_con : Campaign.red_alert_containers ) {
10731047 Campaign.persistent_containers .emplace_back (current_con);
10741048 }
10751049 }
10761050
10771051 for (const auto &container : get_all_sexp_containers ()) {
1078- if (!container.is_eternal ()) {
1079- if (any (container.type & persistence_type)) {
1080- // see if we already have a container with this name
1081- auto cpc_it = std::find_if (Campaign.persistent_containers .begin (),
1082- Campaign.persistent_containers .end (),
1083- [container](const sexp_container &cpc) {
1084- return cpc.name_matches (container);
1085- });
1086-
1087- if (cpc_it != Campaign.persistent_containers .end ()) {
1088- *cpc_it = container;
1089- } else {
1090- // new container
1091- Campaign.persistent_containers .emplace_back (container);
1092- }
1093- }
1094- } else if (any (persistence_type & ContainerType::SAVE_ON_MISSION_PROGRESS) &&
1095- any (container.type & persistence_type) && container.is_eternal ()) {
1096- // we might need to save some eternal player-persistent containers
1052+ if (!any (container.type & persistence_type)) {
1053+ continue ;
1054+ }
1055+
1056+ // player-persistent (aka "eternal")
1057+ if (container.is_eternal ()) {
1058+ // see if we already have a container with this name
10971059 auto ppc_it = std::find_if (Player->containers .begin (),
10981060 Player->containers .end (),
1099- [container](const sexp_container & ppc) {
1061+ [container](const sexp_container& ppc) {
11001062 return ppc.name_matches (container);
11011063 });
11021064
11031065 if (ppc_it != Player->containers .end ()) {
11041066 *ppc_it = container;
11051067 } else {
11061068 // new player-persistent container
1107- Player->containers .emplace_back (container);
1069+ Player->containers .push_back (container);
1070+ }
1071+ }
1072+ // campaign-persistent
1073+ else {
1074+ // see if we already have a container with this name
1075+ auto cpc_it = std::find_if (Campaign.persistent_containers .begin (),
1076+ Campaign.persistent_containers .end (),
1077+ [container](const sexp_container& cpc) {
1078+ return cpc.name_matches (container);
1079+ });
1080+
1081+ if (cpc_it != Campaign.persistent_containers .end ()) {
1082+ *cpc_it = container;
1083+ } else {
1084+ // new container
1085+ Campaign.persistent_containers .emplace_back (container);
11081086 }
11091087 }
11101088 }
11111089}
11121090
1113- void mission_campaign_store_goals_and_events_and_variables ()
1091+ void mission_campaign_store_goals_and_events_and_variables (bool store_red_alert_data )
11141092{
11151093 mission_campaign_store_goals_and_events ();
1116- mission_campaign_store_variables (SEXP_VARIABLE_SAVE_ON_MISSION_PROGRESS);
1117- mission_campaign_store_containers (ContainerType::SAVE_ON_MISSION_PROGRESS);
1094+ mission_campaign_store_variables (SEXP_VARIABLE_SAVE_ON_MISSION_PROGRESS, store_red_alert_data );
1095+ mission_campaign_store_containers (ContainerType::SAVE_ON_MISSION_PROGRESS, store_red_alert_data );
11181096}
11191097
11201098/* *
@@ -1146,9 +1124,6 @@ void mission_campaign_mission_over(bool do_next_mission)
11461124 Campaign.weapons_allowed [Granted_weapons[i]] = 1 ;
11471125 }
11481126
1149- // Goober5000 - player-persistent variables are handled when the mission is
1150- // over, not necessarily when the mission is accepted
1151-
11521127 // update campaign.mission stats (used to allow backout inRedAlert)
11531128 // .. but we don't do this if we are inside of the prev/current loop hack
11541129 if ( Campaign.prev_mission != Campaign.current_mission ) {
@@ -1682,6 +1657,9 @@ void mission_campaign_end_init()
16821657
16831658void mission_campaign_end_do ()
16841659{
1660+ mission_campaign_store_variables (SEXP_VARIABLE_SAVE_ON_MISSION_PROGRESS, false );
1661+ mission_campaign_store_containers (ContainerType::SAVE_ON_MISSION_PROGRESS, false );
1662+
16851663 // close out the mission
16861664 event_music_level_close ();
16871665 mission_goal_fail_incomplete ();
@@ -1728,7 +1706,7 @@ void mission_campaign_skip_to_next()
17281706 mission_goal_mark_events_complete ();
17291707
17301708 // store
1731- mission_campaign_store_goals_and_events_and_variables ();
1709+ mission_campaign_store_goals_and_events_and_variables (false );
17321710
17331711 // now set the next mission
17341712 mission_campaign_eval_next_mission ();
@@ -1845,84 +1823,6 @@ bool mission_campaign_jump_to_mission(const char* filename, bool no_skip)
18451823 }
18461824}
18471825
1848- // Goober5000
1849- void mission_campaign_save_on_close_variables ()
1850- {
1851- int i;
1852-
1853- // make sure we are actually playing a single-player campaign
1854- if (!(Game_mode & GM_CAMPAIGN_MODE) || (Campaign.type != CAMPAIGN_TYPE_SINGLE) || (Campaign.current_mission < 0 ))
1855- return ;
1856-
1857- // now save variables
1858- for (i = 0 ; i < sexp_variable_count (); i++) {
1859- // we only want the on mission close type. On campaign progress type are dealt with elsewhere
1860- if ( !(Sexp_variables[i].type & SEXP_VARIABLE_SAVE_ON_MISSION_CLOSE) ) {
1861- continue ;
1862- }
1863-
1864- bool found = false ;
1865-
1866- // deal with eternals
1867- if ((Sexp_variables[i].type & SEXP_VARIABLE_SAVE_TO_PLAYER_FILE)) {
1868- // check if variable already exists and updated it
1869- for (auto & current_variable : Player->variables ) {
1870- if (!(stricmp (Sexp_variables[i].variable_name , current_variable.variable_name ))) {
1871- current_variable = Sexp_variables[i];
1872-
1873- found = true ;
1874- break ;
1875- }
1876- }
1877-
1878- // if not found then add new entry
1879- if (!found) {
1880- Player->variables .push_back (Sexp_variables[i]);
1881- }
1882- }
1883-
1884- }
1885-
1886- // store any non-eternal on mission close variables
1887- mission_campaign_store_variables (SEXP_VARIABLE_SAVE_ON_MISSION_CLOSE, false );
1888- }
1889-
1890- // jg18 - adapted from mission_campaign_save_on_close_variables()
1891- void mission_campaign_save_on_close_containers ()
1892- {
1893- // make sure we are actually playing a single-player campaign
1894- if (!(Game_mode & GM_CAMPAIGN_MODE) || (Campaign.type != CAMPAIGN_TYPE_SINGLE) || (Campaign.current_mission < 0 ))
1895- return ;
1896-
1897- // now save containers
1898- for (const auto &container : get_all_sexp_containers ()) {
1899- // we only want the on mission close type. On campaign progress type are dealt with elsewhere
1900- if (none (container.type & ContainerType::SAVE_ON_MISSION_CLOSE)) {
1901- continue ;
1902- }
1903-
1904- // deal with eternals
1905- if (container.is_eternal ()) {
1906- // check if container already exists and update it
1907- auto ppc_it = std::find_if (Player->containers .begin (),
1908- Player->containers .end (),
1909- [container](const sexp_container &ppc) {
1910- return ppc.name_matches (container);
1911- });
1912-
1913- if (ppc_it != Player->containers .end ()) {
1914- *ppc_it = container;
1915- } else {
1916- // if not found then add new entry
1917- Player->containers .emplace_back (container);
1918- }
1919- }
1920- }
1921-
1922- // store any non-eternal on mission close containers
1923- mission_campaign_store_containers (ContainerType::SAVE_ON_MISSION_CLOSE, false );
1924- }
1925-
19261826void mission_campaign_load_failure_popup ()
19271827{
19281828 if (Campaign_load_failure == 0 ) {
0 commit comments