Skip to content

Commit

Permalink
Accessibility IFF colors (#6300)
Browse files Browse the repository at this point in the history
* accessibility iff colors

* appease clang the conqueror
  • Loading branch information
MjnMixael authored Aug 26, 2024
1 parent 91a673a commit 6280ffe
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 26 deletions.
155 changes: 130 additions & 25 deletions code/iff_defs/iff_defs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "mission/missionparse.h"
#include "parse/parselo.h"
#include "ship/ship.h"
#include "options/Option.h"

extern int radar_target_id_flags;

Expand Down Expand Up @@ -40,6 +41,21 @@ flag_def_list rti_flags[] = {

int Num_rti_flags = sizeof(rti_flags)/sizeof(flag_def_list);

static bool AccessiblitySupported = false;

// used by In-Game Options menu
static bool AccessibilityEnabled = false;

static auto AccessibilityOption = options::OptionBuilder<bool>("Game.IffAccessibility",
std::pair<const char*, int>{"Accessibility IFF Colors", 1855},
std::pair<const char*, int>{"Enables or disables IFF Accessibility color overrides", 1856})
.category(std::make_pair("Game", 1824))
.default_val(false)
.level(options::ExpertLevel::Advanced)
.bind_to_once(&AccessibilityEnabled)
.importance(60)
.finish();

/**
* Borrowed from ship.cpp, ship_iff_init_colors
*
Expand Down Expand Up @@ -113,6 +129,8 @@ struct observed_color_t {

static SCP_vector<SCP_vector<observed_color_t>> observed_color_table;

static SCP_vector<SCP_vector<observed_color_t>> accessibility_observed_color_table;

void resolve_iff_data()
{
// first get the traitor
Expand Down Expand Up @@ -157,13 +175,30 @@ void resolve_iff_data()
int target_iff = iff_lookup(observed_color.iff_name);

// valid?
if (target_iff >= 0)
if (target_iff >= 0) {
iff->observed_color_map[target_iff] = observed_color.color_index;
else
} else{
Warning(LOCATION,
"Observed color IFF %s not found for IFF %s in iff_defs.tbl!\n",
observed_color.iff_name,
iff->iff_name);
}
}

// resolve the accessibility observed color list names
for (const auto& observed_color : accessibility_observed_color_table[cur_iff]) {
// find out who
int target_iff = iff_lookup(observed_color.iff_name);

// valid?
if (target_iff >= 0) {
iff->accessibility_observed_color_map[target_iff] = observed_color.color_index;
} else {
Warning(LOCATION,
"Observed color IFF %s not found for IFF %s in iff_defs.tbl!\n",
observed_color.iff_name,
iff->iff_name);
}
}

// resolve the all teams at war relationships
Expand Down Expand Up @@ -246,6 +281,10 @@ void parse_iff_table(const char* filename)
stuff_string(traitor_name, F_NAME, NAME_LENGTH);
}

if (optional_string("$Accessibility Supported:")) {
stuff_boolean(&AccessiblitySupported);
}

int rgb[3];

// check if alternate colours are wanted to be used for these
Expand Down Expand Up @@ -435,9 +474,12 @@ void parse_iff_table(const char* filename)
Iff_info.push_back(ifft);
attack_names.emplace_back();
observed_color_table.emplace_back();
accessibility_observed_color_table.emplace_back();
iffp = &Iff_info[Iff_info.size() - 1];
//Initialize this to white for new IFFs
iffp->color_index = iff_init_color(255, 255, 255);
// Initialize this to white for new IFFs
iffp->accessibility_color_index = iff_init_color(255, 255, 255);
//Make sure flags are reset for new IFFs
iffp->default_parse_flags.reset();
}
Expand All @@ -450,6 +492,12 @@ void parse_iff_table(const char* filename)
iffp->color_index = iff_init_color(rgb[0], rgb[1], rgb[2]);
}

// get the accessiblity iff color
if (optional_string_either("$Accessibility Colour:", "$Accessibility Color:") != -1) {
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
iffp->accessibility_color_index = iff_init_color(rgb[0], rgb[1], rgb[2]);
}


// get relationships between IFFs -------------------------------------

Expand All @@ -470,6 +518,18 @@ void parse_iff_table(const char* filename)
observed_color_table[cur_iff].back().color_index = iff_init_color(rgb[0], rgb[1], rgb[2]);
}

// get the list of accessibility observed colors
while (optional_string("+Accessibility Sees")) {
accessibility_observed_color_table[cur_iff].emplace_back();
// get iff observed
stuff_string_until(accessibility_observed_color_table[cur_iff].back().iff_name, "As:", NAME_LENGTH);
required_string("As:");

// get color observed
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
accessibility_observed_color_table[cur_iff].back().color_index = iff_init_color(rgb[0], rgb[1], rgb[2]);
}

// get F3 override
iffp->hotkey_team = IFF_hotkey_team::Default;
if (optional_string("+Hotkey Team:"))
Expand Down Expand Up @@ -551,6 +611,11 @@ void iff_init()
// parse any modular tables
parse_modular_table("*-iff.tbm", parse_iff_table);

if (!AccessiblitySupported) {
options::OptionsManager::instance()->removeOption(AccessibilityOption);
AccessibilityEnabled = false;
}

// now resolve the relationships
resolve_iff_data();
}
Expand Down Expand Up @@ -665,14 +730,29 @@ color *iff_get_color(int color_index, int is_bright)
*/
color *iff_get_color_by_team(int team, int seen_from_team, int is_bright)
{
Assert(team >= 0 && team < (int)Iff_info.size());
Assert(seen_from_team < (int)Iff_info.size());
Assert(is_bright == 0 || is_bright == 1);
Assertion(SCP_vector_inbounds(Iff_info, team), "Cannot get color by team because team is invalid. Get a coder!");
Assertion((is_bright == 0 || is_bright == 1), "Error with brightness selection when getting color. Get a coder!");

int color_index;
SCP_map<int, int> color_map;

if (AccessibilityEnabled) {
color_index = Iff_info[team].accessibility_color_index;
if (SCP_vector_inbounds(Iff_info, seen_from_team)) {
color_map = Iff_info[seen_from_team].accessibility_observed_color_map;
}
} else {
color_index = Iff_info[team].color_index;
if (SCP_vector_inbounds(Iff_info, seen_from_team)) {
color_map = Iff_info[seen_from_team].observed_color_map;
}
}


// is this guy being seen by anyone?
if (seen_from_team < 0)
return is_bright == 0 ? &Iff_colors[Iff_info[team].color_index].first : &Iff_colors[Iff_info[team].color_index].second;
if (seen_from_team < 0) {
return is_bright == 0 ? &Iff_colors[color_index].first : &Iff_colors[color_index].second;
}

// Goober5000 - base the following on "sees X as" from iff code
// c.f. AL's comment:
Expand All @@ -682,13 +762,17 @@ color *iff_get_color_by_team(int team, int seen_from_team, int is_bright)
// drawn friendly. If the team is different than the player's, then draw the
// appropriate IFF.

// This goes here because seen_from_team can validly be a negative number. In that case color_map is undefined
// but that doesn't matter because we return in the statement above here. Below here, color_map needs to be defined
// which will happen if seen_from_team is valid.
Assertion(SCP_vector_inbounds(Iff_info, seen_from_team), "Cannot get color because seen_from_team is invalid. Get a coder!");

// assume an observed color is defined; if not, use normal color
auto it = Iff_info[seen_from_team].observed_color_map.find(team);
int color_index = Iff_info[team].color_index;
auto it = color_map.find(team);

if (it != Iff_info[seen_from_team].observed_color_map.end())
if (it != color_map.end()) {
color_index = it->second;
}

return is_bright == 0 ? &Iff_colors[color_index].first : &Iff_colors[color_index].second;
}
Expand All @@ -700,23 +784,43 @@ color *iff_get_color_by_team(int team, int seen_from_team, int is_bright)
*/
color *iff_get_color_by_team_and_object(int team, int seen_from_team, int is_bright, object *objp)
{
Assert(team >= 0 && team < (int)Iff_info.size());
Assert(seen_from_team < (int)Iff_info.size());
Assert(is_bright == 0 || is_bright == 1);
Assertion(SCP_vector_inbounds(Iff_info, team), "Cannot get color by team because team is invalid. Get a coder!");
Assertion((is_bright == 0 || is_bright == 1), "Error with brightness selection when getting color. Get a coder!");

int alt_color_index = -1;
int color_index;
SCP_map<int, int> color_map;

if (AccessibilityEnabled) {
color_index = Iff_info[team].accessibility_color_index;
if (SCP_vector_inbounds(Iff_info, seen_from_team)) {
color_map = Iff_info[seen_from_team].accessibility_observed_color_map;
}
} else {
color_index = Iff_info[team].color_index;
if (SCP_vector_inbounds(Iff_info, seen_from_team)) {
color_map = Iff_info[seen_from_team].observed_color_map;
}
}

// is this guy being seen by anyone?
if (seen_from_team < 0)
return is_bright == 0 ? &Iff_colors[Iff_info[team].color_index].first : &Iff_colors[Iff_info[team].color_index].second;
if (seen_from_team < 0) {
return is_bright == 0 ? &Iff_colors[color_index].first : &Iff_colors[color_index].second;
}

// This goes here because seen_from_team can validly be a negative number. In that case color_map is undefined
// but that doesn't matter because we return in the statement above here. Below here, color_map needs to be defined
// which will happen if seen_from_team is valid.
Assertion(SCP_vector_inbounds(Iff_info, seen_from_team), "Cannot get color because seen_from_team is invalid. Get a coder!");

int color_index = -1;
int this_color_index = -1;
{
auto it = Iff_info[seen_from_team].observed_color_map.find(team);
if (it != Iff_info[seen_from_team].observed_color_map.end())
color_index = it->second;
auto it = color_map.find(team);
if (it != color_map.end())
this_color_index = it->second;
}

int alt_color_index = -1;

// switch in case some sort of parent iff color inheritance for example for bombs is wanted...
switch(objp->type)
{
Expand All @@ -740,11 +844,12 @@ color *iff_get_color_by_team_and_object(int team, int seen_from_team, int is_bri
}

// temporary solution....
if (alt_color_index >= 0)
color_index = alt_color_index;
if (color_index < 0)
color_index = Iff_info[team].color_index;
if (alt_color_index >= 0) {
this_color_index = alt_color_index;
} else {
this_color_index = color_index;
}


return is_bright == 0 ? &Iff_colors[color_index].first : &Iff_colors[color_index].second;
return is_bright == 0 ? &Iff_colors[this_color_index].first : &Iff_colors[this_color_index].second;
}
2 changes: 2 additions & 0 deletions code/iff_defs/iff_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,13 @@ typedef struct iff_info {
// required stuff
char iff_name[NAME_LENGTH];
int color_index; // treat this as private and use iff_get_color or iff_get_color_by_team
int accessibility_color_index;

// relationships
int attackee_bitmask; // treat this as private and use iff_get_attackee_mask or iff_x_attacks_y
int attackee_bitmask_all_teams_at_war; // treat this as private and use iff_get_attackee_mask or iff_x_attacks_y
SCP_map<int, int> observed_color_map; // treat this as private and use iff_get_color or iff_get_color_by_team
SCP_map<int, int> accessibility_observed_color_map;
IFF_hotkey_team hotkey_team;

// flags
Expand Down
2 changes: 1 addition & 1 deletion code/localization/localize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ bool *Lcl_unexpected_tstring_check = nullptr;
// NOTE: with map storage of XSTR strings, the indexes no longer need to be contiguous,
// but internal strings should still increment XSTR_SIZE to avoid collisions.
// retail XSTR_SIZE = 1570
// #define XSTR_SIZE 1855 // This is the next available ID
// #define XSTR_SIZE 1857 // This is the next available ID


// struct to allow for strings.tbl-determined x offset
Expand Down

0 comments on commit 6280ffe

Please sign in to comment.