Skip to content
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

Refactor aiming UI and its target selection / aim preservation #39785

Merged
merged 48 commits into from
May 3, 2020
Merged
Changes from 1 commit
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
dd72c80
Use separate functions for modes & derive relevant info from arguments
olanti-p Apr 17, 2020
d8bfb43
Pass arguments as class members
olanti-p Apr 17, 2020
949a0f5
Remove duplicate code for window creation, input context setup, setti…
olanti-p Apr 17, 2020
6a0b030
Deduplicate checks fired when npc/monster has been selected as target
olanti-p Apr 17, 2020
3529ad7
Consolidate movement of aim point and center of view
olanti-p Apr 18, 2020
7965e6d
Cache critter under cursor; deduplicate 'set_as_target';
olanti-p Apr 18, 2020
5764f04
Deduplicate and refine 'confirm_non_enemy_target'
olanti-p Apr 18, 2020
e5e1475
Deduplicate and refine target cycling
olanti-p Apr 18, 2020
74cbe45
Extract some variables used by FIRE and SPELL modes
olanti-p Apr 18, 2020
64e9345
Refactor how penalty from moving aim point applies to current aim
olanti-p Apr 18, 2020
b677379
Deduplicate event loop
olanti-p Apr 19, 2020
1625c61
Deduplicate terrain drawing; fix cursor-related visual bug.
olanti-p Apr 19, 2020
fc74251
Refactor drawing of window base and list of controls
olanti-p Apr 19, 2020
304a542
Break up and reorganize rendering of panels inside aiming window
olanti-p Apr 19, 2020
6516d41
Re-implement reloading guns from aiming UI
olanti-p Apr 20, 2020
7a0d7fb
Handle empty gun modes and gun modes with different range
olanti-p Apr 20, 2020
b67a646
Some minor improvements & cleanup
olanti-p Apr 20, 2020
6a0e7b7
Refactored display of vehicle turrets in range;
olanti-p Apr 20, 2020
69c2ec9
Keep 'snap-to-target' state across turns
olanti-p Apr 20, 2020
e5dee87
Refactor target selection; save aim when killing target
olanti-p Apr 20, 2020
7bb5020
Remove old comments
olanti-p Apr 20, 2020
46f2157
Extract window creation and input context setup into function
olanti-p Apr 20, 2020
eca972b
Replace enum TARGET_MODE_* with enum class TargetMode
olanti-p Apr 20, 2020
f394840
Show info about creatures only if player can see them
olanti-p Apr 20, 2020
117918c
Merge branch 'master' into target_ui-as-class
olanti-p Apr 20, 2020
dc93ba3
Update list of targets when range changes
olanti-p Apr 21, 2020
82342c3
Prevent an exploit when firing from monster list
olanti-p Apr 21, 2020
5907ca0
Remove debug output
olanti-p Apr 21, 2020
ca0ea7c
Disable switching aim mode when you can't aim/shoot
olanti-p Apr 21, 2020
80097f3
For compact version, draw over bottom border
olanti-p Apr 21, 2020
a6d5eb2
Invalidate aim point when moving
olanti-p Apr 21, 2020
0a61cb2
Fix player's sprite disappearing when changing Z levels
olanti-p Apr 21, 2020
3e8d092
Appease clang-tidy
olanti-p Apr 21, 2020
b97c960
Merge branch 'master' into target_ui-as-class
olanti-p Apr 21, 2020
1bd24b0
Fix incorrect usage of ui_adaptor::disable_uis_below
olanti-p Apr 22, 2020
9acbb8b
Update src/ranged.cpp
olanti-p Apr 22, 2020
53a4cf4
When extremely short on space, collapse blank lines reserved for target.
olanti-p Apr 22, 2020
661a841
Merge commit 'd1c39eb0d81c202e7a7b69d57988d2c2d9242fa5' into target_u…
olanti-p Apr 30, 2020
1197d21
Migrate '[?] show help' from master
olanti-p Apr 30, 2020
584f058
Dynamically shrink list of controls
olanti-p May 1, 2020
7a6b3d7
Migrate the rest of the changes from master
olanti-p May 1, 2020
327846c
Merge branch 'master' into target_ui-as-class
olanti-p May 1, 2020
7ec443b
Some positioning-related fixes
olanti-p May 1, 2020
d452cac
Remove a duplicate check
olanti-p May 1, 2020
dc64250
Better comments
olanti-p May 1, 2020
5ec7c37
Don't re-confirm attack when aim-and-fire takes multiple turns
olanti-p May 1, 2020
a3073c6
Fix regression related to aim point not snapping to nearest target wh…
olanti-p May 1, 2020
42a145d
Appease clang-tidy
olanti-p May 1, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Dynamically shrink list of controls
Resolves the problem of text overlapping on small sizes and shouldn't confuse new players since '[?] show help' is always there now
  • Loading branch information
olanti-p committed May 1, 2020
commit 584f05872cd245b1f87ac343ccfd51fd4cb3ddd3
115 changes: 74 additions & 41 deletions src/ranged.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,8 @@ class target_ui
void draw_help_notice();

// Draw list of available controls at the bottom of the window.
// Returns how much lines it took.
int draw_controls_list();
// text_y - first free line counting from the top
void draw_controls_list( int text_y );

void panel_cursor_info( int &text_y );
void panel_gun_info( int &text_y );
Expand Down Expand Up @@ -1351,9 +1351,9 @@ static int print_aim( const player &p, const catacurses::window &w, int line_num
range, target_size, predicted_recoil );
}

static int draw_throw_aim( const player &p, const catacurses::window &w, int line_number,
input_context &ctxt,
const item &weapon, const tripoint &target_pos, bool is_blind_throw )
static void draw_throw_aim( const player &p, const catacurses::window &w, int &text_y,
input_context &ctxt,
const item &weapon, const tripoint &target_pos, bool is_blind_throw )
{
Creature *target = g->critter_at( target_pos, true );
if( target != nullptr && !p.sees( *target ) ) {
Expand Down Expand Up @@ -1381,9 +1381,9 @@ static int draw_throw_aim( const player &p, const catacurses::window &w, int lin
const target_ui::TargetMode throwing_target_mode = is_blind_throw ?
target_ui::TargetMode::ThrowBlind :
target_ui::TargetMode::Throw;
return print_ranged_chance( p, w, line_number, throwing_target_mode, ctxt, weapon, dispersion,
confidence_config,
range, target_size );
text_y = print_ranged_chance( p, w, text_y, throwing_target_mode, ctxt, weapon, dispersion,
confidence_config,
range, target_size );
}

std::vector<aim_type> Character::get_aim_types( const item &gun ) const
Expand Down Expand Up @@ -2582,7 +2582,6 @@ void target_ui::draw_ui_window( player &pc )
draw_border( w_target );
draw_window_title();
draw_help_notice();
draw_controls_list();

int text_y = 1; // Skip top border

Expand Down Expand Up @@ -2614,6 +2613,8 @@ void target_ui::draw_ui_window( player &pc )
}
}

draw_controls_list( text_y );

wrefresh( w_target );
}

Expand Down Expand Up @@ -2664,32 +2665,51 @@ void target_ui::draw_help_notice()
wprintz( w_target, c_white, " >" );
}

int target_ui::draw_controls_list()
void target_ui::draw_controls_list( int text_y )
{
// Change UI colors for visual feedback
// TODO: Colorize keys inside brackets to be consistent with other UI windows
nc_color col_enabled = c_white;
nc_color col_disabled = c_light_gray;
nc_color col_move = ( status != Status::OutOfAmmo ? col_enabled : col_disabled );
nc_color col_fire = ( status == Status::Good ? col_enabled : col_disabled );

// Get first key bound to given action OR ' ' if there are none.
const auto bound_key = [this]( const std::string & s ) {
const auto keys = ctxt.keys_bound_to( s );
const std::vector<char> keys = this->ctxt.keys_bound_to( s );
return keys.empty() ? ' ' : keys.front();
};
const auto colored = [col_enabled]( nc_color color, const std::string & s ) {
if( color == col_enabled ) {
// col_enabled is the default one when printing
return s;
} else {
return colorize( s, color );
}
};

nc_color move_color = ( status != Status::OutOfAmmo ? c_white : c_light_gray );
nc_color fire_color = ( status == Status::Good ? c_white : c_light_gray );
int height = getmaxy( w_target );
struct line {
size_t order; // Lines with highest 'order' are removed first
std::string str;
};
std::vector<line> lines;

// Since this list is of variable length and positioned
// at the bottom, we draw everything in reverse order
int text_y = height - 2; // Don't draw over bottom border
// Compile full list
lines.push_back( {8, colored( col_move, _( "Move cursor with directional keys" ) )} );
if( is_mouse_enabled() ) {
const char *label_mouse = "Mouse: LMB: Target, Wheel: Cycle,";
int text_x = utf8_width( label_mouse ) + 2; // '2' for border + space at the end
mvwprintz( w_target, point( 1, text_y ), move_color, label_mouse );
mvwprintz( w_target, point( text_x, text_y-- ), fire_color, _( "RMB: Fire" ) );
std::string move = _( "Mouse: LMB: Target, Wheel: Cycle, " );
std::string fire = _( "RMB: Fire" );
lines.push_back( {7, colored( col_move, move ) + colored( col_fire, fire )} );
}
if( mode == TargetMode::Fire || mode == TargetMode::TurretManual ) {
mvwprintz( w_target, point( 1, text_y-- ), c_white, _( "[%c] to reload/switch ammo." ),
bound_key( "SWITCH_AMMO" ) );
mvwprintz( w_target, point( 1, text_y-- ), c_white, _( "[%c] to switch firing modes." ),
bound_key( "SWITCH_MODE" ) );
{
std::string cycle = string_format( _( "[%s] Cycle targets; " ), ctxt.get_desc( "NEXT_TARGET", 1 ) );
std::string fire = string_format( _( "[%c] %s." ), bound_key( "FIRE" ), uitext_fire() );
lines.push_back( {0, colored( col_move, cycle ) + colored( col_fire, fire )} );
}
{
std::string text = string_format( _( "[%c] target self; [%c] toggle snap-to-target" ),
bound_key( "CENTER" ), bound_key( "TOGGLE_SNAP_TO_TARGET" ) );
lines.push_back( {3, colored( col_enabled, text )} );
}
if( mode == TargetMode::Fire ) {
std::string aim_and_fire;
Expand All @@ -2698,25 +2718,38 @@ int target_ui::draw_controls_list()
aim_and_fire += string_format( "[%c] ", bound_key( e.action ) );
}
}
aim_and_fire += _( "to aim and fire." );

mvwprintz( w_target, point( 1, text_y-- ), fire_color, _( "[%c] to switch aiming modes." ),
bound_key( "SWITCH_AIM" ) );
mvwprintz( w_target, point( 1, text_y-- ), fire_color, _( "%sto aim and fire" ), aim_and_fire );
mvwprintz( w_target, point( 1, text_y-- ), fire_color, _( "[%c] to steady your aim. (10 moves)" ),
bound_key( "AIM" ) );
std::string aim = string_format( _( "[%c] to steady your aim. (10 moves)" ),
bound_key( "AIM" ) );
std::string sw_aim = string_format( _( "[%c] to switch aiming modes." ),
bound_key( "SWITCH_AIM" ) );

lines.push_back( {2, colored( col_fire, aim )} );
lines.push_back( {1, colored( col_fire, sw_aim )} );
lines.push_back( {4, colored( col_fire, aim_and_fire )} );
}
if( mode == TargetMode::Fire || mode == TargetMode::TurretManual ) {
lines.push_back( {5, colored( col_enabled, string_format( _( "[%c] to switch firing modes." ),
bound_key( "SWITCH_MODE" ) ) )} );
lines.push_back( {6, colored( col_enabled, string_format( _( "[%c] to reload/switch ammo." ),
bound_key( "SWITCH_AMMO" ) ) )} );
}
mvwprintz( w_target, point( 1, text_y-- ), c_white,
_( "[%c] target self; [%c] toggle snap-to-target" ), bound_key( "CENTER" ),
bound_key( "TOGGLE_SNAP_TO_TARGET" ) );

auto label_cycle = string_format( _( "[%s] Cycle targets;" ), ctxt.get_desc( "NEXT_TARGET", 1 ) );
int text_x = utf8_width( label_cycle ) + 2; // '2' for border + space at the end
mvwprintz( w_target, point( 1, text_y ), move_color, label_cycle );
mvwprintz( w_target, point( text_x, text_y-- ), fire_color, "[%c] %s.", bound_key( "FIRE" ),
uitext_fire() );
// Shrink the list until it fits
int height = getmaxy( w_target );
size_t available_lines = static_cast<size_t>( height - text_y - 1 ); // 1 for bottom border
while( lines.size() > available_lines ) {
lines.erase( std::max_element( lines.begin(), lines.end(), []( const line & l1, const line & l2 ) {
return l1.order < l2.order;
} ) );
}

mvwprintz( w_target, point( 1, text_y-- ), move_color, _( "Move cursor with directional keys" ) );
return height - text_y;
text_y = height - lines.size() - 1;
for( const line &l : lines ) {
nc_color col = col_enabled;
print_colored_text( w_target, point( 1, text_y++ ), col, col, l.str );
}
}

void target_ui::panel_cursor_info( int &text_y )
Expand Down