Skip to content

Commit 1f81371

Browse files
committed
check dockpoints when changing ship class
If a ship changes class, the dockpoints on the new model may not match the dockpoints on the old model. This is most likely to happen when changing a docked ship in FRED to an incompatible ship class, but it can also happen when using the `change-ship-class` SEXP. So check the dockpoints, update them if they should be updated, and undock them if they can't.
1 parent 2296d7d commit 1f81371

1 file changed

Lines changed: 33 additions & 2 deletions

File tree

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)