std::string peek_related_recipe( const recipe *current, const recipe_subset &available ) { // current recipe components std::vector<std::pair<itype_id, std::string>> related_components; const requirement_data &req = current->requirements(); for( const std::vector<item_comp> &comp_list : req.get_components() ) { for( const item_comp &a : comp_list ) { related_components.push_back( { a.type, item::nname( a.type, 1 ) } ); } } // current recipe result std::vector<std::pair<itype_id, std::string>> related_results; item tmp = current->create_result(); itype_id tid; if( tmp.contents.empty() ) { // use this item tid = tmp.typeId(); } else { // use the contained item tid = tmp.contents.front().typeId(); } const std::set<const recipe *> &known_recipes = g->u.get_learned_recipes().of_component( tid ); for( const auto &b : known_recipes ) { if( available.contains( b ) ) { related_results.push_back( { b->result(), b->result_name() } ); } } std::stable_sort( related_results.begin(), related_results.end(), []( const std::pair<std::string, std::string> &a, const std::pair<std::string, std::string> &b ) { return a.second < b.second; } ); uilist rel_menu; int np_last = -1; if( !related_components.empty() ) { rel_menu.addentry( ++np_last, false, -1, _( "COMPONENTS" ) ); } np_last = related_menu_fill( rel_menu, related_components, available ); if( !related_results.empty() ) { rel_menu.addentry( ++np_last, false, -1, _( "RESULTS" ) ); } np_last = related_menu_fill( rel_menu, related_results, available ); rel_menu.settext( _( "Related recipes:" ) ); rel_menu.query(); if( rel_menu.ret != UILIST_CANCEL ) { std::wstring wstr_recipe_name = utf8_to_wstr( rel_menu.entries[ rel_menu.ret ].txt ); return wstr_to_utf8( wstr_recipe_name.substr( 2 ) ); // 2 = prefix length } return ""; }
std::string obscure_message( const std::string &str, std::function<char()> f ) { //~ translators: place some random 1-width characters here in your language if possible, or leave it as is std::string gibberish_narrow = _( "abcdefghijklmnopqrstuvwxyz" ); //~ translators: place some random 2-width characters here in your language if possible, or leave it as is std::string gibberish_wide = _( "に坂索トし荷測のンおク妙免イロコヤ梅棋厚れ表幌" ); std::wstring w_gibberish_narrow = utf8_to_wstr( gibberish_narrow ); std::wstring w_gibberish_wide = utf8_to_wstr( gibberish_wide ); std::wstring w_str = utf8_to_wstr( str ); char transformation[2] = { 0 }; // a trailing NULL terminator is necessary for utf8_width function for( size_t i = 0; i < w_str.size(); ++i ) { transformation[0] = f(); std::string this_char = wstr_to_utf8( std::wstring( 1, w_str[i] ) ); if( transformation[0] == -1 ) { continue; } else if( transformation[0] == 0 ) { if( utf8_width( this_char ) == 1 ) { w_str[i] = random_entry( w_gibberish_narrow ); } else { w_str[i] = random_entry( w_gibberish_wide ); } } else { // Only support the case e.g. replace current character to symbols like # or ? if( utf8_width( transformation ) != 1 ) { debugmsg( "target character isn't narrow" ); } // A 2-width wide character in the original string should be replace by two narrow characters w_str.replace( i, 1, utf8_to_wstr( std::string( utf8_width( this_char ), transformation[0] ) ) ); } } std::string result = wstr_to_utf8( w_str ); if( utf8_width( str ) != utf8_width( result ) ) { debugmsg( "utf8_width differ between original string and obscured string" ); } return result; }