void game::construction_menu() { WINDOW *w_con = newwin(25, 80, 0, 0); wborder(w_con, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX, LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX ); mvwprintz(w_con, 0, 1, c_red, "Construction"); mvwputch(w_con, 0, 30, c_white, LINE_OXXX); mvwputch(w_con, 24, 30, c_white, LINE_XXOX); for (int i = 1; i < 24; i++) mvwputch(w_con, i, 30, c_white, LINE_XOXO); mvwprintz(w_con, 1, 31, c_white, "Difficulty:"); wrefresh(w_con); bool update_info = true; int select = 0; char ch; inventory total_inv; total_inv.form_from_map(this, point(u.posx, u.posy), PICKUP_RANGE); total_inv.add_stack(u.inv_dump()); if (u.has_bionic(bio_tools)) { item tools(itypes[itm_toolset], turn); tools.charges = u.power_level; total_inv += tools; } do { // Erase existing list of constructions for (int i = 1; i < 24; i++) { for (int j = 1; j < 29; j++) mvwputch(w_con, i, j, c_black, 'x'); } // Determine where in the master list to start printing int offset = select - 11; if (offset > constructions.size() - 22) offset = constructions.size() - 22; if (offset < 0) offset = 0; // Print the constructions between offset and max (or how many will fit) for (int i = 0; i < 22 && i + offset < constructions.size(); i++) { int current = i + offset; nc_color col = (player_can_build(u, total_inv, constructions[current], 0) ? c_white : c_dkgray); if (current == select) col = hilite(col); mvwprintz(w_con, 1 + i, 1, col, constructions[current]->name.c_str()); } if (update_info) { update_info = false; constructable* current_con = constructions[select]; // Print difficulty int pskill = u.sklevel[sk_carpentry], diff = current_con->difficulty; mvwprintz(w_con, 1, 43, (pskill >= diff ? c_white : c_red), "%d ", diff); // Clear out lines for tools & materials for (int i = 2; i < 24; i++) { for (int j = 31; j < 79; j++) mvwputch(w_con, i, j, c_black, 'x'); } // Print stages and their requirements int posx = 33, posy = 2; for (int n = 0; n < current_con->stages.size(); n++) { nc_color color_stage = (player_can_build(u, total_inv, current_con, n) ? c_white : c_dkgray); mvwprintz(w_con, posy, 31, color_stage, "Stage %d: %s", n + 1, current_con->stages[n].terrain == t_null? "" : terlist[current_con->stages[n].terrain].name.c_str()); posy++; // Print tools construction_stage stage = current_con->stages[n]; bool has_tool[3] = {stage.tools[0].empty(), stage.tools[1].empty(), stage.tools[2].empty()}; for (int i = 0; i < 3 && !has_tool[i]; i++) { posy++; posx = 33; for (int j = 0; j < stage.tools[i].size(); j++) { itype_id tool = stage.tools[i][j]; nc_color col = c_red; if (total_inv.has_amount(tool, 1)) { has_tool[i] = true; col = c_green; } int length = itypes[tool]->name.length(); if (posx + length > 79) { posy++; posx = 33; } mvwprintz(w_con, posy, posx, col, itypes[tool]->name.c_str()); posx += length + 1; // + 1 for an empty space if (j < stage.tools[i].size() - 1) { // "OR" if there's more if (posx > 77) { posy++; posx = 33; } mvwprintz(w_con, posy, posx, c_white, "OR"); posx += 3; } } } // Print components posy++; posx = 33; bool has_component[3] = {stage.components[0].empty(), stage.components[1].empty(), stage.components[2].empty()}; for (int i = 0; i < 3; i++) { posx = 33; while (has_component[i]) i++; for (int j = 0; j < stage.components[i].size() && i < 3; j++) { nc_color col = c_red; component comp = stage.components[i][j]; if (( itypes[comp.type]->is_ammo() && total_inv.has_charges(comp.type, comp.count)) || (!itypes[comp.type]->is_ammo() && total_inv.has_amount(comp.type, comp.count))) { has_component[i] = true; col = c_green; } int length = itypes[comp.type]->name.length(); if (posx + length > 79) { posy++; posx = 33; } mvwprintz(w_con, posy, posx, col, "%s x%d", itypes[comp.type]->name.c_str(), comp.count); posx += length + 3; // + 2 for " x", + 1 for an empty space // Add more space for the length of the count if (comp.count < 10) posx++; else if (comp.count < 100) posx += 2; else posx += 3; if (j < stage.components[i].size() - 1) { // "OR" if there's more if (posx > 77) { posy++; posx = 33; } mvwprintz(w_con, posy, posx, c_white, "OR"); posx += 3; } } posy++; } } wrefresh(w_con); } // Finished updating ch = input(); switch (ch) { case 'j': update_info = true; if (select < constructions.size() - 1) select++; else select = 0; break; case 'k': update_info = true; if (select > 0) select--; else select = constructions.size() - 1; break; case '\n': case 'l': if (player_can_build(u, total_inv, constructions[select], 0)) { place_construction(constructions[select]); ch = 'q'; } else { popup("You can't build that!"); for (int i = 1; i < 24; i++) mvwputch(w_con, i, 30, c_white, LINE_XOXO); update_info = true; } break; } } while (ch != 'q' && ch != 'Q' && ch != KEY_ESCAPE); refresh_all(); }
void safemode::test_pattern( const int tab_in, const int row_in ) { std::vector<std::string> creature_list; std::string creature_name; auto &temp_rules = ( tab_in == GLOBAL_TAB ) ? global_rules : character_rules; if( temp_rules[row_in].rule.empty() ) { return; } if( g->u.name.empty() ) { popup( _( "No monsters loaded. Please start a game first." ) ); return; } //Loop through all monster mtypes for( const auto &mtype : MonsterGenerator::generator().get_all_mtypes() ) { creature_name = mtype.nname(); if( wildcard_match( creature_name, temp_rules[row_in].rule ) ) { creature_list.push_back( creature_name ); } } const int offset_x = 15 + ( ( TERMX > FULL_SCREEN_WIDTH ) ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0 ); const int offset_y = 5 + ( ( TERMY > FULL_SCREEN_HEIGHT ) ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0 ); int start_pos = 0; const int content_height = FULL_SCREEN_HEIGHT - 8; const int content_width = FULL_SCREEN_WIDTH - 30; WINDOW *w_test_rule_border = newwin( content_height + 2, content_width, offset_y, offset_x ); WINDOW_PTR w_test_rule_borderptr( w_test_rule_border ); WINDOW *w_test_rule_content = newwin( content_height, content_width - 2, 1 + offset_y, 1 + offset_x ); WINDOW_PTR w_test_rule_contentptr( w_test_rule_content ); draw_border( w_test_rule_border ); int nmatch = creature_list.size(); std::string buf = string_format( ngettext( "%1$d monster matches: %2$s", "%1$d monsters match: %2$s", nmatch ), nmatch, temp_rules[row_in].rule.c_str() ); mvwprintz( w_test_rule_border, 0, content_width / 2 - utf8_width( buf ) / 2, hilite( c_white ), "%s", buf.c_str() ); mvwprintz( w_test_rule_border, content_height + 1, 1, red_background( c_white ), _( "Lists monsters regardless of their attitude." ) ); wrefresh( w_test_rule_border ); int line = 0; input_context ctxt( "SAFEMODE_TEST" ); ctxt.register_updown(); ctxt.register_action( "QUIT" ); while( true ) { // Clear the lines for( int i = 0; i < content_height; i++ ) { for( int j = 0; j < 79; j++ ) { mvwputch( w_test_rule_content, i, j, c_black, ' ' ); } } calcStartPos( start_pos, line, content_height, creature_list.size() ); // display safe mode for( int i = start_pos; i < ( int )creature_list.size(); i++ ) { if( i >= start_pos && i < start_pos + std::min( content_height, static_cast<int>( creature_list.size() ) ) ) { nc_color line_color = c_white; mvwprintz( w_test_rule_content, i - start_pos, 0, line_color, "%d", i + 1 ); mvwprintz( w_test_rule_content, i - start_pos, 4, line_color, "" ); wprintz( w_test_rule_content, c_yellow, ( line == i ) ? ">> " : " " ); wprintz( w_test_rule_content, ( line == i ) ? hilite( line_color ) : line_color, "%s", creature_list[i].c_str() ); } } wrefresh( w_test_rule_content ); const std::string action = ctxt.handle_input(); if( action == "DOWN" ) { line++; if( line >= ( int )creature_list.size() ) { line = 0; } } else if( action == "UP" ) { line--; if( line < 0 ) { line = creature_list.size() - 1; } } else { break; } } }
void safemode::show( const std::string &custom_name_in, bool is_safemode_in ) { auto global_rules_old = global_rules; auto character_rules_old = character_rules; const int header_height = 4; const int content_height = FULL_SCREEN_HEIGHT - 2 - header_height; const int offset_x = ( TERMX > FULL_SCREEN_WIDTH ) ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0; const int offset_y = ( TERMY > FULL_SCREEN_HEIGHT ) ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0; enum Columns : int { COLUMN_RULE, COLUMN_ATTITUDE, COLUMN_PROXIMITY, COLUMN_WHITE_BLACKLIST, }; std::map<int, int> column_pos; column_pos[COLUMN_RULE] = 4; column_pos[COLUMN_ATTITUDE] = 48; column_pos[COLUMN_PROXIMITY] = 59; column_pos[COLUMN_WHITE_BLACKLIST] = 66; const int num_columns = column_pos.size(); WINDOW *w_help = newwin( ( FULL_SCREEN_HEIGHT / 2 ) - 2, FULL_SCREEN_WIDTH * 3 / 4, 7 + offset_y + ( FULL_SCREEN_HEIGHT / 2 ) / 2, offset_x + 19 / 2 ); WINDOW_PTR w_helpptr( w_help ); WINDOW *w_border = newwin( FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, offset_y, offset_x ); WINDOW_PTR w_borderptr( w_border ); WINDOW *w_header = newwin( header_height, FULL_SCREEN_WIDTH - 2, 1 + offset_y, 1 + offset_x ); WINDOW_PTR w_headerptr( w_header ); WINDOW *w = newwin( content_height, FULL_SCREEN_WIDTH - 2, header_height + 1 + offset_y, 1 + offset_x ); WINDOW_PTR wptr( w ); draw_border( w_border, BORDER_COLOR, custom_name_in ); mvwputch( w_border, 3, 0, c_ltgray, LINE_XXXO ); // |- mvwputch( w_border, 3, 79, c_ltgray, LINE_XOXX ); // -| for( auto &column : column_pos ) { mvwputch( w_border, FULL_SCREEN_HEIGHT - 1, column.second + 1, c_ltgray, LINE_XXOX ); // _|_ } wrefresh( w_border ); static const std::vector<std::string> hotkeys = {{ _( "<A>dd" ), _( "<R>emove" ), _( "<C>opy" ), _( "<M>ove" ), _( "<E>nable" ), _( "<D>isable" ), _( "<T>est" ) } }; int tmpx = 0; for( auto &hotkey : hotkeys ) { tmpx += shortcut_print( w_header, 0, tmpx, c_white, c_ltgreen, hotkey ) + 2; } tmpx = 0; tmpx += shortcut_print( w_header, 1, tmpx, c_white, c_ltgreen, _( "<+-> Move up/down" ) ) + 2; tmpx += shortcut_print( w_header, 1, tmpx, c_white, c_ltgreen, _( "<Enter>-Edit" ) ) + 2; shortcut_print( w_header, 1, tmpx, c_white, c_ltgreen, _( "<Tab>-Switch Page" ) ); for( int i = 0; i < 78; i++ ) { mvwputch( w_header, 2, i, c_ltgray, LINE_OXOX ); // Draw line under header } for( auto &pos : column_pos ) { mvwputch( w_header, 2, pos.second, c_ltgray, LINE_OXXX ); mvwputch( w_header, 3, pos.second, c_ltgray, LINE_XOXO ); } mvwprintz( w_header, 3, 1, c_white, "#" ); mvwprintz( w_header, 3, column_pos[COLUMN_RULE] + 4, c_white, _( "Rules" ) ); mvwprintz( w_header, 3, column_pos[COLUMN_ATTITUDE] + 2, c_white, _( "Attitude" ) ); mvwprintz( w_header, 3, column_pos[COLUMN_PROXIMITY] + 2, c_white, _( "Dist" ) ); mvwprintz( w_header, 3, column_pos[COLUMN_WHITE_BLACKLIST] + 2, c_white, _( "B/W" ) ); wrefresh( w_header ); int tab = GLOBAL_TAB; int line = 0; int column = 0; int start_pos = 0; bool changes_made = false; input_context ctxt( "SAFEMODE" ); ctxt.register_cardinal(); ctxt.register_action( "CONFIRM" ); ctxt.register_action( "QUIT" ); ctxt.register_action( "NEXT_TAB" ); ctxt.register_action( "PREV_TAB" ); ctxt.register_action( "ADD_DEFAULT_RULESET" ); ctxt.register_action( "ADD_RULE" ); ctxt.register_action( "REMOVE_RULE" ); ctxt.register_action( "COPY_RULE" ); ctxt.register_action( "ENABLE_RULE" ); ctxt.register_action( "DISABLE_RULE" ); ctxt.register_action( "MOVE_RULE_UP" ); ctxt.register_action( "MOVE_RULE_DOWN" ); ctxt.register_action( "TEST_RULE" ); ctxt.register_action( "HELP_KEYBINDINGS" ); if( is_safemode_in ) { ctxt.register_action( "SWITCH_SAFEMODE_OPTION" ); ctxt.register_action( "SWAP_RULE_GLOBAL_CHAR" ); } while( true ) { int locx = 17; locx += shortcut_print( w_header, 2, locx, c_white, ( tab == GLOBAL_TAB ) ? hilite( c_white ) : c_white, _( "[<Global>]" ) ) + 1; shortcut_print( w_header, 2, locx, c_white, ( tab == CHARACTER_TAB ) ? hilite( c_white ) : c_white, _( "[<Character>]" ) ); locx = 55; mvwprintz( w_header, 0, locx, c_white, _( "Safe Mode enabled:" ) ); locx += shortcut_print( w_header, 1, locx, ( ( get_option<bool>( "SAFEMODE" ) ) ? c_ltgreen : c_ltred ), c_white, ( ( get_option<bool>( "SAFEMODE" ) ) ? _( "True" ) : _( "False" ) ) ); locx += shortcut_print( w_header, 1, locx, c_white, c_ltgreen, " " ); locx += shortcut_print( w_header, 1, locx, c_white, c_ltgreen, _( "<S>witch" ) ); shortcut_print( w_header, 1, locx, c_white, c_ltgreen, " " ); wrefresh( w_header ); // Clear the lines for( int i = 0; i < content_height; i++ ) { for( int j = 0; j < 79; j++ ) { mvwputch( w, i, j, c_black, ' ' ); } for( auto &pos : column_pos ) { mvwputch( w, i, pos.second, c_ltgray, LINE_XOXO ); } } auto ¤t_tab = ( tab == GLOBAL_TAB ) ? global_rules : character_rules; if( tab == CHARACTER_TAB && g->u.name.empty() ) { character_rules.clear(); mvwprintz( w, 8, 15, c_white, _( "Please load a character first to use this page!" ) ); } else if( empty() ) { mvwprintz( w, 8, 15, c_white, _( "Safe Mode manager currently inactive." ) ); mvwprintz( w, 9, 15, c_white, _( "Default rules are used. Add a rule to activate." ) ); mvwprintz( w, 10, 15, c_white, _( "Press ~ to add a default ruleset to get started." ) ); } draw_scrollbar( w_border, line, content_height, current_tab.size(), 5 ); wrefresh( w_border ); calcStartPos( start_pos, line, content_height, current_tab.size() ); // display safe mode for( int i = start_pos; i < ( int )current_tab.size(); i++ ) { if( i >= start_pos && i < start_pos + std::min( content_height, static_cast<int>( current_tab.size() ) ) ) { auto rule = current_tab[i]; nc_color line_color = ( rule.active ) ? c_white : c_ltgray; mvwprintz( w, i - start_pos, 1, line_color, "%d", i + 1 ); mvwprintz( w, i - start_pos, 5, c_yellow, ( line == i ) ? ">> " : " " ); auto draw_column = [&]( Columns column_in, std::string text_in ) { mvwprintz( w, i - start_pos, column_pos[column_in] + 2, ( line == i && column == column_in ) ? hilite( line_color ) : line_color, "%s", text_in.c_str() ); }; draw_column( COLUMN_RULE, ( rule.rule.empty() ) ? _( "<empty rule>" ) : rule.rule ); draw_column( COLUMN_ATTITUDE, Creature::get_attitude_ui_data( rule.attitude ).first ); draw_column( COLUMN_PROXIMITY, ( !rule.whitelist ) ? to_string( rule.proximity ).c_str() : "---" ); draw_column( COLUMN_WHITE_BLACKLIST, ( rule.whitelist ) ? _( "Whitelist" ) : _( "Blacklist" ) ); } } wrefresh( w ); const std::string action = ctxt.handle_input(); if( action == "NEXT_TAB" ) { tab++; if( tab >= MAX_TAB ) { tab = 0; line = 0; } } else if( action == "PREV_TAB" ) { tab--; if( tab < 0 ) { tab = MAX_TAB - 1; line = 0; } } else if( action == "QUIT" ) { break; } else if( tab == CHARACTER_TAB && g->u.name.empty() ) { //Only allow loaded games to use the char sheet } else if( action == "DOWN" ) { line++; if( line >= ( int )current_tab.size() ) { line = 0; } } else if( action == "UP" ) { line--; if( line < 0 ) { line = current_tab.size() - 1; } } else if( action == "ADD_DEFAULT_RULESET" ) { changes_made = true; current_tab.push_back( rules_class( "*", true, false, Creature::A_HOSTILE, 0 ) ); line = current_tab.size() - 1; } else if( action == "ADD_RULE" ) { changes_made = true; current_tab.push_back( rules_class( "", true, false, Creature::A_HOSTILE, get_option<int>( "SAFEMODEPROXIMITY" ) ) ); line = current_tab.size() - 1; } else if( action == "REMOVE_RULE" && !current_tab.empty() ) { changes_made = true; current_tab.erase( current_tab.begin() + line ); if( line > ( int )current_tab.size() - 1 ) { line--; } if( line < 0 ) { line = 0; } } else if( action == "COPY_RULE" && !current_tab.empty() ) { changes_made = true; current_tab.push_back( current_tab[line] ); line = current_tab.size() - 1; } else if( action == "SWAP_RULE_GLOBAL_CHAR" && !current_tab.empty() ) { if( ( tab == GLOBAL_TAB && !g->u.name.empty() ) || tab == CHARACTER_TAB ) { changes_made = true; //copy over auto &temp_rules_from = ( tab == GLOBAL_TAB ) ? global_rules : character_rules; auto &temp_rules_to = ( tab == GLOBAL_TAB ) ? character_rules : global_rules; temp_rules_to.push_back( temp_rules_from[line] ); //remove old temp_rules_from.erase( temp_rules_from.begin() + line ); line = temp_rules_from.size() - 1; tab = ( tab == GLOBAL_TAB ) ? CHARACTER_TAB : GLOBAL_TAB; } } else if( action == "CONFIRM" && !current_tab.empty() ) { changes_made = true; if( column == COLUMN_RULE ) { fold_and_print( w_help, 1, 1, 999, c_white, _( "* is used as a Wildcard. A few Examples:\n" "\n" "human matches every NPC\n" "zombie matches the monster name exactly\n" "acidic zo* matches monsters beginning with 'acidic zo'\n" "*mbie matches monsters ending with 'mbie'\n" "*cid*zo*ie multiple * are allowed\n" "AcI*zO*iE case insensitive search" ) ); draw_border( w_help ); wrefresh( w_help ); current_tab[line].rule = wildcard_trim_rule( string_input_popup() .title( _( "Safe Mode Rule:" ) ) .width( 30 ) .text( current_tab[line].rule ) .query_string() ); } else if( column == COLUMN_WHITE_BLACKLIST ) { current_tab[line].whitelist = !current_tab[line].whitelist; } else if( column == COLUMN_ATTITUDE ) { auto &attitude = current_tab[line].attitude; switch( attitude ) { case Creature::A_HOSTILE: attitude = Creature::A_NEUTRAL; break; case Creature::A_NEUTRAL: attitude = Creature::A_FRIENDLY; break; case Creature::A_FRIENDLY: attitude = Creature::A_ANY; break; case Creature::A_ANY: attitude = Creature::A_HOSTILE; } } else if( column == COLUMN_PROXIMITY && !current_tab[line].whitelist ) { const auto text = string_input_popup() .title( _( "Proximity Distance (0=max viewdistance)" ) ) .width( 4 ) .text( to_string( current_tab[line].proximity ) ) .description( _( "Option: " ) + to_string( get_option<int>( "SAFEMODEPROXIMITY" ) ) + " " + get_options().get_option( "SAFEMODEPROXIMITY" ).getDefaultText() ) .max_length( 3 ) .only_digits( true ) .query_string(); if( text.empty() ) { current_tab[line].proximity = get_option<int>( "SAFEMODEPROXIMITY" ); } else { //Let the options class handle the validity of the new value auto temp_option = get_options().get_option( "SAFEMODEPROXIMITY" ); temp_option.setValue( text ); current_tab[line].proximity = atoi( temp_option.getValue().c_str() ); } } } else if( action == "ENABLE_RULE" && !current_tab.empty() ) { changes_made = true; current_tab[line].active = true; } else if( action == "DISABLE_RULE" && !current_tab.empty() ) { changes_made = true; current_tab[line].active = false; } else if( action == "LEFT" ) { column--; if( column < 0 ) { column = num_columns - 1; } } else if( action == "RIGHT" ) { column++; if( column >= num_columns ) { column = 0; } } else if( action == "MOVE_RULE_UP" && !current_tab.empty() ) { changes_made = true; if( line < ( int )current_tab.size() - 1 ) { std::swap( current_tab[line], current_tab[line + 1] ); line++; column = 0; } } else if( action == "MOVE_RULE_DOWN" && !current_tab.empty() ) { changes_made = true; if( line > 0 ) { std::swap( current_tab[line], current_tab[line - 1] ); line--; column = 0; } } else if( action == "TEST_RULE" && !current_tab.empty() ) { test_pattern( tab, line ); } else if( action == "SWITCH_SAFEMODE_OPTION" ) { get_options().get_option( "SAFEMODE" ).setNext(); get_options().save(); } } if( !changes_made ) { return; } if( query_yn( _( "Save changes?" ) ) ) { if( is_safemode_in ) { save_global(); if( !g->u.name.empty() ) { save_character(); } } else { create_rules(); } } else { global_rules = global_rules_old; character_rules = character_rules_old; } }
void veh_interact::move_cursor (int dx, int dy) { mvwputch (w_disp, cy + 6, cx + 6, cpart >= 0 ? veh->part_color (cpart) : c_black, special_symbol(cpart >= 0 ? veh->part_sym (cpart) : ' ')); cx += dx; cy += dy; cpart = part_at (cx, cy); int vdx = -ddx - cy; int vdy = cx - ddy; int vx, vy; veh->coord_translate (vdx, vdy, vx, vy); int vehx = veh->global_x() + vx; int vehy = veh->global_y() + vy; bool obstruct = g->m.move_cost_ter_furn (vehx, vehy) == 0; vehicle *oveh = g->m.veh_at (vehx, vehy); if (oveh && oveh != veh) { obstruct = true; } nc_color col = cpart >= 0 ? veh->part_color (cpart) : c_black; mvwputch (w_disp, cy + 6, cx + 6, obstruct ? red_background(col) : hilite(col), special_symbol(cpart >= 0 ? veh->part_sym (cpart) : ' ')); wrefresh (w_disp); werase (w_parts); veh->print_part_desc (w_parts, 0, winw2, cpart, -1); wrefresh (w_parts); can_mount.clear(); has_mats.clear(); if (!obstruct) for (int i = 1; i < num_vparts; i++) { if (veh->can_mount (vdx, vdy, (vpart_id) i)) can_mount.push_back (i); } need_repair.clear(); parts_here.clear(); ptank = -1; wheel = -1; if (cpart >= 0) { parts_here = veh->internal_parts(cpart); parts_here.insert (parts_here.begin(), cpart); for (int i = 0; i < parts_here.size(); i++) { int p = parts_here[i]; if (veh->parts[p].hp < veh->part_info(p).durability) { need_repair.push_back (i); } if (veh->part_flag(p, vpf_fuel_tank) && veh->parts[p].amount < veh->part_info(p).size) { ptank = p; } if (veh->part_flag(p, vpf_wheel) && veh->parts[p].amount < veh->part_info(p).size) { wheel = p; } } } has_fuel = ptank >= 0 ? g->pl_refill_vehicle(*veh, ptank, true) : false; werase (w_msg); wrefresh (w_msg); display_mode (' '); }
void game::construction_menu() { WINDOW *w_con = newwin(25, 80, 0, 0); wborder(w_con, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX, LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX ); mvwprintz(w_con, 0, 1, c_red, "Construction"); mvwputch(w_con, 0, 30, c_white, LINE_OXXX); mvwputch(w_con, 24, 30, c_white, LINE_XXOX); for (int i = 1; i < 24; i++) mvwputch(w_con, i, 30, c_white, LINE_XOXO); mvwprintz(w_con, 1, 31, c_white, "Difficulty:"); wrefresh(w_con); bool update_info = true; int select = 0; char ch; inventory total_inv = crafting_inventory(); do { // Erase existing list of constructions for (int i = 1; i < 24; i++) { for (int j = 1; j < 29; j++) mvwputch(w_con, i, j, c_black, 'x'); } // Determine where in the master list to start printing //int offset = select - 11; int offset = 0; if (select >= 22) offset = select - 22; // Print the constructions between offset and max (or how many will fit) for (int i = 0; i <= 22 && (i + offset) < constructions.size(); i++) { int current = i + offset; nc_color col = (player_can_build(u, total_inv, constructions[current]) ? c_white : c_dkgray); // Map menu items to hotkey letters, skipping j, k, l, and q. char hotkey = current + ((current < 9) ? 97 : ((current < 13) ? 100 : 101)); if (current == select) col = hilite(col); mvwprintz(w_con, 1 + i, 1, col, "%c %s", hotkey, constructions[current]->name.c_str()); } if (update_info) { update_info = false; constructable* current_con = constructions[select]; // Print difficulty int pskill = u.skillLevel("carpentry").level(); int diff = current_con->difficulty > 0 ? current_con->difficulty : 0; mvwprintz(w_con, 1, 43, (pskill >= diff ? c_white : c_red), "%d ", diff); // Clear out lines for tools & materials for (int i = 2; i < 24; i++) { for (int j = 31; j < 79; j++) mvwputch(w_con, i, j, c_black, 'x'); } // Print stages and their requirements int posx = 33, posy = 2; for (int n = 0; n < current_con->stages.size(); n++) { nc_color color_stage = (player_can_build(u, total_inv, current_con, n, false, true) ? c_white : c_dkgray); mvwprintz(w_con, posy, 31, color_stage, "Stage %d: %s", n + 1, current_con->stages[n].terrain == t_null? "" : terlist[current_con->stages[n].terrain].name.c_str()); posy++; // Print tools construction_stage stage = current_con->stages[n]; bool has_tool[3] = {stage.tools[0].empty(), stage.tools[1].empty(), stage.tools[2].empty()}; for (int i = 0; i < 3 && !has_tool[i]; i++) { posy++; posx = 33; for (int j = 0; j < stage.tools[i].size(); j++) { itype_id tool = stage.tools[i][j]; nc_color col = c_red; if (total_inv.has_amount(tool, 1)) { has_tool[i] = true; col = c_green; } int length = itypes[tool]->name.length(); if (posx + length > 79) { posy++; posx = 33; } mvwprintz(w_con, posy, posx, col, itypes[tool]->name.c_str()); posx += length + 1; // + 1 for an empty space if (j < stage.tools[i].size() - 1) { // "OR" if there's more if (posx > 77) { posy++; posx = 33; } mvwprintz(w_con, posy, posx, c_white, "OR"); posx += 3; } } } // Print components posy++; posx = 33; bool has_component[3] = {stage.components[0].empty(), stage.components[1].empty(), stage.components[2].empty()}; for (int i = 0; i < 3; i++) { posx = 33; while (has_component[i]) i++; for (int j = 0; j < stage.components[i].size() && i < 3; j++) { nc_color col = c_red; component comp = stage.components[i][j]; if (( itypes[comp.type]->is_ammo() && total_inv.has_charges(comp.type, comp.count)) || (!itypes[comp.type]->is_ammo() && total_inv.has_amount(comp.type, comp.count))) { has_component[i] = true; col = c_green; } int length = itypes[comp.type]->name.length(); if (posx + length > 79) { posy++; posx = 33; } mvwprintz(w_con, posy, posx, col, "%s x%d", itypes[comp.type]->name.c_str(), comp.count); posx += length + 3; // + 2 for " x", + 1 for an empty space // Add more space for the length of the count if (comp.count < 10) posx++; else if (comp.count < 100) posx += 2; else posx += 3; if (j < stage.components[i].size() - 1) { // "OR" if there's more if (posx > 77) { posy++; posx = 33; } mvwprintz(w_con, posy, posx, c_white, "OR"); posx += 3; } } posy++; } } wrefresh(w_con); } // Finished updating ch = input(); switch (ch) { case 'j': update_info = true; if (select < constructions.size() - 1) select++; else select = 0; break; case 'k': update_info = true; if (select > 0) select--; else select = constructions.size() - 1; break; case '\n': case 'l': if (player_can_build(u, total_inv, constructions[select])) { place_construction(constructions[select]); ch = 'q'; } else { popup("You can't build that!"); for (int i = 1; i < 24; i++) mvwputch(w_con, i, 30, c_white, LINE_XOXO); update_info = true; } break; case 'q': case 'Q': case KEY_ESCAPE: break; default: if (ch < 96 || ch > constructions.size() + 101) break; // Map menu items to hotkey letters, skipping j, k, l, and q. char hotkey = ch - ((ch < 106) ? 97 : ((ch < 112) ? 100 : 101)); if (player_can_build(u, total_inv, constructions[hotkey])) { place_construction(constructions[hotkey]); ch = 'q'; } else { popup("You can't build that!"); for (int i = 1; i < 24; i++) mvwputch(w_con, i, 30, c_white, LINE_XOXO); update_info = true; } break; } } while (ch != 'q' && ch != 'Q' && ch != KEY_ESCAPE); refresh_all(); }
int main(int argc, char **argv) { FILE *fp; int i; static char *title[] = { "Normal Text", "Bold Text", "Status Line" }; int colors[COLORCNT]; int cur; /* initialize the console */ oss_con_init(); /* use a different default color scheme for monochrome */ if (ossmon()) colors[2] = 0x70; else colors[2] = 23; colors[0] = 7; colors[1] = 15; /* read existing trcolor.dat if present */ if (fp = fopen("trcolor.dat", "r")) { for (i = 0 ; i < COLORCNT ; ++i) { char buf[128]; fgets(buf, sizeof(buf), fp); colors[i] = atoi(buf); } fclose(fp); } /* set up the screen */ ossclr(0, 0, 25, 80, 0); ossdsp(3, 8, TNORMAL, "TADS Runtime Color Setup - Copyright (c) 1993, 2007 " "Michael J. Roberts"); /* copyright-date-string */ for (i = 0 ; i < 128 ; ++i) ossdsp((i / 16) + CYOFS, (i % 16) + CXOFS, i, "+"); for (i = 0 ; i < COLORCNT ; ++i) hilitetitle(i, title[i], colors[i], i == 0); /* show instructions */ ossdsp(16, 17, TNORMAL, "Use Tab and Shift-Tab to select text types."); ossdsp(17, 17, TNORMAL, "Use cursor arrows to change colors."); ossdsp(18, 17, TNORMAL, "Press S to save changes and exit."); ossdsp(19, 17, TNORMAL, "Press Esc or Q to quit without saving changes."); /* hilite current color */ hilite(colors[0], TRUE); for (cur = 0 ;; ) { ossloc(0, 0); switch(getch()) { case 0: switch(getch()) { case 0115: /* right arrow */ hilite(colors[cur], FALSE); if (++colors[cur] >= 128) colors[cur] = 0; hilite(colors[cur], TRUE); hilitetitle(cur, title[cur], colors[cur], TRUE); break; case 0113: /* left arrow */ hilite(colors[cur], FALSE); if (--colors[cur] <= 0) colors[cur] = 127; hilite(colors[cur], TRUE); hilitetitle(cur, title[cur], colors[cur], TRUE); break; case 0120: /* down arrow */ hilite(colors[cur], FALSE); if ((colors[cur] += 16) >= 128) colors[cur] -= 128; hilite(colors[cur], TRUE); hilitetitle(cur, title[cur], colors[cur], TRUE); break; case 0110: /* up arrow */ hilite(colors[cur], FALSE); if ((colors[cur] -= 16) <= 0) colors[cur] += 128; hilite(colors[cur], TRUE); hilitetitle(cur, title[cur], colors[cur], TRUE); break; case 15: /* backtab */ /* unhilite current color */ hilitetitle(cur, title[cur], colors[cur], FALSE); hilite(colors[cur], FALSE); /* select new color and hilite it */ if (--cur < 0) cur = COLORCNT - 1; hilitetitle(cur, title[cur], colors[cur], TRUE); hilite(colors[cur], TRUE); break; } break; case 9: /* unhilite current color */ hilitetitle(cur, title[cur], colors[cur], FALSE); hilite(colors[cur], FALSE); /* select new color and hilite it */ if (++cur >= COLORCNT) cur = 0; hilitetitle(cur, title[cur], colors[cur], TRUE); hilite(colors[cur], TRUE); break; case 27: case 'q': case 'Q': ossloc(24, 0); oss_con_uninit(); printf("\n\nNo changes saved.\n"); exit(0); case 's': case 'S': ossloc(24, 0); printf("\n\n"); if (!(fp = fopen("trcolor.dat", "w"))) { oss_con_uninit(); printf("Error - unable to create TRCOLOR.DAT\n"); exit(1); } for (i = 0 ; i < COLORCNT ; ++i) fprintf(fp, "%d\n", colors[i]); fclose(fp); oss_con_uninit(); printf("TRCOLOR.DAT successfully updated!\n"); exit(0); } } return 0; }
void auto_pickup::test_pattern(const int iCurrentPage, const int iCurrentLine) { std::vector<std::string> vMatchingItems; std::string sItemName = ""; if (vRules[iCurrentPage][iCurrentLine].sRule == "") { return; } //Loop through all itemfactory items //APU now ignores prefixes, bottled items and suffix combinations still not generated for( auto &p : item_controller->get_all_itypes() ) { sItemName = p.second->nname(1); if (vRules[iCurrentPage][iCurrentLine].bActive && match(sItemName, vRules[iCurrentPage][iCurrentLine].sRule)) { vMatchingItems.push_back(sItemName); } } const int iOffsetX = 15 + ((TERMX > FULL_SCREEN_WIDTH) ? (TERMX - FULL_SCREEN_WIDTH) / 2 : 0); const int iOffsetY = 5 + ((TERMY > FULL_SCREEN_HEIGHT) ? (TERMY - FULL_SCREEN_HEIGHT) / 2 : 0); int iStartPos = 0; const int iContentHeight = FULL_SCREEN_HEIGHT - 8; const int iContentWidth = FULL_SCREEN_WIDTH - 30; std::ostringstream sTemp; WINDOW *w_test_rule_border = newwin(iContentHeight + 2, iContentWidth, iOffsetY, iOffsetX); WINDOW_PTR w_test_rule_borderptr( w_test_rule_border ); WINDOW *w_test_rule_content = newwin(iContentHeight, iContentWidth - 2, 1 + iOffsetY, 1 + iOffsetX); WINDOW_PTR w_test_rule_contentptr( w_test_rule_content ); draw_border(w_test_rule_border); int nmatch = vMatchingItems.size(); std::string buf = string_format(ngettext("%1$d item matches: %2$s", "%1$d items match: %2$s", nmatch), nmatch, vRules[iCurrentPage][iCurrentLine].sRule.c_str()); mvwprintz(w_test_rule_border, 0, iContentWidth / 2 - utf8_width(buf) / 2, hilite(c_white), "%s", buf.c_str()); mvwprintz(w_test_rule_border, iContentHeight + 1, 1, red_background(c_white), _("Won't display bottled and suffixes=(fits)")); wrefresh(w_test_rule_border); int iLine = 0; input_context ctxt("AUTO_PICKUP_TEST"); ctxt.register_updown(); ctxt.register_action("QUIT"); while(true) { // Clear the lines for (int i = 0; i < iContentHeight; i++) { for (int j = 0; j < 79; j++) { mvwputch(w_test_rule_content, i, j, c_black, ' '); } } calcStartPos(iStartPos, iLine, iContentHeight, vMatchingItems.size()); // display auto pickup for (int i = iStartPos; i < (int)vMatchingItems.size(); i++) { if (i >= iStartPos && i < iStartPos + ((iContentHeight > (int)vMatchingItems.size()) ? (int)vMatchingItems.size() : iContentHeight)) { nc_color cLineColor = c_white; sTemp.str(""); sTemp << i + 1; mvwprintz(w_test_rule_content, i - iStartPos, 0, cLineColor, "%s", sTemp.str().c_str()); mvwprintz(w_test_rule_content, i - iStartPos, 4, cLineColor, ""); if (iLine == i) { wprintz(w_test_rule_content, c_yellow, ">> "); } else { wprintz(w_test_rule_content, c_yellow, " "); } wprintz(w_test_rule_content, (iLine == i) ? hilite(cLineColor) : cLineColor, vMatchingItems[i].c_str()); } } wrefresh(w_test_rule_content); const std::string action = ctxt.handle_input(); if (action == "DOWN") { iLine++; if (iLine >= (int)vMatchingItems.size()) { iLine = 0; } } else if (action == "UP") { iLine--; if (iLine < 0) { iLine = vMatchingItems.size() - 1; } } else { break; } } }
void auto_pickup::show() { save_reset_changes(false); const int iHeaderHeight = 4; const int iContentHeight = FULL_SCREEN_HEIGHT - 2 - iHeaderHeight; const int iOffsetX = (TERMX > FULL_SCREEN_WIDTH) ? (TERMX - FULL_SCREEN_WIDTH) / 2 : 0; const int iOffsetY = (TERMY > FULL_SCREEN_HEIGHT) ? (TERMY - FULL_SCREEN_HEIGHT) / 2 : 0; std::map<int, bool> mapLines; mapLines[4] = true; mapLines[50] = true; mapLines[54] = true; const int iTotalCols = mapLines.size() - 1; WINDOW *w_help = newwin((FULL_SCREEN_HEIGHT / 2) - 2, FULL_SCREEN_WIDTH * 3 / 4, 7 + iOffsetY + (FULL_SCREEN_HEIGHT / 2) / 2, iOffsetX + 19 / 2); WINDOW_PTR w_helpptr( w_help ); WINDOW *w_border = newwin(FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, iOffsetY, iOffsetX); WINDOW_PTR w_borderptr( w_border ); WINDOW *w_header = newwin(iHeaderHeight, FULL_SCREEN_WIDTH - 2, 1 + iOffsetY, 1 + iOffsetX); WINDOW_PTR w_headerptr( w_header ); WINDOW *w = newwin(iContentHeight, FULL_SCREEN_WIDTH - 2, iHeaderHeight + 1 + iOffsetY, 1 + iOffsetX); WINDOW_PTR wptr( w ); draw_border(w_border); mvwputch(w_border, 3, 0, c_ltgray, LINE_XXXO); // |- mvwputch(w_border, 3, 79, c_ltgray, LINE_XOXX); // -| for( auto &mapLine : mapLines ) { mvwputch( w_border, FULL_SCREEN_HEIGHT - 1, mapLine.first + 1, c_ltgray, LINE_XXOX ); // _|_ } mvwprintz(w_border, 0, 29, c_ltred, _(" AUTO PICKUP MANAGER ")); wrefresh(w_border); int tmpx = 0; tmpx += shortcut_print(w_header, 0, tmpx, c_white, c_ltgreen, _("<A>dd")) + 2; tmpx += shortcut_print(w_header, 0, tmpx, c_white, c_ltgreen, _("<R>emove")) + 2; tmpx += shortcut_print(w_header, 0, tmpx, c_white, c_ltgreen, _("<C>opy")) + 2; tmpx += shortcut_print(w_header, 0, tmpx, c_white, c_ltgreen, _("<M>ove")) + 2; tmpx += shortcut_print(w_header, 0, tmpx, c_white, c_ltgreen, _("<E>nable")) + 2; tmpx += shortcut_print(w_header, 0, tmpx, c_white, c_ltgreen, _("<D>isable")) + 2; shortcut_print(w_header, 0, tmpx, c_white, c_ltgreen, _("<T>est")); tmpx = 0; tmpx += shortcut_print(w_header, 1, tmpx, c_white, c_ltgreen, _("<+-> Move up/down")) + 2; tmpx += shortcut_print(w_header, 1, tmpx, c_white, c_ltgreen, _("<Enter>-Edit")) + 2; shortcut_print(w_header, 1, tmpx, c_white, c_ltgreen, _("<Tab>-Switch Page")); for (int i = 0; i < 78; i++) { if (mapLines[i]) { mvwputch(w_header, 2, i, c_ltgray, LINE_OXXX); mvwputch(w_header, 3, i, c_ltgray, LINE_XOXO); } else { mvwputch(w_header, 2, i, c_ltgray, LINE_OXOX); // Draw line under header } } mvwprintz(w_header, 3, 1, c_white, "#"); mvwprintz(w_header, 3, 8, c_white, _("Rules")); mvwprintz(w_header, 3, 51, c_white, _("I/E")); wrefresh(w_header); int iCurrentPage = 1; int iCurrentLine = 0; int iCurrentCol = 1; int iStartPos = 0; bool bStuffChanged = false; input_context ctxt("AUTO_PICKUP"); ctxt.register_cardinal(); ctxt.register_action("CONFIRM"); ctxt.register_action("QUIT"); ctxt.register_action("NEXT_TAB"); ctxt.register_action("PREV_TAB"); ctxt.register_action("ADD_RULE"); ctxt.register_action("REMOVE_RULE"); ctxt.register_action("COPY_RULE"); ctxt.register_action("SWAP_RULE_GLOBAL_CHAR"); ctxt.register_action("ENABLE_RULE"); ctxt.register_action("DISABLE_RULE"); ctxt.register_action("MOVE_RULE_UP"); ctxt.register_action("MOVE_RULE_DOWN"); ctxt.register_action("TEST_RULE"); ctxt.register_action("SWITCH_AUTO_PICKUP_OPTION"); ctxt.register_action("HELP_KEYBINDINGS"); std::ostringstream sTemp; while(true) { int locx = 17; locx += shortcut_print(w_header, 2, locx, c_white, (iCurrentPage == 1) ? hilite(c_white) : c_white, _("[<Global>]")) + 1; shortcut_print(w_header, 2, locx, c_white, (iCurrentPage == 2) ? hilite(c_white) : c_white, _("[<Character>]")); locx = 55; mvwprintz(w_header, 0, locx, c_white, _("Auto pickup enabled:")); locx += shortcut_print(w_header, 1, locx, ((OPTIONS["AUTO_PICKUP"]) ? c_ltgreen : c_ltred), c_white, ((OPTIONS["AUTO_PICKUP"]) ? _("True") : _("False"))); locx += shortcut_print(w_header, 1, locx, c_white, c_ltgreen, " "); locx += shortcut_print(w_header, 1, locx, c_white, c_ltgreen, _("<S>witch")); shortcut_print(w_header, 1, locx, c_white, c_ltgreen, " "); wrefresh(w_header); // Clear the lines for (int i = 0; i < iContentHeight; i++) { for (int j = 0; j < 79; j++) { if (mapLines[j]) { mvwputch(w, i, j, c_ltgray, LINE_XOXO); } else { mvwputch(w, i, j, c_black, ' '); } } } const bool currentPageNonEmpty = !vRules[iCurrentPage].empty(); if (iCurrentPage == 2 && g->u.name == "") { vRules[2].clear(); mvwprintz(w, 8, 15, c_white, _("Please load a character first to use this page!")); } draw_scrollbar(w_border, iCurrentLine, iContentHeight, vRules[iCurrentPage].size(), 5); wrefresh(w_border); calcStartPos(iStartPos, iCurrentLine, iContentHeight, vRules[iCurrentPage].size()); // display auto pickup for (int i = iStartPos; i < (int)vRules[iCurrentPage].size(); i++) { if (i >= iStartPos && i < iStartPos + ((iContentHeight > (int)vRules[iCurrentPage].size()) ? (int)vRules[iCurrentPage].size() : iContentHeight)) { nc_color cLineColor = (vRules[iCurrentPage][i].bActive) ? c_white : c_ltgray; sTemp.str(""); sTemp << i + 1; mvwprintz(w, i - iStartPos, 1, cLineColor, "%s", sTemp.str().c_str()); mvwprintz(w, i - iStartPos, 5, cLineColor, ""); if (iCurrentLine == i) { wprintz(w, c_yellow, ">> "); } else { wprintz(w, c_yellow, " "); } wprintz(w, (iCurrentLine == i && iCurrentCol == 1) ? hilite(cLineColor) : cLineColor, "%s", ((vRules[iCurrentPage][i].sRule == "") ? _("<empty rule>") : vRules[iCurrentPage][i].sRule).c_str()); mvwprintz(w, i - iStartPos, 52, (iCurrentLine == i && iCurrentCol == 2) ? hilite(cLineColor) : cLineColor, "%s", ((vRules[iCurrentPage][i].bExclude) ? rm_prefix(_("<Exclude>E")).c_str() : rm_prefix( _("<Include>I")).c_str())); } } wrefresh(w); const std::string action = ctxt.handle_input(); if (action == "NEXT_TAB") { iCurrentPage++; if (iCurrentPage > 2) { iCurrentPage = 1; iCurrentLine = 0; } } else if (action == "PREV_TAB") { iCurrentPage--; if (iCurrentPage < 1) { iCurrentPage = 2; iCurrentLine = 0; } } else if (action == "QUIT") { break; } else if (iCurrentPage == 2 && g->u.name.empty()) { //Only allow loaded games to use the char sheet } else if (action == "DOWN") { iCurrentLine++; iCurrentCol = 1; if (iCurrentLine >= (int)vRules[iCurrentPage].size()) { iCurrentLine = 0; } } else if (action == "UP") { iCurrentLine--; iCurrentCol = 1; if (iCurrentLine < 0) { iCurrentLine = vRules[iCurrentPage].size() - 1; } } else if (action == "ADD_RULE") { bStuffChanged = true; vRules[iCurrentPage].push_back(cRules("", true, false)); iCurrentLine = vRules[iCurrentPage].size() - 1; } else if (action == "REMOVE_RULE" && currentPageNonEmpty) { bStuffChanged = true; vRules[iCurrentPage].erase(vRules[iCurrentPage].begin() + iCurrentLine); if (iCurrentLine > (int)vRules[iCurrentPage].size() - 1) { iCurrentLine--; } if(iCurrentLine < 0){ iCurrentLine = 0; } } else if (action == "COPY_RULE" && currentPageNonEmpty) { bStuffChanged = true; vRules[iCurrentPage].push_back(cRules( vRules[iCurrentPage][iCurrentLine].sRule, vRules[iCurrentPage][iCurrentLine].bActive, vRules[iCurrentPage][iCurrentLine].bExclude)); iCurrentLine = vRules[iCurrentPage].size() - 1; } else if (action == "SWAP_RULE_GLOBAL_CHAR" && currentPageNonEmpty) { if ((iCurrentPage == 1 && g->u.name != "") || iCurrentPage == 2) { bStuffChanged = true; //copy over vRules[(iCurrentPage == 1) ? 2 : 1].push_back(cRules( vRules[iCurrentPage][iCurrentLine].sRule, vRules[iCurrentPage][iCurrentLine].bActive, vRules[iCurrentPage][iCurrentLine].bExclude)); //remove old vRules[iCurrentPage].erase(vRules[iCurrentPage].begin() + iCurrentLine); iCurrentLine = vRules[(iCurrentPage == 1) ? 2 : 1].size() - 1; iCurrentPage = (iCurrentPage == 1) ? 2 : 1; } } else if (action == "CONFIRM" && currentPageNonEmpty) { bStuffChanged = true; if (iCurrentCol == 1) { fold_and_print(w_help, 1, 1, 999, c_white, _( "* is used as a Wildcard. A few Examples:\n" "\n" "wooden arrow matches the itemname exactly\n" "wooden ar* matches items beginning with wood ar\n" "*rrow matches items ending with rrow\n" "*avy fle*fi*arrow multiple * are allowed\n" "heAVY*woOD*arrOW case insensitive search\n" "") ); draw_border(w_help); wrefresh(w_help); vRules[iCurrentPage][iCurrentLine].sRule = trim_rule(string_input_popup(_("Pickup Rule:"), 30, vRules[iCurrentPage][iCurrentLine].sRule)); } else if (iCurrentCol == 2) { vRules[iCurrentPage][iCurrentLine].bExclude = !vRules[iCurrentPage][iCurrentLine].bExclude; } } else if (action == "ENABLE_RULE" && currentPageNonEmpty) { bStuffChanged = true; vRules[iCurrentPage][iCurrentLine].bActive = true; } else if (action == "DISABLE_RULE" && currentPageNonEmpty) { bStuffChanged = true; vRules[iCurrentPage][iCurrentLine].bActive = false; } else if (action == "LEFT") { iCurrentCol--; if (iCurrentCol < 1) { iCurrentCol = iTotalCols; } } else if (action == "RIGHT") { iCurrentCol++; if (iCurrentCol > iTotalCols) { iCurrentCol = 1; } } else if (action == "MOVE_RULE_UP" && currentPageNonEmpty) { bStuffChanged = true; if (iCurrentLine < (int)vRules[iCurrentPage].size() - 1) { std::swap(vRules[iCurrentPage][iCurrentLine], vRules[iCurrentPage][iCurrentLine + 1]); iCurrentLine++; iCurrentCol = 1; } } else if (action == "MOVE_RULE_DOWN" && currentPageNonEmpty) { bStuffChanged = true; if (iCurrentLine > 0) { std::swap(vRules[iCurrentPage][iCurrentLine], vRules[iCurrentPage][iCurrentLine - 1]); iCurrentLine--; iCurrentCol = 1; } } else if (action == "TEST_RULE" && currentPageNonEmpty) { test_pattern(iCurrentPage, iCurrentLine); } else if (action == "SWITCH_OPTION") { OPTIONS["AUTO_PICKUP"].setNext(); get_options().save((g->u.name != "")); } } if (bStuffChanged) { if(query_yn(_("Save changes?"))) { save(false); if (g->u.name != "") { save(true); } } else { save_reset_changes(true); } } }