Skip to content

Commit 7eff790

Browse files
authored
Allow mods to tune generic debris generation (#7027)
* Allow 'No Impact Debris' to also apply to explosions The ship/subsystem flag `no impact debris` prevents the default debris shards from spawning, which is very valuable especially now that impact effects can be completely customized via the -particles table. Now that particle effects are also an option for ship and subsystems explosions, it is also invaluable to have the ability to turn off the spawning of shards when either of those explosions happen. This PR uses the same flag of `no impact debris` and simply does not spawn the default shards for ship explosions or subsystem explosions of that flag is enabled. I thought about adding two new flags, but that would add to the flag clutter, and most folks who use these flags to turn off impacts I would estimate also want them off for actual explosions. Also, a new flag called `no explosion debris` would likely be confusing, so if a new flag were to be added it should be called something like `no default explosion debris shards` or something. Overall I've opted with the simpler and cleaner solution to just have it all under the impact flags. If two new flags are desired though I can easily add them. Tested and works as expected. * throw clang a bone * use two different flags * update flag name * typo and logic fix * allow custom generic debris to always work * update to better methods * cleanup logic * clang
1 parent 2808606 commit 7eff790

8 files changed

Lines changed: 66 additions & 15 deletions

File tree

code/debris/debris.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,14 +1305,21 @@ void create_generic_debris(object* ship_objp, const vec3d* pos, float min_num_de
13051305
if (ship_objp->type != OBJ_SHIP)
13061306
return;
13071307

1308+
// determine if using custom or non-custom generic debris
1309+
int model_num = use_ship_debris ? Ship_info[Ships[ship_objp->instance].ship_info_index].generic_debris_model_num : -1;
1310+
1311+
// if using non-custom generic debris, then bail early if that kind of debris is not allowed --wookeejedi
1312+
if ( (model_num < 0) && (Disable_all_noncustom_generic_debris) ) {
1313+
return;
1314+
}
1315+
13081316
float num_debris = frand_range(min_num_debris, max_num_debris);
13091317

13101318
num_debris *= (Detail.num_small_debris + 0.5f) / 4.5f;
13111319

13121320
vec3d create_pos = *pos;
13131321
for (int i = 0; i < num_debris; i++) {
1314-
int model_num = use_ship_debris ? Ship_info[Ships[ship_objp->instance].ship_info_index].generic_debris_model_num : -1;
1315-
debris_create(ship_objp, model_num, -1, &create_pos, pos, 0, speed_mult);
1322+
debris_create(ship_objp, model_num, -1, &create_pos, pos, false, speed_mult);
13161323
}
13171324
}
13181325

code/mod_table/mod_table.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ bool Disabled_or_disrupted_engines_silent;
162162
std::array<std::tuple<float, float>, 6> Fred_spacemouse_nonlinearity;
163163
bool Randomize_particle_rotation;
164164
bool Disable_shield_effects;
165+
bool Disable_all_noncustom_generic_debris;
165166
bool Calculate_subsystem_hitpoints_after_parsing;
166167
bool Disable_internal_loadout_restoration_system;
167168
bool Contrails_use_absolute_speed;
@@ -995,6 +996,10 @@ void parse_mod_table(const char *filename)
995996
stuff_boolean(&Disable_shield_effects);
996997
}
997998

999+
if (optional_string("$Disable all non-custom generic debris:")) {
1000+
stuff_boolean(&Disable_all_noncustom_generic_debris);
1001+
}
1002+
9981003
optional_string("#NETWORK SETTINGS");
9991004

10001005
if (optional_string("$FS2NetD port:")) {
@@ -1823,6 +1828,7 @@ void mod_table_reset()
18231828
std::tuple<float, float>{ 1.0f, 1.0f }
18241829
}};
18251830
Randomize_particle_rotation = false;
1831+
Disable_all_noncustom_generic_debris = false;
18261832
Disable_shield_effects = false;
18271833
Calculate_subsystem_hitpoints_after_parsing = false;
18281834
Disable_internal_loadout_restoration_system = false;

code/mod_table/mod_table.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ extern bool Disabled_or_disrupted_engines_silent;
177177
extern std::array<std::tuple<float, float>, 6> Fred_spacemouse_nonlinearity;
178178
extern bool Randomize_particle_rotation;
179179
extern bool Disable_shield_effects;
180+
extern bool Disable_all_noncustom_generic_debris;
180181
extern bool Calculate_subsystem_hitpoints_after_parsing;
181182
extern bool Disable_internal_loadout_restoration_system;
182183
extern bool Contrails_use_absolute_speed;

code/model/model_flags.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ namespace Model {
6868
No_autorepair_if_disabled, // Inversion of the previous; disallows this particular subsystem if the ship-wide flag is set (MageKing17)
6969
Share_fire_direction, // (DahBlount) Whenever the turret fires a beam, make all beams fire in the same direction.
7070
No_sparks, // Subsystem does not generate sparks if hit - m!m
71-
No_impact_debris, // Don't spawn the small debris on impact - m!m
71+
Disable_all_generic_impact_debris, // Don't spawn generic debris pieces on impact - m!m
72+
Disable_all_generic_explosion_debris, // Don't spawn generic debris pieces on explosion - wookieejedi
7273
Hide_turret_from_loadout_stats, // Turret is not accounted for in auto-generated "Turrets" line in the ship loadout window --wookieejedi
7374
Turret_distant_firepoint, //Turret barrel is very long and should be taken into account when aiming -- Kiloku
7475
Override_submodel_impact, // if a weapon impacted a submodel, but this subsystem is within range, the subsystem takes priority -- Goober5000

code/ship/ship.cpp

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,8 @@ flag_def_list_new<Model::Subsystem_Flags> Subsystem_flags[] = {
353353
{ "don't autorepair if disabled", Model::Subsystem_Flags::No_autorepair_if_disabled, true, false },
354354
{ "share fire direction", Model::Subsystem_Flags::Share_fire_direction, true, false },
355355
{ "no damage spew", Model::Subsystem_Flags::No_sparks, true, false },
356-
{ "no impact debris", Model::Subsystem_Flags::No_impact_debris, true, false },
356+
{ "disable all generic impact debris", Model::Subsystem_Flags::Disable_all_generic_impact_debris, true, false },
357+
{ "disable all generic explosion debris", Model::Subsystem_Flags::Disable_all_generic_explosion_debris, true, false },
357358
{ "hide turret from loadout stats", Model::Subsystem_Flags::Hide_turret_from_loadout_stats, true, false },
358359
{ "turret has distant firepoint", Model::Subsystem_Flags::Turret_distant_firepoint, true, false },
359360
{ "override submodel impact", Model::Subsystem_Flags::Override_submodel_impact, true, false },
@@ -412,7 +413,8 @@ flag_def_list_new<Info_Flags> Ship_flags[] = {
412413
{ "don't clamp max velocity", Info_Flags::Dont_clamp_max_velocity, true, false },
413414
{ "instantaneous acceleration", Info_Flags::Instantaneous_acceleration, true, false },
414415
{ "large ship deathroll", Info_Flags::Large_ship_deathroll, true, false },
415-
{ "no impact debris", Info_Flags::No_impact_debris, true, false },
416+
{ "disable all generic impact debris", Info_Flags::Disable_all_generic_impact_debris, true, false },
417+
{ "disable all generic explosion debris", Info_Flags::Disable_all_generic_explosion_debris, true, false },
416418
// to keep things clean, obsolete options go last
417419
{ "ballistic primaries", Info_Flags::Ballistic_primaries, false, false }
418420
};
@@ -4461,6 +4463,10 @@ static void parse_ship_values(ship_info* sip, const bool is_template, const bool
44614463
flag_found = true;
44624464
sip->flags.set(Ship::Info_Flags::Dont_clamp_max_velocity);
44634465
}
4466+
if (!stricmp(cur_flag, "no impact debris")) {
4467+
flag_found = true;
4468+
sip->flags.set(Ship::Info_Flags::Disable_all_generic_impact_debris);
4469+
}
44644470

44654471
if ( !flag_found && (ship_type_index < 0) )
44664472
Warning(LOCATION, "Bogus string in ship flags: %s\n", cur_flag);
@@ -5837,7 +5843,25 @@ static void parse_ship_values(ship_info* sip, const bool is_template, const bool
58375843
SCP_vector<SCP_string> errors;
58385844
flagset<Model::Subsystem_Flags> tmp_flags;
58395845
parse_string_flag_list(tmp_flags, Subsystem_flags, Num_subsystem_flags, &errors);
5840-
5846+
5847+
// Map of deprecated strings to their new flags
5848+
static const SCP_unordered_map<SCP_string, Model::Subsystem_Flags, SCP_string_lcase_hash, SCP_string_lcase_equal_to>
5849+
deprecated_map = {
5850+
{"no impact debris", Model::Subsystem_Flags::Disable_all_generic_impact_debris},
5851+
// { "old name", Model::Subsystem_Flags::New_flag }, // future additions
5852+
};
5853+
5854+
// Walk through errors, remap if deprecated
5855+
for (auto it = errors.begin(); it != errors.end();) {
5856+
auto found = deprecated_map.find(*it);
5857+
if (found != deprecated_map.end()) {
5858+
tmp_flags.set(found->second);
5859+
it = errors.erase(it); // remove so no bogus warning
5860+
} else {
5861+
++it;
5862+
}
5863+
}
5864+
58415865
if (optional_string("+noreplace")) {
58425866
sp->flags |= tmp_flags;
58435867
}

code/ship/ship_flags.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ namespace Ship {
217217
Instantaneous_acceleration, // Goober5000
218218
Has_display_name, // Goober5000
219219
Large_ship_deathroll, // Asteroth - big ships dont normally deathroll, this makes them do it!
220-
No_impact_debris, // wookieejedi - Don't spawn the small debris on impact
220+
Disable_all_generic_impact_debris, // wookieejedi - Don't spawn debris on impact
221+
Disable_all_generic_explosion_debris, // wookieejedi - Don't spawn debris on explosion
221222

222223
NUM_VALUES
223224
};

code/ship/shipfx.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,10 +285,19 @@ void shipfx_blow_off_subsystem(object *ship_objp, ship *ship_p, const ship_subsy
285285

286286
// create debris shards
287287
if (!(subsys->flags[Ship::Subsystem_Flags::Vanished]) && !no_explosion) {
288-
shipfx_blow_up_model(ship_objp, psub->subobj_num, 50, &subobj_pos, subsys );
288+
// default debris shard creation is flag dependent --wookieejedi
289+
int num_shards;
290+
if (Disable_all_noncustom_generic_debris ||
291+
(Ship_info[ship_p->ship_info_index].flags[Ship::Info_Flags::Disable_all_generic_explosion_debris]) ||
292+
(subsys->system_info->flags[Model::Subsystem_Flags::Disable_all_generic_explosion_debris])) {
293+
num_shards = 0;
294+
} else {
295+
num_shards = 50;
296+
}
297+
shipfx_blow_up_model(ship_objp, psub->subobj_num, num_shards, &subobj_pos, subsys);
289298

290299
// create live debris objects, if any
291-
// TODO: some MULTIPLAYER implcations here!!
300+
// TODO: some MULTIPLAYER implications here!!
292301
shipfx_subsystem_maybe_create_live_debris(ship_objp, ship_p, subsys, exp_center, 1.0f, no_fireballs);
293302

294303
if (!no_fireballs) {

code/ship/shiphit.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -797,8 +797,8 @@ std::pair<std::optional<ConditionData>, float> do_subobj_hit_stuff(object *ship_
797797
if (!global_damage) {
798798
auto subsys = ship_get_subsys_for_submodel(ship_p, submodel_num);
799799

800-
if ( !(Ship_info[ship_p->ship_info_index].flags[Ship::Info_Flags::No_impact_debris]) &&
801-
( subsys == nullptr || !(subsys->system_info->flags[Model::Subsystem_Flags::No_impact_debris]) ) ) {
800+
if ( !(Ship_info[ship_p->ship_info_index].flags[Ship::Info_Flags::Disable_all_generic_impact_debris]) &&
801+
( subsys == nullptr || !(subsys->system_info->flags[Model::Subsystem_Flags::Disable_all_generic_impact_debris]) ) ) {
802802
create_generic_debris(ship_objp, hitpos, 1.0f, 5.0f, 1.0f, false);
803803
}
804804
}
@@ -1855,19 +1855,21 @@ static void ship_vaporize(ship *shipp)
18551855
object *ship_objp;
18561856

18571857
// sanity
1858-
Assert(shipp != NULL);
1859-
if(shipp == NULL){
1858+
Assert(shipp != nullptr);
1859+
if (shipp == nullptr) {
18601860
return;
18611861
}
18621862
Assert((shipp->objnum >= 0) && (shipp->objnum < MAX_OBJECTS));
1863-
if((shipp->objnum < 0) || (shipp->objnum >= MAX_OBJECTS)){
1863+
if ( (shipp->objnum < 0) || (shipp->objnum >= MAX_OBJECTS) ) {
18641864
return;
18651865
}
18661866
ship_objp = &Objects[shipp->objnum];
18671867
ship_info* sip = &Ship_info[shipp->ship_info_index];
18681868

18691869
// create debris shards
1870-
create_generic_debris(ship_objp, &ship_objp->pos, (float)sip->generic_debris_spew_num, sip->generic_debris_spew_num * 2.0f, 1.4f, true);
1870+
if ( !(sip->flags[Ship::Info_Flags::Disable_all_generic_explosion_debris]) ) {
1871+
create_generic_debris(ship_objp, &ship_objp->pos, (float)sip->generic_debris_spew_num, sip->generic_debris_spew_num * 2.0f, 1.4f, true);
1872+
}
18711873
}
18721874

18731875
// *ship_objp was hit and we've determined he's been killed! By *other_obj!

0 commit comments

Comments
 (0)