diff --git a/src/editmap.cpp b/src/editmap.cpp index 7b9a49b81adad..e199394f662a0 100644 --- a/src/editmap.cpp +++ b/src/editmap.cpp @@ -31,7 +31,6 @@ #include "flexbuffer_json-inl.h" #include "game.h" #include "game_constants.h" -#include "input_context.h" #include "input_enums.h" #include "item.h" #include "level_cache.h" @@ -265,7 +264,8 @@ tripoint editmap::pos2screen( const tripoint_bub_ms &p ) /* * get_direction with extended moving via HJKL keys */ -bool editmap::eget_direction( tripoint_rel_ms &p, const std::string &action ) const +bool editmap::eget_direction( tripoint_rel_ms &p, const std::string &action, + const input_context &ctxt ) const { p = tripoint_rel_ms::zero; if( action == "CENTER" ) { @@ -282,16 +282,23 @@ bool editmap::eget_direction( tripoint_rel_ms &p, const std::string &action ) co p.z() = -1; } else if( action == "LEVEL_UP" ) { p.z() = 1; + } else if( action == "SELECT" ) { + const std::optional mouse_pos = ctxt.get_coordinates( + g->w_terrain, g->ter_view_p.raw().xy(), true ); + if( !mouse_pos ) { + return false; + } + p = *mouse_pos - target; } else { - input_context ctxt( "EGET_DIRECTION" ); - ctxt.set_iso( true ); - const std::optional vec = ctxt.get_direction_rel_ms( action ); + input_context ctxt_iso( "EGET_DIRECTION" ); + ctxt_iso.set_iso( true ); + const std::optional vec = ctxt_iso.get_direction_rel_ms( action ); if( !vec ) { return false; } p = *vec; } - return true; + return p != tripoint_rel_ms::zero; } class editmap::game_draw_callback_t_container @@ -352,6 +359,7 @@ std::optional editmap::edit() input_context ctxt( "EDITMAP" ); ctxt.set_iso( true ); ctxt.register_directions(); + ctxt.register_action( "SELECT" ); ctxt.register_action( "LEFT_WIDE" ); ctxt.register_action( "RIGHT_WIDE" ); ctxt.register_action( "UP_WIDE" ); @@ -366,7 +374,7 @@ std::optional editmap::edit() ctxt.register_action( "EDIT_OVERMAP" ); ctxt.register_action( "EDIT_ITEMS" ); ctxt.register_action( "EDIT_MONSTER" ); - ctxt.register_action( "EDITMAP_SHOW_ALL" ); + ctxt.register_action( "EDITMAP_SHOW_ALL" ); // Only supported for curses ctxt.register_action( "QUIT" ); ctxt.register_action( "HELP_KEYBINDINGS" ); // Needed for timeout to be useful @@ -395,18 +403,18 @@ std::optional editmap::edit() // \u00A0 is the non-breaking space info_txt_curr = string_format( pgettext( "keybinding descriptions", - "%s, %s, %s, [%s,%s,%s,%s]\u00A0fast scroll, %s, %s, %s, %s, %s, %s" ), + "%s, %s, %s, %s, %s, %s, %s" ), ctxt.describe_key_and_name( "EDIT_TRAPS" ), ctxt.describe_key_and_name( "EDIT_FIELDS" ), ctxt.describe_key_and_name( "EDIT_RADS" ), - ctxt.get_desc( "LEFT_WIDE", 1 ), ctxt.get_desc( "RIGHT_WIDE", 1 ), - ctxt.get_desc( "UP_WIDE", 1 ), ctxt.get_desc( "DOWN_WIDE", 1 ), - ctxt.describe_key_and_name( "EDITMAP_SHOW_ALL" ), ctxt.describe_key_and_name( "EDIT_TERRAIN" ), ctxt.describe_key_and_name( "EDIT_FURNITURE" ), ctxt.describe_key_and_name( "EDIT_OVERMAP" ), - ctxt.describe_key_and_name( "EDIT_ITEMS" ), - ctxt.describe_key_and_name( "QUIT" ) ); + ctxt.describe_key_and_name( "EDIT_ITEMS" ) ); +#ifndef TILES + info_txt_curr += ", "; + info_txt_curr += ctxt.describe_key_and_name( "EDITMAP_SHOW_ALL" ); +#endif info_title_curr = pgettext( "map editor state", "Looking around" ); do_ui_invalidation(); @@ -437,7 +445,7 @@ std::optional editmap::edit() target_list.clear(); origin = target; target_list.push_back( target ); - } else if( move_target( action, 1 ) ) { + } else if( move_target( action, ctxt, 1 ) ) { recalc_target( editshape ); // target_list must follow movement } blink = action == "TIMEOUT" ? !blink : true; @@ -733,40 +741,50 @@ void editmap::update_view_with_help( const std::string &txt, const std::string & int off = 1; draw_border( w_info ); - mvwprintz( w_info, point( 2, 0 ), c_light_gray, "< %d,%d,%d >", target.x(), target.y(), + // NOLINTNEXTLINE(cata-use-named-point-constants) + mvwprintz( w_info, point( 1, 0 ), c_light_gray, "< %d,%d,%d >", target.x(), target.y(), target.z() ); - mvwputch( w_info, point( 2, off ), terrain_type.color(), terrain_type.symbol() ); - mvwprintw( w_info, point( 4, off ), _( "%d: %s; move cost %d" ), t.to_i(), - static_cast( terrain_type.id ), - terrain_type.movecost - ); - off++; // 2 + mvwputch( w_info, point( 1, off ), terrain_type.color(), terrain_type.symbol() ); + mvwprintw( w_info, point( 2, off++ ), _( "Ter: %s (%d); move cost %d" ), terrain_type.id.str(), + t.to_i(), terrain_type.movecost ); // 2 + const furn_id &f = here.furn( target ); if( f.to_i() > 0 ) { - mvwputch( w_info, point( 2, off ), furniture_type.color(), furniture_type.symbol() ); - mvwprintw( w_info, point( 4, off ), _( "%d: %s; move cost %d movestr %d" ), - f.to_i(), - static_cast( furniture_type.id ), - furniture_type.movecost, - furniture_type.move_str_req - ); - off++; // 3 + mvwputch( w_info, point( 1, off ), furniture_type.color(), furniture_type.symbol() ); + mvwprintw( w_info, point( 2, off++ ), _( "Furn: %s (%d); move cost %d; movestr %d" ), + furniture_type.id.str(), f.to_i(), furniture_type.movecost, furniture_type.move_str_req ); // 3 } + + const trap &cur_trap = here.tr_at( target ); + if( !cur_trap.is_null() ) { + mvwputch( w_info, point( 1, off ), cur_trap.color, cur_trap.sym ); + mvwprintw( w_info, point( 2, off++ ), _( "Trap: %s (%d)" ), cur_trap.id.str(), + cur_trap.loadid.to_i() ); // 4 + } + + for( auto &fld : here.get_field( target ) ) { + const field_entry &cur = fld.second; + mvwputch( w_info, point( 1, off ), cur.color(), cur.symbol() ); + mvwprintw( w_info, point( 2, off++ ), _( "Field: %s (%d); Intensity:%d (%s); Age:%d" ), + cur.get_field_type().id().str(), cur.get_field_type().to_i(), cur.get_field_intensity(), cur.name(), + to_turns( cur.get_field_age() ) ); // 5 (+1 for each field) + } + const level_cache &map_cache = here.get_cache( target.z() ); Character &player_character = get_player_character(); const std::string u_see_msg = player_character.sees( target ) ? _( "yes" ) : _( "no" ); mvwprintw( w_info, point( 1, off++ ), _( "dist: %d u_see: %s veh: %s scent: %d" ), - rl_dist( player_character.pos_bub(), target ), u_see_msg, veh_msg, get_scent().get( target ) ); + rl_dist( player_character.pos_bub(), target ), u_see_msg, veh_msg, get_scent().get( target ) ); // 6 mvwprintw( w_info, point( 1, off++ ), _( "sight_range: %d, noon_sight_range: %d," ), player_character.sight_range( g->light_level( player_character.posz() ) ), - player_character.sight_range( sun_moon_light_at_noon_near( calendar::turn ) ) ); + player_character.sight_range( sun_moon_light_at_noon_near( calendar::turn ) ) ); // 7 mvwprintw( w_info, point( 1, off++ ), _( "cache{transp:%.4f seen:%.4f cam:%.4f}" ), map_cache.transparency_cache[target.x()][target.y()], map_cache.seen_cache[target.x()][target.y()], map_cache.camera_cache[target.x()][target.y()] - ); + ); // 8 map::apparent_light_info al = map::apparent_light_helper( map_cache, tripoint_bub_ms( target ) ); int apparent_light = static_cast( here.apparent_light_at( target, here.get_visibility_variables_cache() ) ); @@ -774,11 +792,11 @@ void editmap::update_view_with_help( const std::string &txt, const std::string & static_cast( here.is_outside( target ) ), static_cast( al.obstructed ), static_cast( here.has_floor( target ) ) - ); + ); // 9 mvwprintw( w_info, point( 1, off++ ), _( "light_at: %s" ), - map_cache.lm[target.x()][target.y()].to_string() ); + map_cache.lm[target.x()][target.y()].to_string() ); // 10 mvwprintw( w_info, point( 1, off++ ), _( "apparent light: %.5f (%d)" ), - al.apparent_light, apparent_light ); + al.apparent_light, apparent_light ); // 11 std::string extras; if( vp ) { extras += _( " [vehicle]" ); @@ -790,50 +808,28 @@ void editmap::update_view_with_help( const std::string &txt, const std::string & extras += _( " [roof]" ); } - mvwprintw( w_info, point( 1, off ), "%s %s", here.features( target ), extras ); - // 9 - off++; - for( auto &fld : here.get_field( target ) ) { - const field_entry &cur = fld.second; - mvwprintz( w_info, point( 1, off ), cur.color(), - _( "field: %s L:%d[%s] A:%d" ), - cur.get_field_type().id().str(), - cur.get_field_intensity(), - cur.name(), - to_turns( cur.get_field_age() ) - ); - off++; // 10ish - } - - const trap &cur_trap = here.tr_at( target ); - if( !cur_trap.is_null() ) { - mvwprintz( w_info, point( 1, off ), cur_trap.color, _( "trap: %s (%d)" ), cur_trap.name(), - cur_trap.loadid.to_i() ); - off++; // 11 - } + mvwprintw( w_info, point( 1, off++ ), "%s %s", here.features( target ), extras ); // 12 const Creature *critter = get_creature_tracker().creature_at( target ); if( critter != nullptr ) { off = critter->print_info( w_info, off, 5, 1 ); } else if( vp ) { - mvwprintw( w_info, point( 1, off ), _( "There is a %s there. Parts:" ), vp->vehicle().name ); - off++; + mvwprintw( w_info, point( 1, off++ ), _( "There is a %s there. Parts:" ), + vp->vehicle().name ); // 13 vp->vehicle().print_part_list( w_info, off, getmaxy( w_info ) - 1, width, vp->part_index() ); off += 6; - } + } // 19?? map_stack target_stack = here.i_at( target ); const int target_stack_size = target_stack.size(); if( !here.has_flag( ter_furn_flag::TFLAG_CONTAINER, target ) && target_stack_size > 0 ) { - trim_and_print( w_info, point( 1, off ), getmaxx( w_info ), c_light_gray, + trim_and_print( w_info, point( 1, off++ ), getmaxx( w_info ), c_light_gray, _( "There is a %s there." ), target_stack.begin()->tname() ); - off++; if( target_stack_size > 1 ) { - mvwprintw( w_info, point( 1, off ), n_gettext( "There is %d other item there as well.", + mvwprintw( w_info, point( 1, off++ ), n_gettext( "There is %d other item there as well.", "There are %d other items there as well.", target_stack_size - 1 ), target_stack_size - 1 ); - off++; } } @@ -1145,12 +1141,15 @@ void editmap::edit_feature() } input_context ctxt( emenu.input_category, keyboard_mode::keycode ); - info_txt_curr = string_format( pgettext( "keybinding descriptions", "%s, %s, %s, %s, %s" ), + info_txt_curr = string_format( pgettext( "keybinding descriptions", "%s, %s, %s, %s" ), ctxt.describe_key_and_name( "CONFIRM" ), ctxt.describe_key_and_name( "CONFIRM_QUIT" ), - ctxt.describe_key_and_name( "EDITMAP_SHOW_ALL" ), ctxt.describe_key_and_name( "EDITMAP_TAB" ), ctxt.describe_key_and_name( "EDITMAP_MOVE" ) ); +#ifndef TILES + info_txt_curr += ", "; + info_txt_curr += ctxt.describe_key_and_name( "EDITMAP_SHOW_ALL" ); +#endif info_title_curr = info_title(); do_ui_invalidation(); @@ -1268,13 +1267,15 @@ void editmap::edit_fld() input_context ctxt( fmenu.input_category, keyboard_mode::keycode ); // \u00A0 is the non-breaking space info_txt_curr = string_format( pgettext( "keybinding descriptions", - "%s, %s, [%s,%s]\u00A0intensity, %s, %s, %s" ), + "%s, %s, [%s,%s]\u00A0intensity, %s" ), ctxt.describe_key_and_name( "EDITMAP_TAB" ), ctxt.describe_key_and_name( "EDITMAP_MOVE" ), ctxt.get_desc( "LEFT", 1 ), ctxt.get_desc( "RIGHT", 1 ), - ctxt.describe_key_and_name( "CONFIRM" ), - ctxt.describe_key_and_name( "QUIT" ), - ctxt.describe_key_and_name( "EDITMAP_SHOW_ALL" ) ); + ctxt.describe_key_and_name( "CONFIRM" ) ); +#ifndef TILES + info_txt_curr += ", "; + info_txt_curr += ctxt.describe_key_and_name( "EDITMAP_SHOW_ALL" ); +#endif info_title_curr = pgettext( "Map editor: Editing field effects", "Field effects" ); do_ui_invalidation(); @@ -1641,22 +1642,23 @@ static int limited_shift( int var, int &shift, int min, int max ) * 0: no, 1: yes, -1 (or none): as per bool 'editmap.moveall'. * if input or ch are not valid movement keys, do nothing and return false */ -bool editmap::move_target( const std::string &action, int moveorigin ) +bool editmap::move_target( const std::string &action, const input_context &ctxt, + int moveorigin ) { tripoint_rel_ms mp; + if( !eget_direction( mp, action, ctxt ) ) { + return false; + } bool move_origin = moveorigin == 1 ? true : moveorigin == 0 ? false : moveall; - if( eget_direction( mp, action ) ) { - target.x() = limited_shift( target.x(), mp.x(), 0, MAPSIZE_X ); - target.y() = limited_shift( target.y(), mp.y(), 0, MAPSIZE_Y ); - // OVERMAP_HEIGHT is the limit, not size of a 0 based vector, and limited_shift restricts to <, not <= - target.z() = limited_shift( target.z(), mp.z(), -OVERMAP_DEPTH, OVERMAP_HEIGHT + 1 ); - if( move_origin ) { - origin += mp; - } - return true; + target.x() = limited_shift( target.x(), mp.x(), 0, MAPSIZE_X ); + target.y() = limited_shift( target.y(), mp.y(), 0, MAPSIZE_Y ); + // OVERMAP_HEIGHT is the limit, not size of a 0 based vector, and limited_shift restricts to <, not <= + target.z() = limited_shift( target.z(), mp.z(), -OVERMAP_DEPTH, OVERMAP_HEIGHT + 1 ); + if( move_origin ) { + origin += mp; } - return false; + return true; } /* @@ -1671,6 +1673,7 @@ int editmap::select_shape( shapetype shape, int mode ) input_context ctxt( "EDITMAP_SHAPE" ); ctxt.set_iso( true ); ctxt.register_directions(); + ctxt.register_action( "SELECT" ); ctxt.register_action( "LEFT_WIDE" ); ctxt.register_action( "RIGHT_WIDE" ); ctxt.register_action( "UP_WIDE" ); @@ -1705,23 +1708,27 @@ int editmap::select_shape( shapetype shape, int mode ) do { if( moveall ) { - info_txt_curr = string_format( pgettext( "keybinding descriptions", "%s, %s, %s, %s, %s" ), + info_txt_curr = string_format( pgettext( "keybinding descriptions", "%s, %s, %s" ), ctxt.describe_key_and_name( "RESIZE" ), ctxt.describe_key_and_name( "SWAP" ), - ctxt.describe_key_and_name( "CONFIRM" ), - ctxt.describe_key_and_name( "QUIT" ), - ctxt.describe_key_and_name( "EDITMAP_SHOW_ALL" ) ); + ctxt.describe_key_and_name( "CONFIRM" ) ); +#ifndef TILES + info_txt_curr += ", "; + info_txt_curr += ctxt.describe_key_and_name( "EDITMAP_SHOW_ALL" ); +#endif info_title_curr = _( "Moving selection" ); } else { info_txt_curr = string_format( pgettext( "keybinding descriptions", - "%s, %s, %s, %s, %s, %s, %s" ), + "%s, %s, %s, %s, %s" ), ctxt.describe_key_and_name( "EDITMAP_MOVE" ), ctxt.describe_key_and_name( "RESIZE" ), ctxt.describe_key_and_name( "SWAP" ), ctxt.describe_key_and_name( "START" ), - ctxt.describe_key_and_name( "CONFIRM" ), - ctxt.describe_key_and_name( "QUIT" ), - ctxt.describe_key_and_name( "EDITMAP_SHOW_ALL" ) ); + ctxt.describe_key_and_name( "CONFIRM" ) ); +#ifndef TILES + info_txt_curr += ", "; + info_txt_curr += ctxt.describe_key_and_name( "EDITMAP_SHOW_ALL" ); +#endif info_title_curr = _( "Resizing selection" ); } do_ui_invalidation(); @@ -1789,7 +1796,7 @@ int editmap::select_shape( shapetype shape, int mode ) } else { moveall = true; } - } else if( move_target( action ) ) { + } else if( move_target( action, ctxt ) ) { update = true; } if( update ) { @@ -1836,6 +1843,7 @@ void editmap::mapgen_preview( const real_coords &tc, uilist &gmenu ) gmenu.hilight_color = c_black_white; //gmenu.create_or_get_ui_adaptor()->invalidate_ui(); + // TODO: gpmenu could really do with not being in the centre of the screen covering up the preview uilist gpmenu; gpmenu.addentry( pgettext( "map generator", "Regenerate" ) ); gpmenu.addentry( pgettext( "map generator", "Rotate" ) ); @@ -1844,8 +1852,6 @@ void editmap::mapgen_preview( const real_coords &tc, uilist &gmenu ) gpmenu.input_category = "MAPGEN_PREVIEW"; gpmenu.additional_actions = { - { "LEFT", translation() }, - { "RIGHT", translation() }, { "HELP_KEYBINDINGS", translation() } // to refresh the view after exiting from keybindings }; gpmenu.allow_additional = true; @@ -1864,6 +1870,7 @@ void editmap::mapgen_preview( const real_coords &tc, uilist &gmenu ) bool showpreview = true; do { if( gmenu.selected != lastsel ) { + // TODO: gmenu should be hidden with current filter/selection preserved until closing gpmenu,at which point it should fully close if you chose either apply lastsel = gmenu.selected; overmap_buffer.ter_set( omt_pos, oter_id( gmenu.selected ) ); cleartmpmap( tmpmap ); @@ -1878,12 +1885,8 @@ void editmap::mapgen_preview( const real_coords &tc, uilist &gmenu ) } input_context ctxt( gpmenu.input_category, keyboard_mode::keycode ); // \u00A0 is the non-breaking space - info_txt_curr = string_format( pgettext( "keybinding descriptions", - "[%s,%s]\u00A0prev/next oter type, [%s,%s]\u00A0select, %s, %s" ), - ctxt.get_desc( "LEFT", 1 ), ctxt.get_desc( "RIGHT", 1 ), - ctxt.get_desc( "UP", 1 ), ctxt.get_desc( "DOWN", 1 ), - ctxt.describe_key_and_name( "CONFIRM" ), - ctxt.describe_key_and_name( "QUIT" ) ); + info_txt_curr = string_format( pgettext( "keybinding descriptions", "[%s] Reselect, %s" ), + ctxt.get_desc( "QUIT", 1 ), ctxt.describe_key_and_name( "CONFIRM" ) ); info_title_curr = string_format( pgettext( "map editor state", "Mapgen: %s" ), oter_id( gmenu.selected ).id().str() ); do_ui_invalidation(); @@ -1955,14 +1958,6 @@ void editmap::mapgen_preview( const real_coords &tc, uilist &gmenu ) popup( _( "Changed oter_id from '%s' (%s) to '%s' (%s)" ), orig_oters->get_name( om_vision_level::full ), orig_oters.id().str(), omt_ref->get_name( om_vision_level::full ), omt_ref.id().str() ); - } else if( gpmenu.ret == UILIST_ADDITIONAL ) { - if( gpmenu.ret_act == "LEFT" ) { - gmenu.scrollby( -1 ); - //gmenu.create_or_get_ui_adaptor()->invalidate_ui(); - } else if( gpmenu.ret_act == "RIGHT" ) { - gmenu.scrollby( 1 ); - //gmenu.create_or_get_ui_adaptor()->invalidate_ui(); - } } showpreview = gpmenu.ret == UILIST_TIMEOUT ? !showpreview : true; } while( gpmenu.ret != 2 && gpmenu.ret != 3 && gpmenu.ret != UILIST_CANCEL ); @@ -2068,9 +2063,8 @@ void editmap::mapgen_retarget() blink = true; do { - info_txt_curr = string_format( pgettext( "keybinding descriptions", "%s, %s" ), - ctxt.describe_key_and_name( "CONFIRM" ), - ctxt.describe_key_and_name( "QUIT" ) ); + info_txt_curr = string_format( pgettext( "keybinding descriptions", "%s" ), + ctxt.describe_key_and_name( "CONFIRM" ) ); info_title_curr = pgettext( "map generator", "Mapgen: Moving target" ); do_ui_invalidation(); @@ -2156,10 +2150,9 @@ void editmap::edit_mapgen() blink = true; input_context ctxt( gmenu.input_category, keyboard_mode::keycode ); - info_txt_curr = string_format( pgettext( "keybinding descriptions", "%s, %s, %s" ), + info_txt_curr = string_format( pgettext( "keybinding descriptions", "%s, %s" ), ctxt.describe_key_and_name( "EDITMAP_MOVE" ), - ctxt.describe_key_and_name( "CONFIRM" ), - ctxt.describe_key_and_name( "QUIT" ) ); + ctxt.describe_key_and_name( "CONFIRM" ) ); info_title_curr = pgettext( "map generator", "Mapgen stamp" ); do_ui_invalidation(); diff --git a/src/editmap.h b/src/editmap.h index f89dab7f74bc2..b714a7934beab 100644 --- a/src/editmap.h +++ b/src/editmap.h @@ -12,6 +12,7 @@ #include "color.h" #include "coordinates.h" #include "cursesdef.h" +#include "input_context.h" #include "point.h" #include "type_id.h" @@ -49,7 +50,8 @@ class editmap { public: tripoint pos2screen( const tripoint_bub_ms &p ); - bool eget_direction( tripoint_rel_ms &p, const std::string &action ) const; + bool eget_direction( tripoint_rel_ms &p, const std::string &action, + const input_context &ctxt ) const; std::optional edit(); void uber_draw_ter( const catacurses::window &w, map *m ); void update_view_with_help( const std::string &txt, const std::string &title ); @@ -74,7 +76,7 @@ class editmap catacurses::window w_info; void recalc_target( shapetype shape ); - bool move_target( const std::string &action, int moveorigin = -1 ); + bool move_target( const std::string &action, const input_context &ctxt, int moveorigin = -1 ); int sel_field; int sel_field_intensity; @@ -105,7 +107,7 @@ class editmap tinymap *tmpmap_ptr = nullptr; - const int width = 45; + const int width = 60; const int offsetX = 0; const int infoHeight = 20;