diff --git a/data/raw/keybindings.json b/data/raw/keybindings.json index 3c1ae69d0e5d1..d967babb1f06c 100644 --- a/data/raw/keybindings.json +++ b/data/raw/keybindings.json @@ -2968,5 +2968,11 @@ "category": "NPC_TRADE", "name": "Cancel trading", "bindings": [ { "input_method": "keyboard", "key": "ESC" } ] + }, + { + "type": "keybinding", + "id": "CHANGE_PROFESSION_NAME", + "name": "Change profession name", + "bindings": [ { "input_method": "keyboard", "key": "*" } ] } ] diff --git a/src/character.cpp b/src/character.cpp index c7b6c2909ddce..79eb63ca5e169 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -413,6 +413,7 @@ Character::Character() : healed_total = { { 0, 0, 0, 0, 0, 0 } }; name.clear(); + custom_profession.clear(); *path_settings = pathfinding_settings{ 0, 1000, 1000, 0, true, true, true, false, true }; diff --git a/src/character.h b/src/character.h index 040ef7dc54a3b..bf76f7eee88b6 100644 --- a/src/character.h +++ b/src/character.h @@ -621,6 +621,8 @@ class Character : public Creature, public visitable double recoil = MAX_RECOIL; + std::string custom_profession; + /** Returns true if the player is able to use a miss recovery technique */ bool can_miss_recovery( const item &weap ) const; /** Returns true if the player has quiet melee attacks */ diff --git a/src/player_display.cpp b/src/player_display.cpp index 0445e6e2c3e99..514a71cb7d9c0 100644 --- a/src/player_display.cpp +++ b/src/player_display.cpp @@ -23,6 +23,7 @@ #include "skill.h" #include "string_formatter.h" #include "string_id.h" +#include "string_input_popup.h" #include "translations.h" #include "ui_manager.h" #include "units.h" @@ -1308,7 +1309,7 @@ void player::disp_info() catacurses::newwin( effect_win_size_y, 26, point( 54, infooffsetybottom ) ); catacurses::window w_speed = - catacurses::newwin( 9, 26, point( 54, 1 ) ); + catacurses::newwin( 9, 26, point( 54, 1 ) ); catacurses::window w_skills = catacurses::newwin( skill_win_size_y, 26, point( 0, infooffsetybottom ) ); @@ -1326,27 +1327,33 @@ void player::disp_info() effect_win_size_y--; // Print name and header - // Post-humanity trumps your pre-Cataclysm life. - if( crossed_threshold() ) { - std::string race; - for( const trait_id &mut : get_mutations() ) { - const mutation_branch &mdata = mut.obj(); - if( mdata.threshold ) { - race = mdata.name(); - break; + // Post-humanity trumps your pre-Cataclysm life + // Unless you have a custom profession. + std::string race; + if( g->u.custom_profession.empty() ) { + if( crossed_threshold() ) { + for( const trait_id &mut : get_mutations() ) { + const mutation_branch &mdata = mut.obj(); + if( mdata.threshold ) { + race = mdata.name(); + break; + } } + //~ player info window: 1s - name, 2s - gender, 3s - Prof or Mutation name + mvwprintw( w_tip, point_zero, _( " %1$s | %2$s | %3$s" ), name, + male ? _( "Male" ) : _( "Female" ), race ); + } else if( prof == nullptr || prof == profession::generic() ) { + // Regular person. Nothing interesting. + //~ player info window: 1s - name, 2s - gender '|' - field separator. + mvwprintw( w_tip, point_zero, _( " %1$s | %2$s" ), name, + male ? _( "Male" ) : _( "Female" ) ); + } else { + mvwprintw( w_tip, point_zero, _( " %1$s | %2$s | %3$s" ), name, + male ? _( "Male" ) : _( "Female" ), prof->gender_appropriate_name( male ) ); } - //~ player info window: 1s - name, 2s - gender, 3s - Prof or Mutation name - mvwprintw( w_tip, point_zero, _( " %1$s | %2$s | %3$s" ), name, - male ? _( "Male" ) : _( "Female" ), race ); - } else if( prof == nullptr || prof == profession::generic() ) { - // Regular person. Nothing interesting. - //~ player info window: 1s - name, 2s - gender '|' - field separator. - mvwprintw( w_tip, point_zero, _( " %1$s | %2$s" ), name, - male ? _( "Male" ) : _( "Female" ) ); } else { mvwprintw( w_tip, point_zero, _( " %1$s | %2$s | %3$s" ), name, - male ? _( "Male" ) : _( "Female" ), prof->gender_appropriate_name( male ) ); + male ? _( "Male" ) : _( "Female" ), g->u.custom_profession ); } input_context ctxt( "PLAYER_INFO" ); @@ -1355,6 +1362,7 @@ void player::disp_info() ctxt.register_action( "PREV_TAB", to_translation( "Cycle to previous category" ) ); ctxt.register_action( "QUIT" ); ctxt.register_action( "CONFIRM", to_translation( "Toggle skill training" ) ); + ctxt.register_action( "CHANGE_PROFESSION_NAME", to_translation( "Change profession name" ) ); ctxt.register_action( "HELP_KEYBINDINGS" ); std::string action; @@ -1402,6 +1410,56 @@ void player::disp_info() // and "hover" over different items for more info. do { werase( w_info ); + + if( action == "CHANGE_PROFESSION_NAME" ) { + string_input_popup popup; + popup.title( _( "Profession Name: " ) ) + .width( 25 ) + .text( "" ) + .max_length( 25 ) + .query(); + + g->u.custom_profession = popup.text(); + + werase( w_tip ); + + g->refresh_all(); + + draw_grid_borders( w_grid_top, w_grid_skill, w_grid_trait, w_grid_bionics, w_grid_effect, + info_win_size_y, infooffsetybottom, skill_win_size_y + 1, trait_win_size_y + 1, + bionics_win_size_y + 1, effect_win_size_y + 1 ); + + // Print name and header + if( g->u.custom_profession.empty() ) { + if( crossed_threshold() ) { + //~ player info window: 1s - name, 2s - gender, 3s - Prof or Mutation name + mvwprintw( w_tip, point_zero, _( " %1$s | %2$s | %3$s" ), name, + male ? _( "Male" ) : _( "Female" ), race ); + } else if( prof == nullptr || prof == profession::generic() ) { + // Regular person. Nothing interesting. + //~ player info window: 1s - name, 2s - gender '|' - field separator. + mvwprintw( w_tip, point_zero, _( " %1$s | %2$s" ), name, + male ? _( "Male" ) : _( "Female" ) ); + } else { + mvwprintw( w_tip, point_zero, _( " %1$s | %2$s | %3$s" ), name, + male ? _( "Male" ) : _( "Female" ), prof->gender_appropriate_name( male ) ); + } + } else { + mvwprintw( w_tip, point_zero, _( " %1$s | %2$s | %3$s" ), name, + male ? _( "Male" ) : _( "Female" ), g->u.custom_profession ); + } + + right_print( w_tip, 0, 0, c_white, string_format( + _( "[%s]" ), + ctxt.get_desc( "HELP_KEYBINDINGS" ) ) ); + + wrefresh( w_tip ); + + draw_initial_windows( w_stats, w_encumb, w_traits, w_bionics, w_effects, w_skills, w_speed, *this, + line, traitslist, bionicslist, effect_name_and_text, skillslist, bionics_win_size_y, + effect_win_size_y, trait_win_size_y, skill_win_size_y ); + } + switch( curtab ) { case 1: // Stats tab diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index c983f7dd58a81..63243da949f31 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -431,6 +431,8 @@ void Character::load( const JsonObject &data ) data.read( "base_age", init_age ); data.read( "base_height", init_height ); + data.read( "custom_profession", custom_profession ); + // needs data.read( "thirst", thirst ); data.read( "hunger", hunger ); @@ -691,6 +693,8 @@ void Character::store( JsonOut &json ) const json.member( "base_age", init_age ); json.member( "base_height", init_height ); + json.member( "custom_profession", custom_profession ); + // health json.member( "healthy", healthy ); json.member( "healthy_mod", healthy_mod );