void game::compare(int iCompareX, int iCompareY) { int examx, examy; int ch = (int)'.'; if (iCompareX != -999 && iCompareX != -999) { examx = iCompareX; examy = iCompareY; } else { mvwprintw(w_terrain, 0, 0, "Compare where? (Direction button)"); wrefresh(w_terrain); ch = input(); last_action += ch; if (ch == KEY_ESCAPE || ch == 'q') return; if (ch == '\n' || ch == 'I') ch = '.'; get_direction(this, examx, examy, ch); if (examx == -2 || examy == -2) { add_msg("Invalid direction."); return; } } examx += u.posx; examy += u.posy; std::vector <item> here = m.i_at(examx, examy); std::vector <item> grounditems; //Filter out items with the same name (keep only one of them) std::map <std::string, bool> dups; for (int i = 0; i < here.size(); i++) { if (!dups[here[i].tname(this).c_str()]) { grounditems.push_back(here[i]); dups[here[i].tname(this).c_str()] = true; } } //Only the first 10 Items due to numbering 0-9 const int groundsize = (grounditems.size() > 10 ? 10 : grounditems.size()); u.inv.sort(); u.inv.restack(&u); invslice stacks = u.inv.slice(0, u.inv.size()); WINDOW* w_inv = newwin(TERMY-VIEW_OFFSET_Y*2, TERMX-VIEW_OFFSET_X*2, VIEW_OFFSET_Y, VIEW_OFFSET_X); int maxitems = TERMY-5-VIEW_OFFSET_Y*2; // Number of items to show at one time. std::vector<int> compare_list; // Count of how many we'll drop from each stack bool bFirst = false; // First Item selected bool bShowCompare = false; char cLastCh; compare_list.resize(u.inv.size() + groundsize, 0); std::vector<char> weapon_and_armor; // Always single, not counted print_inv_statics(this, w_inv, "Compare:", weapon_and_armor); // Gun, ammo, weapon, armor, food, tool, book, other std::vector<int> first = find_firsts(stacks); std::vector<int> firsts; if (groundsize > 0) { firsts.push_back(0); } for (int i = 0; i < first.size(); i++) { firsts.push_back((first[i] >= 0) ? first[i]+groundsize : -1); } ch = '.'; int start = 0, cur_it; do { if (( ch == '<' || ch == KEY_PPAGE ) && start > 0) { for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); start -= maxitems; if (start < 0) start = 0; mvwprintw(w_inv, maxitems + 4, 0, " "); } if (( ch == '>' || ch == KEY_NPAGE ) && cur_it < u.inv.size() + groundsize) { start = cur_it; mvwprintw(w_inv, maxitems + 4, 12, " "); for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); } int cur_line = 2; int iHeaderOffset = (groundsize > 0) ? 0 : 1; for (cur_it = start; cur_it < start + maxitems && cur_line < maxitems+3; cur_it++) { // Clear the current line; mvwprintw(w_inv, cur_line, 0, " "); // Print category header for (int i = iHeaderOffset; i < iCategorieNum; i++) { if (cur_it == firsts[i-iHeaderOffset]) { mvwprintz(w_inv, cur_line, 0, c_magenta, CATEGORIES[i].c_str()); cur_line++; } } if (cur_it < u.inv.size() + groundsize) { char icon = '-'; if (compare_list[cur_it] == 1) icon = '+'; if (cur_it < groundsize) { mvwputch (w_inv, cur_line, 0, c_white, '1'+((cur_it<9) ? cur_it: -1)); nc_color col = (compare_list[cur_it] == 0 ? c_ltgray : c_white); mvwprintz(w_inv, cur_line, 1, col, " %c %s", icon, grounditems[cur_it].tname(this).c_str()); } else { item& it = stacks[cur_it-groundsize]->front(); mvwputch (w_inv, cur_line, 0, c_white, it.invlet); nc_color col = (compare_list[cur_it] == 0 ? c_ltgray : c_white); mvwprintz(w_inv, cur_line, 1, col, " %c %s", icon, it.tname(this).c_str()); if (stacks[cur_it-groundsize]->size() > 1) wprintz(w_inv, col, " [%d]", stacks[cur_it-groundsize]->size()); if (it.charges > 0) wprintz(w_inv, col, " (%d)", it.charges); else if (it.contents.size() == 1 && it.contents[0].charges > 0) wprintw(w_inv, " (%d)", it.contents[0].charges); } } cur_line++; } if (start > 0) mvwprintw(w_inv, maxitems + 4, 0, "< Go Back"); if (cur_it < u.inv.size() + groundsize) mvwprintw(w_inv, maxitems + 4, 12, "> More items"); wrefresh(w_inv); ch = getch(); if (u.has_item(ch)) { item& it = u.inv.item_by_letter(ch); if (it.is_null()) { // Not from inventory bool found = false; for (int i = 0; i < weapon_and_armor.size() && !found; i++) { if (weapon_and_armor[i] == ch) { weapon_and_armor.erase(weapon_and_armor.begin() + i); found = true; bFirst = false; print_inv_statics(this, w_inv, "Compare:", weapon_and_armor); } } if (!found) { if ( ch == u.weapon.invlet && std::find(unreal_itype_ids.begin(), unreal_itype_ids.end(), u.weapon.type->id) != unreal_itype_ids.end()){ //Do Bionic stuff here?! } else { if (!bFirst) { weapon_and_armor.push_back(ch); print_inv_statics(this, w_inv, "Compare:", weapon_and_armor); bFirst = true; cLastCh = ch; } else { bShowCompare = true; } } } } else { int index = -1; for (int i = 0; i < stacks.size(); ++i) { if (stacks[i]->front().invlet == it.invlet) { index = i; break; } } if (index == -1) { debugmsg("Inventory got out of sync with inventory slice?"); } if (compare_list[index+groundsize] == 1) { compare_list[index+groundsize] = 0; bFirst = false; } else { if (!bFirst) { compare_list[index+groundsize] = 1; bFirst = true; cLastCh = ch; } else { bShowCompare = true; } } } } else if ((ch >= '1' && ch <= '9' && ch-'1' < groundsize) || (ch == '0' && groundsize == 10)) { //Ground Items int iZero = 0; if (ch == '0') { iZero = 10; } if (compare_list[ch-'1'+iZero] == 1) { compare_list[ch-'1'+iZero] = 0; bFirst = false; } else { if (!bFirst) { compare_list[ch-'1'+iZero] = 1; bFirst = true; cLastCh = ch; } else { bShowCompare = true; } } } if (bShowCompare) { std::vector<iteminfo> vItemLastCh, vItemCh; std::string sItemLastCh, sItemCh; if (cLastCh >= '0' && cLastCh <= '9') { int iZero = 0; if (cLastCh == '0') { iZero = 10; } grounditems[cLastCh-'1'+iZero].info(true, &vItemLastCh); sItemLastCh = grounditems[cLastCh-'1'+iZero].tname(this); } else { u.i_at(cLastCh).info(true, &vItemLastCh); sItemLastCh = u.i_at(cLastCh).tname(this); } if (ch >= '0' && ch <= '9') { int iZero = 0; if (ch == '0') { iZero = 10; } grounditems[ch-'1'+iZero].info(true, &vItemCh); sItemCh = grounditems[ch-'1'+iZero].tname(this); } else { u.i_at(ch).info(true, &vItemCh); sItemCh = u.i_at(ch).tname(this); } compare_split_screen_popup(0, (TERMX-VIEW_OFFSET_X*2)/2, TERMY-VIEW_OFFSET_Y*2, sItemLastCh, vItemLastCh, vItemCh); compare_split_screen_popup((TERMX-VIEW_OFFSET_X*2)/2, (TERMX-VIEW_OFFSET_X*2)/2, TERMY-VIEW_OFFSET_Y*2, sItemCh, vItemCh, vItemLastCh); wclear(w_inv); print_inv_statics(this, w_inv, "Compare:", weapon_and_armor); bShowCompare = false; } } while (ch != '\n' && ch != KEY_ESCAPE && ch != ' '); werase(w_inv); delwin(w_inv); erase(); refresh_all(); }
char game::inv_type(std::string title, item_cat inv_item_type) { // this function lists inventory objects by type // refer to enum item_cat in itype.h for list of categories WINDOW* w_inv = newwin(((VIEWY < 12) ? 25 : VIEWY*2+1), ((VIEWX < 12) ? 80 : VIEWX*2+56), VIEW_OFFSET_Y, VIEW_OFFSET_X); const int maxitems = (VIEWY < 12) ? 20 : VIEWY*2-4; // Number of items to show at one time. int ch = (int)'.'; int start = 0, cur_it; u.inv.sort(); u.inv.restack(&u); std::vector<char> null_vector; print_inv_statics(this, w_inv, title, null_vector); // Gun, ammo, weapon, armor, food, tool, book, other // Create the reduced inventory inventory reduced_inv = u.inv.filter_by_category(inv_item_type, u); invslice slice = reduced_inv.slice(0, reduced_inv.size()); std::vector<int> firsts = find_firsts(slice); do { if (( ch == '<' || ch == KEY_PPAGE ) && start > 0) { // Clear lines and shift for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); start -= maxitems; if (start < 0) start = 0; mvwprintw(w_inv, maxitems + 4, 0, " "); } if (( ch == '>' || ch == KEY_NPAGE ) && cur_it < reduced_inv.size()) { // Clear lines and shift start = cur_it; mvwprintw(w_inv, maxitems + 4, 12, " "); for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); } int cur_line = 2; for (cur_it = start; cur_it < start + maxitems && cur_line < maxitems+3; cur_it++) { // Clear the current line; mvwprintw(w_inv, cur_line, 0, " "); for (int i = 1; i < iCategorieNum; i++) { if (cur_it == firsts[i-1]) { mvwprintz(w_inv, cur_line, 0, c_magenta, CATEGORIES[i].c_str()); cur_line++; } } if (cur_it < slice.size()) { item& it = slice[cur_it]->front(); mvwputch (w_inv, cur_line, 0, c_white, it.invlet); mvwprintz(w_inv, cur_line, 1, it.color_in_inventory(&u), " %s", it.tname(this).c_str()); if (slice[cur_it]->size() > 1) wprintw(w_inv, " [%d]", slice[cur_it]->size()); if (it.charges > 0) wprintw(w_inv, " (%d)", it.charges); else if (it.contents.size() == 1 && it.contents[0].charges > 0) wprintw(w_inv, " (%d)", it.contents[0].charges); cur_line++; } // cur_line++; } if (start > 0) mvwprintw(w_inv, maxitems + 4, 0, "< Go Back"); if (cur_it < reduced_inv.size()) mvwprintw(w_inv, maxitems + 4, 12, "> More items"); wrefresh(w_inv); ch = getch(); } while (ch == '<' || ch == '>' || ch == KEY_NPAGE || ch == KEY_PPAGE ); werase(w_inv); delwin(w_inv); erase(); refresh_all(); return (char)ch; }
std::vector<item> game::multidrop() { u.inv.sort(); u.inv.restack(&u); WINDOW* w_inv = newwin(((VIEWY < 12) ? 25 : VIEWY*2+1), ((VIEWX < 12) ? 80 : VIEWX*2+56), VIEW_OFFSET_Y, VIEW_OFFSET_X); const int maxitems = (VIEWY < 12) ? 20 : VIEWY*2-4; // Number of items to show at one time. std::map<char, int> dropping; // Count of how many we'll drop from each stack int count = 0; // The current count std::vector<char> weapon_and_armor; // Always single, not counted bool warned_about_bionic = false; // Printed add_msg re: dropping bionics print_inv_statics(this, w_inv, "Multidrop:", weapon_and_armor); int base_weight = u.weight_carried(); int base_volume = u.volume_carried(); int ch = (int)'.'; int start = 0, cur_it; invslice stacks = u.inv.slice(0, u.inv.size()); std::vector<int> firsts = find_firsts(stacks); do { inventory drop_subset = u.inv.subset(dropping); int new_weight = base_weight - drop_subset.weight(); int new_volume = base_volume - drop_subset.volume(); for (int i = 0; i < weapon_and_armor.size(); ++i) { new_weight -= u.i_at(weapon_and_armor[i]).weight(); } print_inv_weight_vol(this, w_inv, new_weight, new_volume); if (( ch == '<' || ch == KEY_PPAGE ) && start > 0) { for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); start -= maxitems; if (start < 0) start = 0; mvwprintw(w_inv, maxitems + 4, 0, " "); } if (( ch == '>' || ch == KEY_NPAGE ) && cur_it < u.inv.size()) { start = cur_it; mvwprintw(w_inv, maxitems + 4, 12, " "); for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); } int cur_line = 2; for (cur_it = start; cur_it < start + maxitems && cur_line < maxitems+3; cur_it++) { // Clear the current line; mvwprintw(w_inv, cur_line, 0, " "); // Print category header for (int i = 1; i < iCategorieNum; i++) { if (cur_it == firsts[i-1]) { mvwprintz(w_inv, cur_line, 0, c_magenta, CATEGORIES[i].c_str()); cur_line++; } } if (cur_it < stacks.size()) { item& it = stacks[cur_it]->front(); mvwputch (w_inv, cur_line, 0, c_white, it.invlet); char icon = '-'; if (dropping[it.invlet] >= (it.count_by_charges() ? it.charges : stacks[cur_it]->size())) icon = '+'; else if (dropping[it.invlet] > 0) icon = '#'; nc_color col = (dropping[it.invlet] == 0 ? c_ltgray : c_white); mvwprintz(w_inv, cur_line, 1, col, " %c %s", icon, it.tname(this).c_str()); if (stacks[cur_it]->size() > 1) wprintz(w_inv, col, " [%d]", stacks[cur_it]->size()); if (it.charges > 0) wprintz(w_inv, col, " (%d)", it.charges); else if (it.contents.size() == 1 && it.contents[0].charges > 0) wprintw(w_inv, " (%d)", it.contents[0].charges); } cur_line++; } if (start > 0) mvwprintw(w_inv, maxitems + 4, 0, "< Go Back"); if (cur_it < u.inv.size()) mvwprintw(w_inv, maxitems + 4, 12, "> More items"); wrefresh(w_inv); ch = input(); if (ch >= '0'&& ch <= '9') { ch = (char)ch - '0'; count *= 10; count += ch; } else if (u.has_item(ch)) { item& it = u.inv.item_by_letter(ch); if (it.is_null()) { // Not from inventory int found = false; for (int i = 0; i < weapon_and_armor.size() && !found; i++) { if (weapon_and_armor[i] == ch) { weapon_and_armor.erase(weapon_and_armor.begin() + i); found = true; print_inv_statics(this, w_inv, "Multidrop:", weapon_and_armor); } } if (!found) { if ( ch == u.weapon.invlet && std::find(unreal_itype_ids.begin(), unreal_itype_ids.end(), u.weapon.type->id) != unreal_itype_ids.end()){ if (!warned_about_bionic) add_msg("You cannot drop your %s.", u.weapon.tname(this).c_str()); warned_about_bionic = true; } else { weapon_and_armor.push_back(ch); print_inv_statics(this, w_inv, "Multidrop:", weapon_and_armor); } } } else { int index = -1; for (int i = 0; i < stacks.size(); ++i) { if (stacks[i]->front().invlet == it.invlet) { index = i; break; } } if (index == -1) { debugmsg("Inventory got out of sync with inventory slice?"); } if (count == 0) { if (it.count_by_charges()) { if (dropping[it.invlet] == 0) dropping[it.invlet] = -1; else dropping[it.invlet] = 0; } else { if (dropping[it.invlet] == 0) dropping[it.invlet] = stacks[index]->size(); else dropping[it.invlet] = 0; } } else if (count >= stacks[index]->size() && !it.count_by_charges()) dropping[it.invlet] = stacks[index]->size(); else dropping[it.invlet] = count; count = 0; } } } while (ch != '\n' && ch != KEY_ESCAPE && ch != ' '); werase(w_inv); delwin(w_inv); erase(); refresh_all(); std::vector<item> ret; if (ch != '\n') return ret; // Canceled! for (std::map<char,int>::iterator it = dropping.begin(); it != dropping.end(); it++) { if (it->second == -1) ret.push_back( u.inv.remove_item_by_letter( it->first)); else if (it->second && u.inv.item_by_letter( it->first).count_by_charges()) { int charges = u.inv.item_by_letter( it->first).charges;// >= it->second ? : it->second; ret.push_back( u.inv.remove_item_by_charges( it->first, it->second > charges ? charges : it->second)); } else if (it->second) for (int j = it->second; j > 0; j--) ret.push_back( u.inv.remove_item_by_letter( it->first)); } for (int i = 0; i < weapon_and_armor.size(); i++) ret.push_back(u.i_rem(weapon_and_armor[i])); return ret; }
// Display current inventory. char game::inv(std::string title) { WINDOW* w_inv = newwin(((VIEWY < 12) ? 25 : VIEWY*2+1), ((VIEWX < 12) ? 80 : VIEWX*2+56), VIEW_OFFSET_Y, VIEW_OFFSET_X); const int maxitems = (VIEWY < 12) ? 20 : VIEWY*2-4; // Number of items to show at one time. int ch = (int)'.'; int start = 0, cur_it, max_it; u.inv.sort(); u.inv.restack(&u); invslice slice = u.inv.slice(0, u.inv.size()); std::vector<char> null_vector; print_inv_statics(this, w_inv, title, null_vector); // Gun, ammo, weapon, armor, food, tool, book, other std::vector<int> firsts = find_firsts(slice); int selected=-1; int selected_char=(int)' '; if( uistate.last_inv_start >= 0 ) start = uistate.last_inv_start; if( uistate.last_inv_sel >= 0 ) selected = uistate.last_inv_sel; do { selected_char=(int)' '; if (( ch == '<' || ch == KEY_PPAGE ) && start > 0) { // Clear lines and shift for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); start -= maxitems; if (start < 0) start = 0; mvwprintw(w_inv, maxitems + 4, 0, " "); if ( selected > -1 ) selected = start; // oy, the cheese } if ((ch == '>' || ch == KEY_NPAGE ) && cur_it < u.inv.size()) { // Clear lines and shift start = cur_it; mvwprintw(w_inv, maxitems + 4, 12, " "); for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); if ( selected < start && selected > -1 ) selected = start; } int cur_line = 2; max_it = 0; for (cur_it = start; cur_it < start + maxitems && cur_line < maxitems+3; cur_it++) { // Clear the current line; mvwprintw(w_inv, cur_line, 0, " "); // Print category header for (int i = 1; i < iCategorieNum; i++) { if (cur_it == firsts[i-1]) { mvwprintz(w_inv, cur_line, 0, c_magenta, CATEGORIES[i].c_str()); cur_line++; } } if (cur_it < slice.size()) { item& it = slice[cur_it]->front(); if(cur_it==selected) selected_char=(int)it.invlet; mvwputch (w_inv, cur_line, 0, (cur_it == selected ? h_white : c_white), it.invlet); mvwprintz(w_inv, cur_line, 1, (cur_it == selected ? h_white : it.color_in_inventory(&u) ), " %s", it.tname(this).c_str()); if (slice[cur_it]->size() > 1) wprintw(w_inv, " [%d]", slice[cur_it]->size()); if (it.charges > 0) wprintw(w_inv, " (%d)", it.charges); else if (it.contents.size() == 1 && it.contents[0].charges > 0) wprintw(w_inv, " (%d)", it.contents[0].charges); max_it=cur_it; } cur_line++; } if (start > 0) mvwprintw(w_inv, maxitems + 4, 0, "< Go Back"); if (cur_it < u.inv.size()) mvwprintw(w_inv, maxitems + 4, 12, "> More items"); wrefresh(w_inv); ch = getch(); if ( ch == KEY_DOWN ) { if ( selected < 0 ) { selected = start; } else { selected++; } if ( selected > max_it ) { if( cur_it < u.inv.size() ) { ch='>'; } else { selected = u.inv.size() - 1; // wraparound? } } } else if ( ch == KEY_UP ) { selected--; if ( selected < -1 ) { selected = -1; // wraparound? } else if ( selected < start ) { if ( start > 0 ) { for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); start -= maxitems; if (start < 0) start = 0; mvwprintw(w_inv, maxitems + 4, 0, " "); } } } else if ( ch == '\n' || ch == KEY_RIGHT ) { // if ( uistate.last_inv_start > -2 && uistate.last_inv_sel > -2 ) { uistate.last_inv_start=start; uistate.last_inv_sel=selected; // } ch = selected_char; } } while (ch == '<' || ch == '>' || ch == KEY_NPAGE || ch == KEY_PPAGE || ch == KEY_UP || ch == KEY_DOWN ); werase(w_inv); delwin(w_inv); erase(); refresh_all(); return (char)ch; }
std::vector<item> game::multidrop() { WINDOW* w_inv = newwin(TERRAIN_WINDOW_HEIGHT, TERRAIN_WINDOW_WIDTH + (use_narrow_sidebar() ? 45 : 55), VIEW_OFFSET_Y, VIEW_OFFSET_X); const int maxitems = TERRAIN_WINDOW_HEIGHT - 5; u.inv.restack(&u); u.inv.sort(); int drp_line_width=getmaxx(w_inv)-90; const std::string drp_line_padding = ( drp_line_width > 1 ? std::string(drp_line_width, ' ') : " "); std::map<int, int> dropping; // Count of how many we'll drop from each position int count = 0; // The current count std::vector<char> weapon_and_armor; // Always single, not counted bool warned_about_bionic = false; // Printed add_msg re: dropping bionics print_inv_statics(this, w_inv, _("Multidrop:"), weapon_and_armor); int base_weight = u.weight_carried(); int base_volume = u.volume_carried(); int ch = (int)'.'; int start = 0, cur_it = 0, max_it; indexed_invslice stacks = u.inv.slice_filter(); CategoriesVector CATEGORIES; std::vector<int> firsts = find_firsts(stacks, CATEGORIES); int selected = -1; int selected_pos = INT_MIN; int next_category_at = 0; int prev_category_at = 0; bool inCategoryMode = false; std::vector<int> category_order; category_order.reserve(firsts.size()); // Items are not guaranteed to be in the same order as their categories, in fact they almost never are. // So we sort the categories by which items actually show up first in the inventory. for (int current_item = 0; current_item < u.inv.size(); ++current_item) { for (int i = 1; i < CATEGORIES.size(); ++i) { if (current_item == firsts[i - 1]) { category_order.push_back(i - 1); } } } do { // Find the inventory position of the first item in the previous and next category (in relation // to the currently selected category). for (int i = 0; i < category_order.size(); ++i) { if (selected > firsts[category_order[i]] && prev_category_at <= firsts[category_order[i]]) { prev_category_at = firsts[category_order[i]]; } if (selected < firsts[category_order[i]] && next_category_at <= selected) { next_category_at = firsts[category_order[i]]; } } inventory drop_subset = u.inv.subset(dropping); int new_weight = base_weight - drop_subset.weight(); int new_volume = base_volume - drop_subset.volume(); for (int i = 0; i < weapon_and_armor.size(); ++i) { new_weight -= u.i_at(weapon_and_armor[i]).weight(); } print_inv_weight_vol(this, w_inv, new_weight, new_volume); int cur_line = 2; max_it = 0; int drp_line = 1; // Print weapon to be dropped, the first position is reserved for high visibility mvwprintw(w_inv, 0, 90, "%s", drp_line_padding.c_str()); bool dropping_w = false; for (int k = 0; k < weapon_and_armor.size() && !dropping_w; k++) { if (weapon_and_armor[k] == u.weapon.invlet) { dropping_w = true; } if (dropping_w && u.is_armed()) { mvwprintz(w_inv, 0, 90, c_ltblue, "%c + %s", u.weapon.invlet, u.weapname().c_str()); } } // Print worn items to be dropped if(dropping_w) { mvwprintw(w_inv, drp_line, 90, "%s", drp_line_padding.c_str()); drp_line++; } bool dropping_a = false; if (u.worn.size() > 0){ for (int k = 0; k < u.worn.size(); k++) { bool dropping_w = false; for (int j = 0; j < weapon_and_armor.size() && !dropping_w; j++) { if (weapon_and_armor[j] == u.worn[k].invlet) { dropping_w = true; dropping_a = true; mvwprintw(w_inv, drp_line, 90, "%s", drp_line_padding.c_str()); mvwprintz(w_inv, drp_line, 90, c_cyan, "%c + %s", u.worn[k].invlet, u.worn[k].tname().c_str()); drp_line++; } } } } if(dropping_a) { mvwprintw(w_inv, drp_line, 90, "%s", drp_line_padding.c_str()); drp_line++; } for (cur_it = start; cur_it < start + maxitems && cur_line < maxitems+3; cur_it++) { // Clear the current line; mvwprintw(w_inv, cur_line, 0, " "); mvwprintw(w_inv, drp_line, 90, "%s", drp_line_padding.c_str()); mvwprintw(w_inv, drp_line + 1, 90, "%s", drp_line_padding.c_str()); // Print category header for (int i = 1; i < CATEGORIES.size(); i++) { if (cur_it == firsts[i-1]) { mvwprintz(w_inv, cur_line, 0, c_magenta, CATEGORIES[i].name.c_str()); cur_line++; } } if ( selected < start && selected > -1 ) selected = start; if (cur_it < stacks.size()) { item& it = stacks[cur_it].first->front(); if( cur_it == selected) { selected_pos = stacks[cur_it].second; } nc_color selected_line_color = inCategoryMode ? c_white_red : h_white; mvwputch (w_inv, cur_line, 0, (cur_it == selected ? selected_line_color : c_white), it.invlet); char icon = '-'; if (dropping[cur_it] >= (it.count_by_charges() ? it.charges : stacks[cur_it].first->size())) { icon = '+'; } else if (dropping[cur_it] > 0) { icon = '#'; } nc_color col = ( cur_it == selected ? selected_line_color : (dropping[cur_it] == 0 ? c_ltgray : c_white ) ); mvwprintz(w_inv, cur_line, 1, col, " %c %s", icon, it.tname().c_str()); if (stacks[cur_it].first->size() > 1) { wprintz(w_inv, col, " x %d", stacks[cur_it].first->size()); } if (it.charges > 0) { wprintz(w_inv, col, " (%d)", it.charges); } else if (it.contents.size() == 1 && it.contents[0].charges > 0) { wprintw(w_inv, " (%d)", it.contents[0].charges); } if (icon=='+'||icon=='#') { mvwprintz(w_inv, drp_line, 90, col, "%c %c %s", it.invlet, icon, it.tname().c_str()); if (icon=='+') { if (stacks[cur_it].first->size() > 1) { wprintz(w_inv, col, " x %d", stacks[cur_it].first->size()); } if (it.charges > 0) { wprintz(w_inv, col, " (%d)", it.charges); } } if (icon=='#') { wprintz(w_inv, col, " {%d}", dropping[cur_it]); } drp_line++; } } cur_line++; max_it=cur_it; } if (inCategoryMode) { mvwprintz(w_inv, maxitems + 4, 32, c_white_red, _("In category select mode! Press [SPACE] to enter item select mode.")); } else { mvwprintz(w_inv, maxitems + 4, 32, h_white, _("In item select mode! Press [SPACE] to enter category select mode.")); } if (start > 0) { mvwprintw(w_inv, maxitems + 4, 0, _("< Go Back")); } if (cur_it < u.inv.size()) { mvwprintw(w_inv, maxitems + 4, 12, _("> More items")); } wrefresh(w_inv); /* back to (int)getch() as input() mangles arrow keys ch = input(); */ ch = getch(); if (ch == ' ') { inCategoryMode = !inCategoryMode; } else if ( ch == '<' || ch == KEY_PPAGE ) { if( start > 0) { for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); start -= maxitems; if (start < 0) start = 0; mvwprintw(w_inv, maxitems + 4, 0, " "); if ( selected > -1 ) selected = start; // oy, the cheese } } else if ( ch == '>' || ch == KEY_NPAGE ) { if ( cur_it < u.inv.size()) { start = cur_it; mvwprintw(w_inv, maxitems + 4, 12, " "); for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); if ( selected < start && selected > -1 ) selected = start; } } else if ( ch == KEY_DOWN ) { if ( selected < 0 ) { selected = start; } else { if (inCategoryMode) { selected < firsts[category_order[category_order.size() - 1]] ? selected = next_category_at : 0; } else { selected++; } next_category_at = prev_category_at = 0; } if ( selected > max_it ) { if( cur_it < u.inv.size() ) { start = cur_it; mvwprintw(w_inv, maxitems + 4, 12, " "); for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); } else { selected = u.inv.size() - 1; // wraparound? } } } else if ( ch == KEY_UP ) { inCategoryMode ? selected = prev_category_at : selected--; next_category_at = prev_category_at = 0; if ( selected < -1 ) { selected = -1; // wraparound? } else if ( selected < start ) { if ( start > 0 ) { for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); start -= maxitems; if (start < 0) start = 0; mvwprintw(w_inv, maxitems + 4, 0, " "); } } } else if (ch >= '0'&& ch <= '9') { ch = (char)ch - '0'; count *= 10; count += ch; } else { // todo: reformat and maybe rewrite item* it; int it_pos; if ( ch == '\t' || ch == KEY_RIGHT || ch == KEY_LEFT ) { it_pos = selected_pos; it = &u.inv.find_item(it_pos); } else { it = &u.inv.item_by_letter((char)ch); it_pos = u.inv.position_by_item(it); } if (it == 0 || it->is_null()) { // Not from inventory int found = false; for (int i = 0; i < weapon_and_armor.size() && !found; i++) { if (weapon_and_armor[i] == ch) { weapon_and_armor.erase(weapon_and_armor.begin() + i); found = true; print_inv_statics(this, w_inv, _("Multidrop:"), weapon_and_armor); } } if (!found) { if ( ch == u.weapon.invlet && std::find(unreal_itype_ids.begin(), unreal_itype_ids.end(), u.weapon.type->id) != unreal_itype_ids.end()){ if (!warned_about_bionic) add_msg(_("You cannot drop your %s."), u.weapon.tname().c_str()); warned_about_bionic = true; } else { weapon_and_armor.push_back(ch); print_inv_statics(this, w_inv, _("Multidrop:"), weapon_and_armor); } } } else { int index = -1; for (int i = 0; i < stacks.size(); ++i) { if (stacks[i].first->front().invlet == it->invlet) { index = i; break; } } if (index == -1) { debugmsg("Inventory got out of sync with inventory slice?"); } if (count == 0) { if (it->count_by_charges()) { if (dropping[it_pos] == 0) { dropping[it_pos] = -1; } else { dropping[it_pos] = 0; } } else { if (dropping[it_pos] == 0) { dropping[it_pos] = stacks[index].first->size(); } else { dropping[it_pos] = 0; } } } else if (count >= stacks[index].first->size() && !it->count_by_charges()) { dropping[it_pos] = stacks[index].first->size(); } else { dropping[it_pos] = count; } count = 0; } } } while (ch != '\n' && ch != KEY_ESCAPE); werase(w_inv); delwin(w_inv); erase(); refresh_all(); std::vector<item> ret; if (ch != '\n') return ret; // Canceled! // We iterate backwards because deletion will invalidate later indices. for (std::map<int,int>::reverse_iterator it = dropping.rbegin(); it != dropping.rend(); ++it) { if (it->second == -1) ret.push_back( u.inv.remove_item( it->first)); else if (it->second && u.inv.find_item( it->first).count_by_charges()) { int charges = u.inv.find_item( it->first).charges;// >= it->second ? : it->second; ret.push_back( u.inv.reduce_charges( it->first, it->second > charges ? charges : it->second)); } else if (it->second) for (int j = it->second; j > 0; j--) ret.push_back( u.inv.remove_item( it->first)); } for (int i = 0; i < weapon_and_armor.size(); i++) { int wornpos = u.invlet_to_position(weapon_and_armor[i]); if (wornpos == INT_MIN || !u.takeoff(this, wornpos, true)) { continue; } // Item could have been dropped after taking it off if (&u.inv.item_by_letter(weapon_and_armor[i]) != &u.inv.nullitem) { ret.push_back(u.i_rem(weapon_and_armor[i])); } } return ret; }
int game::display_slice(indexed_invslice& slice, const std::string& title) { WINDOW* w_inv = newwin( TERRAIN_WINDOW_HEIGHT, TERRAIN_WINDOW_WIDTH + (use_narrow_sidebar() ? 45 : 55), VIEW_OFFSET_Y, VIEW_OFFSET_X ); const int maxitems = TERRAIN_WINDOW_HEIGHT - 5; int ch = (int)'.'; int start = 0, cur_it = 0, max_it; std::vector<char> null_vector; print_inv_statics(this, w_inv, title, null_vector); // Gun, ammo, weapon, armor, food, tool, book, other CategoriesVector CATEGORIES; std::vector<int> firsts = find_firsts(slice, CATEGORIES); int selected =- 1; int selected_pos = INT_MIN; int next_category_at = 0; int prev_category_at = 0; bool inCategoryMode = false; std::vector<int> category_order; category_order.reserve(firsts.size()); // Items are not guaranteed to be in the same order as their categories, in fact they almost never are. // So we sort the categories by which items actually show up first in the inventory. for (int current_item = 0; current_item < slice.size(); ++current_item) { for (int i = 1; i < CATEGORIES.size(); ++i) { if (current_item == firsts[i - 1]) { category_order.push_back(i - 1); } } } do { if (( ch == '<' || ch == KEY_PPAGE ) && start > 0) { // Clear lines and shift for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); start -= maxitems; if (start < 0) start = 0; mvwprintw(w_inv, maxitems + 4, 0, " "); if ( selected > -1 ) selected = start; // oy, the cheese } if (( ch == '>' || ch == KEY_NPAGE ) && cur_it < slice.size()) { // Clear lines and shift start = cur_it; mvwprintw(w_inv, maxitems + 4, 12, " "); for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); if ( selected < start && selected > -1 ) selected = start; } int cur_line = 2; max_it = 0; // Find the inventory position of the first item in the previous and next category (in relation // to the currently selected category). for (int i = 0; i < category_order.size(); ++i) { if (selected > firsts[category_order[i]] && prev_category_at <= firsts[category_order[i]]) { prev_category_at = firsts[category_order[i]]; } if (selected < firsts[category_order[i]] && next_category_at <= selected) { next_category_at = firsts[category_order[i]]; } } for (cur_it = start; cur_it < start + maxitems && cur_line < maxitems+3; cur_it++) { // Clear the current line; mvwprintw(w_inv, cur_line, 0, " "); for (int i = 1; i < CATEGORIES.size(); i++) { if (cur_it == firsts[i-1]) { mvwprintz(w_inv, cur_line, 0, c_magenta, CATEGORIES[i].name.c_str()); cur_line++; } } if (cur_it < slice.size()) { item& it = slice[cur_it].first->front(); if(cur_it == selected) { selected_pos=slice[cur_it].second; } nc_color selected_line_color = inCategoryMode ? c_white_red : h_white; mvwputch(w_inv, cur_line, 0, (cur_it == selected ? selected_line_color : c_white), it.invlet); mvwprintz(w_inv, cur_line, 1, (cur_it == selected ? selected_line_color : it.color_in_inventory()), " %s", it.display_name().c_str()); if (slice[cur_it].first->size() > 1) { wprintw(w_inv, " x %d", slice[cur_it].first->size()); } cur_line++; max_it = cur_it; } } if (inCategoryMode) { mvwprintz(w_inv, maxitems + 4, 32, c_white_red, _("In category select mode! Press [SPACE] to enter item select mode.")); } else { mvwprintz(w_inv, maxitems + 4, 32, h_white, _("In item select mode! Press [SPACE] to enter category select mode.")); } if (start > 0) mvwprintw(w_inv, maxitems + 4, 0, _("< Go Back")); if (cur_it < slice.size()) mvwprintw(w_inv, maxitems + 4, 12, _("> More items")); wrefresh(w_inv); input_context ctxt("INVENTORY"); ctxt.register_action("ANY_INPUT"); ctxt.handle_input(); ch = ctxt.get_raw_input().get_first_input(); if (ch == ' ') { inCategoryMode = !inCategoryMode; } else if ( ch == KEY_DOWN ) { if ( selected < 0 ) { selected = start; } else { if (inCategoryMode) { selected < firsts[category_order[category_order.size() - 1]] ? selected = next_category_at : 0; } else { selected++; } next_category_at = prev_category_at = 0; } if ( selected > max_it ) { if( cur_it < u.inv.size() ) { ch='>'; } else { selected = u.inv.size() - 1; // wraparound? } } } else if ( ch == KEY_UP ) { inCategoryMode ? selected = prev_category_at : selected--; next_category_at = prev_category_at = 0; if ( selected < -1 ) { selected = -1; // wraparound? } else if ( selected < start ) { if ( start > 0 ) { for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); start -= maxitems; if (start < 0) start = 0; mvwprintw(w_inv, maxitems + 4, 0, " "); } } } else if ( ch == '\n' || ch == KEY_RIGHT ) { ch = '\n'; } } while (ch == '<' || ch == '>' || ch == ' ' || ch == KEY_NPAGE || ch == KEY_PPAGE || ch == KEY_UP || ch == KEY_DOWN ); werase(w_inv); delwin(w_inv); erase(); refresh_all(); if (ch == '\n') { // user hit enter (or equivalent). return selected_pos; } else { // user hit an invlet (or exited out, which will resolve to INT_MIN) return u.invlet_to_position((char)ch); } }
std::vector<item> game::multidrop() { WINDOW* w_inv = newwin(TERRAIN_WINDOW_HEIGHT, TERRAIN_WINDOW_WIDTH + (use_narrow_sidebar() ? 45 : 55), VIEW_OFFSET_Y, VIEW_OFFSET_X); const int maxitems = TERRAIN_WINDOW_HEIGHT - 5; u.inv.restack(&u); u.inv.sort(); int drp_line_width=getmaxx(w_inv)-90; const std::string drp_line_padding = ( drp_line_width > 1 ? std::string(drp_line_width, ' ') : " "); std::map<char, int> dropping; // Count of how many we'll drop from each stack int count = 0; // The current count std::vector<char> weapon_and_armor; // Always single, not counted bool warned_about_bionic = false; // Printed add_msg re: dropping bionics print_inv_statics(this, w_inv, _("Multidrop:"), weapon_and_armor); int base_weight = u.weight_carried(); int base_volume = u.volume_carried(); int ch = (int)'.'; int start = 0, cur_it = 0, max_it; invslice stacks = u.inv.slice(0, u.inv.size()); std::vector<int> firsts = find_firsts(stacks); int selected=-1; int selected_char=(int)' '; do { inventory drop_subset = u.inv.subset(dropping); int new_weight = base_weight - drop_subset.weight(); int new_volume = base_volume - drop_subset.volume(); for (int i = 0; i < weapon_and_armor.size(); ++i) { new_weight -= u.i_at(weapon_and_armor[i]).weight(); } print_inv_weight_vol(this, w_inv, new_weight, new_volume); int cur_line = 2; max_it = 0; int drp_line = 1; // Print weapon to be dropped, the first position is reserved for high visibility mvwprintw(w_inv, 0, 90, "%s", drp_line_padding.c_str()); bool dropping_w = false; for (int k = 0; k < weapon_and_armor.size() && !dropping_w; k++) { if (weapon_and_armor[k] == u.weapon.invlet) { dropping_w = true; } if (dropping_w && u.is_armed()) { mvwprintz(w_inv, 0, 90, c_ltblue, "%c + %s", u.weapon.invlet, u.weapname().c_str()); } } // Print worn items to be dropped if(dropping_w) { mvwprintw(w_inv, drp_line, 90, "%s", drp_line_padding.c_str()); drp_line++; } bool dropping_a = false; if (u.worn.size() > 0){ for (int k = 0; k < u.worn.size(); k++) { bool dropping_w = false; for (int j = 0; j < weapon_and_armor.size() && !dropping_w; j++) { if (weapon_and_armor[j] == u.worn[k].invlet) { dropping_w = true; dropping_a = true; mvwprintw(w_inv, drp_line, 90, "%s", drp_line_padding.c_str()); mvwprintz(w_inv, drp_line, 90, c_cyan, "%c + %s", u.worn[k].invlet, u.worn[k].tname(this).c_str()); drp_line++; } } } } if(dropping_a) { mvwprintw(w_inv, drp_line, 90, "%s", drp_line_padding.c_str()); drp_line++; } for (cur_it = start; cur_it < start + maxitems && cur_line < maxitems+3; cur_it++) { // Clear the current line; mvwprintw(w_inv, cur_line, 0, " "); mvwprintw(w_inv, drp_line, 90, "%s", drp_line_padding.c_str()); mvwprintw(w_inv, drp_line + 1, 90, "%s", drp_line_padding.c_str()); // Print category header for (int i = 1; i < iCategorieNum; i++) { if (cur_it == firsts[i-1]) { mvwprintz(w_inv, cur_line, 0, c_magenta, _(CATEGORIES[i].c_str())); cur_line++; } } if ( selected < start && selected > -1 ) selected = start; if (cur_it < stacks.size()) { item& it = stacks[cur_it]->front(); if(cur_it==selected) selected_char=(int)it.invlet; mvwputch (w_inv, cur_line, 0, (cur_it == selected ? h_white : c_white), it.invlet); char icon = '-'; if (dropping[it.invlet] >= (it.count_by_charges() ? it.charges : stacks[cur_it]->size())) icon = '+'; else if (dropping[it.invlet] > 0) icon = '#'; nc_color col = ( cur_it == selected ? h_white : (dropping[it.invlet] == 0 ? c_ltgray : c_white ) ); mvwprintz(w_inv, cur_line, 1, col, " %c %s", icon, it.tname(this).c_str()); if (stacks[cur_it]->size() > 1) wprintz(w_inv, col, " [%d]", stacks[cur_it]->size()); if (it.charges > 0) wprintz(w_inv, col, " (%d)", it.charges); else if (it.contents.size() == 1 && it.contents[0].charges > 0) wprintw(w_inv, " (%d)", it.contents[0].charges); if (icon=='+'||icon=='#') { mvwprintz(w_inv, drp_line, 90, col, "%c %c %s", it.invlet, icon, it.tname(this).c_str()); if (icon=='+'){ if (stacks[cur_it]->size() > 1) wprintz(w_inv, col, " [%d]", stacks[cur_it]->size()); if (it.charges > 0) wprintz(w_inv, col, " (%d)", it.charges); } if (icon=='#') { wprintz(w_inv, col, " {%d}", dropping[it.invlet]); } drp_line++; } } cur_line++; max_it=cur_it; } if (start > 0) mvwprintw(w_inv, maxitems + 4, 0, _("< Go Back")); if (cur_it < u.inv.size()) mvwprintw(w_inv, maxitems + 4, 12, _("> More items")); wrefresh(w_inv); /* back to (int)getch() as input() mangles arrow keys ch = input(); */ ch = getch(); if ( ch == '<' || ch == KEY_PPAGE ) { if( start > 0) { for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); start -= maxitems; if (start < 0) start = 0; mvwprintw(w_inv, maxitems + 4, 0, " "); if ( selected > -1 ) selected = start; // oy, the cheese } } else if ( ch == '>' || ch == KEY_NPAGE ) { if ( cur_it < u.inv.size()) { start = cur_it; mvwprintw(w_inv, maxitems + 4, 12, " "); for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); if ( selected < start && selected > -1 ) selected = start; } } else if ( ch == KEY_DOWN ) { if ( selected < 0 ) { selected = start; } else { selected++; } if ( selected > max_it ) { if( cur_it < u.inv.size() ) { start = cur_it; mvwprintw(w_inv, maxitems + 4, 12, " "); for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); } else { selected = u.inv.size() - 1; // wraparound? } } } else if ( ch == KEY_UP ) { selected--; if ( selected < -1 ) { selected = -1; // wraparound? } else if ( selected < start ) { if ( start > 0 ) { for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); start -= maxitems; if (start < 0) start = 0; mvwprintw(w_inv, maxitems + 4, 0, " "); } } } else if (ch >= '0'&& ch <= '9') { ch = (char)ch - '0'; count *= 10; count += ch; } else { // todo: reformat and maybe rewrite if ( ch == '\t' || ch == KEY_RIGHT || ch == KEY_LEFT ) { ch = selected_char; } if (u.has_item(ch)) { item& it = u.inv.item_by_letter(ch); if (it.is_null()) { // Not from inventory int found = false; for (int i = 0; i < weapon_and_armor.size() && !found; i++) { if (weapon_and_armor[i] == ch) { weapon_and_armor.erase(weapon_and_armor.begin() + i); found = true; print_inv_statics(this, w_inv, _("Multidrop:"), weapon_and_armor); } } if (!found) { if ( ch == u.weapon.invlet && std::find(unreal_itype_ids.begin(), unreal_itype_ids.end(), u.weapon.type->id) != unreal_itype_ids.end()){ if (!warned_about_bionic) add_msg(_("You cannot drop your %s."), u.weapon.tname(this).c_str()); warned_about_bionic = true; } else { weapon_and_armor.push_back(ch); print_inv_statics(this, w_inv, _("Multidrop:"), weapon_and_armor); } } } else { int index = -1; for (int i = 0; i < stacks.size(); ++i) { if (stacks[i]->front().invlet == it.invlet) { index = i; break; } } if (index == -1) { debugmsg("Inventory got out of sync with inventory slice?"); } if (count == 0) { if (it.count_by_charges()) { if (dropping[it.invlet] == 0) dropping[it.invlet] = -1; else dropping[it.invlet] = 0; } else { if (dropping[it.invlet] == 0) dropping[it.invlet] = stacks[index]->size(); else dropping[it.invlet] = 0; } } else if (count >= stacks[index]->size() && !it.count_by_charges()) dropping[it.invlet] = stacks[index]->size(); else dropping[it.invlet] = count; count = 0; } } } } while (ch != '\n' && ch != KEY_ESCAPE && ch != ' '); werase(w_inv); delwin(w_inv); erase(); refresh_all(); std::vector<item> ret; if (ch != '\n') return ret; // Canceled! for (std::map<char,int>::iterator it = dropping.begin(); it != dropping.end(); ++it) { if (it->second == -1) ret.push_back( u.inv.remove_item_by_letter( it->first)); else if (it->second && u.inv.item_by_letter( it->first).count_by_charges()) { int charges = u.inv.item_by_letter( it->first).charges;// >= it->second ? : it->second; ret.push_back( u.inv.remove_item_by_charges( it->first, it->second > charges ? charges : it->second)); } else if (it->second) for (int j = it->second; j > 0; j--) ret.push_back( u.inv.remove_item_by_letter( it->first)); } for (int i = 0; i < weapon_and_armor.size(); i++) { if (!u.takeoff(this, weapon_and_armor[i], true)) { continue; } // Item could have been dropped after taking it off if (&u.inv.item_by_letter(weapon_and_armor[i]) != &u.inv.nullitem) { ret.push_back(u.i_rem(weapon_and_armor[i])); } } return ret; }
char game::inv(inventory& inv, std::string title) { WINDOW* w_inv = newwin(TERRAIN_WINDOW_HEIGHT, TERRAIN_WINDOW_WIDTH + (use_narrow_sidebar() ? 45 : 55), VIEW_OFFSET_Y, VIEW_OFFSET_X); const int maxitems = TERRAIN_WINDOW_HEIGHT - 5; int ch = (int)'.'; int start = 0, cur_it = 0, max_it; inv.sort(); std::vector<char> null_vector; print_inv_statics(this, w_inv, title, null_vector); // Gun, ammo, weapon, armor, food, tool, book, other invslice slice = inv.slice(0, inv.size()); std::vector<int> firsts = find_firsts(slice); int selected =- 1; int selected_char = (int)' '; do { if (( ch == '<' || ch == KEY_PPAGE ) && start > 0) { // Clear lines and shift for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); start -= maxitems; if (start < 0) start = 0; mvwprintw(w_inv, maxitems + 4, 0, " "); if ( selected > -1 ) selected = start; // oy, the cheese } if (( ch == '>' || ch == KEY_NPAGE ) && cur_it < inv.size()) { // Clear lines and shift start = cur_it; mvwprintw(w_inv, maxitems + 4, 12, " "); for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); if ( selected < start && selected > -1 ) selected = start; } int cur_line = 2; max_it = 0; for (cur_it = start; cur_it < start + maxitems && cur_line < maxitems+3; cur_it++) { // Clear the current line; mvwprintw(w_inv, cur_line, 0, " "); for (int i = 1; i < iCategorieNum; i++) { if (cur_it == firsts[i-1]) { mvwprintz(w_inv, cur_line, 0, c_magenta, _(CATEGORIES[i].c_str())); cur_line++; } } if (cur_it < slice.size()) { item& it = slice[cur_it]->front(); if(cur_it==selected) selected_char=(int)it.invlet; mvwputch (w_inv, cur_line, 0, (cur_it == selected ? h_white : c_white), it.invlet); mvwprintz(w_inv, cur_line, 1, (cur_it == selected ? h_white : it.color_in_inventory(&u) ), " %s", it.tname(this).c_str()); if (slice[cur_it]->size() > 1) wprintw(w_inv, " [%d]", slice[cur_it]->size()); if (it.charges > 0) wprintw(w_inv, " (%d)", it.charges); else if (it.contents.size() == 1 && it.contents[0].charges > 0) wprintw(w_inv, " (%d)", it.contents[0].charges); cur_line++; max_it=cur_it; } // cur_line++; } if (start > 0) mvwprintw(w_inv, maxitems + 4, 0, _("< Go Back")); if (cur_it < inv.size()) mvwprintw(w_inv, maxitems + 4, 12, _("> More items")); wrefresh(w_inv); ch = getch(); if ( ch == KEY_DOWN ) { if ( selected < 0 ) { selected = start; } else { selected++; } if ( selected > max_it ) { if( cur_it < u.inv.size() ) { ch='>'; } else { selected = u.inv.size() - 1; // wraparound? } } } else if ( ch == KEY_UP ) { selected--; if ( selected < -1 ) { selected = -1; // wraparound? } else if ( selected < start ) { if ( start > 0 ) { for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); start -= maxitems; if (start < 0) start = 0; mvwprintw(w_inv, maxitems + 4, 0, " "); } } } else if ( ch == '\n' || ch == KEY_RIGHT ) { ch = selected_char; } } while (ch == '<' || ch == '>' || ch == KEY_NPAGE || ch == KEY_PPAGE || ch == KEY_UP || ch == KEY_DOWN ); werase(w_inv); delwin(w_inv); erase(); refresh_all(); return (char)ch; }