Skip to content

Commit be8ec82

Browse files
authored
Merge pull request #5642 from BMagnu/fix_null_shiphit
Fix null dereference when a subsystem is hit for damage by a null object
2 parents b72b768 + c2e0186 commit be8ec82

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

code/ship/shiphit.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,10 @@ float do_subobj_hit_stuff(object *ship_objp, object *other_obj, vec3d *hitpos, i
675675
int subsys_hit_first = -1; // the subsys which should be hit first and take most of the damage; index into subsys_list
676676
vec3d hitpos2;
677677
float ss_dif_scale = 1.0f; // Nuke: Set a base dificulty scale for compatibility
678+
679+
const bool other_obj_is_weapon = other_obj && other_obj->type == OBJ_WEAPON;
680+
const bool other_obj_is_shockwave = other_obj && other_obj->type == OBJ_SHOCKWAVE;
681+
const bool other_obj_is_beam = other_obj && other_obj->type == OBJ_BEAM;
678682

679683
//WMC - first, set this to damage if it isn't NULL, in case we want to return with no damage to subsystems
680684
if(hull_should_apply_armor != NULL) {
@@ -694,7 +698,7 @@ float do_subobj_hit_stuff(object *ship_objp, object *other_obj, vec3d *hitpos, i
694698
}
695699

696700
// Shockwave damage is applied like weapon damage. It gets consumed.
697-
if ((other_obj != NULL) && (other_obj->type == OBJ_SHOCKWAVE)) // Goober5000 check for NULL
701+
if (other_obj_is_shockwave)
698702
{
699703
// MK, 9/2/99. Shockwaves do zero subsystem damage on small ships.
700704
// Goober5000 - added back in via flag
@@ -713,8 +717,8 @@ float do_subobj_hit_stuff(object *ship_objp, object *other_obj, vec3d *hitpos, i
713717

714718
// scale subsystem damage if appropriate
715719
weapon_info_index = shiphit_get_damage_weapon(other_obj); // Goober5000 - a NULL other_obj returns -1
716-
if ((weapon_info_index >= 0) && ((other_obj->type == OBJ_WEAPON) ||
717-
(Beams_use_damage_factors && (other_obj->type == OBJ_BEAM)))) {
720+
if ((weapon_info_index >= 0) && (other_obj_is_weapon ||
721+
(Beams_use_damage_factors && other_obj_is_beam))) {
718722
if ( Weapon_info[weapon_info_index].wi_flags[Weapon::Info_Flags::Training] ) {
719723
return damage_left;
720724
}
@@ -891,7 +895,7 @@ float do_subobj_hit_stuff(object *ship_objp, object *other_obj, vec3d *hitpos, i
891895
if ( (j == 0) && (!(parent_armor_flags & SAF_IGNORE_SS_ARMOR))) {
892896
if(subsystem->armor_type_idx > -1)
893897
{
894-
damage = Armor_types[subsystem->armor_type_idx].GetDamage(damage, dmg_type_idx, 1.0f, other_obj->type == OBJ_BEAM); // Nuke: I don't think we need to apply damage sacaling to this one, using 1.0f
898+
damage = Armor_types[subsystem->armor_type_idx].GetDamage(damage, dmg_type_idx, 1.0f, other_obj_is_beam); // Nuke: I don't think we need to apply damage sacaling to this one, using 1.0f
895899
if(hull_should_apply_armor) {
896900
*hull_should_apply_armor = false;
897901
}
@@ -903,7 +907,7 @@ float do_subobj_hit_stuff(object *ship_objp, object *other_obj, vec3d *hitpos, i
903907
// miss their target. There is code dating to FS1 in the collision code to detect that a bomb or
904908
// missile has somehow missed its target. It gets its lifeleft set to 0.1 and then it detonates.
905909
// Unfortunately, the shockwave damage was cut by 4 above. So boost it back up here.
906-
if ((weapon_info_index >= 0) && (dist < 10.0f) && ((other_obj) && (other_obj->type == OBJ_SHOCKWAVE))) { // Goober5000 check for NULL
910+
if ((weapon_info_index >= 0) && (dist < 10.0f) && other_obj_is_shockwave) { // Goober5000 check for NULL
907911
damage_left *= 4.0f * Weapon_info[weapon_info_index].subsystem_factor;
908912
damage_if_hull *= 4.0f * Weapon_info[weapon_info_index].armor_factor;
909913
}
@@ -953,9 +957,9 @@ float do_subobj_hit_stuff(object *ship_objp, object *other_obj, vec3d *hitpos, i
953957

954958
// if this subsystem doesn't carry damage then subtract it off of our total return
955959
if (subsystem->system_info->flags[Model::Subsystem_Flags::Carry_no_damage]) {
956-
if ((other_obj->type != OBJ_SHOCKWAVE) || (!(subsystem->system_info->flags[Model::Subsystem_Flags::Carry_shockwave]))) {
960+
if (!other_obj_is_shockwave || !(subsystem->system_info->flags[Model::Subsystem_Flags::Carry_shockwave])) {
957961
float subsystem_factor = 0.0f;
958-
if ((weapon_info_index >= 0) && ((other_obj->type == OBJ_WEAPON) || (other_obj->type == OBJ_SHOCKWAVE))) {
962+
if ((weapon_info_index >= 0) && (other_obj_is_weapon || other_obj_is_shockwave)) {
959963
if (subsystem->flags[Ship::Subsystem_Flags::Damage_as_hull]) {
960964
subsystem_factor = Weapon_info[weapon_info_index].armor_factor;
961965
} else {
@@ -973,7 +977,7 @@ float do_subobj_hit_stuff(object *ship_objp, object *other_obj, vec3d *hitpos, i
973977
//Apply armor to damage
974978
if (subsystem->armor_type_idx >= 0) {
975979
// Nuke: this will finally factor it in to damage_to_apply and i wont need to factor it in anywhere after this
976-
damage_to_apply = Armor_types[subsystem->armor_type_idx].GetDamage(damage_to_apply, dmg_type_idx, ss_dif_scale, other_obj->type == OBJ_BEAM);
980+
damage_to_apply = Armor_types[subsystem->armor_type_idx].GetDamage(damage_to_apply, dmg_type_idx, ss_dif_scale, other_obj_is_beam);
977981
} else { // Nuke: no get damage call to apply difficulty scaling, so factor it in now
978982
damage_to_apply *= ss_dif_scale;
979983
}

0 commit comments

Comments
 (0)