@@ -935,15 +935,11 @@ void mission_campaign_eval_next_mission()
935935 */
936936void mission_campaign_store_goals_and_events ()
937937{
938- int cur;
939- cmission *mission_obj;
940-
941938 if (!(Game_mode & GM_CAMPAIGN_MODE ) || (Campaign.current_mission < 0 ))
942939 return ;
943940
944- cur = Campaign.current_mission ;
945-
946- mission_obj = &Campaign.missions [cur];
941+ int cur = Campaign.current_mission ;
942+ auto mission_obj = &Campaign.missions [cur];
947943
948944 // first we must save the status of the current missions goals in the campaign mission structure.
949945 // After that, we can determine which mission is tagged as the next mission. Finally, we
@@ -999,66 +995,54 @@ void mission_campaign_store_goals_and_events()
999995
1000996void mission_campaign_store_variables (int persistence_type, bool store_red_alert)
1001997{
1002- int cur, i, j;
1003- cmission *mission_obj;
1004-
1005998 if (!(Game_mode & GM_CAMPAIGN_MODE ) || (Campaign.current_mission < 0 ))
1006999 return ;
10071000
1008- cur = Campaign.current_mission ;
1009- mission_obj = &Campaign.missions [cur];
1001+ int cur = Campaign.current_mission ;
1002+ auto mission_obj = &Campaign.missions [cur];
10101003
1011- // handle variables that are saved on mission victory -------------------------------------
10121004 mission_obj->variables .clear ();
10131005
1014- int num_mission_variables = sexp_campaign_file_variable_count ();
1006+ int num_sexp_variables = sexp_variable_count ();
1007+ for (int i = 0 ; i < num_sexp_variables; i++) {
1008+ if (!(Sexp_variables[i].type & persistence_type)) {
1009+ continue ;
1010+ }
10151011
1016- if (num_mission_variables > 0 ) {
1017-
1018- if (store_red_alert) {
1019- for (auto & current_rav : Campaign.red_alert_variables ) {
1020- Campaign.persistent_variables .push_back (current_rav);
1012+ // player-persistent (aka "eternal")
1013+ if (Sexp_variables[i].type & SEXP_VARIABLE_SAVE_TO_PLAYER_FILE ) {
1014+ // see if we already have a variable with this name
1015+ int j = find_item_with_string (Player->variables , &sexp_variable::variable_name, Sexp_variables[i].variable_name );
1016+ if (j >= 0 ) {
1017+ Player->variables [j].type = Sexp_variables[i].type ;
1018+ strcpy_s (Player->variables [j].text , Sexp_variables[i].text );
1019+ }
1020+ // new variable
1021+ else {
1022+ Player->variables .push_back (Sexp_variables[i]);
10211023 }
10221024 }
1023-
1024- for (i = 0 ; i < sexp_variable_count (); i++) {
1025- if (!(Sexp_variables[i].type & SEXP_VARIABLE_SAVE_TO_PLAYER_FILE )) {
1026- if (Sexp_variables[i].type & persistence_type) {
1027- bool add_it = true ;
1028-
1029- // see if we already have a variable with this name
1030- for (j = 0 ; j < (int )Campaign.persistent_variables .size (); j++) {
1031- if (!(stricmp (Sexp_variables[i].variable_name , Campaign.persistent_variables [j].variable_name ))) {
1032- add_it = false ;
1033- Campaign.persistent_variables [j].type = Sexp_variables[i].type ;
1034- strcpy_s (Campaign.persistent_variables [j].text , Sexp_variables[i].text );
1035- break ;
1036- }
1037- }
1038-
1039- // new variable
1040- if (add_it) {
1041- Campaign.persistent_variables .push_back (Sexp_variables[i]);
1042- }
1043- }
1025+ // campaign-persistent
1026+ else {
1027+ // see if we already have a variable with this name
1028+ int j = find_item_with_string (Campaign.persistent_variables , &sexp_variable::variable_name, Sexp_variables[i].variable_name );
1029+ if (j >= 0 ) {
1030+ Campaign.persistent_variables [j].type = Sexp_variables[i].type ;
1031+ strcpy_s (Campaign.persistent_variables [j].text , Sexp_variables[i].text );
10441032 }
1045- // we might need to save some eternal variables
1046- 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 )) {
1047- bool add_it = true ;
1048-
1049- for (j = 0 ; j < (int )Player->variables .size (); j++) {
1050- if (!(stricmp (Sexp_variables[i].variable_name , Player->variables [j].variable_name ))) {
1051- Player->variables [j] = Sexp_variables[i];
1052-
1053- add_it = false ;
1054- break ;
1055- }
1056- }
1033+ // new variable
1034+ else {
1035+ Campaign.persistent_variables .push_back (Sexp_variables[i]);
1036+ }
1037+ }
1038+ }
10571039
1058- // if not found then add new entry
1059- if (add_it) {
1060- Player->variables .push_back (Sexp_variables[i]);
1061- }
1040+ if (store_red_alert) {
1041+ for (const auto & current_rav : Campaign.red_alert_variables ) {
1042+ if (find_item_with_string (Campaign.persistent_variables , &sexp_variable::variable_name, current_rav.variable_name ) < 0 ) {
1043+ Campaign.persistent_variables .push_back (current_rav);
1044+ } else {
1045+ Warning (LOCATION , " A red alert variable has the same name as a persistent variable!" );
10621046 }
10631047 }
10641048 }
@@ -1070,58 +1054,68 @@ void mission_campaign_store_containers(ContainerType persistence_type, bool stor
10701054 if (!(Game_mode & GM_CAMPAIGN_MODE ) || (Campaign.current_mission < 0 ))
10711055 return ;
10721056
1073- if (!sexp_container_has_persistent_non_eternal_containers ()) {
1074- // nothing to do
1075- return ;
1076- }
1077-
1078- if (store_red_alert) {
1079- for (const auto & current_con : Campaign.red_alert_containers ) {
1080- Campaign.persistent_containers .emplace_back (current_con);
1057+ for (const auto &container : get_all_sexp_containers ()) {
1058+ if (none (container.type & persistence_type)) {
1059+ continue ;
10811060 }
1082- }
10831061
1084- for (const auto &container : get_all_sexp_containers ()) {
1085- if (!container.is_eternal ()) {
1086- if (any (container.type & persistence_type)) {
1087- // see if we already have a container with this name
1088- auto cpc_it = std::find_if (Campaign.persistent_containers .begin (),
1089- Campaign.persistent_containers .end (),
1090- [container](const sexp_container &cpc) {
1091- return cpc.name_matches (container);
1092- });
1093-
1094- if (cpc_it != Campaign.persistent_containers .end ()) {
1095- *cpc_it = container;
1096- } else {
1097- // new container
1098- Campaign.persistent_containers .emplace_back (container);
1099- }
1100- }
1101- } else if (any (persistence_type & ContainerType::SAVE_ON_MISSION_PROGRESS ) &&
1102- any (container.type & persistence_type) && container.is_eternal ()) {
1103- // we might need to save some eternal player-persistent containers
1062+ // player-persistent (aka "eternal")
1063+ if (container.is_eternal ()) {
1064+ // see if we already have a container with this name
11041065 auto ppc_it = std::find_if (Player->containers .begin (),
11051066 Player->containers .end (),
1106- [container](const sexp_container & ppc) {
1067+ [& container](const sexp_container& ppc) {
11071068 return ppc.name_matches (container);
11081069 });
11091070
11101071 if (ppc_it != Player->containers .end ()) {
11111072 *ppc_it = container;
11121073 } else {
11131074 // new player-persistent container
1114- Player->containers .emplace_back (container);
1075+ Player->containers .push_back (container);
1076+ }
1077+ }
1078+ // campaign-persistent
1079+ else {
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 .push_back (container);
1092+ }
1093+ }
1094+ }
1095+
1096+ if (store_red_alert) {
1097+ for (const auto & container : Campaign.red_alert_containers ) {
1098+ // see if we already have a container with this name
1099+ auto cpc_it = std::find_if (Campaign.persistent_containers .begin (),
1100+ Campaign.persistent_containers .end (),
1101+ [&container](const sexp_container& cpc) {
1102+ return cpc.name_matches (container);
1103+ });
1104+
1105+ if (cpc_it == Campaign.persistent_containers .end ()) {
1106+ Campaign.persistent_containers .push_back (container);
1107+ } else {
1108+ Warning (LOCATION , " A red alert container has the same name as a persistent container!" );
11151109 }
11161110 }
11171111 }
11181112}
11191113
1120- void mission_campaign_store_goals_and_events_and_variables ()
1114+ void mission_campaign_store_goals_and_events_and_variables (bool store_red_alert_data )
11211115{
11221116 mission_campaign_store_goals_and_events ();
1123- mission_campaign_store_variables (SEXP_VARIABLE_SAVE_ON_MISSION_PROGRESS );
1124- mission_campaign_store_containers (ContainerType::SAVE_ON_MISSION_PROGRESS );
1117+ mission_campaign_store_variables (SEXP_VARIABLE_SAVE_ON_MISSION_PROGRESS , store_red_alert_data );
1118+ mission_campaign_store_containers (ContainerType::SAVE_ON_MISSION_PROGRESS , store_red_alert_data );
11251119}
11261120
11271121/* *
@@ -1153,9 +1147,6 @@ void mission_campaign_mission_over(bool do_next_mission)
11531147 Campaign.weapons_allowed [Granted_weapons[i]] = 1 ;
11541148 }
11551149
1156- // Goober5000 - player-persistent variables are handled when the mission is
1157- // over, not necessarily when the mission is accepted
1158-
11591150 // update campaign.mission stats (used to allow backout inRedAlert)
11601151 // .. but we don't do this if we are inside of the prev/current loop hack
11611152 if ( Campaign.prev_mission != Campaign.current_mission ) {
@@ -1686,6 +1677,9 @@ void mission_campaign_end_init()
16861677
16871678void mission_campaign_end_do ()
16881679{
1680+ mission_campaign_store_variables (SEXP_VARIABLE_SAVE_ON_MISSION_PROGRESS , false );
1681+ mission_campaign_store_containers (ContainerType::SAVE_ON_MISSION_PROGRESS , false );
1682+
16891683 // close out the mission
16901684 event_music_level_close ();
16911685 mission_goal_fail_incomplete ();
@@ -1732,7 +1726,7 @@ void mission_campaign_skip_to_next()
17321726 mission_goal_mark_events_complete ();
17331727
17341728 // store
1735- mission_campaign_store_goals_and_events_and_variables ();
1729+ mission_campaign_store_goals_and_events_and_variables (false );
17361730
17371731 // now set the next mission
17381732 mission_campaign_eval_next_mission ();
@@ -1849,84 +1843,6 @@ bool mission_campaign_jump_to_mission(const char* filename, bool no_skip)
18491843 }
18501844}
18511845
1852- // Goober5000
1853- void mission_campaign_save_on_close_variables ()
1854- {
1855- int i;
1856-
1857- // make sure we are actually playing a single-player campaign
1858- if (!(Game_mode & GM_CAMPAIGN_MODE ) || (Campaign.type != CAMPAIGN_TYPE_SINGLE ) || (Campaign.current_mission < 0 ))
1859- return ;
1860-
1861- // now save variables
1862- for (i = 0 ; i < sexp_variable_count (); i++) {
1863- // we only want the on mission close type. On campaign progress type are dealt with elsewhere
1864- if ( !(Sexp_variables[i].type & SEXP_VARIABLE_SAVE_ON_MISSION_CLOSE ) ) {
1865- continue ;
1866- }
1867-
1868- bool found = false ;
1869-
1870- // deal with eternals
1871- if ((Sexp_variables[i].type & SEXP_VARIABLE_SAVE_TO_PLAYER_FILE )) {
1872- // check if variable already exists and updated it
1873- for (auto & current_variable : Player->variables ) {
1874- if (!(stricmp (Sexp_variables[i].variable_name , current_variable.variable_name ))) {
1875- current_variable = Sexp_variables[i];
1876-
1877- found = true ;
1878- break ;
1879- }
1880- }
1881-
1882- // if not found then add new entry
1883- if (!found) {
1884- Player->variables .push_back (Sexp_variables[i]);
1885- }
1886- }
1887-
1888- }
1889-
1890- // store any non-eternal on mission close variables
1891- mission_campaign_store_variables (SEXP_VARIABLE_SAVE_ON_MISSION_CLOSE , false );
1892- }
1893-
1894- // jg18 - adapted from mission_campaign_save_on_close_variables()
1895- void mission_campaign_save_on_close_containers ()
1896- {
1897- // make sure we are actually playing a single-player campaign
1898- if (!(Game_mode & GM_CAMPAIGN_MODE ) || (Campaign.type != CAMPAIGN_TYPE_SINGLE ) || (Campaign.current_mission < 0 ))
1899- return ;
1900-
1901- // now save containers
1902- for (const auto &container : get_all_sexp_containers ()) {
1903- // we only want the on mission close type. On campaign progress type are dealt with elsewhere
1904- if (none (container.type & ContainerType::SAVE_ON_MISSION_CLOSE )) {
1905- continue ;
1906- }
1907-
1908- // deal with eternals
1909- if (container.is_eternal ()) {
1910- // check if container already exists and update it
1911- auto ppc_it = std::find_if (Player->containers .begin (),
1912- Player->containers .end (),
1913- [container](const sexp_container &ppc) {
1914- return ppc.name_matches (container);
1915- });
1916-
1917- if (ppc_it != Player->containers .end ()) {
1918- *ppc_it = container;
1919- } else {
1920- // if not found then add new entry
1921- Player->containers .emplace_back (container);
1922- }
1923- }
1924- }
1925-
1926- // store any non-eternal on mission close containers
1927- mission_campaign_store_containers (ContainerType::SAVE_ON_MISSION_CLOSE , false );
1928- }
1929-
19301846void mission_campaign_load_failure_popup ()
19311847{
19321848 if (Campaign_load_failure == 0 ) {
0 commit comments