int save_npc(Character *ch) { int res = save_character(ch, npc_flags); field_map npc_values[] = { {"nonplayerId", &ch->id, SQL_INT}, {"shortDescr", &ch->npc->shortDescr, SQL_TEXT}, {"longDescr", &ch->npc->longDescr, SQL_TEXT}, {"startPosition", &ch->npc->startPosition, SQL_INT}, {"areaId", &ch->npc->area->id, SQL_INT}, {0, 0, 0} }; if (res == 1) { if (sql_insert_query(npc_values, "nonplayer") != SQL_OK) { log_data("could not insert player"); return 0; } } else if (res == 2) { if (sql_update_query(npc_values, "nonplayer", ch->id) != SQL_OK) { log_data("could not update character"); return 0; } } return UMIN(res, 1); }
int save_player(Character *ch) { if (ch->pc == 0) { log_error("character not a player"); return 0; } db_begin_transaction(); if (!save_account(ch->pc->account)) { return 0; } int res = save_character(ch, plr_flags); const size_t maxCond = MAX_COND; field_map pc_values[] = { {"playerId", &ch->id, SQL_INT}, {"accountId", &ch->pc->account->id, SQL_INT}, {"title", &ch->pc->title, SQL_TEXT}, {"roomId", (ch->inRoom ? &ch->inRoom->id : 0), SQL_INT}, {"prompt", &ch->pc->prompt, SQL_TEXT}, {"battlePrompt", &ch->pc->battlePrompt, SQL_TEXT}, {"explored", &ch->pc->explored, SQL_CUSTOM, NULL, NULL, 0, save_explored}, {"channels", &ch->pc->channels, SQL_FLAG, channel_flags}, {"condition", &ch->pc->condition, SQL_CUSTOM, NULL, &maxCond, 0, db_save_int_array}, {"experience", &ch->pc->experience, SQL_INT}, {"permHit", &ch->pc->permHit, SQL_INT}, {"permMana", &ch->pc->permMana, SQL_INT}, {"permMove", &ch->pc->permMove, SQL_INT}, {"created", &ch->pc->created, SQL_INT}, {0} }; if (res == 1) { if (sql_insert_query(pc_values, "player") != SQL_OK) { log_data("could not insert player"); return 0; } } else if (res == 2) { if (sql_update_query(pc_values, "player", ch->id) != SQL_OK) { log_data("could not update character"); return 0; } } if (!save_char_objs(ch)) { res = 0; } if (!save_char_affects(ch)) { res = 0; } db_end_transaction(); return UMIN(res, 1); }
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; } }