read_inventory_preset( const player &p ) : pickup_inventory_preset( p ), p( p ) { static const std::string unknown( _( "<color_dark_gray>?</color>" ) ); static const std::string martial_arts( _( "martial arts" ) ); append_cell( [ this, &p ]( const item_location & loc ) -> std::string { if( loc->type->can_use( "MA_MANUAL" ) ) { return martial_arts; } if( !is_known( loc ) ) { return unknown; } const auto &book = get_book( loc ); if( book.skill && p.get_skill_level_object( book.skill ).can_train() ) { return string_format( _( "%s to %d" ), book.skill->name().c_str(), book.level ); } return std::string(); }, _( "TRAINS" ), unknown ); append_cell( [ this ]( const item_location & loc ) -> std::string { if( !is_known( loc ) ) { return unknown; } const auto &book = get_book( loc ); const int unlearned = book.recipes.size() - get_known_recipes( book ); return unlearned > 0 ? to_string( unlearned ) : std::string(); }, _( "RECIPES" ), unknown ); append_cell( [ this ]( const item_location & loc ) -> std::string { if( !is_known( loc ) ) { return unknown; } return good_bad_none( get_book( loc ).fun ); }, _( "FUN" ), unknown ); append_cell( [ this, &p ]( const item_location & loc ) -> std::string { if( !is_known( loc ) ) { return unknown; } std::vector<std::string> dummy; const player *reader = p.get_book_reader( *loc, dummy ); if( reader == nullptr ) { return std::string(); // Just to make sure } // Actual reading time (in turns). Can be penalized. const int actual_turns = p.time_to_read( *loc, *reader ) / MOVES( 1 ); // Theoretical reading time (in turns) based on the reader speed. Free of penalties. const int normal_turns = get_book( loc ).time * reader->read_speed() / MOVES( 1 ); const std::string duration = to_string_approx( time_duration::from_turns( actual_turns ), false ); if( actual_turns > normal_turns ) { // Longer - complicated stuff. return string_format( "<color_light_red>%s</color>", duration.c_str() ); } return duration; // Normal speed. }, _( "CHAPTER IN" ), unknown ); }