Skip to content

Commit 0666749

Browse files
committed
mission save compatibility
Make sure that missions without props will still be compatible with earlier mission file formats. If props are included, bump the mission file version. Also, fix some newline behavior in the save code.
1 parent 3763a29 commit 0666749

4 files changed

Lines changed: 47 additions & 18 deletions

File tree

code/globalincs/utility.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,13 @@ int count_items_with_field(const ITEM_T* item_array, int num_items, FIELD_T ITEM
307307
return count;
308308
}
309309

310+
template <typename VECTOR_T>
311+
size_t count_items_with_value(const VECTOR_T& item_vector)
312+
{
313+
return std::count_if(item_vector.begin(), item_vector.end(),
314+
[](const typename VECTOR_T::value_type& element) { return element.has_value(); });
315+
}
316+
310317
template <typename VECTOR_T, typename ITEM_T, typename FIELD_T>
311318
int find_item_with_string(const VECTOR_T& item_vector, FIELD_T* ITEM_T::* field, const char* str)
312319
{

code/mission/missionparse.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9422,3 +9422,8 @@ bool check_for_24_3_data()
94229422
}
94239423
return false;
94249424
}
9425+
9426+
bool check_for_25_1_data()
9427+
{
9428+
return (count_items_with_value(Props) > 0);
9429+
}

code/mission/missionparse.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ extern const gameversion::version LEGACY_MISSION_VERSION;
6262
extern bool check_for_23_3_data();
6363
extern bool check_for_24_1_data();
6464
extern bool check_for_24_3_data();
65+
extern bool check_for_25_1_data();
6566

6667
#define WING_PLAYER_BASE 0x80000 // used by Fred to tell ship_index in a wing points to a player
6768

code/missioneditor/missionsave.cpp

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3032,10 +3032,16 @@ void Fred_mission_save::save_mission_internal(const char* pathname)
30323032
auto version_23_3 = gameversion::version(23, 3);
30333033
auto version_24_1 = gameversion::version(24, 1);
30343034
auto version_24_3 = gameversion::version(24, 3);
3035-
if (MISSION_VERSION >= version_24_3) {
3035+
auto version_25_1 = gameversion::version(25, 1);
3036+
if (MISSION_VERSION >= version_25_1) {
30363037
Warning(LOCATION,
3037-
"Notify an SCP coder: now that the required mission version is at least 24.3, the check_for_24_3_data(), "
3038-
"the check_for_24_1_data() and check_for_23_3_data() code can be removed");
3038+
"Notify an SCP coder: now that the required mission version is at least 25.1, the check_for_25_1_data(), "
3039+
"check_for_24_3_data(), check_for_24_1_data(), and check_for_23_3_data() code can be removed");
3040+
} else if (check_for_25_1_data()) {
3041+
The_mission.required_fso_version = version_25_1;
3042+
} else if (MISSION_VERSION >= version_24_3) {
3043+
Warning(LOCATION, "Notify an SCP coder: now that the required mission version is at least 24.3, the "
3044+
"check_for_24_3_data(), check_for_24_1_data(), and check_for_23_3_data() code can be removed");
30393045
} else if (check_for_24_3_data()) {
30403046
The_mission.required_fso_version = version_24_3;
30413047
} else if (MISSION_VERSION >= version_24_1) {
@@ -3382,7 +3388,7 @@ int Fred_mission_save::save_warp_params(WarpDirection direction, ship* shipp)
33823388
int Fred_mission_save::save_objects()
33833389
{
33843390
SCP_string sexp_out;
3385-
int i, z;
3391+
int i, z, count;
33863392
object* objp;
33873393
ship* shipp;
33883394
ship_info* sip;
@@ -3391,7 +3397,7 @@ int Fred_mission_save::save_objects()
33913397
parse_comments(2);
33923398
fout("\t\t;! %d total\n", ship_get_num_ships());
33933399

3394-
for (i = z = 0; i < MAX_SHIPS; i++) {
3400+
for (i = count = 0; i < MAX_SHIPS; i++) {
33953401
if (Ships[i].objnum < 0) {
33963402
continue;
33973403
}
@@ -3406,9 +3412,11 @@ int Fred_mission_save::save_objects()
34063412
sip = &Ship_info[shipp->ship_info_index];
34073413
required_string_either_fred("$Name:", "#Wings");
34083414
required_string_fred("$Name:");
3409-
parse_comments(z ? 2 : 1);
3415+
parse_comments(count ? 2 : 1);
34103416
fout(" %s\t\t;! Object #%d", shipp->ship_name, i);
34113417

3418+
count++;
3419+
34123420
// Display name
34133421
// The display name is only written if there was one at the start to avoid introducing inconsistencies
34143422
if (save_config.save_format != MissionFormat::RETAIL && ((save_config.always_save_display_names && shipp->wingnum < 0) || shipp->has_display_name())) {
@@ -4153,8 +4161,6 @@ int Fred_mission_save::save_objects()
41534161

41544162
// end of texture replacement -------------------------------
41554163

4156-
z++;
4157-
41584164
fso_comment_pop();
41594165
}
41604166

@@ -4855,18 +4861,19 @@ int Fred_mission_save::save_wings()
48554861
fred_parse_flag = 0;
48564862
required_string_fred("#Wings");
48574863
parse_comments(2);
4858-
fout("\t\t;! %d total", Num_wings);
4864+
fout("\t\t;! %d total\n", Num_wings);
48594865

48604866
for (auto& w : Wings) {
48614867
if (!w.wave_count)
48624868
continue;
48634869

4864-
count++;
48654870
required_string_one_of_fred(3, "$Name:", "#Events", "#Props");
48664871
required_string_fred("$Name:");
4867-
parse_comments(2);
4872+
parse_comments(count ? 2 : 1);
48684873
fout(" %s", w.name);
48694874

4875+
count++;
4876+
48704877
// squad logo - Goober5000
48714878
if (save_config.save_format != MissionFormat::RETAIL) {
48724879
if (strlen(w.wing_squad_filename) > 0) //-V805
@@ -5124,21 +5131,30 @@ int Fred_mission_save::save_wings()
51245131

51255132
int Fred_mission_save::save_props()
51265133
{
5127-
if (save_config.save_format != MissionFormat::RETAIL) {
5134+
auto num_props = count_items_with_value(Props);
5135+
5136+
if ((save_config.save_format != MissionFormat::RETAIL) && (num_props > 0)) {
51285137
fred_parse_flag = 0;
5129-
required_string_fred("#Props");
5130-
parse_comments(2);
5131-
fout("\t\t;! %d total", static_cast<int>(Props.size()));
5138+
size_t count = 0;
5139+
5140+
if (optional_string_fred("#Props", "#End")) {
5141+
parse_comments(2);
5142+
} else {
5143+
fout("\n\n#Props");
5144+
}
5145+
fout("\t\t;! " SIZE_T_ARG " total\n", num_props);
51325146

51335147
for (const auto& p : Props) {
51345148
if (p.has_value()) {
51355149
required_string_either_fred("$Name:", "#Events");
51365150
required_string_fred("$Name:");
5137-
parse_comments(2);
5151+
parse_comments(count ? 2 : 1);
51385152
fout(" %s", p->prop_name);
51395153

5140-
required_string_fred("$Class:");
5141-
parse_comments(2);
5154+
count++;
5155+
5156+
required_string_fred("\n$Class:");
5157+
parse_comments(0);
51425158
fout(" %s", Prop_info[p->prop_info_index].name.c_str());
51435159

51445160
required_string_fred("$Location:");

0 commit comments

Comments
 (0)