Skip to content

Commit c2314f6

Browse files
authored
Merge pull request scp-fs2open#6708 from Goober5000/dockpoint_fix
check dockpoints when changing ship class
2 parents d79f506 + 1f81371 commit c2314f6

2 files changed

Lines changed: 59 additions & 4 deletions

File tree

code/globalincs/utility.h

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ int count_items_with_field(const VECTOR_T& item_vector, FIELD_T ITEM_T::* field,
233233
template <typename ITEM_T, typename FIELD_T>
234234
int count_items_with_string(const ITEM_T* item_array, int num_items, FIELD_T ITEM_T::* field, const char* str)
235235
{
236+
if (item_array == nullptr)
237+
return 0;
238+
236239
int count = 0;
237240
for (int i = 0; i < num_items; ++i)
238241
{
@@ -250,6 +253,9 @@ int count_items_with_string(const ITEM_T* item_array, int num_items, FIELD_T ITE
250253
template <typename ITEM_T, typename FIELD_T>
251254
int count_items_with_ptr_string(const ITEM_T* item_array, int num_items, FIELD_T ITEM_T::* field, const char* str)
252255
{
256+
if (item_array == nullptr)
257+
return 0;
258+
253259
int count = 0;
254260
for (int i = 0; i < num_items; ++i)
255261
{
@@ -267,6 +273,9 @@ int count_items_with_ptr_string(const ITEM_T* item_array, int num_items, FIELD_T
267273
template <typename ITEM_T, typename FIELD_T>
268274
int count_items_with_string(const ITEM_T* item_array, int num_items, FIELD_T ITEM_T::* field, const SCP_string& str)
269275
{
276+
if (item_array == nullptr)
277+
return 0;
278+
270279
int count = 0;
271280
for (int i = 0; i < num_items; ++i)
272281
if (lcase_equal(item_array[i].*field, str))
@@ -278,7 +287,7 @@ int count_items_with_string(const ITEM_T* item_array, int num_items, FIELD_T ITE
278287
template <typename ITEM_T>
279288
int count_items_with_string(const ITEM_T* item_array, int num_items, SCP_string ITEM_T::* field, const char* str)
280289
{
281-
if (str == nullptr)
290+
if (item_array == nullptr || str == nullptr)
282291
return 0;
283292

284293
return count_items_with_string(item_array, num_items, field, SCP_string(str));
@@ -287,6 +296,9 @@ int count_items_with_string(const ITEM_T* item_array, int num_items, SCP_string
287296
template <typename ITEM_T, typename FIELD_T>
288297
int count_items_with_field(const ITEM_T* item_array, int num_items, FIELD_T ITEM_T::* field, const FIELD_T& search)
289298
{
299+
if (item_array == nullptr)
300+
return 0;
301+
290302
int count = 0;
291303
for (int i = 0; i < num_items; ++i)
292304
if (item_array[i].*field == search)
@@ -375,6 +387,9 @@ int find_item_with_field(const VECTOR_T& item_vector, FIELD_T ITEM_T::* field, c
375387
template <typename ITEM_T, typename FIELD_T>
376388
int find_item_with_string(const ITEM_T* item_array, int num_items, FIELD_T ITEM_T::* field, const char* str)
377389
{
390+
if (item_array == nullptr)
391+
return -1;
392+
378393
for (int i = 0; i < num_items; ++i)
379394
{
380395
if (str == nullptr && item_array[i].*field == nullptr)
@@ -391,6 +406,9 @@ int find_item_with_string(const ITEM_T* item_array, int num_items, FIELD_T ITEM_
391406
template <typename ITEM_T, typename FIELD_T>
392407
int find_item_with_ptr_string(const ITEM_T* item_array, int num_items, FIELD_T ITEM_T::* field, const char* str)
393408
{
409+
if (item_array == nullptr)
410+
return -1;
411+
394412
for (int i = 0; i < num_items; ++i)
395413
{
396414
if (str == nullptr && (item_array[i].*field).get() == nullptr)
@@ -407,6 +425,9 @@ int find_item_with_ptr_string(const ITEM_T* item_array, int num_items, FIELD_T I
407425
template <typename ITEM_T, typename FIELD_T>
408426
int find_item_with_string(const ITEM_T* item_array, int num_items, FIELD_T ITEM_T::* field, const SCP_string& str)
409427
{
428+
if (item_array == nullptr)
429+
return -1;
430+
410431
for (int i = 0; i < num_items; ++i)
411432
if (lcase_equal(item_array[i].*field, str))
412433
return i;
@@ -417,7 +438,7 @@ int find_item_with_string(const ITEM_T* item_array, int num_items, FIELD_T ITEM_
417438
template <typename ITEM_T>
418439
int find_item_with_string(const ITEM_T* item_array, int num_items, SCP_string ITEM_T::* field, const char* str)
419440
{
420-
if (str == nullptr)
441+
if (item_array == nullptr || str == nullptr)
421442
return -1;
422443

423444
return find_item_with_string(item_array, num_items, field, str);
@@ -426,6 +447,9 @@ int find_item_with_string(const ITEM_T* item_array, int num_items, SCP_string IT
426447
template <typename ITEM_T, typename FIELD_T>
427448
int find_item_with_field(const ITEM_T* item_array, int num_items, FIELD_T ITEM_T::* field, const FIELD_T& search)
428449
{
450+
if (item_array == nullptr)
451+
return -1;
452+
429453
for (int i = 0; i < num_items; ++i)
430454
if (item_array[i].*field == search)
431455
return i;

code/ship/ship.cpp

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11751,6 +11751,10 @@ void change_ship_type(int n, int ship_type, int by_sexp)
1175111751
ship_model_change(n, ship_type);
1175211752
sp->ship_info_index = ship_type;
1175311753

11754+
// get the before and after models (the new model may have only been loaded in ship_model_change)
11755+
auto pm = model_get(sip->model_num);
11756+
auto pm_orig = model_get(sip_orig->model_num);
11757+
1175411758
// if we have the same warp parameters as the ship class, we will need to update them to point to the new class
1175511759
if (sp->warpin_params_index == sip_orig->warpin_params_index) {
1175611760
sp->warpin_params_index = sip->warpin_params_index;
@@ -11963,6 +11967,35 @@ void change_ship_type(int n, int ship_type, int by_sexp)
1196311967
delete [] subsys_names;
1196411968
delete [] subsys_pcts;
1196511969

11970+
// Goober5000 - collect data about whatever is currently docked and compare the dockpoints on the two models
11971+
auto dock_ptr = objp->dock_list;
11972+
while (dock_ptr != nullptr)
11973+
{
11974+
auto next_ptr = dock_ptr->next; // since we might remove the dock instance we are iterating on
11975+
int dockpoint_index = dock_ptr->dockpoint_used;
11976+
const char *dockpoint_name = pm_orig->docking_bays[dockpoint_index].name;
11977+
11978+
// if it's the same dockpoint index and name, do nothing
11979+
if (dockpoint_index < pm->n_docks && stricmp(dockpoint_name, pm->docking_bays[dockpoint_index].name) == 0)
11980+
{
11981+
dock_ptr = next_ptr;
11982+
continue;
11983+
}
11984+
11985+
// see if this dockpoint is found on the new model under a different name
11986+
int new_dockpoint_index = find_item_with_string(pm->docking_bays, pm->n_docks, &dock_bay::name, dockpoint_name);
11987+
if (new_dockpoint_index >= 0)
11988+
{
11989+
dock_ptr->dockpoint_used = new_dockpoint_index;
11990+
dock_ptr = next_ptr;
11991+
continue;
11992+
}
11993+
11994+
// it wasn't found, so undock these objects
11995+
ai_do_objects_undocked_stuff(objp, dock_ptr->docked_objp);
11996+
dock_ptr = next_ptr;
11997+
}
11998+
1196611999
sp->afterburner_fuel = MAX(0.0f, sip->afterburner_fuel_capacity - (sip_orig->afterburner_fuel_capacity - sp->afterburner_fuel));
1196712000

1196812001
// handle countermeasure counts
@@ -12008,8 +12041,6 @@ void change_ship_type(int n, int ship_type, int by_sexp)
1200812041
sp->ab_count = 0;
1200912042
if (sip->flags[Ship::Info_Flags::Afterburner])
1201012043
{
12011-
polymodel *pm = model_get(sip->model_num);
12012-
1201312044
for (int h = 0; h < pm->n_thrusters; h++)
1201412045
{
1201512046
for (int j = 0; j < pm->thrusters[h].num_points; j++)

0 commit comments

Comments
 (0)