Skip to content

Commit 3a556d9

Browse files
authored
Merge pull request scp-fs2open#7412 from Goober5000/fix/asteroids
fix asteroid field undefined behavior
2 parents 29bb474 + 6e5e342 commit 3a556d9

2 files changed

Lines changed: 24 additions & 7 deletions

File tree

code/asteroid/asteroid.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -648,24 +648,30 @@ void asteroid_create_all()
648648
int max_asteroids = Asteroid_field.num_initial_asteroids; // * (1.0f - 0.1f*(MAX_DETAIL_VALUE-Detail.asteroid_density)));
649649

650650
int num_debris_types = 0;
651+
int num_valid = 0; // count of valid (non-(-1)) entries written into shipDebrisOddsTable
651652

652653
// get number of debris types
653654
if (Asteroid_field.debris_genre == DG_DEBRIS) {
654655
num_debris_types = static_cast<int>(Asteroid_field.field_debris_type.size());
655656

656-
// Calculate the odds table
657+
// Calculate the odds table; skip invalid entries (field_debris_type[idx] == -1 means
658+
// missionparse invalidated the entry because the type no longer exists in Asteroid_info)
657659
for (idx=0; idx<num_debris_types; idx++) {
660+
if (Asteroid_field.field_debris_type[idx] == -1)
661+
continue;
658662
float debris_weight = Asteroid_info[Asteroid_field.field_debris_type[idx]].spawn_weight;
659-
shipDebrisOddsTable[idx].random_threshold = max_weighted_range + debris_weight;
660-
shipDebrisOddsTable[idx].debris_type = Asteroid_field.field_debris_type[idx];
663+
shipDebrisOddsTable[num_valid].random_threshold = max_weighted_range + debris_weight;
664+
shipDebrisOddsTable[num_valid].debris_type = Asteroid_field.field_debris_type[idx];
661665
max_weighted_range += debris_weight;
666+
num_valid++;
662667
}
663668
}
664669

665670
// Load Asteroid/debris models
666671
if (Asteroid_field.debris_genre == DG_DEBRIS) {
667672
for (idx=0; idx<num_debris_types; idx++) {
668-
asteroid_load(Asteroid_field.field_debris_type[idx], 0);
673+
if (Asteroid_field.field_debris_type[idx] != -1)
674+
asteroid_load(Asteroid_field.field_debris_type[idx], 0);
669675
}
670676
} else {
671677
for (const auto& subtype : Asteroid_field.field_asteroid_type) {
@@ -690,7 +696,7 @@ void asteroid_create_all()
690696

691697
float rand_choice = frand() * max_weighted_range;
692698

693-
for (idx = 0; idx < static_cast<int>(Asteroid_field.field_debris_type.size()); idx++) {
699+
for (idx = 0; idx < num_valid; idx++) {
694700
// for ship debris, choose type according to odds table
695701
if (rand_choice < shipDebrisOddsTable[idx].random_threshold) {
696702
asteroid_create(&Asteroid_field, shipDebrisOddsTable[idx].debris_type, 0);
@@ -2641,6 +2647,11 @@ static void verify_asteroid_list()
26412647
if (found)
26422648
continue;
26432649

2650+
if (asteroid_list.empty()) {
2651+
mprintf(("%s asteroid not found and no fallback available in asteroid_list.\n", asteroid_size[i].c_str()));
2652+
continue;
2653+
}
2654+
26442655
//Left this as a log print instead of a Warning because of retail-Mjn
26452656
mprintf(("%s asteroid not found. Using asteroid %s\n", asteroid_size[i].c_str(), asteroid_list[0].name));
26462657
asteroid_list[0].type = i;
@@ -2695,8 +2706,10 @@ void asteroid_init()
26952706
parse_modular_table("*-ast.tbm", asteroid_parse_tbl);
26962707

26972708
//No asteroids defined. Bail!
2698-
if (asteroid_list.empty())
2709+
if (asteroid_list.empty()) {
2710+
mprintf(("No asteroids defined in asteroid.tbl or any modular tables. Asteroid fields will not function.\n"));
26992711
return;
2712+
}
27002713

27012714
// now verify the asteroids were found and put them in the correct order
27022715
verify_asteroid_list();

code/mission/missionparse.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6392,7 +6392,11 @@ void parse_asteroid_fields(mission *pm)
63926392
if (optional_string("+Field Debris Type:")) {
63936393
int subtype;
63946394
stuff_int(&subtype);
6395-
Asteroid_field.field_asteroid_type.push_back(colors[subtype]);
6395+
if (subtype >= 0 && subtype < NUM_ASTEROID_SIZES) {
6396+
Asteroid_field.field_asteroid_type.push_back(colors[subtype]);
6397+
} else {
6398+
WarningEx(LOCATION, "Invalid +Field Debris Type value %d in asteroid field (must be 0-%d); ignoring.", subtype, NUM_ASTEROID_SIZES - 1);
6399+
}
63966400
}
63976401
}
63986402

0 commit comments

Comments
 (0)