Anyone familiar with color code?

Ive been looking for the cause of issue #23759 because it bothers me to the point of unplayability.

So the issue seems related to the hilite function in colors.cpp:

nc_color hilite( nc_color c )
{
    const nc_color color = all_colors.get_highlight( c, HL_BLUE );
    return ( ( int )color > 0 ) ? color : h_white;
}

It seems that the last line always evaluates false and returns h_white, so whatever happens to the color variable doesnt actually matter.

However changing the line to

return color;

Doesn’t actually work, since supposed highlighted tiles will just turn black.

My best bet is that its because the variable color is probably gibberish instead of what it should actually be, and that the error lies in the get_highlight function. However by this point I get lost

nc_color color_manager::get_highlight( const nc_color color, const hl_enum bg ) const
{
    const color_id id = color_to_id( color );
    const color_struct &st = color_array[id];
    const auto &hl = st.highlight;
    return hl[bg];
}

Would someone mind giving me a brief explanation of how this function works?

Would someone mind giving me a brief explanation of how this function works?

nc_color hilite( nc_color c ) returns the highlighted (blue background) color by finding it in color_array (get_highlight). The thing is that the color and the highlighted color - are two different colors.
Here is a search in the color_array:

const color_id id = color_to_id( color );
const color_struct &st = color_array[id];

And here is a search for requested highlighted color:

const auto &hl = st.highlight;
return hl[bg];

highlight is an array of all highlighted colors values for current color (like blue highlighted in red, blue highlighted in white, etc.). These array build in corresponse with an hl_enum.

The only reason ( int )color > 0 evaluates false (as far as i can tell) is here:

const auto &hl = st.highlight;
return hl[bg];

Requested color doesn’t have initialized elements in highlight array.
If you’ll look into void color_manager::finalize() you’ll see, that there ARE colors with no highlight array initialization:

        const size_t underscore_num = std::count( root.begin(), root.end(), '_' ) -
                                      ( root.find( "light_" ) != std::string::npos ) -
                                      ( root.find( "dark_" ) != std::string::npos );
        // do not try to highlight color pairs, highlighted, background, and invalid colors
        if( my_name.substr( 0, 2 ) == "c_" && root != "unset" && underscore_num < 1 ) {
            for( size_t j = 0; j < NUM_HL; j++ ) {
                entry.highlight[j] = highlight_from_names( my_name, hilights[j] );
            }
        }
    }

These colors are basically already backgrounded colors.
That means that when the last line in hilite evaluates false argument nc_color c is already highlighted (or has a background).

From Github issue:

All furniture that contains items, monsters that are stunned or are friendly, and anything else that gets a blue highlight dynamically applied will lose its symbol color and turn white on a blue background.

I have some contrary examples:
Furniture that contains items and has very dark lighting, piles of items on very dark tiles and house floor tiles in e’x’amine mode will not lose their symbol color. All objects/monsters with black or dark_gray colors will not lose their color (stunned zombie necromancers, etc.).

So the problem is not in hilite and get_highlight functions.

May be it’s worthwhile to debug color_array[i].highlight[HL_BLUE] and check, do all basic (with black background: def_c_green, def_c_blue, etc.) colors have highlight[HL_BLUE] initialized.

Thank you Syler!
Actually I think your counter example demonstrates that its a lot of things that are borked, for example, brown colored furniture wont highlight at all when examined!

I’ll check the color array as you say, seems like the problem lies there