-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix graphical overmap notes displays & mission arrow #50190
Changes from 13 commits
9faacca
9b72a71
7a760cf
3c92e3f
95e024f
4edf4b6
3965011
250f9b1
f3c1e71
71dd903
a355853
ae229e6
af19abd
04ba48d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -19,6 +19,7 @@ | |||||
#include <map> | ||||||
#include <memory> | ||||||
#include <set> | ||||||
#include <stack> | ||||||
#include <stdexcept> | ||||||
#include <type_traits> | ||||||
#include <vector> | ||||||
|
@@ -698,7 +699,8 @@ static cata::optional<std::pair<tripoint_abs_omt, std::string>> get_mission_arro | |||||
return std::make_pair( mission_target, mission_arrow_variant ); | ||||||
} | ||||||
|
||||||
const std::vector<tripoint> mission_trajectory = line_to( center.raw(), mission_target.raw() ); | ||||||
const std::vector<tripoint> mission_trajectory = line_to( center.raw(), | ||||||
tripoint( mission_target.raw().xy(), center.raw().z ) ); | ||||||
|
||||||
cata::optional<tripoint> prev; | ||||||
int z = 0; | ||||||
|
@@ -804,6 +806,24 @@ std::string cata_tiles::get_omt_id_rotation_and_subtile( | |||||
return ot_type_id.id().str(); | ||||||
} | ||||||
|
||||||
static point draw_string( Font &font, | ||||||
const SDL_Renderer_Ptr &renderer, | ||||||
const GeometryRenderer_Ptr &geometry, | ||||||
const std::string &str, | ||||||
point p, | ||||||
const unsigned char color ) | ||||||
{ | ||||||
const char *cstr = str.c_str(); | ||||||
int len = str.length(); | ||||||
while( len > 0 ) { | ||||||
const uint32_t ch32 = UTF8_getch( &cstr, &len ); | ||||||
const std::string ch = utf32_to_utf8( ch32 ); | ||||||
font.OutputChar( renderer, geometry, ch, p, color ); | ||||||
p.x += mk_wcwidth( ch32 ) * font.width; | ||||||
} | ||||||
return p; | ||||||
} | ||||||
|
||||||
void cata_tiles::draw_om( const point &dest, const tripoint_abs_omt ¢er_abs_omt, bool blink ) | ||||||
{ | ||||||
if( !g ) { | ||||||
|
@@ -831,10 +851,6 @@ void cata_tiles::draw_om( const point &dest, const tripoint_abs_omt ¢er_abs_ | |||||
geometry->rect( renderer, clipRect, SDL_Color() ); | ||||||
} | ||||||
|
||||||
// color blocks overlay; drawn on top of tiles and on top of overlay strings (if any). | ||||||
color_block_overlay_container color_blocks; | ||||||
// Strings with colors do be drawn with map_font on top of tiles. | ||||||
std::multimap<point, formatted_text> overlay_strings; | ||||||
point s; | ||||||
get_window_tile_counts( width, height, s.x, s.y ); | ||||||
|
||||||
|
@@ -1007,10 +1023,12 @@ void cata_tiles::draw_om( const point &dest, const tripoint_abs_omt ¢er_abs_ | |||||
} | ||||||
} | ||||||
|
||||||
auto npcs_near_player = overmap_buffer.get_npcs_near_player( sight_points ); | ||||||
|
||||||
// draw nearby seen npcs | ||||||
for( const shared_ptr_fast<npc> &guy : overmap_buffer.get_npcs_near_player( sight_points ) ) { | ||||||
for( const shared_ptr_fast<npc> &guy : npcs_near_player ) { | ||||||
const tripoint_abs_omt &guy_loc = guy->global_omt_location(); | ||||||
if( overmap_buffer.seen( guy_loc ) ) { | ||||||
if( guy_loc.z() == center_abs_omt.z() && ( has_debug_vision || overmap_buffer.seen( guy_loc ) ) ) { | ||||||
draw_entity_with_overlays( *guy, global_omt_to_draw_position( guy_loc ), lit_level::LIT, | ||||||
height_3d ); | ||||||
} | ||||||
|
@@ -1022,6 +1040,13 @@ void cata_tiles::draw_om( const point &dest, const tripoint_abs_omt ¢er_abs_ | |||||
false ); | ||||||
|
||||||
if( blink ) { | ||||||
// Draw path for auto-travel | ||||||
for( auto &elem : you.omt_path ) { | ||||||
tripoint_abs_omt pos( elem.xy(), you.posz() ); | ||||||
draw_from_id_string( "cursor", global_omt_to_draw_position( pos ), 0, 0, lit_level::LIT, | ||||||
false ); | ||||||
} | ||||||
|
||||||
// reduce the area where the map cursor is drawn so it doesn't get cut off | ||||||
inclusive_cuboid<tripoint> map_cursor_area = overmap_area; | ||||||
map_cursor_area.p_max.y--; | ||||||
|
@@ -1033,30 +1058,28 @@ void cata_tiles::draw_om( const point &dest, const tripoint_abs_omt ¢er_abs_ | |||||
} | ||||||
} | ||||||
|
||||||
// Labels need to be drawn last, as anything that attempts to draw a sprite after will fail. | ||||||
if( !viewing_weather && uistate.overmap_show_city_labels ) { | ||||||
|
||||||
const auto abs_sm_to_draw_label = [&]( const tripoint_abs_sm & city_pos, const int label_length ) { | ||||||
const tripoint tile_draw_pos = global_omt_to_draw_position( project_to<coords::omt> | ||||||
( city_pos ) ) - o; | ||||||
point draw_point( tile_draw_pos.x * width / max_col, tile_draw_pos.y * height / max_row ); | ||||||
draw_point.x -= label_length * font->width; | ||||||
draw_point.x += width / max_col; | ||||||
point draw_point( tile_draw_pos.x * tile_width + dest.x, | ||||||
tile_draw_pos.y * tile_height + dest.y ); | ||||||
// center text on the tile | ||||||
draw_point += point( ( tile_width - label_length * fontwidth ) / 2, | ||||||
( tile_height - fontheight ) / 2 ); | ||||||
return draw_point; | ||||||
}; | ||||||
|
||||||
// draws a black rectangle behind a label for visibility and legibility | ||||||
const auto label_bg = [&]( const tripoint_abs_sm & pos, const std::string & name ) { | ||||||
const int name_length = name.length(); | ||||||
const int name_length = utf8_width( name ); | ||||||
const point draw_pos = abs_sm_to_draw_label( pos, name_length ); | ||||||
SDL_Rect clipRect = { draw_pos.x, draw_pos.y, name_length * fontwidth, fontheight }; | ||||||
printErrorIf( SDL_RenderSetClipRect( renderer.get(), &clipRect ) != 0, | ||||||
GoLoT marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
"SDL_RenderSetClipRect failed" ); | ||||||
|
||||||
geometry->rect( renderer, clipRect, SDL_Color() ); | ||||||
|
||||||
const point label_pos( draw_pos + point( -( name.length() * fontwidth / 2 ), 0 ) ); | ||||||
map_font->OutputChar( renderer, geometry, name, label_pos, 11 ); | ||||||
draw_string( *font, renderer, geometry, name, draw_pos, 11 ); | ||||||
}; | ||||||
|
||||||
// the tiles on the overmap are overmap tiles, so we need to use | ||||||
|
@@ -1080,6 +1103,119 @@ void cata_tiles::draw_om( const point &dest, const tripoint_abs_omt ¢er_abs_ | |||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
std::vector<std::pair<nc_color, std::string>> notes_window_text; | ||||||
|
||||||
if( uistate.overmap_show_map_notes ) { | ||||||
const std::string ¬e_text = overmap_buffer.note( center_abs_omt ); | ||||||
if( !note_text.empty() ) { | ||||||
const std::tuple<char, nc_color, size_t> note_info = overmap_ui::get_note_display_info( | ||||||
note_text ); | ||||||
const size_t pos = std::get<2>( note_info ); | ||||||
if( pos != std::string::npos ) { | ||||||
notes_window_text.emplace_back( std::get<1>( note_info ), note_text.substr( pos ) ); | ||||||
} | ||||||
if( overmap_buffer.is_marked_dangerous( center_abs_omt ) ) { | ||||||
notes_window_text.emplace_back( c_red, _( "DANGEROUS AREA!" ) ); | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
if( has_debug_vision || overmap_buffer.seen( center_abs_omt ) ) { | ||||||
for( const auto &npc : npcs_near_player ) { | ||||||
if( !npc->marked_for_death && npc->global_omt_location() == center_abs_omt ) { | ||||||
notes_window_text.emplace_back( npc->basic_symbol_color(), npc->name ); | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
for( auto &v : overmap_buffer.get_vehicle( center_abs_omt ) ) { | ||||||
notes_window_text.emplace_back( c_white, v.name ); | ||||||
} | ||||||
|
||||||
if( !notes_window_text.empty() ) { | ||||||
constexpr int padding = 2; | ||||||
|
||||||
const auto draw_note_text = [&]( const point & draw_pos, const std::string & name, | ||||||
nc_color & color ) { | ||||||
char note_fg_color = color == c_yellow ? 11 : | ||||||
cata_cursesport::colorpairs[color.to_color_pair_index()].FG; | ||||||
return draw_string( *font, renderer, geometry, name, draw_pos, note_fg_color ); | ||||||
}; | ||||||
|
||||||
// Find screen coordinates to the right of the center tile | ||||||
auto center_sm = coords::project_to<coords::sm>( tripoint_abs_omt( center_abs_omt.x() + 1, | ||||||
center_abs_omt.y(), center_abs_omt.z() ) ); | ||||||
const tripoint tile_draw_pos = global_omt_to_draw_position( project_to<coords::omt> | ||||||
( center_sm ) ) - o; | ||||||
point draw_point( tile_draw_pos.x * tile_width + dest.x, | ||||||
tile_draw_pos.y * tile_height + dest.y ); | ||||||
draw_point += point( padding, padding ); | ||||||
|
||||||
// Draw notes header. Very simple label at the moment | ||||||
nc_color header_color = c_white; | ||||||
const std::string header_string = _( "-- Notes: --" ); | ||||||
SDL_Rect header_background_rect = { | ||||||
draw_point.x - padding, | ||||||
draw_point.y - padding, | ||||||
fontwidth * utf8_width( header_string ) + padding * 2, | ||||||
fontheight + padding * 2 | ||||||
}; | ||||||
geometry->rect( renderer, header_background_rect, SDL_Color{ 0, 0, 0, 175 } ); | ||||||
draw_note_text( draw_point, header_string, header_color ); | ||||||
draw_point.y += fontheight + padding * 2; | ||||||
|
||||||
const int starting_x = draw_point.x; | ||||||
|
||||||
for( auto &line : notes_window_text ) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
we generally like to limit our usage of auto. |
||||||
const auto color_segments = split_by_color( line.second ); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
as here |
||||||
std::stack<nc_color> color_stack; | ||||||
nc_color default_color = std::get<0>( line ); | ||||||
color_stack.push( default_color ); | ||||||
std::vector<std::tuple<nc_color, std::string>> colored_lines; | ||||||
|
||||||
draw_point.x = starting_x; | ||||||
|
||||||
int line_length = 0; | ||||||
for( auto seg : color_segments ) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
and here |
||||||
if( seg.empty() ) { | ||||||
continue; | ||||||
} | ||||||
|
||||||
if( seg[0] == '<' ) { | ||||||
const color_tag_parse_result::tag_type type = update_color_stack( | ||||||
color_stack, seg, report_color_error::no ); | ||||||
if( type != color_tag_parse_result::non_color_tag ) { | ||||||
seg = rm_prefix( seg ); | ||||||
} | ||||||
} | ||||||
|
||||||
nc_color &color = color_stack.empty() ? default_color : color_stack.top(); | ||||||
colored_lines.emplace_back( color, seg ); | ||||||
line_length += utf8_width( seg ); | ||||||
} | ||||||
|
||||||
// Draw background first for the whole line | ||||||
SDL_Rect background_rect = { | ||||||
draw_point.x - padding, | ||||||
draw_point.y - padding, | ||||||
fontwidth *line_length + padding * 2, | ||||||
fontheight + padding * 2 | ||||||
}; | ||||||
geometry->rect( renderer, background_rect, SDL_Color{ 0, 0, 0, 175 } ); | ||||||
|
||||||
// Draw colored text segments | ||||||
for( auto &colored_line : colored_lines ) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
std::string &text = std::get<1>( colored_line ); | ||||||
draw_point.x = draw_note_text( draw_point, text, std::get<0>( colored_line ) ).x; | ||||||
} | ||||||
|
||||||
draw_point.y += fontheight + padding; | ||||||
} | ||||||
} | ||||||
|
||||||
printErrorIf( SDL_RenderSetClipRect( renderer.get(), nullptr ) != 0, | ||||||
"SDL_RenderSetClipRect failed" ); | ||||||
} | ||||||
|
||||||
static bool draw_window( Font_Ptr &font, const catacurses::window &w, const point &offset ) | ||||||
|
@@ -2307,6 +2443,7 @@ void draw_quick_shortcuts() | |||||
text_x = ( ( i + 0.5f ) * width - ( font->width * utf8_width( text ) ) * text_scale * 0.5f ) / | ||||||
text_scale; | ||||||
} | ||||||
// TODO use draw_string instead | ||||||
text_y = ( WindowHeight - ( height + font->height * text_scale ) * 0.5f ) / text_scale; | ||||||
font->OutputChar( renderer, geometry, text, point( text_x + 1, text_y + 1 ), 0, | ||||||
get_option<int>( "ANDROID_SHORTCUT_OPACITY_SHADOW" ) * 0.01f ); | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this part be moved to a new PR so it can be backported?