From b706cca568cca4e614f97da99af3c2efbb912a97 Mon Sep 17 00:00:00 2001 From: Asteroth Date: Tue, 9 Dec 2025 12:37:53 -0500 Subject: [PATCH] fix for ships blowing up with live debris submodels --- code/model/modelread.cpp | 37 ------------------------------ code/ship/shipfx.cpp | 49 ++++++++++++---------------------------- 2 files changed, 14 insertions(+), 72 deletions(-) diff --git a/code/model/modelread.cpp b/code/model/modelread.cpp index 11f671cb817..fc82b646be8 100644 --- a/code/model/modelread.cpp +++ b/code/model/modelread.cpp @@ -3832,43 +3832,6 @@ void model_set_bay_path_nums(polymodel *pm) } } -// Get "parent" submodel for live debris submodel -int model_get_parent_submodel_for_live_debris( int model_num, int live_debris_model_num ) -{ - polymodel *pm = model_get(model_num); - - Assert(pm->submodel[live_debris_model_num].flags[Model::Submodel_flags::Is_live_debris]); - - int mn; - bsp_info *child; - - // Start with the high level of detail hull - // Check all its children until we find the submodel to which the live debris belongs - child = &pm->submodel[pm->detail[0]]; - mn = child->first_child; - - while (mn > 0) { - child = &pm->submodel[mn]; - - if (child->num_live_debris > 0) { - // check all live debris submodels for the current child - for (int idx=0; idxnum_live_debris; idx++) { - if (child->live_debris[idx] == live_debris_model_num) { - return mn; - } - } - // DKA 5/26/99: can multiple live debris subsystems with each ship - // NO LONGER TRUE Can only be 1 submodel with live debris - // Error( LOCATION, "Could not find parent submodel for live debris. Possible model error"); - } - - // get next child - mn = child->next_sibling; - } - Error( LOCATION, "Could not find parent submodel for live debris"); - return -1; -} - float model_get_radius( int modelnum ) { diff --git a/code/ship/shipfx.cpp b/code/ship/shipfx.cpp index ea3aac21d30..0931603620d 100644 --- a/code/ship/shipfx.cpp +++ b/code/ship/shipfx.cpp @@ -221,7 +221,7 @@ static void shipfx_subsystem_maybe_create_live_debris(object *ship_objp, const s static void shipfx_maybe_create_live_debris_at_ship_death( object *ship_objp ) { // if ship has live debris, detonate that subsystem now - // search for any live debris + // search for any submodels which have live debris ship *shipp = &Ships[ship_objp->instance]; polymodel *pm = model_get(Ship_info[shipp->ship_info_index].model_num); @@ -232,41 +232,20 @@ static void shipfx_maybe_create_live_debris_at_ship_death( object *ship_objp ) return; } - int live_debris_submodel = -1; - for (int idx=0; idxnum_debris_objects; idx++) { - if (pm->submodel[pm->debris_objects[idx]].flags[Model::Submodel_flags::Is_live_debris]) { - live_debris_submodel = pm->debris_objects[idx]; - - // get submodel that produces live debris - int model_get_parent_submodel_for_live_debris( int model_num, int live_debris_model_num ); - int parent = model_get_parent_submodel_for_live_debris(pm->id, live_debris_submodel); - Assert(parent != -1); - - // check if already blown off (ship model set) - if ( !pmi->submodel[parent].blown_off ) { - - // get ship_subsys for live_debris - // Go through all subsystems and look for submodel the subsystems with "parent" submodel. - ship_subsys *pss = NULL; - for ( pss = GET_FIRST(&shipp->subsys_list); pss != END_OF_LIST(&shipp->subsys_list); pss = GET_NEXT(pss) ) { - if (pss->system_info->subobj_num == parent) { - break; - } - } - - Assert (pss != NULL); - if (pss != NULL) { - if (pss->system_info != NULL) { - vec3d exp_center, tmp = ZERO_VECTOR; - model_instance_local_to_global_point(&exp_center, &tmp, pm, pmi, parent, &ship_objp->orient, &ship_objp->pos ); - - // if not blown off, blow it off - shipfx_subsystem_maybe_create_live_debris(ship_objp, shipp, pss, &exp_center, 3.0f); + ship_subsys* pss = nullptr; + for (pss = GET_FIRST(&shipp->subsys_list); pss != END_OF_LIST(&shipp->subsys_list); pss = GET_NEXT(pss)) { + if (pss->system_info != nullptr) { + int submodel_num = pss->system_info->subobj_num; + // find the submodels which aren't already blown up and have live debris + if (!pmi->submodel[submodel_num].blown_off && pm->submodel[submodel_num].num_live_debris > 0) { + vec3d exp_center, tmp = ZERO_VECTOR; + model_instance_local_to_global_point(&exp_center, &tmp, pm, pmi, submodel_num, &ship_objp->orient, &ship_objp->pos); + + // create its debris + shipfx_subsystem_maybe_create_live_debris(ship_objp, shipp, pss, &exp_center, 3.0f); - // now set subsystem as blown off, so we only get one copy - pmi->submodel[parent].blown_off = true; - } - } + // now set subsystem as blown off, so we only get one copy + pmi->submodel[submodel_num].blown_off = true; } } }