// Pick up items at (pos). void Pickup::pick_up( const tripoint &pos, int min ) { int veh_root_part = 0; int cargo_part = -1; vehicle *veh = g->m.veh_at( pos, veh_root_part ); bool from_vehicle = false; if( min != -1 ) { switch( interact_with_vehicle( veh, pos, veh_root_part ) ) { case DONE: return; case ITEMS_FROM_CARGO: cargo_part = veh->part_with_feature( veh_root_part, "CARGO", false ); from_vehicle = cargo_part >= 0; break; case ITEMS_FROM_GROUND: // Nothing to change, default is to pick from ground anyway. if( g->m.has_flag( "SEALED", pos ) ) { return; } break; } } if( !from_vehicle ) { bool isEmpty = ( g->m.i_at( pos ).empty() ); // Hide the pickup window if this is a toilet and there's nothing here // but water. if( ( !isEmpty ) && g->m.furn( pos ) == f_toilet ) { isEmpty = true; for( auto maybe_water : g->m.i_at( pos ) ) { if( maybe_water.typeId() != "water" ) { isEmpty = false; break; } } } if( isEmpty && ( min != -1 || !OPTIONS["AUTO_PICKUP_ADJACENT"] ) ) { return; } } // which items are we grabbing? std::vector<item> here; if( from_vehicle ) { auto vehitems = veh->get_items( cargo_part ); here.resize( vehitems.size() ); std::copy( vehitems.rbegin(), vehitems.rend(), here.begin() ); } else { auto mapitems = g->m.i_at( pos ); here.resize( mapitems.size() ); std::copy( mapitems.rbegin(), mapitems.rend(), here.begin() ); } if( min == -1 ) { if( g->check_zone( "NO_AUTO_PICKUP", pos ) ) { here.clear(); } // Recursively pick up adjacent items if that option is on. if( OPTIONS["AUTO_PICKUP_ADJACENT"] && g->u.pos() == pos ) { //Autopickup adjacent direction adjacentDir[8] = {NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST, NORTHWEST}; for( auto &elem : adjacentDir ) { tripoint apos = tripoint( direction_XY( elem ), 0 ); apos += pos; if( g->m.has_flag( "SEALED", apos ) ) { continue; } if( g->check_zone( "NO_AUTO_PICKUP", apos ) ) { continue; } pick_up( apos, min ); } } } // Not many items, just grab them if( ( int )here.size() <= min && min != -1 ) { g->u.assign_activity( ACT_PICKUP, 0 ); g->u.activity.placement = pos - g->u.pos(); g->u.activity.values.push_back( from_vehicle ); // Only one item means index is 0. g->u.activity.values.push_back( 0 ); // auto-pickup means pick up all. g->u.activity.values.push_back( 0 ); return; } if( min != -1 ) { // don't bother if we're just autopickup-ing g->temp_exit_fullscreen(); } bool sideStyle = use_narrow_sidebar(); // Otherwise, we have Autopickup, 2 or more items and should list them, etc. int maxmaxitems = sideStyle ? TERMY : getmaxy( g->w_messages ) - 3; int itemsH = std::min( 25, TERMY / 2 ); int pickupBorderRows = 3; // The pickup list may consume the entire terminal, minus space needed for its // header/footer and the item info window. int minleftover = itemsH + pickupBorderRows; if( maxmaxitems > TERMY - minleftover ) { maxmaxitems = TERMY - minleftover; } const int minmaxitems = sideStyle ? 6 : 9; std::vector<pickup_count> getitem( here.size() ); int maxitems = here.size(); maxitems = ( maxitems < minmaxitems ? minmaxitems : ( maxitems > maxmaxitems ? maxmaxitems : maxitems ) ); int itemcount = 0; if( min == -1 ) { //Auto Pickup, select matching items if( !select_autopickup_items( here, getitem ) ) { // If we didn't find anything, bail out now. return; } } else { int pickupH = maxitems + pickupBorderRows; int pickupW = getmaxx( g->w_messages ); int pickupY = VIEW_OFFSET_Y; int pickupX = getbegx( g->w_messages ); int itemsW = pickupW; int itemsY = sideStyle ? pickupY + pickupH : TERMY - itemsH; int itemsX = pickupX; WINDOW *w_pickup = newwin( pickupH, pickupW, pickupY, pickupX ); WINDOW *w_item_info = newwin( itemsH, itemsW, itemsY, itemsX ); WINDOW_PTR w_pickupptr( w_pickup ); WINDOW_PTR w_item_infoptr( w_item_info ); std::string action; long raw_input_char = ' '; input_context ctxt( "PICKUP" ); ctxt.register_action( "UP" ); ctxt.register_action( "DOWN" ); ctxt.register_action( "RIGHT" ); ctxt.register_action( "LEFT" ); ctxt.register_action( "NEXT_TAB", _( "Next page" ) ); ctxt.register_action( "PREV_TAB", _( "Previous page" ) ); ctxt.register_action( "SCROLL_UP" ); ctxt.register_action( "SCROLL_DOWN" ); ctxt.register_action( "CONFIRM" ); ctxt.register_action( "SELECT_ALL" ); ctxt.register_action( "QUIT", _( "Cancel" ) ); ctxt.register_action( "ANY_INPUT" ); ctxt.register_action( "HELP_KEYBINDINGS" ); int start = 0, cur_it; player pl_copy = g->u; pl_copy.set_fake( true ); bool update = true; mvwprintw( w_pickup, 0, 0, _( "PICK UP" ) ); int selected = 0; int iScrollPos = 0; if( g->was_fullscreen ) { g->draw_ter(); } // Now print the two lists; those on the ground and about to be added to inv // Continue until we hit return or space do { const std::string pickup_chars = ctxt.get_available_single_char_hotkeys( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ:;" ); int idx = -1; for( int i = 1; i < pickupH; i++ ) { mvwprintw( w_pickup, i, 0, " " ); } if( action == "ANY_INPUT" && raw_input_char >= '0' && raw_input_char <= '9' ) { int raw_input_char_value = ( char )raw_input_char - '0'; itemcount *= 10; itemcount += raw_input_char_value; if( itemcount < 0 ) { itemcount = 0; } } else if( action == "SCROLL_UP" ) { iScrollPos--; } else if( action == "SCROLL_DOWN" ) { iScrollPos++; } else if( action == "PREV_TAB" ) { if( start > 0 ) { start -= maxitems; } else { start = ( int )( ( here.size() - 1 ) / maxitems ) * maxitems; } selected = start; mvwprintw( w_pickup, maxitems + 2, 0, " " ); } else if( action == "NEXT_TAB" ) { if( start + maxitems < ( int )here.size() ) { start += maxitems; } else { start = 0; } iScrollPos = 0; selected = start; mvwprintw( w_pickup, maxitems + 2, pickupH, " " ); } else if( action == "UP" ) { selected--; iScrollPos = 0; if( selected < 0 ) { selected = here.size() - 1; start = ( int )( here.size() / maxitems ) * maxitems; if( start >= ( int )here.size() ) { start -= maxitems; } } else if( selected < start ) { start -= maxitems; } } else if( action == "DOWN" ) { selected++; iScrollPos = 0; if( selected >= ( int )here.size() ) { selected = 0; start = 0; } else if( selected >= start + maxitems ) { start += maxitems; } } else if( selected >= 0 && ( ( action == "RIGHT" && !getitem[selected] ) || ( action == "LEFT" && getitem[selected] ) ) ) { idx = selected; } else if( action == "ANY_INPUT" && raw_input_char == '`' ) { std::string ext = string_input_popup( _( "Enter 2 letters (case sensitive):" ), 3, "", "", "", 2 ); if( ext.size() == 2 ) { int p1 = pickup_chars.find( ext.at( 0 ) ); int p2 = pickup_chars.find( ext.at( 1 ) ); if( p1 != -1 && p2 != -1 ) { idx = pickup_chars.size() + ( p1 * pickup_chars.size() ) + p2; } } } else if( action == "ANY_INPUT" ) { idx = ( raw_input_char <= 127 ) ? pickup_chars.find( raw_input_char ) : -1; iScrollPos = 0; } if( idx >= 0 && idx < ( int )here.size() ) { if( getitem[idx] ) { if( here[idx].count_by_charges() ) { if( getitem[idx].count == 0 ) { pl_copy.inv.find_item( getitem[idx].position ).charges -= here[idx].charges; } else { pl_copy.inv.find_item( getitem[idx].position ).charges -= getitem[idx].count; } } else { unsigned stack_size = pl_copy.inv.const_stack( getitem[idx].position ).size(); pl_copy.i_rem( getitem[idx].position ); //if the stack_was emptied, removing the item invalidated later positions- fix them if( stack_size == 1 ) { for( unsigned i = 0; i < here.size(); i++ ) { if( getitem[i] && getitem[i].position > getitem[idx].position ) { getitem[i].position--; } } } } } //end if getitem[idx] if( itemcount != 0 || getitem[idx].count == 0 ) { if( itemcount >= here[idx].charges || !here[idx].count_by_charges() ) { // Ignore the count if we pickup the whole stack anyway // or something that is not counted by charges (tools) itemcount = 0; } getitem[idx].count = itemcount; itemcount = 0; } // Note: this might not change the value of getitem[idx] at all! getitem[idx].pick = ( action == "RIGHT" ? true : ( action == "LEFT" ? false : !getitem[idx] ) ); if( action != "RIGHT" && action != "LEFT" ) { selected = idx; start = ( int )( idx / maxitems ) * maxitems; } if( getitem[idx] ) { item temp = here[idx]; if( getitem[idx].count != 0 && getitem[idx].count < here[idx].charges ) { temp.charges = getitem[idx].count; } item *added = &( pl_copy.i_add( temp ) ); getitem[idx].position = pl_copy.inv.position_by_item( added ); } else { getitem[idx].count = 0; } update = true; } werase( w_item_info ); if( selected >= 0 && selected <= ( int )here.size() - 1 ) { std::vector<iteminfo> vThisItem, vDummy; here[selected].info( true, vThisItem ); draw_item_info( w_item_info, "", "", vThisItem, vDummy, iScrollPos, true, true ); } draw_custom_border( w_item_info, false ); mvwprintw( w_item_info, 0, 2, "< " ); trim_and_print( w_item_info, 0, 4, itemsW - 8, c_white, "%s >", here[selected].display_name().c_str() ); wrefresh( w_item_info ); if( action == "SELECT_ALL" ) { int count = 0; for( size_t i = 0; i < here.size(); i++ ) { if( getitem[i] ) { count++; } else { item *added = &( pl_copy.i_add( here[i] ) ); getitem[i].position = pl_copy.inv.position_by_item( added ); } getitem[i].pick = true; } if( count == ( int )here.size() ) { for( size_t i = 0; i < here.size(); i++ ) { getitem[i].pick = false; } pl_copy = g->u; pl_copy.set_fake( true ); } update = true; } for( cur_it = start; cur_it < start + maxitems; cur_it++ ) { mvwprintw( w_pickup, 1 + ( cur_it % maxitems ), 0, " " ); if( cur_it < ( int )here.size() ) { nc_color icolor = here[cur_it].color_in_inventory(); if( cur_it == selected ) { icolor = hilite( icolor ); } if( cur_it < ( int )pickup_chars.size() ) { mvwputch( w_pickup, 1 + ( cur_it % maxitems ), 0, icolor, char( pickup_chars[cur_it] ) ); } else if( cur_it < ( int )pickup_chars.size() + ( int )pickup_chars.size() * ( int )pickup_chars.size() ) { int p = cur_it - pickup_chars.size(); int p1 = p / pickup_chars.size(); int p2 = p % pickup_chars.size(); mvwprintz( w_pickup, 1 + ( cur_it % maxitems ), 0, icolor, "`%c%c", char( pickup_chars[p1] ), char( pickup_chars[p2] ) ); } else { mvwputch( w_pickup, 1 + ( cur_it % maxitems ), 0, icolor, ' ' ); } if( getitem[cur_it] ) { if( getitem[cur_it].count == 0 ) { wprintz( w_pickup, c_ltblue, " + " ); } else { wprintz( w_pickup, c_ltblue, " # " ); } } else { wprintw( w_pickup, " - " ); } std::string item_name = here[cur_it].display_name(); if( OPTIONS["ITEM_SYMBOLS"] ) { item_name = string_format( "%s %s", here[cur_it].symbol().c_str(), item_name.c_str() ); } trim_and_print( w_pickup, 1 + ( cur_it % maxitems ), 6, pickupW - 4, icolor, "%s", item_name.c_str() ); } } mvwprintw( w_pickup, maxitems + 1, 0, _( "[%s] Unmark" ), ctxt.get_desc( "LEFT", 1 ).c_str() ); center_print( w_pickup, maxitems + 1, c_ltgray, _( "[%s] Help" ), ctxt.get_desc( "HELP_KEYBINDINGS", 1 ).c_str() ); right_print( w_pickup, maxitems + 1, 0, c_ltgray, _( "[%s] Mark" ), ctxt.get_desc( "RIGHT", 1 ).c_str() ); mvwprintw( w_pickup, maxitems + 2, 0, _( "[%s] Prev" ), ctxt.get_desc( "PREV_TAB", 1 ).c_str() ); center_print( w_pickup, maxitems + 2, c_ltgray, _( "[%s] All" ), ctxt.get_desc( "SELECT_ALL", 1 ).c_str() ); right_print( w_pickup, maxitems + 2, 0, c_ltgray, _( "[%s] Next" ), ctxt.get_desc( "NEXT_TAB", 1 ).c_str() ); if( update ) { // Update weight & volume information update = false; for( int i = 9; i < pickupW; ++i ) { mvwaddch( w_pickup, 0, i, ' ' ); } mvwprintz( w_pickup, 0, 9, ( pl_copy.weight_carried() > g->u.weight_capacity() ? c_red : c_white ), _( "Wgt %.1f" ), convert_weight( pl_copy.weight_carried() ) + 0.05 ); // +0.05 to round up wprintz( w_pickup, c_white, "/%.1f", convert_weight( g->u.weight_capacity() ) ); mvwprintz( w_pickup, 0, 24, ( pl_copy.volume_carried() > g->u.volume_capacity() ? c_red : c_white ), _( "Vol %d" ), pl_copy.volume_carried() ); wprintz( w_pickup, c_white, "/%d", g->u.volume_capacity() ); } wrefresh( w_pickup ); action = ctxt.handle_input(); raw_input_char = ctxt.get_raw_input().get_first_input(); } while( action != "QUIT" && action != "CONFIRM" ); bool item_selected = false; // Check if we have selected an item. for( auto selection : getitem ) { if( selection ) { item_selected = true; } } if( action != "CONFIRM" || !item_selected ) { w_pickupptr.reset(); w_item_infoptr.reset(); add_msg( _( "Never mind." ) ); g->reenter_fullscreen(); g->refresh_all(); return; } } // At this point we've selected our items, register an activity to pick them up. g->u.assign_activity( ACT_PICKUP, 0 ); g->u.activity.placement = pos - g->u.pos(); g->u.activity.values.push_back( from_vehicle ); if( min == -1 ) { // Auto pickup will need to auto resume since there can be several of them on the stack. g->u.activity.auto_resume = true; } std::reverse( getitem.begin(), getitem.end() ); for( size_t i = 0; i < here.size(); i++ ) { if( getitem[i] ) { g->u.activity.values.push_back( i ); g->u.activity.values.push_back( getitem[i].count ); } } g->reenter_fullscreen(); }
// Pick up items at (pos). void Pickup::pick_up( const tripoint &pos, int min ) { int veh_root_part = 0; int cargo_part = -1; vehicle *veh = g->m.veh_at (pos, veh_root_part); bool from_vehicle = false; if( min != -1 ) { switch( interact_with_vehicle( veh, pos, veh_root_part ) ) { case DONE: return; case ITEMS_FROM_CARGO: cargo_part = veh->part_with_feature( veh_root_part, "CARGO", false ); from_vehicle = cargo_part >= 0; break; case ITEMS_FROM_GROUND: // Nothing to change, default is to pick from ground anyway. break; } } if (g->m.has_flag("SEALED", pos)) { return; } //min == -1 is Autopickup if (!g->u.can_pickup(min != -1)) { // no message on autopickup (-1) return; } if( !from_vehicle ) { bool isEmpty = (g->m.i_at(pos).empty()); // Hide the pickup window if this is a toilet and there's nothing here // but water. if ((!isEmpty) && g->m.furn(pos) == f_toilet) { isEmpty = true; for( auto maybe_water : g->m.i_at(pos) ) { if( maybe_water.typeId() != "water") { isEmpty = false; break; } } } if (isEmpty && (min != -1 || !OPTIONS["AUTO_PICKUP_ADJACENT"] )) { return; } } // which items are we grabbing? std::vector<item> here; if( from_vehicle ) { auto vehitems = veh->get_items(cargo_part); here.resize( vehitems.size() ); std::copy( vehitems.begin(), vehitems.end(), here.begin() ); } else { auto mapitems = g->m.i_at(pos); here.resize( mapitems.size() ); std::copy( mapitems.begin(), mapitems.end(), here.begin() ); } if (min == -1) { if( g->check_zone( "NO_AUTO_PICKUP", pos ) ) { here.clear(); } // Recursively pick up adjacent items if that option is on. if( OPTIONS["AUTO_PICKUP_ADJACENT"] && g->u.pos() == pos ) { //Autopickup adjacent direction adjacentDir[8] = {NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST, NORTHWEST}; for( auto &elem : adjacentDir ) { tripoint apos = tripoint( direction_XY( elem ), 0 ); apos += pos; if( g->m.has_flag( "SEALED", apos ) ) { continue; } if( g->check_zone( "NO_AUTO_PICKUP", apos ) ) { continue; } pick_up( apos, min ); } } } // Not many items, just grab them if ((int)here.size() <= min && min != -1) { g->u.assign_activity( ACT_PICKUP, 0 ); g->u.activity.placement = pos - g->u.pos(); g->u.activity.values.push_back( from_vehicle ); // Only one item means index is 0. g->u.activity.values.push_back( 0 ); // auto-pickup means pick up all. g->u.activity.values.push_back( 0 ); return; } if(min != -1) { // don't bother if we're just autopickup-ing g->temp_exit_fullscreen(); } bool sideStyle = use_narrow_sidebar(); // Otherwise, we have Autopickup, 2 or more items and should list them, etc. int maxmaxitems = sideStyle ? TERMY : getmaxy(g->w_messages) - 3; int itemsH = std::min(25, TERMY / 2); int pickupBorderRows = 3; // The pickup list may consume the entire terminal, minus space needed for its // header/footer and the item info window. int minleftover = itemsH + pickupBorderRows; if(maxmaxitems > TERMY - minleftover) { maxmaxitems = TERMY - minleftover; } const int minmaxitems = sideStyle ? 6 : 9; std::vector<bool> getitem; getitem.resize(here.size(), false); int maxitems = here.size(); maxitems = (maxitems < minmaxitems ? minmaxitems : (maxitems > maxmaxitems ? maxmaxitems : maxitems )); int itemcount = 0; std::map<int, unsigned int> pickup_count; // Count of how many we'll pick up from each stack if (min == -1) { //Auto Pickup, select matching items if( !select_autopickup_items( here, getitem) ) { // If we didn't find anything, bail out now. return; } } else { int pickupH = maxitems + pickupBorderRows; int pickupW = getmaxx(g->w_messages); int pickupY = VIEW_OFFSET_Y; int pickupX = getbegx(g->w_messages); int itemsW = pickupW; int itemsY = sideStyle ? pickupY + pickupH : TERMY - itemsH; int itemsX = pickupX; WINDOW *w_pickup = newwin(pickupH, pickupW, pickupY, pickupX); WINDOW *w_item_info = newwin(itemsH, itemsW, itemsY, itemsX); WINDOW_PTR w_pickupptr( w_pickup ); WINDOW_PTR w_item_infoptr( w_item_info ); int ch = ' '; int start = 0, cur_it; int new_weight = g->u.weight_carried(), new_volume = g->u.volume_carried(); bool update = true; mvwprintw(w_pickup, 0, 0, _("PICK UP")); int selected = 0; int iScrollPos = 0; if(g->was_fullscreen) { g->draw_ter(); } // Now print the two lists; those on the ground and about to be added to inv // Continue until we hit return or space do { static const std::string pickup_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ:;"; int idx = -1; for (int i = 1; i < pickupH; i++) { mvwprintw(w_pickup, i, 0, " "); } if (ch >= '0' && ch <= '9') { ch = (char)ch - '0'; itemcount *= 10; itemcount += ch; if( itemcount < 0 ) { itemcount = 0; } } else if ( ch == KEY_PPAGE) { iScrollPos--; } else if ( ch == KEY_NPAGE) { iScrollPos++; } else if ( ch == '<' ) { if ( start > 0 ) { start -= maxitems; } else { start = (int)( (here.size()-1) / maxitems ) * maxitems; } selected = start; mvwprintw(w_pickup, maxitems + 2, 0, " "); } else if ( ch == '>' ) { if ( start + maxitems < (int)here.size() ) { start += maxitems; } else { start = 0; } iScrollPos = 0; selected = start; mvwprintw(w_pickup, maxitems + 2, pickupH, " "); } else if ( ch == KEY_UP ) { selected--; iScrollPos = 0; if ( selected < 0 ) { selected = here.size() - 1; start = (int)( here.size() / maxitems ) * maxitems; if (start >= (int)here.size()) { start -= maxitems; } } else if ( selected < start ) { start -= maxitems; } } else if ( ch == KEY_DOWN ) { selected++; iScrollPos = 0; if ( selected >= (int)here.size() ) { selected = 0; start = 0; } else if ( selected >= start + maxitems ) { start += maxitems; } } else if ( selected >= 0 && ( ( ch == KEY_RIGHT && !getitem[selected]) || ( ch == KEY_LEFT && getitem[selected] ) ) ) { idx = selected; } else if ( ch == '`' ) { std::string ext = string_input_popup( _("Enter 2 letters (case sensitive):"), 3, "", "", "", 2); if(ext.size() == 2) { int p1 = pickup_chars.find(ext.at(0)); int p2 = pickup_chars.find(ext.at(1)); if ( p1 != -1 && p2 != -1 ) { idx = pickup_chars.size() + ( p1 * pickup_chars.size() ) + p2; } } } else { idx = ( ch <= 127 ) ? pickup_chars.find(ch) : -1; iScrollPos = 0; } if( idx >= 0 && idx < (int)here.size()) { if( getitem[idx] ) { if( pickup_count[idx] != 0 && (int)pickup_count[idx] < here[idx].charges ) { item temp = here[idx]; temp.charges = pickup_count[idx]; new_weight -= temp.weight(); new_volume -= temp.volume(); } else { new_weight -= here[idx].weight(); new_volume -= here[idx].volume(); } } if (itemcount != 0 || pickup_count[idx] == 0) { if (itemcount >= here[idx].charges || !here[idx].count_by_charges()) { // Ignore the count if we pickup the whole stack anyway // or something that is not counted by charges (tools) itemcount = 0; } pickup_count[idx] = itemcount; itemcount = 0; } // Note: this might not change the value of getitem[idx] at all! getitem[idx] = ( ch == KEY_RIGHT ? true : ( ch == KEY_LEFT ? false : !getitem[idx] ) ); if ( ch != KEY_RIGHT && ch != KEY_LEFT) { selected = idx; start = (int)( idx / maxitems ) * maxitems; } if (getitem[idx]) { if (pickup_count[idx] != 0 && (int)pickup_count[idx] < here[idx].charges) { item temp = here[idx]; temp.charges = pickup_count[idx]; new_weight += temp.weight(); new_volume += temp.volume(); } else { new_weight += here[idx].weight(); new_volume += here[idx].volume(); } } else { pickup_count[idx] = 0; } update = true; } werase(w_item_info); if ( selected >= 0 && selected <= (int)here.size() - 1 ) { std::vector<iteminfo> vThisItem, vDummy; here[selected].info(true, vThisItem); draw_item_info(w_item_info, "", "", vThisItem, vDummy, iScrollPos, true, true); } draw_custom_border(w_item_info, false); mvwprintw(w_item_info, 0, 2, "< "); trim_and_print(w_item_info, 0, 4, itemsW - 8, c_white, "%s >", here[selected].display_name().c_str()); wrefresh(w_item_info); if (ch == ',') { int count = 0; for (size_t i = 0; i < here.size(); i++) { if (getitem[i]) { count++; } else { new_weight += here[i].weight(); new_volume += here[i].volume(); } getitem[i] = true; } if (count == (int)here.size()) { for (size_t i = 0; i < here.size(); i++) { getitem[i] = false; } new_weight = g->u.weight_carried(); new_volume = g->u.volume_carried(); } update = true; } for (cur_it = start; cur_it < start + maxitems; cur_it++) { mvwprintw(w_pickup, 1 + (cur_it % maxitems), 0, " "); if (cur_it < (int)here.size()) { nc_color icolor = here[cur_it].color_in_inventory(); if (cur_it == selected) { icolor = hilite(icolor); } if (cur_it < (int)pickup_chars.size() ) { mvwputch(w_pickup, 1 + (cur_it % maxitems), 0, icolor, char(pickup_chars[cur_it])); } else { int p = cur_it - pickup_chars.size(); int p1 = p / pickup_chars.size(); int p2 = p % pickup_chars.size(); mvwprintz(w_pickup, 1 + (cur_it % maxitems), 0, icolor, "`%c%c", char(pickup_chars[p1]), char(pickup_chars[p2])); } if (getitem[cur_it]) { if (pickup_count[cur_it] == 0) { wprintz(w_pickup, c_ltblue, " + "); } else { wprintz(w_pickup, c_ltblue, " # "); } } else { wprintw(w_pickup, " - "); } std::string item_name = here[cur_it].display_name(); if (OPTIONS["ITEM_SYMBOLS"]) { item_name = string_format("%c %s", here[cur_it].symbol(), item_name.c_str()); } trim_and_print(w_pickup, 1 + (cur_it % maxitems), 6, pickupW - 4, icolor, "%s", item_name.c_str()); } } int pw = pickupW; const char *unmark = _("[left] Unmark"); const char *scroll = _("[up/dn] Scroll"); const char *mark = _("[right] Mark"); mvwprintw(w_pickup, maxitems + 1, 0, unmark); mvwprintw(w_pickup, maxitems + 1, (pw - std::strlen(scroll)) / 2, scroll); mvwprintw(w_pickup, maxitems + 1, pw - std::strlen(mark), mark); const char *prev = _("[<] Prev"); const char *all = _("[,] All"); const char *next = _("[>] Next"); mvwprintw(w_pickup, maxitems + 2, 0, prev); mvwprintw(w_pickup, maxitems + 2, (pw - std::strlen(all)) / 2, all); mvwprintw(w_pickup, maxitems + 2, pw - std::strlen(next), next); if (update) { // Update weight & volume information update = false; for (int i = 9; i < pickupW; ++i) { mvwaddch(w_pickup, 0, i, ' '); } mvwprintz(w_pickup, 0, 9, (new_weight > g->u.weight_capacity() ? c_red : c_white), _("Wgt %.1f"), g->u.convert_weight(new_weight) + 0.05); // +0.05 to round up wprintz(w_pickup, c_white, "/%.1f", g->u.convert_weight(g->u.weight_capacity())); mvwprintz(w_pickup, 0, 24, (new_volume > g->u.volume_capacity() ? c_red : c_white), _("Vol %d"), new_volume); wprintz(w_pickup, c_white, "/%d", g->u.volume_capacity()); } wrefresh(w_pickup); ch = (int)getch(); } while (ch != ' ' && ch != '\n' && ch != KEY_ENTER && ch != KEY_ESCAPE); bool item_selected = false; // Check if we have selected an item. for( auto selection : getitem ) { if( selection ) { item_selected = true; } } if( (ch != '\n' && ch != KEY_ENTER) || !item_selected ) { w_pickupptr.reset(); w_item_infoptr.reset(); add_msg(_("Never mind.")); g->reenter_fullscreen(); g->refresh_all(); return; } } // At this point we've selected our items, register an activity to pick them up. g->u.assign_activity( ACT_PICKUP, 0 ); g->u.activity.placement = pos - g->u.pos(); g->u.activity.values.push_back( from_vehicle ); if( min == -1 ) { // Auto pickup will need to auto resume since there can be several of them on the stack. g->u.activity.auto_resume = true; } for (size_t i = 0; i < here.size(); i++) { if( getitem[i] ) { g->u.activity.values.push_back( i ); g->u.activity.values.push_back( pickup_count[i] ); } } g->reenter_fullscreen(); }