Skip to content

Commit 26e9eca

Browse files
authored
Allow mods to set threshold at which shield stops taking damage (#6847)
* Allow mods to set threshold at which shield stops taking damage FSO logic dictates that shields collisions and any related sound or visuals related to shields are skipped if the shields are under 10%. This is rather unintuitive especially for mods, so this PR creates a game setting value that allows mods to set this value. Also, this PR fixes a bug where the HUD shield gauge would try and incorporate this feature but did not do it correctly. Specifically, the gauge skips shield segment rendering if the raw shield strength was 0.1 not the percent. Incorrectly using the raw value results in HUD shields being rendered (albeit faintly) even if the damage was skipping the shield and directly damaging the hull. In other words, if the shield segment was 8%, the shield segment would show faintly even the shield is skipping damage. Tested and works as expected. Also happy to discuss or answer any questions! * update local variable name for clarity * rename `ship_quadrant_shield_strength` * cleanup with updated get percent function * more cleanup * wording and safety tuning * use correct default number
1 parent d746ae4 commit 26e9eca

10 files changed

Lines changed: 58 additions & 61 deletions

File tree

code/hud/hudshield.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ void hud_shield_show_mini(const object *objp, int x_force, int y_force, int x_hu
390390
else
391391
num = i;
392392

393-
if (objp->shield_quadrant[num] < 0.1f ) {
393+
if ( (max_shield > 0.0f) && (objp->shield_quadrant[num]/max_shield < Shield_percent_skips_damage) ) {
394394
continue;
395395
}
396396

@@ -738,12 +738,12 @@ void HudGaugeShield::showShields(const object *objp, ShieldGaugeType mode, bool
738738
break;
739739
}
740740

741-
if (!config) {
741+
if ( (!config) && (max_shield > 0.0f) ) {
742742
if (!(sip->flags[Ship::Info_Flags::Model_point_shields])) {
743-
if (objp->shield_quadrant[Quadrant_xlate[i]] < 0.1f)
743+
if (objp->shield_quadrant[Quadrant_xlate[i]]/max_shield < Shield_percent_skips_damage)
744744
continue;
745745
} else {
746-
if (objp->shield_quadrant[i] < 0.1f)
746+
if (objp->shield_quadrant[i]/max_shield < Shield_percent_skips_damage)
747747
continue;
748748
}
749749
}
@@ -1085,7 +1085,7 @@ void HudGaugeShieldMini::showMiniShields(const object *objp, bool config)
10851085
else
10861086
num = i;
10871087

1088-
if (!config && objp->shield_quadrant[num] < 0.1f ) {
1088+
if ( (!config) && (max_shield > 0.0f) && (objp->shield_quadrant[num]/max_shield < Shield_percent_skips_damage) ) {
10891089
continue;
10901090
}
10911091

code/mod_table/mod_table.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ bool Fix_asteroid_bounding_box_check;
172172
bool Disable_intro_movie;
173173
bool Show_locked_status_scramble_missions;
174174
bool Disable_expensive_turret_target_check;
175+
float Shield_percent_skips_damage;
175176

176177

177178
#ifdef WITH_DISCORD
@@ -1539,6 +1540,17 @@ void parse_mod_table(const char *filename)
15391540
stuff_boolean(&Disable_expensive_turret_target_check);
15401541
}
15411542

1543+
if (optional_string("$Threshold below which shield skips damage:")) {
1544+
float threshold;
1545+
stuff_float(&threshold);
1546+
if ((threshold >= 0.0f) && (threshold <= 1.0f)) {
1547+
Shield_percent_skips_damage = threshold;
1548+
} else {
1549+
mprintf(("Game Settings Table: '$Threshold below which shield skips damage' value of %.2f is not between 0 and 1. Using default value of 0.10.\n", threshold));
1550+
Shield_percent_skips_damage = 0.1f;
1551+
}
1552+
}
1553+
15421554
// end of options ----------------------------------------
15431555

15441556
// if we've been through once already and are at the same place, force a move
@@ -1775,6 +1787,7 @@ void mod_table_reset()
17751787
Disable_intro_movie = false;
17761788
Show_locked_status_scramble_missions = false;
17771789
Disable_expensive_turret_target_check = false;
1790+
Shield_percent_skips_damage = 0.1f;
17781791
}
17791792

17801793
void mod_table_set_version_flags()

code/mod_table/mod_table.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ extern bool Fix_asteroid_bounding_box_check;
187187
extern bool Disable_intro_movie;
188188
extern bool Show_locked_status_scramble_missions;
189189
extern bool Disable_expensive_turret_target_check;
190+
extern float Shield_percent_skips_damage;
190191

191192
void mod_table_init();
192193
void mod_table_post_process();

code/object/objectshield.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ void shield_apply_healing(object* objp, float healing)
178178
}
179179

180180
// if the shields are approximately equal give to all quads equally
181-
if (max_shield - min_shield < shield_get_max_strength(objp) * 0.1f) {
181+
if (max_shield - min_shield < shield_get_max_strength(objp) * Shield_percent_skips_damage) {
182182
for (int i = 0; i < n_quadrants; i++)
183183
shield_add_quad(objp, i, healing / n_quadrants);
184184
} else { // else give to weakest
@@ -353,6 +353,16 @@ float shield_get_quad(const object *objp, int quadrant_num)
353353
return objp->shield_quadrant[quadrant_num];
354354
}
355355

356+
float shield_get_quad_percent(const object* objp, int quadrant_num)
357+
{
358+
float max_quad = shield_get_max_quad(objp);
359+
if (max_quad > 0.0f) {
360+
return shield_get_quad(objp, quadrant_num) / max_quad;
361+
} else {
362+
return 0.0f;
363+
}
364+
}
365+
356366
float shield_get_strength(const object *objp)
357367
{
358368
Assert(objp);

code/object/objectshield.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,15 @@ void shield_add_strength(object *objp, float delta);
7575
*/
7676
float shield_get_quad(const object *objp, int quadrant_num);
7777

78+
/**
79+
* Return the shield strength of the specified quadrant on hit_objp
80+
*
81+
* @param objp object pointer to ship object
82+
* @param quadrant_num shield quadrant to check
83+
* @return strength of shields in the checked quadrant as a percentage, between 0 and 1.0
84+
*/
85+
float shield_get_quad_percent(const object* objp, int quadrant_num);
86+
7887
/**
7988
* @brief Sets the strength (in HP) of a shield quadrant/sector
8089
*

code/ship/shield.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -912,14 +912,14 @@ int ship_is_shield_up( const object *obj, int quadrant )
912912
{
913913
if ( (quadrant >= 0) && (quadrant < static_cast<int>(obj->shield_quadrant.size()))) {
914914
// Just check one quadrant
915-
if (shield_get_quad(obj, quadrant) > MAX(2.0f, 0.1f * shield_get_max_quad(obj))) {
915+
if (shield_get_quad(obj, quadrant) > MAX(2.0f, Shield_percent_skips_damage * shield_get_max_quad(obj))) {
916916
return 1;
917917
}
918918
} else {
919919
// Check all quadrants
920920
float strength = shield_get_strength(obj);
921921

922-
if ( strength > MAX(2.0f*4.0f, 0.1f * shield_get_max_strength(obj)) ) {
922+
if ( strength > MAX(2.0f*4.0f, Shield_percent_skips_damage * shield_get_max_strength(obj)) ) {
923923
return 1;
924924
}
925925
}

code/ship/ship.cpp

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17266,40 +17266,6 @@ const char *ship_subsys_get_canonical_name(const ship_subsys *ss)
1726617266
return ss->system_info->subobj_name;
1726717267
}
1726817268

17269-
/**
17270-
* Return the shield strength of the specified quadrant on hit_objp
17271-
*
17272-
* @param hit_objp object pointer to ship getting hit
17273-
* @param quadrant_num shield quadrant that was hit
17274-
* @return strength of shields in the quadrant that was hit as a percentage, between 0 and 1.0
17275-
*/
17276-
float ship_quadrant_shield_strength(const object *hit_objp, int quadrant_num)
17277-
{
17278-
float max_quadrant;
17279-
17280-
// If ship doesn't have shield mesh, then return
17281-
if ( hit_objp->flags[Object::Object_Flags::No_shields] ) {
17282-
return 0.0f;
17283-
}
17284-
17285-
// If shields weren't hit, return 0
17286-
if ( quadrant_num < 0 )
17287-
return 0.0f;
17288-
17289-
max_quadrant = shield_get_max_quad(hit_objp);
17290-
if ( max_quadrant <= 0 ) {
17291-
return 0.0f;
17292-
}
17293-
17294-
Assertion(quadrant_num < static_cast<int>(hit_objp->shield_quadrant.size()), "ship_quadrant_shield_strength() called with a quadrant of %d on a ship with " SIZE_T_ARG " quadrants; get a coder!\n", quadrant_num, hit_objp->shield_quadrant.size());
17295-
17296-
if(hit_objp->shield_quadrant[quadrant_num] > max_quadrant)
17297-
mprintf(("Warning: \"%s\" has shield quadrant strength of %f out of %f\n",
17298-
Ships[hit_objp->instance].ship_name, hit_objp->shield_quadrant[quadrant_num], max_quadrant));
17299-
17300-
return hit_objp->shield_quadrant[quadrant_num]/max_quadrant;
17301-
}
17302-
1730317269
// Determine if a ship is threatened by any dumbfire projectiles (laser or missile)
1730417270
// input: sp => pointer to ship that might be threatened
1730517271
// exit: 0 => no dumbfire threats
@@ -20715,7 +20681,7 @@ void ArmorType::ParseData()
2071520681
no_content = false;
2071620682
}
2071720683

20718-
adt.piercing_start_pct = 0.1f;
20684+
adt.piercing_start_pct = Shield_percent_skips_damage;
2071920685
adt.piercing_type = -1;
2072020686

2072120687
if(optional_string("+Weapon Piercing Effect Start Limit:")) {

code/ship/ship.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1868,9 +1868,6 @@ extern int Show_shield_mesh;
18681868
extern int Ship_auto_repair; // flag to indicate auto-repair of subsystem should occur
18691869
#endif
18701870

1871-
void ship_subsystem_delete(ship *shipp);
1872-
float ship_quadrant_shield_strength(const object *hit_objp, int quadrant_num);
1873-
18741871
int ship_dumbfire_threat(ship *sp);
18751872
int ship_lock_threat(ship *sp);
18761873

code/ship/shiphit.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2424,9 +2424,9 @@ static void ship_do_damage(object *ship_objp, object *other_obj, const vec3d *hi
24242424
ImpactCondition(shipp->shield_armor_type_idx),
24252425
HitType::SHIELD,
24262426
0.0f,
2427-
// we have to do this annoying thing where we reduce the shield health a bit because it turns out the last ten percent of a shield doesn't matter
2428-
MAX(0.0f, ship_objp->shield_quadrant[quadrant] - MAX(2.0f, 0.1f * shield_get_max_quad(ship_objp))),
2429-
shield_get_max_quad(ship_objp) - MAX(2.0f, 0.1f * shield_get_max_quad(ship_objp)),
2427+
// we have to do this annoying thing where we reduce the shield health a bit because it turns out the last X percent of a shield doesn't matter
2428+
MAX(0.0f, ship_objp->shield_quadrant[quadrant] - MAX(2.0f, Shield_percent_skips_damage * shield_get_max_quad(ship_objp))),
2429+
shield_get_max_quad(ship_objp) - MAX(2.0f, Shield_percent_skips_damage * shield_get_max_quad(ship_objp)),
24302430
};
24312431
} else {
24322432
impact_data[static_cast<std::underlying_type_t<HitType>>(HitType::HULL)] = ConditionData {
@@ -2455,9 +2455,9 @@ static void ship_do_damage(object *ship_objp, object *other_obj, const vec3d *hi
24552455
ImpactCondition(shipp->shield_armor_type_idx),
24562456
HitType::SHIELD,
24572457
0.0f,
2458-
// we have to do this annoying thing where we reduce the shield health a bit because it turns out the last ten percent of a shield doesn't matter
2459-
MAX(0.0f, ship_objp->shield_quadrant[quadrant] - MAX(2.0f, 0.1f * shield_get_max_quad(ship_objp))),
2460-
shield_get_max_quad(ship_objp) - MAX(2.0f, 0.1f * shield_get_max_quad(ship_objp)),
2458+
// we have to do this annoying thing where we reduce the shield health a bit because it turns out the last X percent of a shield doesn't matter
2459+
MAX(0.0f, ship_objp->shield_quadrant[quadrant] - MAX(2.0f, Shield_percent_skips_damage * shield_get_max_quad(ship_objp))),
2460+
shield_get_max_quad(ship_objp) - MAX(2.0f, Shield_percent_skips_damage * shield_get_max_quad(ship_objp)),
24612461
};
24622462

24632463
if ( damage > 0.0f ) {
@@ -2873,9 +2873,9 @@ void ship_apply_local_damage(object *ship_objp, object *other_obj, const vec3d *
28732873
ImpactCondition(ship_p->shield_armor_type_idx),
28742874
HitType::SHIELD,
28752875
0.0f,
2876-
// we have to do this annoying thing where we reduce the shield health a bit because it turns out the last ten percent of a shield doesn't matter
2877-
MAX(0.0f, ship_objp->shield_quadrant[quadrant] - MAX(2.0f, 0.1f * shield_get_max_quad(ship_objp))),
2878-
shield_get_max_quad(ship_objp) - MAX(2.0f, 0.1f * shield_get_max_quad(ship_objp)),
2876+
// we have to do this annoying thing where we reduce the shield health a bit because it turns out the last X percent of a shield doesn't matter
2877+
MAX(0.0f, ship_objp->shield_quadrant[quadrant] - MAX(2.0f, Shield_percent_skips_damage * shield_get_max_quad(ship_objp))),
2878+
shield_get_max_quad(ship_objp) - MAX(2.0f, Shield_percent_skips_damage * shield_get_max_quad(ship_objp)),
28792879
};
28802880
} else {
28812881
impact_data[static_cast<std::underlying_type_t<HitType>>(HitType::HULL)] = ConditionData {

code/weapon/weapons.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "network/multiutil.h"
3939
#include "object/objcollide.h"
4040
#include "object/objectdock.h"
41+
#include "object/objectshield.h"
4142
#include "object/objectsnd.h"
4243
#include "parse/parsehi.h"
4344
#include "parse/parselo.h"
@@ -7328,8 +7329,6 @@ void weapon_play_impact_sound(const weapon_info *wip, const vec3d *hitpos, bool
73287329
*/
73297330
void weapon_hit_do_sound(const object *hit_obj, const weapon_info *wip, const vec3d *hitpos, bool is_armed, int quadrant)
73307331
{
7331-
float shield_str;
7332-
73337332
// If non-missiles (namely lasers) expire without hitting a ship, don't play impact sound
73347333
if ( wip->subtype != WP_MISSILE ) {
73357334
if ( !hit_obj ) {
@@ -7366,14 +7365,16 @@ void weapon_hit_do_sound(const object *hit_obj, const weapon_info *wip, const ve
73667365

73677366
if ( timestamp_elapsed(Weapon_impact_timer) ) {
73687367

7368+
float shield_percent;
7369+
73697370
if ( hit_obj->type == OBJ_SHIP && quadrant >= 0 ) {
7370-
shield_str = ship_quadrant_shield_strength(hit_obj, quadrant);
7371+
shield_percent = shield_get_quad_percent(hit_obj, quadrant);
73717372
} else {
7372-
shield_str = 0.0f;
7373+
shield_percent = 0.0f;
73737374
}
73747375

7375-
// play a shield hit if shields are above 10% max in this quadrant
7376-
if ( shield_str > 0.1f ) {
7376+
// play a shield hit if shields are above X% max in this quadrant
7377+
if ( shield_percent > Shield_percent_skips_damage ) {
73777378
// Play a shield impact sound effect
73787379
if ( !(Use_weapon_class_sounds_for_hits_to_player) && (hit_obj == Player_obj)) {
73797380
snd_play_3d( gamesnd_get_game_sound(GameSounds::SHIELD_HIT_YOU), hitpos, &Eye_position );

0 commit comments

Comments
 (0)