Allow defining separate player and target shield icons for config (#6691)

* Allow defining separate player and target shield icons for config

* rename define to prevent confusion with a similar define in shield.cpp

* address some feedback
This commit is contained in:
Mike Nelson authored and GitHub committed 2025-05-02 07:58:25 -04:00
1 parent 36d6fbe7e5
commit 1977c083c7
6 files changed
+100 -35

No files matched your search

+2 -1
View File
@@ -17,6 +17,7 @@
#include "globalincs/pstypes.h"
#include "hud/hudconfig.h"
#include "hud/hudobserver.h"
#include "hud/hudshield.h"
#include "iff_defs/iff_defs.h"
#include "io/key.h"
#include "io/mouse.h"
@@ -171,7 +172,7 @@ int HC_talking_head_frame = -1;
SCP_string HC_head_anim_filename;
bool HC_show_default_hud = true;
std::unordered_set<SCP_string> HC_ignored_huds;
SCP_map<SCP_string, SCP_string> HC_hud_ships;
SCP_map<SCP_string, std::array<SCP_string, num_shield_gauge_types>> HC_hud_shield_ships;
SCP_map<SCP_string, SCP_vector<SCP_string>> HC_hud_primary_weapons;
SCP_map<SCP_string, SCP_vector<SCP_string>> HC_hud_secondary_weapons;
+2 -1
View File
@@ -13,6 +13,7 @@
#define _HUDCONFIG_H
#include "hud/hud.h"
#include "hud/hudshield.h"
#include "ui/ui.h"
class player;
@@ -191,7 +192,7 @@ extern int HC_talking_head_frame;
extern SCP_string HC_head_anim_filename;
extern bool HC_show_default_hud;
extern std::unordered_set<SCP_string> HC_ignored_huds;
extern SCP_map<SCP_string, SCP_string> HC_hud_ships;
extern SCP_map<SCP_string, std::array<SCP_string, num_shield_gauge_types>> HC_hud_shield_ships;
extern SCP_map<SCP_string, SCP_vector<SCP_string>> HC_hud_primary_weapons;
extern SCP_map<SCP_string, SCP_vector<SCP_string>> HC_hud_secondary_weapons;
+1 -1
View File
@@ -963,7 +963,7 @@ void hud_escort_ship_hit(const object *objp, int /*quadrant*/)
for (auto &es : Escort_ships) {
if (es.objnum == objnum) {
hud_gauge_popup_start(HUD_ESCORT_VIEW);
es.escort_hit_timer = timestamp(SHIELD_HIT_DURATION);
es.escort_hit_timer = timestamp(SHIELD_HIT_FLASH_DURATION);
es.escort_hit_next_flash = timestamp(SHIELD_FLASH_INTERVAL);
break;
}
+55 -5
View File
@@ -250,9 +250,9 @@ void parse_hud_gauges_tbl(const char *filename)
bool found = false;
for (auto& ship : Ship_info) {
for (const auto& ship : Ship_info) {
if (!stricmp(ship.name, temp.c_str())) {
HC_hud_ships["default"] = ship.name;
HC_hud_shield_ships["default"][SHIELD_GAUGE_PLAYER] = ship.name;
found = true;
break;
}
@@ -263,6 +263,25 @@ void parse_hud_gauges_tbl(const char *filename)
}
}
if (optional_string("$Shield Gauge Target Ship:")) {
SCP_string temp;
stuff_string(temp, F_NAME);
bool found = false;
for (const auto& ship : Ship_info) {
if (!stricmp(ship.name, temp.c_str())) {
HC_hud_shield_ships["default"][SHIELD_GAUGE_TARGET] = ship.name;
found = true;
break;
}
}
if (!found) {
Warning(LOCATION, "Shield gauge target ship \"%s\" not found in ships.tbl!", temp.c_str());
}
}
if (optional_string("$Primary Weapons:")) {
stuff_string_list(HC_hud_primary_weapons["default"]);
}
@@ -512,10 +531,41 @@ void parse_hud_gauges_tbl(const char *filename)
}
if (optional_string("$Shield Gauge Ship:")) {
SCP_string ship;
stuff_string(ship, F_NAME);
SCP_string temp;
stuff_string(temp, F_NAME);
HC_hud_ships[name] = ship;
bool found = false;
for (const auto& ship : Ship_info) {
if (!stricmp(ship.name, temp.c_str())) {
HC_hud_shield_ships[name][SHIELD_GAUGE_PLAYER] = temp;
found = true;
break;
}
}
if (!found) {
Warning(LOCATION, "Shield gauge ship \"%s\" not found in ships.tbl!", temp.c_str());
}
}
if (optional_string("$Shield Gauge Target Ship:")) {
SCP_string temp;
stuff_string(temp, F_NAME);
bool found = false;
for (const auto& ship : Ship_info) {
if (!stricmp(ship.name, temp.c_str())) {
HC_hud_shield_ships[name][SHIELD_GAUGE_TARGET] = ship.name;
found = true;
break;
}
}
if (!found) {
Warning(LOCATION, "Shield gauge target ship \"%s\" not found in ships.tbl!", temp.c_str());
}
}
if (optional_string("$Primary Weapons:")) {
+30 -24
View File
@@ -111,9 +111,7 @@ int Hud_mini_base[GR_NUM_RESOLUTIONS][2] = {
int Shield_mini_loaded = 0;
hud_frames Shield_mini_gauge;
#define SHIELD_HIT_PLAYER 0
#define SHIELD_HIT_TARGET 1
static shield_hit_info Shield_hit_data[2];
static shield_hit_info Shield_hit_data[num_shield_gauge_types];
// translate between clockwise-from-top shield quadrant ordering to way quadrants are numbered in the game
ubyte Quadrant_xlate[DEFAULT_SHIELD_SECTIONS] = {1,0,2,3};
@@ -372,7 +370,7 @@ void hud_shield_show_mini(const object *objp, int x_force, int y_force, int x_hu
sy = (y_force == -1) ? Shield_mini_coords[gr_screen.res][1] : y_force;
// draw the ship first
hud_shield_maybe_flash(HUD_TARGET_MINI_ICON, SHIELD_HIT_TARGET, Shield_hit_data[SHIELD_HIT_TARGET].hull_hit_index);
hud_shield_maybe_flash(HUD_TARGET_MINI_ICON, SHIELD_GAUGE_TARGET, Shield_hit_data[SHIELD_GAUGE_TARGET].hull_hit_index);
hud_show_mini_ship_integrity(objp, x_force + x_hull_offset,y_force + y_hull_offset);
// draw the four quadrants
@@ -396,7 +394,7 @@ void hud_shield_show_mini(const object *objp, int x_force, int y_force, int x_hu
continue;
}
if ( hud_shield_maybe_flash(HUD_TARGET_MINI_ICON, SHIELD_HIT_TARGET, i) ) {
if ( hud_shield_maybe_flash(HUD_TARGET_MINI_ICON, SHIELD_GAUGE_TARGET, i) ) {
frame_offset = i+n_quadrants;
} else {
frame_offset = i;
@@ -460,9 +458,9 @@ void hud_shield_hit_reset(const object *objp, int player)
shield_hit_info *shi;
if (player) {
shi = &Shield_hit_data[SHIELD_HIT_PLAYER];
shi = &Shield_hit_data[SHIELD_GAUGE_PLAYER];
} else {
shi = &Shield_hit_data[SHIELD_HIT_TARGET];
shi = &Shield_hit_data[SHIELD_GAUGE_TARGET];
}
shield_info_reset(objp, shi);
@@ -516,9 +514,9 @@ void hud_shield_quadrant_hit(const object *objp, int quadrant)
hud_gauge_popup_start(HUD_TARGET_MINI_ICON);
if ( OBJ_INDEX(objp) == Player_ai->target_objnum ) {
shi = &Shield_hit_data[SHIELD_HIT_TARGET];
shi = &Shield_hit_data[SHIELD_GAUGE_TARGET];
} else if ( objp == Player_obj ) {
shi = &Shield_hit_data[SHIELD_HIT_PLAYER];
shi = &Shield_hit_data[SHIELD_GAUGE_PLAYER];
} else {
return;
}
@@ -554,7 +552,7 @@ void HudGaugeShield::render(float /*frametime*/, bool /*config*/)
{
}
void HudGaugeShield::showShields(const object *objp, int mode, bool config)
void HudGaugeShield::showShields(const object *objp, ShieldGaugeType mode, bool config)
{
if (!config && objp->type != OBJ_SHIP )
return;
@@ -569,21 +567,28 @@ void HudGaugeShield::showShields(const object *objp, int mode, bool config)
sp = &Ships[objp->instance];
sip = &Ship_info[sp->ship_info_index];
} else {
SCP_string ship_name = "gtf myrmidon";
// Check if the mod specifies a differnt default
if (auto it = HC_hud_ships.find("default"); it != HC_hud_ships.end()) {
ship_name = it->second;
}
SCP_string ship_name;
// Now check if the current HUD specifies a different ship
if (SCP_vector_inbounds(HC_available_huds, HC_chosen_hud)) {
SCP_string hud = HC_available_huds[HC_chosen_hud].second;
if (auto it = HC_hud_ships.find(hud); it != HC_hud_ships.end()) {
ship_name = it->second;
if (auto it = HC_hud_shield_ships.find(hud); it != HC_hud_shield_ships.end()) {
ship_name = it->second[mode];
}
}
// If we don't have a specific setting then let's try using the global setting
if (ship_name.empty()) {
if (auto it = HC_hud_shield_ships.find("default"); it != HC_hud_shield_ships.end()) {
ship_name = it->second[mode];
}
}
// If we still don't have something then try to use the FS2 retail default
if (ship_name.empty()) {
ship_name = "gtf myrmidon";
}
// Try to find the ship with the name specified in the config
for (ship_info& ship : Ship_info) {
if (!stricmp(ship.name, ship_name.c_str()) &&
@@ -592,6 +597,7 @@ void HudGaugeShield::showShields(const object *objp, int mode, bool config)
break;
}
}
// Couldn't find it so just get the first ship with shields
if (sip == nullptr) {
for (ship_info& ship : Ship_info) {
@@ -653,7 +659,7 @@ void HudGaugeShield::showShields(const object *objp, int mode, bool config)
// draw the ship first
if (!config) {
maybeFlashShield(SHIELD_HIT_PLAYER, Shield_hit_data[SHIELD_HIT_PLAYER].hull_hit_index);
maybeFlashShield(SHIELD_GAUGE_PLAYER, Shield_hit_data[SHIELD_GAUGE_PLAYER].hull_hit_index);
}
if(sip->shield_icon_index != 255)
@@ -909,7 +915,7 @@ void HudGaugeShield::renderShieldIcon(coord2d coords[6])
gr_reset_screen_scale();
}
int HudGaugeShield::maybeFlashShield(int target_index, int shield_offset)
int HudGaugeShield::maybeFlashShield(ShieldGaugeType target_index, int shield_offset)
{
int flashed = 0;
shield_hit_info *shi;
@@ -941,7 +947,7 @@ void HudGaugeShieldPlayer::render(float /*frametime*/, bool config)
if (!config) {
player = Player_obj;
}
showShields(player, SHIELD_HIT_PLAYER, config);
showShields(player, SHIELD_GAUGE_PLAYER, config);
}
HudGaugeShieldTarget::HudGaugeShieldTarget():
@@ -969,7 +975,7 @@ void HudGaugeShieldTarget::render(float /*frametime*/, bool config)
return;
}
showShields(targetp, SHIELD_HIT_TARGET, config);
showShields(targetp, SHIELD_GAUGE_TARGET, config);
}
HudGaugeShieldMini::HudGaugeShieldMini(): // HUD_TARGET_MINI_ICON
@@ -1052,7 +1058,7 @@ void HudGaugeShieldMini::showMiniShields(const object *objp, bool config)
// draw the ship first
if (!config) {
maybeFlashShield(SHIELD_HIT_TARGET, Shield_hit_data[SHIELD_HIT_TARGET].hull_hit_index);
maybeFlashShield(SHIELD_GAUGE_TARGET, Shield_hit_data[SHIELD_GAUGE_TARGET].hull_hit_index);
}
showIntegrity(config ? 1.0f : get_hull_pct(objp), config);
@@ -1084,7 +1090,7 @@ void HudGaugeShieldMini::showMiniShields(const object *objp, bool config)
}
int frame_offset;
if (!config && maybeFlashShield(SHIELD_HIT_TARGET, i) ) {
if (!config && maybeFlashShield(SHIELD_GAUGE_TARGET, i) ) {
frame_offset = i+n_quadrants;
} else {
frame_offset = i;
+10 -3
View File
@@ -15,9 +15,16 @@
#include "globalincs/pstypes.h"
#include "hud/hud.h"
#define SHIELD_HIT_DURATION 1400 // time a shield quadrant flashes after being hit
#define SHIELD_HIT_FLASH_DURATION 1400 // time a shield quadrant flashes after being hit
#define SHIELD_FLASH_INTERVAL 200 // time between shield quadrant flashes
enum ShieldGaugeType {
SHIELD_GAUGE_PLAYER,
SHIELD_GAUGE_TARGET,
num_shield_gauge_types
};
typedef struct shield_hit_info
{
int members;
@@ -57,9 +64,9 @@ protected:
public:
HudGaugeShield();
HudGaugeShield(int _gauge_object, int _gauge_config);
void showShields(const object* objp, int mode, bool config);
void showShields(const object* objp, ShieldGaugeType mode, bool config);
void render(float frametime, bool config = false) override;
int maybeFlashShield(int target_index, int shield_offset);
int maybeFlashShield(ShieldGaugeType target_index, int shield_offset);
void renderShieldIcon(coord2d coords[6]);
};