Exemple #1
0
void exit_handler(int s)
{
    if (s != 2 || query_yn(_("Really Quit? All unsaved changes will be lost."))) {
        erase(); // Clear screen

        int ret;
#if (defined _WIN32 || defined WINDOWS)
        ret = system("cls"); // Tell the terminal to clear itself
        ret = system("color 07");
#else
        ret = system("clear"); // Tell the terminal to clear itself
#endif
        if (ret != 0) {
            DebugLog( D_ERROR, DC_ALL ) << "system(\"clear\"): error returned: " << ret;
        }
        deinitDebug();

        int exit_status = 0;
        if( g != NULL ) {
            if( g->game_error() ) {
                exit_status = 1;
            }
            delete g;
        }

        endwin();

        exit( exit_status );
    }
}
Exemple #2
0
void exit_handler(int s) {
    if (s != 2 || query_yn(_("Really Quit? All unsaved changes will be lost."))) {
        erase(); // Clear screen
        endwin(); // End ncurses
        int ret;
        #if (defined _WIN32 || defined WINDOWS)
            ret = system("cls"); // Tell the terminal to clear itself
            ret = system("color 07");
        #else
            ret = system("clear"); // Tell the terminal to clear itself
        #endif
        if (ret != 0) {
            DebugLog() << "main.cpp:exit_handler(): system(\"clear\"): error returned\n";
        }

        if(g != NULL) {
            if(g->game_error()) {
                delete g;
                exit(1);
            } else {
                delete g;
                exit(0);
            }
        }
        exit(0);
    }
}
Exemple #3
0
void exit_handler(int s) {
 bool bExit = false;

 if (s == 2) {
  if (query_yn("Really Quit? All unsaved changes will be lost.")) {
   bExit = true;
  }
 } else if (s == -999) {
  bExit = true;
 } else {
  //query_yn(g, "Signal received: %d", s);
  bExit = true;
 }

 if (bExit) {
  erase(); // Clear screen
  endwin(); // End ncurses
  #if (defined _WIN32 || defined WINDOWS)
   system("cls"); // Tell the terminal to clear itself
   system("color 07");
  #else
   system("clear"); // Tell the terminal to clear itself
  #endif

  exit(0);
 }
}
void zone_manager::add( const std::string &name, const zone_type_id &type,
                        const bool invert, const bool enabled, const tripoint &start, const tripoint &end,
                        std::shared_ptr<zone_options> options )
{
    zone_data new_zone = zone_data( name, type, invert, enabled, start,
                                    end, options );
    //the start is a vehicle tile with cargo space
    if( const cata::optional<vpart_reference> vp = g->m.veh_at( g->m.getlocal(
                start ) ).part_with_feature( "CARGO", false ) ) {
        // TODO:Allow for loot zones on vehicles to be larger than 1x1
        if( start == end && query_yn( _( "Bind this zone to the cargo part here?" ) ) ) {
            // TODO: refactor zone options for proper validation code
            if( type == zone_type_id( "FARM_PLOT" ) ) {
                popup( _( "You cannot add that type of zone to a vehicle." ), PF_NONE );
                return;
            }

            create_vehicle_loot_zone( vp->vehicle(), vp->mount(), new_zone );
            return;
        }
    }

    //Create a regular zone
    zones.push_back( new_zone );
    cache_data();
}
Exemple #5
0
void trapfunc::sinkhole(int x, int y)
{
    (void)x; (void)y; // unused
 g->add_msg(_("You step into a sinkhole, and start to sink down!"));
 g->u.add_memorial_log(pgettext("memorial_male", "Stepped into a sinkhole."),
                       pgettext("memorial_female", "Stepped into a sinkhole."));
 if (g->u.has_amount("rope_30", 1) &&
     query_yn(_("There is a sinkhole here. Throw your rope out to try to catch something?"))) {
  int throwroll = rng(g->u.skillLevel("throw"),
                      g->u.skillLevel("throw") + g->u.str_cur + g->u.dex_cur);
  if (throwroll >= 12) {
   g->add_msg(_("The rope catches something!"));
   if (rng(g->u.skillLevel("unarmed"),
           g->u.skillLevel("unarmed") + g->u.str_cur) > 6) {
// Determine safe places for the character to get pulled to
    std::vector<point> safe;
    for (int i = g->u.posx - 1; i <= g->u.posx + 1; i++) {
     for (int j = g->u.posy - 1; j <= g->u.posy + 1; j++) {
      if (g->m.move_cost(i, j) > 0 && g->m.tr_at(i, j) != tr_pit)
       safe.push_back(point(i, j));
     }
    }
    if (safe.empty()) {
     g->add_msg(_("There's nowhere to pull yourself to, and you sink!"));
     g->u.use_amount("rope_30", 1);
     g->m.spawn_item(g->u.posx + rng(-1, 1), g->u.posy + rng(-1, 1), "rope_30");
     g->m.ter_set(g->u.posx, g->u.posy, t_hole);
     g->vertical_move(-1, true);
    } else {
     g->add_msg(_("You pull yourself to safety!  The sinkhole collapses."));
     int index = rng(0, safe.size() - 1);
     g->m.ter_set(g->u.posx, g->u.posy, t_hole);
     g->u.posx = safe[index].x;
     g->u.posy = safe[index].y;
     g->update_map(g->u.posx, g->u.posy);
    }
   } else {
    g->add_msg(_("You're not strong enough to pull yourself out..."));
    g->u.moves -= 100;
    g->u.use_amount("rope_30", 1);
    g->m.spawn_item(g->u.posx + rng(-1, 1), g->u.posy + rng(-1, 1), "rope_30");
    g->m.ter_set(g->u.posx, g->u.posy, t_hole);
    g->vertical_move(-1, true);
   }
  } else {
   g->add_msg(_("Your throw misses completely, and you sink!"));
   if (one_in((g->u.str_cur + g->u.dex_cur) / 3)) {
    g->u.use_amount("rope_30", 1);
    g->m.spawn_item(g->u.posx + rng(-1, 1), g->u.posy + rng(-1, 1), "rope_30");
   }
   g->m.ter_set(g->u.posx, g->u.posy, t_hole);
   g->vertical_move(-1, true);
  }
 } else {
  g->add_msg(_("You sink into the sinkhole!"));
  g->m.ter_set(g->u.posx, g->u.posy, t_hole);
  g->vertical_move(-1, true);
 }
}
Exemple #6
0
bool player::install_bionics(it_bionic *type)
{
    if (type == NULL) {
        debugmsg("Tried to install NULL bionic");
        return false;
    }
    if (bionics.count(type->id) == 0) {
        popup("invalid / unknown bionic id %s", type->id.c_str());
        return false;
    }
    if (has_bionic(type->id)) {
        if (!(type->id == "bio_power_storage" || type->id == "bio_power_storage_mkII")) {
            popup(_("You have already installed this bionic."));
            return false;
        }
    }
    int chance_of_success = bionic_manip_cos(int_cur,
                            skillLevel("electronics"),
                            skillLevel("firstaid"),
                            skillLevel("mechanics"),
                            type->difficulty);

    if (!query_yn(
            _("WARNING: %i percent chance of genetic damage, blood loss, or damage to existing bionics! Install anyway?"),
            100 - chance_of_success)) {
        return false;
    }
    int pow_up = 0;
    if (type->id == "bio_power_storage" || type->id == "bio_power_storage_mkII") {
        pow_up = BATTERY_AMOUNT;
        if (type->id == "bio_power_storage_mkII") {
            pow_up = 250;
        }
    }

    practice( "electronics", int((100 - chance_of_success) * 1.5) );
    practice( "firstaid", int((100 - chance_of_success) * 1.0) );
    practice( "mechanics", int((100 - chance_of_success) * 0.5) );
    int success = chance_of_success - rng(1, 100);
    if (success > 0) {
        add_memorial_log(pgettext("memorial_male", "Installed bionic: %s."),
                         pgettext("memorial_female", "Installed bionic: %s."),
                         bionics[type->id]->name.c_str());
        if (pow_up) {
            max_power_level += pow_up;
            add_msg_if_player(m_good, _("Increased storage capacity by %i"), pow_up);
        } else {
            add_msg(m_good, _("Successfully installed %s."), bionics[type->id]->name.c_str());
            add_bionic(type->id);
        }
    } else {
        add_memorial_log(pgettext("memorial_male", "Installed bionic: %s."),
                         pgettext("memorial_female", "Installed bionic: %s."),
                         bionics[type->id]->name.c_str());
        bionics_install_failure(this, type, success);
    }
    g->refresh_all();
    return true;
}
Exemple #7
0
void trapfunc::sinkhole(game *g, int x, int y)
{
 g->add_msg("You step into a sinkhole, and start to sink down!");
 if (g->u.has_amount(itm_rope_30, 1) &&
     query_yn("Throw your rope to try to catch soemthing?")) {
  int throwroll = rng(g->u.sklevel[sk_throw],
                      g->u.sklevel[sk_throw] + g->u.str_cur + g->u.dex_cur);
  if (throwroll >= 12) {
   g->add_msg("The rope catches something!");
   if (rng(g->u.sklevel[sk_unarmed],
           g->u.sklevel[sk_unarmed] + g->u.str_cur) > 6) {
// Determine safe places for the character to get pulled to
    std::vector<point> safe;
    for (int i = g->u.posx - 1; i <= g->u.posx + 1; i++) {
     for (int j = g->u.posx - 1; j <= g->u.posx + 1; j++) {
      if (g->m.move_cost(i, j) > 0 && g->m.tr_at(i, j) != tr_pit)
       safe.push_back(point(i, j));
     }
    }
    if (safe.size() == 0) {
     g->add_msg("There's nowhere to pull yourself to, and you sink!");
     g->u.use_amount(itm_rope_30, 1);
     g->m.add_item(g->u.posx + rng(-1, 1), g->u.posy + rng(-1, 1),
                   g->itypes[itm_rope_30], g->turn);
     g->m.tr_at(g->u.posx, g->u.posy) = tr_pit;
     g->vertical_move(-1, true);
    } else {
     g->add_msg("You pull yourself to safety!  The sinkhole collapses.");
     int index = rng(0, safe.size() - 1);
     g->u.posx = safe[index].x;
     g->u.posy = safe[index].y;
     g->update_map(g->u.posx, g->u.posy);
     g->m.tr_at(g->u.posx, g->u.posy) = tr_pit;
    }
   } else {
    g->add_msg("You're not strong enough to pull yourself out...");
    g->u.moves -= 100;
    g->u.use_amount(itm_rope_30, 1);
    g->m.add_item(g->u.posx + rng(-1, 1), g->u.posy + rng(-1, 1),
                  g->itypes[itm_rope_30], g->turn);
    g->vertical_move(-1, true);
   }
  } else {
   g->add_msg("Your throw misses completely, and you sink!");
   if (one_in((g->u.str_cur + g->u.dex_cur) / 3)) {
    g->u.use_amount(itm_rope_30, 1);
    g->m.add_item(g->u.posx + rng(-1, 1), g->u.posy + rng(-1, 1),
                  g->itypes[itm_rope_30], g->turn);
   }
   g->m.tr_at(g->u.posx, g->u.posy) = tr_pit;
   g->vertical_move(-1, true);
  }
 } else {
  g->add_msg("You sink into the sinkhole!");
  g->vertical_move(-1, true);
 }
}
WORLDPTR worldfactory::make_new_world()
{
    // Window variables
    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;
    // World to return after generating
    WORLDPTR retworld = new WORLD();
    // set up window
    WINDOW *wf_win = newwin(FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, iOffsetY, iOffsetX);
    // prepare tab display order
    std::vector<worldgen_display> tabs;
    std::vector<std::string> tab_strings;

    tabs.push_back(&worldfactory::show_worldgen_tab_options);
    tabs.push_back(&worldfactory::show_worldgen_tab_confirm);

    tab_strings.push_back(_("World Gen Options"));
    tab_strings.push_back(_("CONFIRMATION"));

    int curtab = 0;
    int lasttab; // give placement memory to menus, sorta.
    const int numtabs = tabs.size();
    while (curtab >= 0 && curtab < numtabs) {
        lasttab = curtab;
        draw_worldgen_tabs(wf_win, curtab, tab_strings);
        curtab += (world_generator->*tabs[curtab])(wf_win, retworld);

        if (curtab < 0) {
            if (!query_yn(_("Do you want to abort World Generation?"))) {
                curtab = lasttab;
            }
        }
    }
    if (curtab < 0) {
        delete retworld;
        return NULL;
    }

    // add world to world list
    all_worlds[retworld->world_name] = retworld;
    all_worldnames.push_back(retworld->world_name);

    std::stringstream path;
    path << SAVE_DIR << PATH_SEPARATOR << retworld->world_name;
    retworld->world_path = path.str();

    if (!save_world(retworld)) {
        std::string worldname = retworld->world_name;
        std::vector<std::string>::iterator it = std::find(all_worldnames.begin(), all_worldnames.end(), worldname);
        all_worldnames.erase(it);
        delete all_worlds[worldname];
        delete retworld;
        all_worlds.erase(worldname);
        return NULL;
    }
    return retworld;
}
Exemple #9
0
void auto_pickup::add_rule(const std::string &sRule)
{
    vRules[CHARACTER].push_back(cRules(sRule, true, false));
    merge_vector();
    create_rules();

    if (!OPTIONS["AUTO_PICKUP"] &&
        query_yn(_("Autopickup is not enabled in the options. Enable it now?")) ) {
        OPTIONS["AUTO_PICKUP"].setNext();
        get_options().save();
    }
}
void addPickupRule(std::string sRule)
{
    vAutoPickupRules[2].push_back(cPickupRules(sRule, true, false));
    merge_vector();
    createPickupRules();

    if (!OPTIONS["AUTO_PICKUP"] &&
        query_yn(_("Autopickup is not enabled in the options. Enable it now?")) ) {
        OPTIONS["AUTO_PICKUP"].setNext();
        save_options(true);
    }
}
Exemple #11
0
void safemode::add_rule( const std::string &rule_in, const Creature::Attitude attitude_in,
                         const int proximity_in,
                         const rule_state state_in )
{
    character_rules.push_back( rules_class( rule_in, true, ( state_in == RULE_WHITELISTED ),
                                            attitude_in, proximity_in ) );
    create_rules();

    if( !get_option<bool>( "SAFEMODE" ) &&
        query_yn( _( "Safe Mode is not enabled in the options. Enable it now?" ) ) ) {
        get_options().get_option( "SAFEMODE" ).setNext();
        get_options().save();
    }
}
bool craft_command::query_continue( const std::vector<comp_selection<item_comp>> &missing_items,
                                    const std::vector<comp_selection<tool_comp>> &missing_tools )
{
    std::stringstream ss;
    ss << _( "Some components used previously are missing. Continue?" );

    if( !missing_items.empty() ) {
        ss << std::endl << _( "Item(s): " );
        component_list_string( ss, missing_items );
    }

    if( !missing_tools.empty() ) {
        ss << std::endl << _( "Tool(s): " );
        component_list_string( ss, missing_tools );
    }

    return query_yn( ss.str() );
}
Exemple #13
0
void construct::done_digormine_stair( const tripoint &p, bool dig )
{
    tripoint const abs_pos = p;
    tripoint const pos_sm = ms_to_sm_copy( abs_pos );
    tinymap tmpmap;
    tmpmap.load( pos_sm.x, pos_sm.y, pos_sm.z - 1, false );
    tripoint const local_tmp = tmpmap.getlocal( abs_pos );

    bool dig_muts = g->u.has_trait( "PAINRESIST_TROGLO" ) || g->u.has_trait( "STOCKY_TROGLO" );

    int no_mut_penalty = dig_muts ? 10 : 0;
    int mine_penalty = dig ? 0 : 10;
    g->u.mod_hunger( 5 + mine_penalty + no_mut_penalty );
    g->u.mod_thirst( 5 + mine_penalty + no_mut_penalty );
    g->u.mod_fatigue( 10 + mine_penalty + no_mut_penalty );

    if( tmpmap.ter( local_tmp ) == t_lava ) {
        if( !( query_yn( _( "The rock feels much warmer than normal. Proceed?" ) ) ) ) {
            g->m.ter_set( p, t_pit ); // You dug down a bit before detecting the problem
            unroll_digging( dig ? 8 : 12 );
        } else {
            add_msg( m_warning, _( "You just tunneled into lava!" ) );
            g->u.add_memorial_log( pgettext( "memorial_male", "Dug a shaft into lava." ),
                                   pgettext( "memorial_female", "Dug a shaft into lava." ) );
            g->m.ter_set( p, t_hole );
        }

        return;
    }

    bool impassable = tmpmap.impassable( local_tmp );
    if( !impassable ) {
        add_msg( _( "You dig into a preexisting space, and improvise a ladder." ) );
    } else if( dig ) {
        add_msg( _( "You dig a stairway, adding sturdy timbers and a rope for safety." ) );
    } else {
        add_msg( _( "You drill out a passage, heading deeper underground." ) );
    }
    g->m.ter_set( p, t_stairs_down ); // There's the top half
    // Again, need to use submap-local coordinates.
    tmpmap.ter_set( local_tmp, impassable ? t_stairs_up : t_ladder_up ); // and there's the bottom half.
    // And save to the center coordinate of the current active map.
    tmpmap.save();
}
Exemple #14
0
void exit_handler(int s)
{
    const int old_timeout = inp_mngr.get_timeout();
    inp_mngr.reset_timeout();
    if (s != 2 || query_yn(_("Really Quit? All unsaved changes will be lost."))) {
        erase(); // Clear screen

        deinitDebug();

        int exit_status = 0;
        if( g != NULL ) {
            delete g;
        }

        endwin();

        exit( exit_status );
    }
    inp_mngr.set_timeout( old_timeout );
}
Exemple #15
0
void exit_handler(int s)
{
    if (s != 2 || query_yn(_("Really Quit? All unsaved changes will be lost."))) {
        erase(); // Clear screen

        deinitDebug();

        int exit_status = 0;
        if( g != NULL ) {
            if( g->game_error() ) {
                exit_status = 1;
            }
            delete g;
        }

        endwin();

        exit( exit_status );
    }
}
tripoint start_location::find_player_initial_location() const
{
    const bool using_existing_initial_overmap = overmap_buffer.has( 0, 0 );
    // The coordinates of an overmap that is known to *not* exist. We can regenerate this
    // as often we like.
    point non_existing_omt = point( 0, 0 );

    if( using_existing_initial_overmap ) {
        // arbitrary, should be large enough to include all overmaps ever created
        const int radius = 32;
        for( const point omp : closest_points_first( radius, point( 0, 0 ) ) ) {
            const overmap *omap = overmap_buffer.get_existing( omp.x, omp.y );
            if( omap == nullptr ) {
                if( non_existing_omt == point( 0, 0 ) ) {
                    non_existing_omt = omp;
                }
                continue;
            }
            const tripoint omtstart = omap->find_random_omt( target() );
            if( omtstart != overmap::invalid_tripoint ) {
                return omtstart + point( omp.x * OMAPX, omp.y * OMAPY );
            }
        }
    }

    while( true ) {
        popup_nowait( _( "Please wait as we build your world" ) );
        const overmap &initial_overmap = overmap_buffer.get( non_existing_omt.x, non_existing_omt.y );
        const tripoint omtstart = initial_overmap.find_random_omt( target() );
        if( omtstart != overmap::invalid_tripoint ) {
            return omtstart + point( non_existing_omt.x * OMAPX, non_existing_omt.y * OMAPY );
        }
        if( !query_yn(
                _( "The game could not create a world with a suitable starting location.\n\n"
                   "Depending on the world options, the starting location may never appear. If the problem persists, you can try another starting location, or change the world options.\n\n"
                   "Try again?" ) ) ) {
            return overmap::invalid_tripoint;
        }
        overmap_buffer.clear();
    }
}
Exemple #17
0
bool player::disassemble( item &obj, int pos, bool ground, bool interactive )
{
    // check sufficient tools for disassembly
    std::string err;
    if( !can_disassemble( obj, crafting_inventory(), &err ) ) {
        if( interactive ) {
            add_msg_if_player( m_info, "%s", err.c_str() );
        }
        return false;
    }

    const auto &r = recipe_dictionary::get_uncraft( obj.typeId() );
    // last chance to back out
    if( interactive && get_option<bool>( "QUERY_DISASSEMBLE" ) ) {
        const auto components( r.disassembly_requirements().get_components() );
        std::ostringstream list;
        for( const auto &elem : components ) {
            list << "- " << elem.front().to_string() << std::endl;
        }

        if( !query_yn( _( "Disassembling the %s may yield:\n%s\nReally disassemble?" ), obj.tname().c_str(),
                       list.str().c_str() ) ) {
            return false;
        }
    }

    if( activity.id() != activity_id( "ACT_DISASSEMBLE" ) ) {
        assign_activity( activity_id( "ACT_DISASSEMBLE" ), r.time );
    } else if( activity.moves_left <= 0 ) {
        activity.moves_left = r.time;
    }

    activity.values.push_back( pos );
    activity.coords.push_back( ground ? this->pos() : tripoint_min );
    activity.str_values.push_back( r.result );

    return true;
}
Exemple #18
0
void exit_handler(int s) {
     if (s != 2 || query_yn(_("Really Quit? All unsaved changes will be lost."))) {
         erase(); // Clear screen
         endwin(); // End ncurses
         #if (defined _WIN32 || defined WINDOWS)
             system("cls"); // Tell the terminal to clear itself
             system("color 07");
         #else
             system("clear"); // Tell the terminal to clear itself
         #endif

         if(g != NULL) {
             if(g->game_error()) {
                 delete g;
                 exit(1);
             } else {
                 delete g;
                 exit(0);
             }
         }
         exit(0);
     }
}
Exemple #19
0
bool player::feed_reactor_with( item &it )
{
    if( !can_feed_reactor_with( it ) ) {
        return false;
    }

    const auto iter = plut_charges.find( it.typeId() );
    const int max_amount = iter != plut_charges.end() ? iter->second : 0;
    const int amount = std::min( get_acquirable_energy( it, rechargeable_cbm::reactor ), max_amount );

    if( amount >= PLUTONIUM_CHARGES * 10 &&
        !query_yn( _( "Thats a LOT of plutonium.  Are you sure you want that much?" ) ) ) {
        return false;
    }

    add_msg_player_or_npc( _( "You add your %s to your reactor's tank." ),
                           _( "<npcname> pours %s into their reactor's tank." ),
                           it.tname().c_str() );

    tank_plut += amount; // @todo Encapsulate
    it.charges -= 1;
    mod_moves( -250 );
    return true;
}
Exemple #20
0
WORLDPTR worldfactory::make_new_world( bool show_prompt )
{
    // World to return after generating
    WORLDPTR retworld = new WORLD();
    if( show_prompt ) {
        // Window variables
        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;
        // set up window
        WINDOW *wf_win = newwin(FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, iOffsetY, iOffsetX);
        WINDOW_PTR wf_winptr( wf_win );

        int curtab = 0;
        int lasttab; // give placement memory to menus, sorta.
        const int numtabs = tabs.size();
        while (curtab >= 0 && curtab < numtabs) {
            lasttab = curtab;
            draw_worldgen_tabs(wf_win, curtab);
            curtab += (world_generator->*tabs[curtab])(wf_win, retworld);

            if (curtab < 0) {
                if (!query_yn(_("Do you want to abort World Generation?"))) {
                    curtab = lasttab;
                }
            }
        }
        if (curtab < 0) {
            delete retworld;
            return NULL;
        }
    } else { // 'Play NOW'
#ifndef LUA
        // Silently remove all Lua mods setted by default.
        std::vector<std::string>::iterator mod_it;
        for (mod_it = retworld->active_mod_order.begin(); mod_it != retworld->active_mod_order.end();) {
            MOD_INFORMATION *minfo = mman->mod_map[*mod_it];
            if ( minfo->need_lua ) {
                mod_it = retworld->active_mod_order.erase(mod_it);
            } else {
                mod_it++;
            }
        }
#endif
    }

    // add world to world list
    all_worlds[retworld->world_name] = retworld;
    all_worldnames.push_back(retworld->world_name);

    std::stringstream path;
    path << FILENAMES["savedir"] << retworld->world_name;
    retworld->world_path = path.str();
    //debugmsg("worldpath: %s", path.str().c_str());

    if (!save_world(retworld)) {
        std::string worldname = retworld->world_name;
        std::vector<std::string>::iterator it = std::find(all_worldnames.begin(), all_worldnames.end(),
                                                worldname);
        all_worldnames.erase(it);
        if (all_worlds[worldname] != retworld) {
            delete retworld;
        }
        delete all_worlds[worldname];
        all_worlds.erase(worldname);
        return NULL;
    }
    return retworld;
}
Exemple #21
0
void game::show_options()
{
    std::map<std::string, cOpt> OPTIONS_OLD = OPTIONS;

    const int iTooltipHeight = 3;
    const int iContentHeight = FULL_SCREEN_HEIGHT-3-iTooltipHeight;

    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[3] = true;
    mapLines[60] = true;
    //mapLines[68] = true;

    WINDOW* w_options_border = newwin(FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, iOffsetY, iOffsetX);

    WINDOW* w_options_tooltip = newwin(iTooltipHeight, FULL_SCREEN_WIDTH - 2, 1 + iOffsetY, 1 + iOffsetX);
    WINDOW* w_options_header = newwin(1, FULL_SCREEN_WIDTH - 2, 1 + iTooltipHeight + iOffsetY, 1 + iOffsetX);
    WINDOW* w_options = newwin(iContentHeight, FULL_SCREEN_WIDTH - 2, iTooltipHeight + 2 + iOffsetY, 1 + iOffsetX);

    wborder(w_options_border, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX, LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX);
    mvwputch(w_options_border, 4,  0, c_ltgray, LINE_XXXO); // |-
    mvwputch(w_options_border, 4, 79, c_ltgray, LINE_XOXX); // -|

    for (std::map<int, bool>::iterator iter = mapLines.begin(); iter != mapLines.end(); ++iter) {
        mvwputch(w_options_border, FULL_SCREEN_HEIGHT-1, iter->first + 1, c_ltgray, LINE_XXOX); // _|_
    }

    mvwprintz(w_options_border, 0, 36, c_ltred, _(" OPTIONS "));
    wrefresh(w_options_border);

    for (int i = 0; i < 78; i++) {
        if (mapLines[i]) {
            mvwputch(w_options_header, 0, i, c_ltgray, LINE_OXXX);
        } else {
            mvwputch(w_options_header, 0, i, c_ltgray, LINE_OXOX); // Draw header line
        }
    }

    //mvwprintz(w_options_header, 3, 0, c_white, "#");
    //mvwprintz(w_options_header, 3, 7, c_white, _("Option"));
    //mvwprintz(w_options_header, 3, 52, c_white, _("Value"));

    wrefresh(w_options_header);

    int iCurrentPage = 0;
    int iCurrentLine = 0;
    int iStartPos = 0;
    bool bStuffChanged = false;
    char ch = ' ';

    std::stringstream sTemp;

    do {
        //Clear the lines
        for (int i = 0; i < iContentHeight; i++) {
            for (int j = 0; j < 79; j++) {
                if (mapLines[j]) {
                    mvwputch(w_options, i, j, c_ltgray, LINE_XOXO);
                } else {
                    mvwputch(w_options, i, j, c_black, ' ');
                }

                if (i < iTooltipHeight) {
                    mvwputch(w_options_tooltip, i, j, c_black, ' ');
                }
            }
        }

        if (mPageItems[iCurrentPage].size() > iContentHeight) {
            iStartPos = iCurrentLine - (iContentHeight - 1) / 2;

            if (iStartPos < 0) {
                iStartPos = 0;
            } else if (iStartPos + iContentHeight > mPageItems[iCurrentPage].size()) {
                iStartPos = mPageItems[iCurrentPage].size() - iContentHeight;
            }
        }

        //Draw options
        for (int i = iStartPos; i < mPageItems[iCurrentPage].size(); i++) {
            if (i >= iStartPos && i < iStartPos + ((iContentHeight > mPageItems[iCurrentPage].size()) ? mPageItems[iCurrentPage].size() : iContentHeight)) {
                nc_color cLineColor = c_ltgreen;

                sTemp.str("");
                sTemp << i + 1;
                mvwprintz(w_options, i - iStartPos, 0, c_white, sTemp.str().c_str());
                mvwprintz(w_options, i - iStartPos, 4, c_white, "");

                if (iCurrentLine == i) {
                    wprintz(w_options, c_yellow, ">> ");
                } else {
                    wprintz(w_options, c_yellow, "   ");
                }

                wprintz(w_options, c_white, "%s", (OPTIONS[mPageItems[iCurrentPage][i]].getMenuText()).c_str());

                if (OPTIONS[mPageItems[iCurrentPage][i]].getValue() == "False") {
                    cLineColor = c_ltred;
                }

                mvwprintz(w_options, i - iStartPos, 62, (iCurrentLine == i) ? hilite(cLineColor) : cLineColor, "%s", (OPTIONS[mPageItems[iCurrentPage][i]].getValue()).c_str());
            }
        }

        //Draw Tabs
        mvwprintz(w_options_header, 0, 7, c_white, "");
        for (int i = 0; i < vPages.size(); i++) {
            if (mPageItems[i].size() > 0) { //skip empty pages
                wprintz(w_options_header, c_white, "[");
                wprintz(w_options_header, (iCurrentPage == i) ? hilite(c_white) : c_white, vPages[i].c_str());
                wprintz(w_options_header, c_white, "]");
                wputch(w_options_header, c_white, LINE_OXOX);
            }
        }

        wrefresh(w_options_header);

        fold_and_print(w_options_tooltip, 0, 0, 78, c_white, "%s", (OPTIONS[mPageItems[iCurrentPage][iCurrentLine]].getTooltip() + "  #Default: " + OPTIONS[mPageItems[iCurrentPage][iCurrentLine]].getDefaultText()).c_str());
        wrefresh(w_options_tooltip);

        wrefresh(w_options);

        ch = input();

        if (mPageItems[iCurrentPage].size() > 0 || ch == '\t') {
            switch(ch) {
                case 'j': //move down
                    iCurrentLine++;
                    if (iCurrentLine >= mPageItems[iCurrentPage].size()) {
                        iCurrentLine = 0;
                    }
                    break;
                case 'k': //move up
                    iCurrentLine--;
                    if (iCurrentLine < 0) {
                        iCurrentLine = mPageItems[iCurrentPage].size()-1;
                    }
                    break;
                case 'l': //set to prev value
                    OPTIONS[mPageItems[iCurrentPage][iCurrentLine]].setNext();
                    bStuffChanged = true;
                    break;
                case 'h': //set to next value
                    OPTIONS[mPageItems[iCurrentPage][iCurrentLine]].setPrev();
                    bStuffChanged = true;
                    break;
                case '>':
                case '\t': //Switch to next Page
                    iCurrentLine = 0;
                    do { //skip empty pages
                        iCurrentPage++;
                        if (iCurrentPage >= vPages.size()) {
                            iCurrentPage = 0;
                        }
                    } while(mPageItems[iCurrentPage].size() == 0);

                    break;
                case '<':
                    iCurrentLine = 0;
                    do { //skip empty pages
                        iCurrentPage--;
                        if (iCurrentPage < 0) {
                            iCurrentPage = vPages.size()-1;
                        }
                    } while(mPageItems[iCurrentPage].size() == 0);
                    break;
            }
        }
    } while(ch != 'q' && ch != 'Q' && ch != KEY_ESCAPE);

    if (bStuffChanged) {
        if(query_yn(_("Save changes?"))) {
            save_options();
        } else {
            OPTIONS = OPTIONS_OLD;
        }
    }

    werase(w_options);
    werase(w_options_border);
    werase(w_options_header);
    werase(w_options_tooltip);
}
Exemple #22
0
int worldfactory::show_worldgen_tab_confirm(WINDOW *win, WORLDPTR world)
{
    const int iTooltipHeight = 1;
    const int iContentHeight = FULL_SCREEN_HEIGHT - 3 - iTooltipHeight;

    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;

    const char* line_of_32_underscores = "________________________________";

    WINDOW *w_confirmation = newwin(iContentHeight, FULL_SCREEN_WIDTH - 2,
                                    iTooltipHeight + 2 + iOffsetY, 1 + iOffsetX);
    WINDOW_PTR w_confirmationptr( w_confirmation );

    unsigned namebar_y = 1;
    unsigned namebar_x = 3 + utf8_width(_("World Name:"));

    int line = 1;
    bool noname = false;
    input_context ctxt("WORLDGEN_CONFIRM_DIALOG");
    ctxt.register_action("HELP_KEYBINDINGS");
    ctxt.register_action("QUIT");
    ctxt.register_action("ANY_INPUT");
    ctxt.register_action("NEXT_TAB");
    ctxt.register_action("PREV_TAB");
    ctxt.register_action("PICK_RANDOM_WORLDNAME");

    std::string worldname = world->world_name;
    do {
        mvwprintz(w_confirmation, namebar_y, 2, c_white, _("World Name:"));
        mvwprintz(w_confirmation, namebar_y, namebar_x, c_ltgray, line_of_32_underscores);
        fold_and_print(w_confirmation, 3, 2, 76, c_ltgray,
                       _("Press <color_yellow>%s</color> to pick a random name for your world."), ctxt.get_desc("PICK_RANDOM_WORLDNAME").c_str());
        fold_and_print(w_confirmation, FULL_SCREEN_HEIGHT / 2 - 2, 2, 76, c_ltgray, _("\
Press <color_yellow>%s</color> when you are satisfied with the world as it is and are ready \
to continue, or <color_yellow>%s</color> to go back and review your world."), ctxt.get_desc("NEXT_TAB").c_str(), ctxt.get_desc("PREV_TAB").c_str());
        if (!noname) {
            mvwprintz(w_confirmation, namebar_y, namebar_x, c_ltgray, "%s", worldname.c_str());
            if (line == 1) {
                wprintz(w_confirmation, h_ltgray, "_");
            }
        }
        if (noname) {
            mvwprintz(w_confirmation, namebar_y, namebar_x, c_ltgray, line_of_32_underscores);
            noname = false;
        }

        wrefresh(win);
        wrefresh(w_confirmation);
        refresh();

        const std::string action = ctxt.handle_input();
        if (action == "NEXT_TAB") {
#ifndef LUA
            MOD_INFORMATION *temp = NULL;
            for (std::string &mod : world->active_mod_order) {
                temp = mman->mod_map[mod];
                if ( temp->need_lua ) {
                    popup(_("Mod '%s' requires Lua support."), temp->name.c_str());
                    return -2; // Move back to modselect tab.
                }
            }
#endif
            if (worldname.empty()) {
                mvwprintz(w_confirmation, namebar_y, namebar_x, h_ltgray, _("_______NO NAME ENTERED!!!!______"));
                noname = true;
                wrefresh(w_confirmation);
                if (!query_yn(_("Are you SURE you're finished? World name will be randomly generated."))) {
                    continue;
                } else {
                    world->world_name = pick_random_name();
                    if (!valid_worldname(world->world_name)) {
                        continue;
                    }
                    return 1;
                }
            } else if (query_yn(_("Are you SURE you're finished?")) && valid_worldname(worldname)) {
                world->world_name = worldname;
                return 1;
            } else {
                continue;
            }
        } else if (action == "PREV_TAB") {
            world->world_name = worldname;
            return -1;
        } else if (action == "PICK_RANDOM_WORLDNAME") {
            mvwprintz(w_confirmation, namebar_y, namebar_x, c_ltgray, line_of_32_underscores);
            world->world_name = worldname = pick_random_name();
        } else if (action == "QUIT") {
            // Cache the current name just in case they say No to the exit query.
            world->world_name = worldname;
            return -999;
        } else if (action == "ANY_INPUT") {
            const input_event ev = ctxt.get_raw_input();
            const long ch = ev.get_first_input();
            switch (line) {
            case 1: {
                utf8_wrapper wrap(worldname);
                utf8_wrapper newtext( ev.text );
                if( ch == KEY_BACKSPACE ) {
                    if (!wrap.empty()) {
                        wrap.erase(wrap.length() - 1, 1);
                        worldname = wrap.str();
                    }
                } else if(ch == KEY_F(2)) {
                    std::string tmp = get_input_string_from_file();
                    int tmplen = utf8_width( tmp );
                    if(tmplen > 0 && tmplen + utf8_width(worldname) < 30) {
                        worldname.append(tmp);
                    }
                } else if( !newtext.empty() && is_char_allowed( newtext.at( 0 ) ) ) {
                    // No empty string, no slash, no backslash, no control sequence
                    wrap.append( newtext );
                    worldname = wrap.str();
                }
                mvwprintz(w_confirmation, namebar_y, namebar_x, c_ltgray, line_of_32_underscores);
                mvwprintz(w_confirmation, namebar_y, namebar_x, c_ltgray, "%s", worldname.c_str());
                wprintz(w_confirmation, h_ltgray, "_");
            }
            break;
            }
        }
    } while (true);

    return 0;
}
Exemple #23
0
WORLDPTR worldfactory::pick_world( bool show_prompt )
{
    std::map<std::string, WORLDPTR> worlds = get_all_worlds();
    std::vector<std::string> world_names = all_worldnames;

    // Filter out special worlds (TUTORIAL | DEFENSE) from world_names.
    for (std::vector<std::string>::iterator it = world_names.begin(); it != world_names.end();) {
        if (*it == "TUTORIAL" || *it == "DEFENSE") {
            it = world_names.erase(it);
        } else if (world_need_lua_build(*it)) {
            it = world_names.erase(it);
        } else {
            ++it;
        }
    }
    // If there is only one world to pick from, autoreturn it.
    if (world_names.size() == 1) {
        return worlds[world_names[0]];
    }
    // If there are no worlds to pick from, immediately try to make one.
    else if (world_names.empty()) {
        return make_new_world( show_prompt );
    }
    // If we're skipping prompts, just return the first one.
    else if( !show_prompt ) {
        return worlds[world_names[0]];
    }

    const int iTooltipHeight = 3;
    const int iContentHeight = FULL_SCREEN_HEIGHT - 3 - iTooltipHeight;
    const unsigned int num_pages = world_names.size() / iContentHeight + 1; // at least 1 page
    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[3] = true;

    std::map<int, std::vector<std::string> > world_pages;
    unsigned int worldnum = 0;
    for (size_t i = 0; i < num_pages; ++i) {
        for (int j = 0; j < iContentHeight && worldnum < world_names.size(); ++j) {
            world_pages[i].push_back(world_names[worldnum++]);
        }
    }
    unsigned int sel = 0, selpage = 0;

    WINDOW *w_worlds_border = newwin(FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, iOffsetY, iOffsetX);
    WINDOW *w_worlds_tooltip = newwin(iTooltipHeight, FULL_SCREEN_WIDTH - 2, 1 + iOffsetY,
                                      1 + iOffsetX);
    WINDOW *w_worlds_header = newwin(1, FULL_SCREEN_WIDTH - 2, 1 + iTooltipHeight + iOffsetY,
                                     1 + iOffsetX);
    WINDOW *w_worlds        = newwin(iContentHeight, FULL_SCREEN_WIDTH - 2,
                                     iTooltipHeight + 2 + iOffsetY, 1 + iOffsetX);

    draw_border(w_worlds_border);
    mvwputch(w_worlds_border, 4, 0, BORDER_COLOR, LINE_XXXO); // |-
    mvwputch(w_worlds_border, 4, FULL_SCREEN_WIDTH - 1, BORDER_COLOR, LINE_XOXX); // -|

    for( auto &mapLine : mapLines ) {
        mvwputch( w_worlds_border, FULL_SCREEN_HEIGHT - 1, mapLine.first + 1, BORDER_COLOR,
                  LINE_XXOX ); // _|_
    }

    center_print(w_worlds_border, 0, c_ltred, _(" WORLD SELECTION "));
    wrefresh(w_worlds_border);

    for (int i = 0; i < 78; i++) {
        if (mapLines[i]) {
            mvwputch(w_worlds_header, 0, i, BORDER_COLOR, LINE_OXXX);
        } else {
            mvwputch(w_worlds_header, 0, i, BORDER_COLOR, LINE_OXOX); // Draw header line
        }
    }

    wrefresh(w_worlds_header);

    input_context ctxt("PICK_WORLD_DIALOG");
    ctxt.register_updown();
    ctxt.register_action("HELP_KEYBINDINGS");
    ctxt.register_action("QUIT");
    ctxt.register_action("NEXT_TAB");
    ctxt.register_action("PREV_TAB");
    ctxt.register_action("CONFIRM");

    std::stringstream sTemp;

    while(true) {
        //Clear the lines
        for (int i = 0; i < iContentHeight; i++) {
            for (int j = 0; j < 79; j++) {
                if (mapLines[j]) {
                    mvwputch(w_worlds, i, j, BORDER_COLOR, LINE_XOXO);
                } else {
                    mvwputch(w_worlds, i, j, c_black, ' ');
                }

                if (i < iTooltipHeight) {
                    mvwputch(w_worlds_tooltip, i, j, c_black, ' ');
                }
            }
        }

        //Draw World Names
        for (size_t i = 0; i < world_pages[selpage].size(); ++i) {
            sTemp.str("");
            sTemp << i + 1;
            mvwprintz(w_worlds, i, 0, c_white, "%s", sTemp.str().c_str());
            mvwprintz(w_worlds, i, 4, c_white, "");

            std::string world_name = (world_pages[selpage])[i];
            size_t saves_num = world_generator->all_worlds[world_name]->world_saves.size();

            if (i == sel) {
                wprintz(w_worlds, c_yellow, ">> ");
            } else {
                wprintz(w_worlds, c_yellow, "   ");
            }

            if (world_need_lua_build(world_name)) {
                wprintz(w_worlds, c_dkgray, "%s (%i)", world_name.c_str(), saves_num);
            } else {
                wprintz(w_worlds, c_white, "%s (%i)", world_name.c_str(), saves_num);
            }
        }

        //Draw Tabs
        mvwprintz(w_worlds_header, 0, 7, c_white, "");

        for (size_t i = 0; i < num_pages; ++i) {
            nc_color tabcolor = (selpage == i) ? hilite(c_white) : c_white;
            if (!world_pages[i].empty()) { //skip empty pages
                wprintz(w_worlds_header, c_white, "[");
                wprintz(w_worlds_header, tabcolor, _("Page %d"), i + 1);
                wprintz(w_worlds_header, c_white, "]");
                wputch(w_worlds_header, BORDER_COLOR, LINE_OXOX);
            }
        }

        wrefresh(w_worlds_header);

        fold_and_print(w_worlds_tooltip, 0, 0, 78, c_white, _("Pick a world to enter game"));
        wrefresh(w_worlds_tooltip);

        wrefresh(w_worlds);

        const std::string action = ctxt.handle_input();

        if (action == "QUIT") {
            break;
        } else if (!world_pages[selpage].empty() && action == "DOWN") {
            sel++;
            if (sel >= world_pages[selpage].size()) {
                sel = 0;
            }
        } else if (!world_pages[selpage].empty() && action == "UP") {
            if (sel == 0) {
                sel = world_pages[selpage].size() - 1;
            } else {
                sel--;
            }
        } else if (action == "NEXT_TAB") {
            sel = 0;
            do { //skip empty pages
                selpage++;
                if (selpage >= world_pages.size()) {
                    selpage = 0;
                }
            } while(world_pages[selpage].empty());
        } else if (action == "PREV_TAB") {
            sel = 0;
            do { //skip empty pages
                if (selpage != 0) {
                    selpage--;
                } else {
                    selpage = world_pages.size() - 1;
                }
            } while(world_pages[selpage].empty());
        } else if (action == "CONFIRM") {
            if (world_need_lua_build(world_pages[selpage][sel])) {
                popup(_("Can't start in world [%s]. Some of mods require Lua support."),
                      world_pages[selpage][sel].c_str());
                continue;
            }
            // we are wanting to get out of this by confirmation, so ask if we want to load the level [y/n prompt] and if yes exit
            if (query_yn(_("Do you want to start the game in world [%s]?"),
                         world_pages[selpage][sel].c_str())) {
                werase(w_worlds);
                werase(w_worlds_border);
                werase(w_worlds_header);
                werase(w_worlds_tooltip);
                return all_worlds[world_pages[selpage][sel]];//sel + selpage * iContentHeight;
            }
        }
    }

    werase(w_worlds);
    werase(w_worlds_border);
    werase(w_worlds_header);
    werase(w_worlds_tooltip);

    return NULL;
}
Exemple #24
0
void defense_game::caravan(game *g)
{
 std::vector<itype_id> items[NUM_CARAVAN_CATEGORIES];
 std::vector<int> item_count[NUM_CARAVAN_CATEGORIES];

// Init the items for each category
 for (int i = 0; i < NUM_CARAVAN_CATEGORIES; i++) {
  items[i] = caravan_items( caravan_category(i) );
  for (int j = 0; j < items[i].size(); j++) {
   if (current_wave == 0 || !one_in(4))
    item_count[i].push_back(0); // Init counts to 0 for each item
   else { // Remove the item
    items[i].erase( items[i].begin() + j);
    j--;
   }
  }
 }

 int total_price = 0;

 WINDOW *w = newwin(25, 80, 0, 0);

 int offset = 0, item_selected = 0, category_selected = 0;

 int current_window = 0;

 draw_caravan_borders(w, current_window);
 draw_caravan_categories(w, category_selected, total_price, g->u.cash);

 bool done = false;
 bool cancel = false;
 while (!done) {

  char ch = input();
  switch (ch) {
   case '?':
    popup_top("\
CARAVAN:\n\
Start by selecting a category using your favorite up/down keys.\n\
Switch between category selection and item selecting by pressing Tab.\n\
Pick an item with the up/down keys, press + to buy 1 more, - to buy 1 less.\n\
Press Enter to buy everything in your cart, Esc to buy nothing.");
    draw_caravan_categories(w, category_selected, total_price, g->u.cash);
    draw_caravan_items(w, g, &(items[category_selected]),
                       &(item_count[category_selected]), offset, item_selected);
    draw_caravan_borders(w, current_window);
    break;

   case 'j':
    if (current_window == 0) { // Categories
     category_selected++;
     if (category_selected == NUM_CARAVAN_CATEGORIES)
      category_selected = CARAVAN_CART;
     draw_caravan_categories(w, category_selected, total_price, g->u.cash);
     offset = 0;
     item_selected = 0;
     draw_caravan_items(w, g, &(items[category_selected]),
                        &(item_count[category_selected]), offset,
                        item_selected);
     draw_caravan_borders(w, current_window);
    } else if (items[category_selected].size() > 0) { // Items
     if (item_selected < items[category_selected].size() - 1)
      item_selected++;
     else {
      item_selected = 0;
      offset = 0;
     }
     if (item_selected > offset + 22)
      offset++;
     draw_caravan_items(w, g, &(items[category_selected]),
                        &(item_count[category_selected]), offset,
                        item_selected);
     draw_caravan_borders(w, current_window);
    }
    break;

   case 'k':
    if (current_window == 0) { // Categories
     if (category_selected == 0)
      category_selected = NUM_CARAVAN_CATEGORIES - 1;
     else
      category_selected--;
     if (category_selected == NUM_CARAVAN_CATEGORIES)
      category_selected = CARAVAN_CART;
     draw_caravan_categories(w, category_selected, total_price, g->u.cash);
     offset = 0;
     item_selected = 0;
     draw_caravan_items(w, g, &(items[category_selected]),
                        &(item_count[category_selected]), offset,
                        item_selected);
     draw_caravan_borders(w, current_window);
    } else if (items[category_selected].size() > 0) { // Items
     if (item_selected > 0)
      item_selected--;
     else {
      item_selected = items[category_selected].size() - 1;
      offset = item_selected - 22;
      if (offset < 0)
       offset = 0;
     }
     if (item_selected < offset)
      offset--;
     draw_caravan_items(w, g, &(items[category_selected]),
                        &(item_count[category_selected]), offset,
                        item_selected);
     draw_caravan_borders(w, current_window);
    }
    break;

   case '+':
   case 'l':
    if (current_window == 1 && items[category_selected].size() > 0) {
     item_count[category_selected][item_selected]++;
     itype_id tmp_itm = items[category_selected][item_selected];
     total_price += caravan_price(g->u, g->itypes[tmp_itm]->price);
     if (category_selected == CARAVAN_CART) { // Find the item in its category
      for (int i = 1; i < NUM_CARAVAN_CATEGORIES; i++) {
       for (int j = 0; j < items[i].size(); j++) {
        if (items[i][j] == tmp_itm)
         item_count[i][j]++;
       }
      }
     } else { // Add / increase the item in the shopping cart
      bool found_item = false;
      for (int i = 0; i < items[0].size() && !found_item; i++) {
       if (items[0][i] == tmp_itm) {
        found_item = true;
        item_count[0][i]++;
       }
      }
      if (!found_item) {
       items[0].push_back(items[category_selected][item_selected]);
       item_count[0].push_back(1);
      }
     }
     draw_caravan_categories(w, category_selected, total_price, g->u.cash);
     draw_caravan_items(w, g, &(items[category_selected]),
                       &(item_count[category_selected]), offset, item_selected);
     draw_caravan_borders(w, current_window);
    }
    break;

   case '-':
   case 'h':
    if (current_window == 1 && items[category_selected].size() > 0 &&
        item_count[category_selected][item_selected] > 0) {
     item_count[category_selected][item_selected]--;
     itype_id tmp_itm = items[category_selected][item_selected];
     total_price -= caravan_price(g->u, g->itypes[tmp_itm]->price);
     if (category_selected == CARAVAN_CART) { // Find the item in its category
      for (int i = 1; i < NUM_CARAVAN_CATEGORIES; i++) {
       for (int j = 0; j < items[i].size(); j++) {
        if (items[i][j] == tmp_itm)
         item_count[i][j]--;
       }
      }
     } else { // Decrease / remove the item in the shopping cart
      bool found_item = false;
      for (int i = 0; i < items[0].size() && !found_item; i++) {
       if (items[0][i] == tmp_itm) {
        found_item = true;
        item_count[0][i]--;
        if (item_count[0][i] == 0) {
         item_count[0].erase(item_count[0].begin() + i);
         items[0].erase(items[0].begin() + i);
        }
       }
      }
     }
     draw_caravan_categories(w, category_selected, total_price, g->u.cash);
     draw_caravan_items(w, g, &(items[category_selected]),
                       &(item_count[category_selected]), offset, item_selected);
     draw_caravan_borders(w, current_window);
    }
    break;

   case '\t':
    current_window = (current_window + 1) % 2;
    draw_caravan_borders(w, current_window);
    break;

   case KEY_ESCAPE:
    if (query_yn("Really buy nothing?")) {
     cancel = true;
     done = true;
    } else {
     draw_caravan_categories(w, category_selected, total_price, g->u.cash);
     draw_caravan_items(w, g, &(items[category_selected]),
                       &(item_count[category_selected]), offset, item_selected);
     draw_caravan_borders(w, current_window);
    }
    break;

   case '\n':
    if (total_price > g->u.cash)
     popup("You can't afford those items!");
    else if ((items[0].empty() && query_yn("Really buy nothing?")) ||
             (!items[0].empty() &&
              query_yn("Buy %d items, leaving you with $%d?", items[0].size(),
                       g->u.cash - total_price)))
     done = true;
    if (!done) { // We canceled, so redraw everything
     draw_caravan_categories(w, category_selected, total_price, g->u.cash);
     draw_caravan_items(w, g, &(items[category_selected]),
                       &(item_count[category_selected]), offset, item_selected);
     draw_caravan_borders(w, current_window);
    }
    break;
  } // switch (ch)

 } // while (!done)

 if (!cancel) {
  g->u.cash -= total_price;
  bool dropped_some = false;
  for (int i = 0; i < items[0].size(); i++) {
   item tmp(g->itypes[ items[0][i] ], g->turn);
   tmp = tmp.in_its_container(&(g->itypes));
   for (int j = 0; j < item_count[0][i]; j++) {
    if (g->u.volume_carried() + tmp.volume() <= g->u.volume_capacity() &&
        g->u.weight_carried() + tmp.weight() <= g->u.weight_capacity() &&
        g->u.inv.size() < inv_chars.size())
     g->u.i_add(tmp);
    else { // Could fit it in the inventory!
     dropped_some = true;
     g->m.add_item(g->u.posx, g->u.posy, tmp);
    }
   }
  }
  if (dropped_some)
   g->add_msg("You drop some items.");
 }
}
void game::show_options()
{
 int iMaxX = (VIEWX < 12) ? 80 : (VIEWX*2)+56;
 int iMaxY = (VIEWY < 12) ? 25 : (VIEWY*2)+1;

 WINDOW* w_options_border = newwin(25, 80, (iMaxY > 25) ? (iMaxY-25)/2 : 0, (iMaxX > 80) ? (iMaxX-80)/2 : 0);
 WINDOW* w_options = newwin(23, 78, 1 + (int)((iMaxY > 25) ? (iMaxY-25)/2 : 0), 1 + (int)((iMaxX > 80) ? (iMaxX-80)/2 : 0));

 int offset = 1;
 int line = 0;
 char ch = ' ';
 bool changed_options = false;
 bool needs_refresh = true;
 do {
  wborder(w_options_border, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX,
                            LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX);
  mvwprintz(w_options_border, 0, 36, c_ltred, " OPTIONS ");
  wrefresh(w_options_border);

// TODO: change instructions
  if (needs_refresh) {
    werase(w_options);
    mvwprintz(w_options, 0, 40, c_white, "Use up/down keys to scroll through");
    mvwprintz(w_options, 1, 40, c_white, "available options.");
    mvwprintz(w_options, 2, 40, c_white, "Use left/right keys to toggle.");
    mvwprintz(w_options, 3, 40, c_white, "Press ESC or q to return.             ");
// highlight options for option descriptions
    std::string tmp = option_desc(option_key(offset + line));
    std::string out;
    size_t pos;
    int displayline = 5;
    do {
      pos = tmp.find_first_of('\n');
      out = tmp.substr(0, pos);
      mvwprintz(w_options, displayline, 40, c_white, out.c_str());
      tmp = tmp.substr(pos + 1);
      displayline++;
    } while (pos != std::string::npos && displayline < 12);
   needs_refresh = false;
  }

// Clear the lines
  for (int i = 0; i < 25; i++)
   mvwprintz(w_options, i, 0, c_black, "                                        ");
  int valid_option_count = 0;

// display options
  for (int i = 0; i < 25 && offset + i < NUM_OPTION_KEYS; i++)
  {
       valid_option_count++;
       mvwprintz(w_options, i, 0, c_white, "%s: ",
                option_name( option_key(offset + i) ).c_str());

      if (option_is_bool(option_key(offset + i)))
      {
        bool on = OPTIONS[ option_key(offset + i) ];
        if (i == line)
          mvwprintz(w_options, i, 30, hilite(c_ltcyan), (on ? "True" : "False"));
        else
          mvwprintz(w_options, i, 30, (on ? c_ltgreen : c_ltred), (on ? "True" : "False"));
      } else {
        char option_val = OPTIONS[ option_key(offset + i) ];
        if (i == line)
          mvwprintz(w_options, i, 30, hilite(c_ltcyan), "%d", option_val );
        else
          mvwprintz(w_options, i, 30, c_ltgreen, "%d", option_val );
      }
  }
  wrefresh(w_options);
  refresh();
  ch = input();
  needs_refresh = true;
  refresh();

 switch (ch) {
// move up and down
  case 'j':
   line++;
   if (line == NUM_OPTION_KEYS - 1)
    line = 0;
   break;
  case 'k':
   line--;
   if (line < 0)
    line = NUM_OPTION_KEYS - 2;
   break;
// toggle options with left/right keys
  case 'h':
      if (option_is_bool(option_key(offset + line)))
        OPTIONS[ option_key(offset + line) ] = !(OPTIONS[ option_key(offset + line) ]);
      else
      {
        OPTIONS[ option_key(offset + line) ]--;
        if ((OPTIONS[ option_key(offset + line) ]) < 0 )
          OPTIONS[ option_key(offset + line) ] = option_max_options(option_key(offset + line)) - 1;
      }
      changed_options = true;
  break;
  case 'l':
    if (option_is_bool(option_key(offset + line)))
      OPTIONS[ option_key(offset + line) ] = !(OPTIONS[ option_key(offset + line) ]);
    else
    {
      OPTIONS[ option_key(offset + line) ]++;
      if ((OPTIONS[ option_key(offset + line) ]) >= option_max_options(option_key(offset + line)))
        OPTIONS[ option_key(offset + line) ] = 0;
    }
    changed_options = true;
  break;
  }
 } while (ch != 'q' && ch != 'Q' && ch != KEY_ESCAPE);

 if (changed_options && query_yn(this->VIEWX, this->VIEWY, "Save changes?"))
  save_options();
 werase(w_options);
}
Exemple #26
0
bool Player::create_new_character()
{
  Window w_newch(0, 0, 80, 24);
  cuss::interface i_newch;
  if (!i_newch.load_from_file(CUSS_DIR + "/i_newchar_stats.cuss")) {
    return false;
  }

  New_char_screen cur_screen = NCS_STATS;

  Stat_selected cur_stat = STATSEL_STR;
  int* stat_value = &(stats.strength);

/* We need to set up a list of traits which does NOT include the placeholder / 
 * marker "traits" like TRAIT_MAX_GOOD and TRAIT_MAX_NEUTRAL etc.
 */
  std::vector<Trait_id> selectable_traits;
  for (int i = 1; i < TRAIT_MAX_BAD; i++) {
    if (i != TRAIT_MAX_GOOD && i != TRAIT_MAX_NEUTRAL) {
      selectable_traits.push_back( Trait_id(i) );
    }
  }

  std::vector<std::string> traits_list     = get_trait_list     (this);
  std::vector<std::string> profession_list = get_profession_list(this);

  name = "";

  int points = 4;
  int num_traits = 0;

  i_newch.ref_data("num_points", &points);

  i_newch.ref_data("num_strength",     &stats.strength);
  i_newch.ref_data("num_dexterity",    &stats.dexterity);
  i_newch.ref_data("num_perception",   &stats.perception);
  i_newch.ref_data("num_intelligence", &stats.intelligence);
  i_newch.set_data("text_description", get_stat_description(cur_stat));

  i_newch.set_data("text_strength",     "<c=ltblue>Strength<c=/>");
  i_newch.set_data("text_dexterity",    "<c=ltgray>Dexterity<c=/>");
  i_newch.set_data("text_perception",   "<c=ltgray>Perception<c=/>");
  i_newch.set_data("text_intelligence", "<c=ltgray>Intelligence<c=/>");

  bool done = false;

  while (!done) {  // We'll exit this function via keypresses, always
// Always set num_points!

    i_newch.draw(&w_newch);
    w_newch.refresh();

    long ch = getch();
    bool changed_screen = false;

    if (ch == '<') {
      cur_screen = New_char_screen( cur_screen - 1 );
      if (cur_screen == NCS_CANCEL) {
        if (query_yn("Cancel character creation?")) {
          return false;
        }
        cur_screen = NCS_STATS;
      } else {
        changed_screen = true;
      }
    } else if (ch == '>') {
      cur_screen = New_char_screen( cur_screen + 1 );
      if (cur_screen == NCS_DONE) {
        std::string reason_for_fail;
        if (points > 0) {
          reason_for_fail += "\nYou have unspent points!";
        }
        if (profession == NULL) {
          reason_for_fail += "\nYou didn't choose a profession!";
        }
        if (name.empty()) {
          reason_for_fail += "\nYour name is blank!";
        }
        if (!reason_for_fail.empty()) {
          popup("Wait, you can't start the game yet!%s",
                reason_for_fail.c_str());
        } else if (query_yn("Complete character and start the game?")) {
          done = true;
        }
        cur_screen = NCS_DESCRIPTION;
      } else {
        changed_screen = true;
      }
    } else {
// We should be doing this with cuss keybindings, but... that gets complex.
// Maybe one day I'll update cuss to be more friendly.
      switch (cur_screen) {

        case NCS_STATS: {
          bool changed_stat = false;
          switch (ch) {
            case '2':
            case 'j':
            case KEY_DOWN:
              if (cur_stat == STATSEL_INT) {
                cur_stat = STATSEL_STR;
              } else {
                cur_stat = Stat_selected( cur_stat + 1 );
              }
              changed_stat = true;
              break;

            case '8':
            case 'k':
            case KEY_UP:
              if (cur_stat == STATSEL_STR) {
                cur_stat = STATSEL_INT;
              } else {
                cur_stat = Stat_selected( cur_stat - 1 );
              }
              changed_stat = true;
              break;

            case '4':
            case 'h':
            case KEY_LEFT:
              if (*stat_value > 4) {
                if (*stat_value > 16) {
                  points++; // Stats above 16 cost 2 points, so get extra back
                }
                points++;
                (*stat_value)--;
              }
              break;

            case '6':
            case 'l':
            case KEY_RIGHT: {
              int point_req = (*stat_value >= 16 ? 2 : 1);
              if (*stat_value < 20 && points >= point_req) {
                points -= point_req;
                (*stat_value)++;
              }
            } break;
          } // switch (ch)

          if (changed_stat) { // Update stat_value
            i_newch.set_data("text_strength",    "<c=ltgray>Strength<c=/>");
            i_newch.set_data("text_dexterity",   "<c=ltgray>Dexterity<c=/>");
            i_newch.set_data("text_perception",  "<c=ltgray>Perception<c=/>");
            i_newch.set_data("text_intelligence","<c=ltgray>Intelligence<c=/>");

            i_newch.set_data("text_description",
                             get_stat_description(cur_stat));
            switch (cur_stat) {
              case STATSEL_STR:
                stat_value = &(stats.strength);
                i_newch.set_data("text_strength",
                                 "<c=ltblue>Strength<c=/>");
                break;
              case STATSEL_DEX:
                stat_value = &(stats.dexterity);
                i_newch.set_data("text_dexterity",
                                 "<c=ltblue>Dexterity<c=/>");
                break;
              case STATSEL_PER:
                stat_value = &(stats.perception);
                i_newch.set_data("text_perception",
                                 "<c=ltblue>Perception<c=/>");
                break;
              case STATSEL_INT:
                stat_value = &(stats.intelligence);
                i_newch.set_data("text_intelligence",
                                 "<c=ltblue>Intelligence<c=/>");
                break;
            }
          }
        } break;

        case NCS_TRAITS: {
          switch (ch) {
            case '2':
            case 'j':
            case KEY_DOWN:
            {
              i_newch.add_data("list_traits", 1);
              int sel = i_newch.get_int("list_traits");
              Trait_id cur_trait = selectable_traits[sel];
              i_newch.set_data("num_cost", abs(trait_cost(cur_trait)));
              if (trait_cost(cur_trait) >= 0) {
                i_newch.set_data("text_cost", "<c=yellow>Cost:<c=/>");
              } else {
                i_newch.set_data("text_cost", "<c=yellow>Earns:<c=/>");
              }
              if (trait_cost(cur_trait) > points) {
                i_newch.set_data("num_cost", c_red);
              } else {
                i_newch.set_data("num_cost", c_white);
              }
              i_newch.set_data("text_description",
                               trait_description(cur_trait));
            } break;

            case '8':
            case 'k':
            case KEY_UP:
            {
              i_newch.add_data("list_traits", -1);
              int sel = i_newch.get_int("list_traits");
              Trait_id cur_trait = selectable_traits[sel];
              i_newch.set_data("num_cost", abs(trait_cost(cur_trait)));
              if (trait_cost(cur_trait) >= 0) {
                i_newch.set_data("text_cost", "<c=yellow>Cost:<c=/>");
              } else {
                i_newch.set_data("text_cost", "<c=yellow>Earns:<c=/>");
              }
              if (trait_cost(cur_trait) > points) {
                i_newch.set_data("num_cost", c_red);
              } else {
                i_newch.set_data("num_cost", c_white);
              }
              i_newch.set_data("text_description",
                               trait_description(cur_trait));
            } break;

            case '\n':
            case ' ':
            {
              int sel = i_newch.get_int("list_traits");
              Trait_id cur_trait = selectable_traits[sel];
              if (has_trait(cur_trait)) {
                traits[cur_trait] = false;
                points += trait_cost(cur_trait);
                num_traits--;
                traits_list = get_trait_list(this);
              } else if (points >= trait_cost(cur_trait) && num_traits < 5){
                traits[cur_trait] = true;
                points -= trait_cost(cur_trait);
                num_traits++;
                traits_list = get_trait_list(this);
              }
              i_newch.set_data("num_traits_left", 5 - num_traits);
              if (num_traits >= 5) {
                i_newch.set_data("num_traits_left", c_red);
              }
            } break;

          } // switch (ch)
        } break;

        case NCS_PROFESSION: {
          switch (ch) {
            case '2':
            case 'j':
            case KEY_DOWN:
            {
              i_newch.add_data("list_professions", 1);
              std::string prof_name = i_newch.get_str("list_professions");
              prof_name = remove_color_tags(prof_name);
              Profession* cur_prof = PROFESSIONS.lookup_name(prof_name);
              if (!cur_prof) {
                debugmsg("No such profession as '%s'!", prof_name.c_str());
                return false;
              }
              i_newch.set_data("text_description", cur_prof->description);
            } break;

            case '8':
            case 'k':
            case KEY_UP:
            {
              i_newch.add_data("list_professions", -1);
              std::string prof_name = i_newch.get_str("list_professions");
              prof_name = remove_color_tags(prof_name);
              Profession* cur_prof = PROFESSIONS.lookup_name(prof_name);
              if (!cur_prof) {
                debugmsg("No such profession as '%s'!", prof_name.c_str());
                return false;
              }
              i_newch.set_data("text_description", cur_prof->description);
            } break;

            case '\n':
            case ' ':
            {
              std::string prof_name = i_newch.get_str("list_professions");
              prof_name = remove_color_tags(prof_name);
              Profession* cur_prof = PROFESSIONS.lookup_name(prof_name);
              if (!cur_prof) {
                debugmsg("No such profession as '%s'!", prof_name.c_str());
                return false;
              }
              set_profession(cur_prof);
              profession_list = get_profession_list(this);
            } break;

          } // switch (ch)
        } break;

        case NCS_DESCRIPTION: {
          if (ch == '/') {
            male = !male;
            if (male) {
              i_newch.set_data("text_male",   "<c=yellow>Male<c=/>");
              i_newch.set_data("text_female", "<c=dkgray>Female<c=/>");
            } else {
              i_newch.set_data("text_male",   "<c=dkgray>Male<c=/>");
              i_newch.set_data("text_female", "<c=yellow>Female<c=/>");
            }
          } else {
/* Let the interface handle name entry; this includes cursor movement,
 * backspace, etc.  The only downside is that this allows entry of "invalid"
 * name characters like "'&^%$#@ etc.  Bad?
 */
            cuss::element* entry = i_newch.find_by_name("entry_name");
            entry->handle_keypress(ch);
          }
            
        } break;

      } // switch (cur_screen)
    } // key pressed isn't '<' or '>'

    if (changed_screen) {
      std::string filename = CUSS_DIR + "/i_newchar_";
      switch (cur_screen) {
        case NCS_STATS:       filename += "stats.cuss";       break;
        case NCS_TRAITS:      filename += "traits.cuss";      break;
        case NCS_PROFESSION:  filename += "profession.cuss";  break;
        case NCS_DESCRIPTION: filename += "description.cuss"; break;
      }
      if (!i_newch.load_from_file(filename)) {
        return false;
      }

      i_newch.ref_data("num_points", &points);

      switch (cur_screen) {

        case NCS_STATS:
          cur_stat = STATSEL_STR;
          i_newch.set_data("text_strength",     "<c=ltblue>Strength<c=/>");
          i_newch.set_data("text_dexterity",    "<c=ltgray>Dexterity<c=/>");
          i_newch.set_data("text_perception",   "<c=ltgray>Perception<c=/>");
          i_newch.set_data("text_intelligence", "<c=ltgray>Intelligence<c=/>");
          i_newch.ref_data("num_strength",     &stats.strength);
          i_newch.ref_data("num_dexterity",    &stats.dexterity);
          i_newch.ref_data("num_perception",   &stats.perception);
          i_newch.ref_data("num_intelligence", &stats.intelligence);
          i_newch.set_data("text_description", get_stat_description(cur_stat));
          break;

        case NCS_TRAITS: {
          i_newch.select("list_traits");
          i_newch.ref_data("list_traits", &traits_list);
          int sel = i_newch.get_int("list_traits");
          Trait_id cur_trait = selectable_traits[sel];
          i_newch.set_data("text_description", trait_description(cur_trait));
          i_newch.set_data("num_cost", abs(trait_cost(cur_trait)));
          if (trait_cost(cur_trait) >= 0) {
            i_newch.set_data("text_cost", "<c=yellow>Cost:<c=/>");
          } else {
            i_newch.set_data("text_cost", "<c=yellow>Earns:<c=/>");
          }
          if (trait_cost(cur_trait) > points) {
            i_newch.set_data("num_cost", c_red);
          } else {
            i_newch.set_data("num_cost", c_white);
          }
          i_newch.set_data("num_traits_left", 5 - num_traits);
          if (num_traits >= 5) {
            i_newch.set_data("num_traits_left", c_red);
          }
        } break;

        case NCS_PROFESSION: {
          i_newch.select("list_professions");
          i_newch.ref_data("list_professions", &profession_list);
          std::string prof_name = i_newch.get_str("list_professions");
          prof_name = remove_color_tags(prof_name);
          Profession* cur_prof = PROFESSIONS.lookup_name(prof_name);
          if (!cur_prof) {
            debugmsg("No such profession as '%s'!", prof_name.c_str());
            return false;
          }
          i_newch.set_data("text_description", cur_prof->description);
        } break;

        case NCS_DESCRIPTION:
          i_newch.ref_data("entry_name", &name);
          if (male) {
            i_newch.set_data("text_male",   "<c=yellow>Male<c=/>");
            i_newch.set_data("text_female", "<c=dkgray>Female<c=/>");
          } else {
            i_newch.set_data("text_male",   "<c=dkgray>Male<c=/>");
            i_newch.set_data("text_female", "<c=yellow>Female<c=/>");
          }
          break;
      } // switch (cur_screen)
    } // if (changed_screen)
  }

// Now set up our skills and equipment based on our profession
  if (!profession) {
    debugmsg("Character creation finished without a profession!");
    return false;
  }
  std::vector<Item_type_chance> prof_items = profession->items.item_types;
  for (int i = 0; i < prof_items.size(); i++) {
    int count = prof_items[i].number;
    Item tmp_it(prof_items[i].item);
    for (int i = 0; i < count; i++) {
      if (tmp_it.get_item_class() == ITEM_CLASS_CLOTHING) {
        items_worn.push_back(tmp_it);
      } else {
        inventory.push_back(tmp_it);
      }
    }
  }

  skills = profession->skills;

// The "Durable" trait needs to be set up here.
  if (has_trait(TRAIT_DURABLE)) {
    for (int i = 0; i < HP_PART_MAX; i++) {
      current_hp[i] = 115;
      max_hp[i] = 115;
    }
  }

// Myopic characters get free glasses
  if (has_trait(TRAIT_MYOPIC)) {
    Item_type* glasses = ITEM_TYPES.lookup_name("glasses");
    if (!glasses) {
      debugmsg("No item 'glasses' exists - required for the Myopic trait!");
      return false;
    }
    Item tmp_it(glasses);
    items_worn.push_back(tmp_it);
  }

  return true;
}
Exemple #27
0
// Why put this in a Big Switch?  Why not let bionics have pointers to
// functions, much like monsters and items?
//
// Well, because like diseases, which are also in a Big Switch, bionics don't
// share functions....
void player::activate_bionic(int b, game *g)
{
 bionic bio = my_bionics[b];
 int power_cost = bionics[bio.id].power_cost;
 if (weapon.type->id == itm_bio_claws && bio.id == bio_claws)
  power_cost = 0;
 if (power_level < power_cost) {
  if (my_bionics[b].powered) {
   g->add_msg("Your %s powers down.", bionics[bio.id].name.c_str());
   my_bionics[b].powered = false;
  } else
   g->add_msg("You cannot power your %s", bionics[bio.id].name.c_str());
  return;
 }

 if (my_bionics[b].powered && my_bionics[b].charge > 0) {
// Already-on units just lose a bit of charge
  my_bionics[b].charge--;
 } else {
// Not-on units, or those with zero charge, have to pay the power cost
  if (bionics[bio.id].charge_time > 0) {
   my_bionics[b].powered = true;
   my_bionics[b].charge = bionics[bio.id].charge_time;
  }
  power_level -= power_cost;
 }

 std::string junk;
 std::vector<point> traj;
 std::vector<std::string> good;
 std::vector<std::string> bad;
 WINDOW* w;
 int dirx, diry, t, index;
 unsigned int l;
 item tmp_item;

 switch (bio.id) {
 case bio_painkiller:
  pkill += 6;
  pain -= 2;
  if (pkill > pain)
   pkill = pain;
  break;

 case bio_nanobots:
  healall(4);
  break;

 case bio_resonator:
  g->sound(posx, posy, 30, "VRRRRMP!");
  for (int i = posx - 1; i <= posx + 1; i++) {
   for (int j = posy - 1; j <= posy + 1; j++) {
    g->m.bash(i, j, 40, junk);
    g->m.bash(i, j, 40, junk);	// Multibash effect, so that doors &c will fall
    g->m.bash(i, j, 40, junk);
    if (g->m.is_destructable(i, j) && rng(1, 10) >= 4)
     g->m.ter(i, j) = t_rubble;
   }
  }
  break;

 case bio_time_freeze:
  moves += 100 * power_level;
  power_level = 0;
  g->add_msg("Your speed suddenly increases!");
  if (one_in(3)) {
   g->add_msg("Your muscles tear with the strain.");
   hurt(g, bp_arms, 0, rng(5, 10));
   hurt(g, bp_arms, 1, rng(5, 10));
   hurt(g, bp_legs, 0, rng(7, 12));
   hurt(g, bp_legs, 1, rng(7, 12));
   hurt(g, bp_torso, 0, rng(5, 15));
  }
  if (one_in(5))
   add_disease(DI_TELEGLOW, rng(50, 400), g);
  break;

 case bio_teleport:
  g->teleport();
  add_disease(DI_TELEGLOW, 300, g);
  break;

// TODO: More stuff here (and bio_blood_filter)
 case bio_blood_anal:
  w = newwin(20, 40, 3, 10);
  wborder(w, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX,
             LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX );
  if (has_disease(DI_FUNGUS))
   bad.push_back("Fungal Parasite");
  if (has_disease(DI_DERMATIK))
   bad.push_back("Insect Parasite");
  if (has_disease(DI_POISON))
   bad.push_back("Poison");
  if (radiation > 0)
   bad.push_back("Irradiated");
  if (has_disease(DI_PKILL1))
   good.push_back("Minor Painkiller");
  if (has_disease(DI_PKILL2))
   good.push_back("Moderate Painkiller");
  if (has_disease(DI_PKILL3))
   good.push_back("Heavy Painkiller");
  if (has_disease(DI_PKILL_L))
   good.push_back("Slow-Release Painkiller");
  if (has_disease(DI_DRUNK))
   good.push_back("Alcohol");
  if (has_disease(DI_CIG))
   good.push_back("Nicotine");
  if (has_disease(DI_HIGH))
   good.push_back("Intoxicant: Other");
  if (has_disease(DI_TOOK_PROZAC))
   good.push_back("Prozac");
  if (has_disease(DI_TOOK_FLUMED))
   good.push_back("Antihistamines");
  if (has_disease(DI_ADRENALINE))
   good.push_back("Adrenaline Spike");
  if (good.size() == 0 && bad.size() == 0)
   mvwprintz(w, 1, 1, c_white, "No effects.");
  else {
   for (unsigned int line = 1; line < 39 && line <= good.size() + bad.size(); line++) {
    if (line <= bad.size())
     mvwprintz(w, line, 1, c_red, bad[line - 1].c_str());
    else
     mvwprintz(w, line, 1, c_green, good[line - 1 - bad.size()].c_str());
   }
  }
  wrefresh(w);
  refresh();
  getch();
  delwin(w);
  break;

 case bio_blood_filter:
  rem_disease(DI_FUNGUS);
  rem_disease(DI_POISON);
  rem_disease(DI_PKILL1);
  rem_disease(DI_PKILL2);
  rem_disease(DI_PKILL3);
  rem_disease(DI_PKILL_L);
  rem_disease(DI_DRUNK);
  rem_disease(DI_CIG);
  rem_disease(DI_HIGH);
  rem_disease(DI_TOOK_PROZAC);
  rem_disease(DI_TOOK_FLUMED);
  rem_disease(DI_ADRENALINE);
  break;

 case bio_evap:
  if (query_yn("Drink directly? Otherwise you will need a container.")) {
   tmp_item = item(g->itypes[itm_water], 0);
   thirst -= 50;
   if (has_trait(PF_GOURMAND) && thirst < -60) {
     g->add_msg("You can't finish it all!");
     thirst = -60;
   } else if (!has_trait(PF_GOURMAND) && thirst < -20) {
     g->add_msg("You can't finish it all!");
     thirst = -20;
   }
  } else {
   t = g->inv("Choose a container:");
   if (i_at(t).type == 0) {
    g->add_msg("You don't have that item!");
    power_level += bionics[bio_evap].power_cost;
   } else if (!i_at(t).is_container()) {
    g->add_msg("That %s isn't a container!", i_at(t).tname().c_str());
    power_level += bionics[bio_evap].power_cost;
   } else {
    it_container *cont = dynamic_cast<it_container*>(i_at(t).type);
    if (i_at(t).volume_contained() + 1 > cont->contains) {
     g->add_msg("There's no space left in your %s.", i_at(t).tname().c_str());
     power_level += bionics[bio_evap].power_cost;
    } else if (!(cont->flags & con_wtight)) {
     g->add_msg("Your %s isn't watertight!", i_at(t).tname().c_str());
     power_level += bionics[bio_evap].power_cost;
    } else {
     g->add_msg("You pour water into your %s.", i_at(t).tname().c_str());
     i_at(t).put_in(item(g->itypes[itm_water], 0));
    }
   }
  }
  break;

 case bio_lighter:
  g->draw();
  mvprintw(0, 0, "Torch in which direction?");
  get_direction(g, dirx, diry, input());
  if (dirx == -2) {
   g->add_msg("Invalid direction.");
   power_level += bionics[bio_lighter].power_cost;
   return;
  }
  dirx += posx;
  diry += posy;
  if (!g->m.add_field(g, dirx, diry, fd_fire, 1))	// Unsuccessful.
   g->add_msg("You can't light a fire there.");
  break;

 case bio_claws:
  if (weapon.type->id == itm_bio_claws) {
   g->add_msg("You withdraw your claws.");
   weapon = ret_null;
  } else if (weapon.type->id != 0) {
   g->add_msg("Your claws extend, forcing you to drop your %s.",
              weapon.tname().c_str());
   g->m.add_item(posx, posy, weapon);
   weapon = item(g->itypes[itm_bio_claws], 0);
   weapon.invlet = '#';
  } else {
   g->add_msg("Your claws extend!");
   weapon = item(g->itypes[itm_bio_claws], 0);
   weapon.invlet = '#';
  }
  break;

 case bio_blaster:
  tmp_item = weapon;
  weapon = item(g->itypes[itm_bio_blaster], 0);
  weapon.curammo = dynamic_cast<it_ammo*>(g->itypes[itm_bio_fusion]);
  weapon.charges = 1;
  g->refresh_all();
  g->plfire(false);
  weapon = tmp_item;
  break;

 case bio_laser:
  tmp_item = weapon;
  weapon = item(g->itypes[itm_v29], 0);
  weapon.curammo = dynamic_cast<it_ammo*>(g->itypes[itm_laser_pack]);
  weapon.charges = 1;
  g->refresh_all();
  g->plfire(false);
  weapon = tmp_item;
  break;

 case bio_emp:
  g->draw();
  mvprintw(0, 0, "Fire EMP in which direction?");
  get_direction(g, dirx, diry, input());
  if (dirx == -2) {
   g->add_msg("Invalid direction.");
   power_level += bionics[bio_emp].power_cost;
   return;
  }
  dirx += posx;
  diry += posy;
  g->emp_blast(dirx, diry);
  break;

 case bio_hydraulics:
  g->add_msg("Your muscles hiss as hydraulic strength fills them!");
  break;

 case bio_water_extractor:
  for (unsigned int i = 0; i < g->m.i_at(posx, posy).size(); i++) {
   item tmp = g->m.i_at(posx, posy)[i];
   if (tmp.type->id == itm_corpse && query_yn("Extract water from the %s",
                                              tmp.tname().c_str())) {
    i = g->m.i_at(posx, posy).size() + 1;	// Loop is finished
    t = g->inv("Choose a container:");
    if (i_at(t).type == 0) {
     g->add_msg("You don't have that item!");
     power_level += bionics[bio_water_extractor].power_cost;
    } else if (!i_at(t).is_container()) {
     g->add_msg("That %s isn't a container!", i_at(t).tname().c_str());
     power_level += bionics[bio_water_extractor].power_cost;
    } else {
     it_container *cont = dynamic_cast<it_container*>(i_at(t).type);
     if (i_at(t).volume_contained() + 1 > cont->contains) {
      g->add_msg("There's no space left in your %s.", i_at(t).tname().c_str());
      power_level += bionics[bio_water_extractor].power_cost;
     } else {
      g->add_msg("You pour water into your %s.", i_at(t).tname().c_str());
      i_at(t).put_in(item(g->itypes[itm_water], 0));
     }
    }
   }
   if (i == g->m.i_at(posx, posy).size() - 1)	// We never chose a corpse
    power_level += bionics[bio_water_extractor].power_cost;
  }
  break;

 case bio_magnet:
  for (int i = posx - 10; i <= posx + 10; i++) {
   for (int j = posy - 10; j <= posy + 10; j++) {
    if (g->m.i_at(i, j).size() > 0) {
     if (g->m.sees(i, j, posx, posy, -1, t))
      traj = line_to(i, j, posx, posy, t);
     else
      traj = line_to(i, j, posx, posy, 0);
    }
    traj.insert(traj.begin(), point(i, j));
    for (unsigned int k = 0; k < g->m.i_at(i, j).size(); k++) {
     if (g->m.i_at(i, j)[k].made_of(IRON) || g->m.i_at(i, j)[k].made_of(STEEL)){
      tmp_item = g->m.i_at(i, j)[k];
      g->m.i_rem(i, j, k);
      for (l = 0; l < traj.size(); l++) {
       index = g->mon_at(traj[l].x, traj[l].y);
       if (index != -1) {
        if (g->z[index].hurt(tmp_item.weight() * 2))
         g->kill_mon(index, true);
        g->m.add_item(traj[l].x, traj[l].y, tmp_item);
        l = traj.size() + 1;
       } else if (l > 0 && g->m.move_cost(traj[l].x, traj[l].y) == 0) {
        g->m.bash(traj[l].x, traj[l].y, tmp_item.weight() * 2, junk);
        g->sound(traj[l].x, traj[l].y, 12, junk);
        if (g->m.move_cost(traj[l].x, traj[l].y) == 0) {
         g->m.add_item(traj[l - 1].x, traj[l - 1].y, tmp_item);
         l = traj.size() + 1;
        }
       }
      }
      if (l == traj.size())
       g->m.add_item(posx, posy, tmp_item);
     }
    }
   }
  }
  break;

 case bio_lockpick:
  g->draw();
  mvprintw(0, 0, "Unlock in which direction?");
  get_direction(g, dirx, diry, input());
  if (dirx == -2) {
   g->add_msg("Invalid direction.");
   power_level += bionics[bio_lockpick].power_cost;
   return;
  }
  dirx += posx;
  diry += posy;
  if (g->m.ter(dirx, diry) == t_door_locked) {
   moves -= 40;
   g->add_msg("You unlock the door.");
   g->m.ter(dirx, diry) = t_door_c;
  } else
   g->add_msg("You can't unlock that %s.", g->m.tername(dirx, diry).c_str());
  break;

  // Unused enums added for completeness.
 default:
  break;
 }
}
Exemple #28
0
void game::show_options()
{
    WINDOW* w_options_border = newwin(25, 80, (TERMY > 25) ? (TERMY-25)/2 : 0, (TERMX > 80) ? (TERMX-80)/2 : 0);
    WINDOW* w_options = newwin(23, 78, 1 + ((TERMY > 25) ? (TERMY-25)/2 : 0), 1 + ((TERMX > 80) ? (TERMX-80)/2 : 0));

    int offset = 1;
    const int MAX_LINE = 22;
    int line = 0;
    char ch = ' ';
    bool changed_options = false;
    bool needs_refresh = true;
    wborder(w_options_border, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX,
            LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX);
    mvwprintz(w_options_border, 0, 36, c_ltred, " OPTIONS ");
    wrefresh(w_options_border);
    do {
// TODO: change instructions
        if(needs_refresh) {
            werase(w_options);
            mvwprintz(w_options, 0, 40, c_white, "Use up/down keys to scroll through");
            mvwprintz(w_options, 1, 40, c_white, "available options.");
            mvwprintz(w_options, 2, 40, c_white, "Use left/right keys to toggle.");
            mvwprintz(w_options, 3, 40, c_white, "Press ESC or q to return.             ");
// highlight options for option descriptions
            std::string tmp = option_desc(option_key(offset + line));
            std::string out;
            size_t pos;
            int displayline = 5;
            do {
                pos = tmp.find_first_of('\n');
                out = tmp.substr(0, pos);
                mvwprintz(w_options, displayline, 40, c_white, out.c_str());
                tmp = tmp.substr(pos + 1);
                displayline++;
            } while(pos != std::string::npos && displayline < 12);
            needs_refresh = false;
        }

// Clear the lines
        for(int i = 0; i < 25; i++) {
            mvwprintz(w_options, i, 0, c_black, "                                        ");
        }
        int valid_option_count = 0;

// display options
        for(int i = 0; i < 26 && offset + i < NUM_OPTION_KEYS; i++) {
            valid_option_count++;
            mvwprintz(w_options, i, 0, c_white, "%s: ",
                      option_name(option_key(offset + i)).c_str());

            if(option_is_bool(option_key(offset + i))) {
                bool on = OPTIONS[ option_key(offset + i) ];
                if(i == line) {
                    mvwprintz(w_options, i, 30, hilite(c_ltcyan), (on ? "True" : "False"));
                } else {
                    mvwprintz(w_options, i, 30, (on ? c_ltgreen : c_ltred), (on ? "True" : "False"));
                }
            } else {
                char option_val = OPTIONS[ option_key(offset + i) ];
                if(i == line) {
                    mvwprintz(w_options, i, 30, hilite(c_ltcyan), "%d", option_val);
                } else {
                    mvwprintz(w_options, i, 30, c_ltgreen, "%d", option_val);
                }
            }
        }
        wrefresh(w_options);
        ch = input();
        needs_refresh = true;

        switch(ch) {
// move up and down
        case 'j':
            line++;
            if(line > MAX_LINE/2 && offset + 1 < NUM_OPTION_KEYS - MAX_LINE) {
                ++offset;
                --line;
            }
            if(line > MAX_LINE) {
                line = 0;
                offset = 1;
            }
            break;
        case 'k':
            line--;
            if(line < MAX_LINE/2 && offset > 1) {
                --offset;
                ++line;
            }
            if(line < 0) {
                line = MAX_LINE;
                offset = NUM_OPTION_KEYS - MAX_LINE - 1;
            }
            break;
// toggle options with left/right keys
        case 'h':
            if(option_is_bool(option_key(offset + line))) {
                OPTIONS[ option_key(offset + line) ] = !(OPTIONS[ option_key(offset + line) ]);
            } else {
                OPTIONS[ option_key(offset + line) ]--;
                if((OPTIONS[ option_key(offset + line) ]) < option_min_options(option_key(offset + line))) {
                    OPTIONS[ option_key(offset + line) ] = option_max_options(option_key(offset + line)) - 1;
                }
            }
            changed_options = true;
            break;
        case 'l':
            if(option_is_bool(option_key(offset + line))) {
                OPTIONS[ option_key(offset + line) ] = !(OPTIONS[ option_key(offset + line) ]);
            } else {
                OPTIONS[ option_key(offset + line) ]++;
                if((OPTIONS[ option_key(offset + line) ]) >= option_max_options(option_key(offset + line))) {
                    OPTIONS[ option_key(offset + line) ] = option_min_options(option_key(offset + line));
                }
            }
            changed_options = true;
            break;
        }
        if(changed_options && OPTIONS[OPT_SEASON_LENGTH] < 1) { OPTIONS[OPT_SEASON_LENGTH]=option_max_options(OPT_SEASON_LENGTH)-1; }
    } while(ch != 'q' && ch != 'Q' && ch != KEY_ESCAPE);

    if(changed_options && query_yn("Save changes?")) {
        save_options();
        trigdist=(OPTIONS[OPT_CIRCLEDIST] ? true : false);
    }
    werase(w_options);
}
void show_auto_pickup()
{
    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[3] = true;
    mapLines[50] = true;
    mapLines[54] = true;

    const int iTotalCols = mapLines.size()-1;

    WINDOW* w_auto_pickup_options = newwin(FULL_SCREEN_HEIGHT/2, FULL_SCREEN_WIDTH/2, iOffsetY + (FULL_SCREEN_HEIGHT/2)/2, iOffsetX + (FULL_SCREEN_WIDTH/2)/2);
    WINDOW* w_auto_pickup_help = newwin((FULL_SCREEN_HEIGHT/2)-2, FULL_SCREEN_WIDTH * 3/4, 8 + iOffsetY + (FULL_SCREEN_HEIGHT/2)/2, iOffsetX + 19/2);

    WINDOW* w_auto_pickup_border = newwin(FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, iOffsetY, iOffsetX);
    WINDOW* w_auto_pickup_header = newwin(iHeaderHeight, FULL_SCREEN_WIDTH - 2, 1 + iOffsetY, 1 + iOffsetX);
    WINDOW* w_auto_pickup = newwin(iContentHeight, FULL_SCREEN_WIDTH - 2, iHeaderHeight + 1 + iOffsetY, 1 + iOffsetX);

    wborder(w_auto_pickup_border, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX, LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX);
    mvwputch(w_auto_pickup_border, 3,  0, c_ltgray, LINE_XXXO); // |-
    mvwputch(w_auto_pickup_border, 3, 79, c_ltgray, LINE_XOXX); // -|

    for (std::map<int, bool>::iterator iter = mapLines.begin(); iter != mapLines.end(); ++iter) {
        mvwputch(w_auto_pickup_border, FULL_SCREEN_HEIGHT-1, iter->first + 1, c_ltgray, LINE_XXOX); // _|_
    }

    mvwprintz(w_auto_pickup_border, 0, 29, c_ltred, _(" AUTO PICKUP MANAGER "));
    wrefresh(w_auto_pickup_border);

    int tmpx = 0;
    tmpx += shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<A>dd"))+2;
    tmpx += shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<R>emove"))+2;
    tmpx += shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<C>opy"))+2;
    tmpx += shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<M>ove"))+2;
    tmpx += shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<E>nable"))+2;
    tmpx += shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<D>isable"))+2;
    shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<T>est"));
    tmpx = 0;
    tmpx += shortcut_print(w_auto_pickup_header, 1, tmpx, c_white, c_ltgreen, _("<+-> Move up/down"))+2;
    tmpx += shortcut_print(w_auto_pickup_header, 1, tmpx, c_white, c_ltgreen, _("<Enter>-Edit"))+2;
    shortcut_print(w_auto_pickup_header, 1, tmpx, c_white, c_ltgreen, _("<Tab>-Switch Page"));

    for (int i = 0; i < 78; i++) {
        if (mapLines[i]) {
            mvwputch(w_auto_pickup_header, 2, i, c_ltgray, LINE_OXXX);
            mvwputch(w_auto_pickup_header, 3, i, c_ltgray, LINE_XOXO);
        } else {
            mvwputch(w_auto_pickup_header, 2, i, c_ltgray, LINE_OXOX); // Draw line under header
        }
    }

    mvwprintz(w_auto_pickup_header, 3, 0, c_white, "#");
    mvwprintz(w_auto_pickup_header, 3, 7, c_white, _("Rules"));
    mvwprintz(w_auto_pickup_header, 3, 51, c_white, _("I/E"));

    wrefresh(w_auto_pickup_header);

    int iCurrentPage = 1;
    int iCurrentLine = 0;
    int iCurrentCol = 1;
    int iStartPos = 0;
    bool bStuffChanged = false;
    char ch = ' ';

    std::stringstream sTemp;

    do {
        int locx = 17;
        locx += shortcut_print(w_auto_pickup_header, 2, locx, c_white, (iCurrentPage == 1) ? hilite(c_white) : c_white, _("[<Global>]"))+1;
        shortcut_print(w_auto_pickup_header, 2, locx, c_white, (iCurrentPage == 2) ? hilite(c_white) : c_white, _("[<Character>]"));

        wrefresh(w_auto_pickup_header);

        // Clear the lines
        for (int i = 0; i < iContentHeight; i++) {
            for (int j = 0; j < 79; j++) {
                if (mapLines[j]) {
                    mvwputch(w_auto_pickup, i, j, c_ltgray, LINE_XOXO);
                } else {
                    mvwputch(w_auto_pickup, i, j, c_black, ' ');
                }
            }
        }

        if (iCurrentPage == 1 || iCurrentPage == 2) {
            if (iCurrentPage == 2 && g->u.name == "") {
                vAutoPickupRules[2].clear();
                mvwprintz(w_auto_pickup, 8, 15, c_white, _("Please load a character first to use this page!"));
            }

            //Draw Scrollbar
            draw_scrollbar(w_auto_pickup_border, iCurrentLine, iContentHeight, vAutoPickupRules[iCurrentPage].size(), 5);

            calcStartPos(iStartPos, iCurrentLine, iContentHeight, vAutoPickupRules[iCurrentPage].size());

            // display auto pickup
            for (int i = iStartPos; i < vAutoPickupRules[iCurrentPage].size(); i++) {
                if (i >= iStartPos && i < iStartPos + ((iContentHeight > vAutoPickupRules[iCurrentPage].size()) ? vAutoPickupRules[iCurrentPage].size() : iContentHeight)) {
                    nc_color cLineColor = (vAutoPickupRules[iCurrentPage][i].bActive) ? c_white : c_ltgray;

                    sTemp.str("");
                    sTemp << i + 1;
                    mvwprintz(w_auto_pickup, i - iStartPos, 0, cLineColor, sTemp.str().c_str());
                    mvwprintz(w_auto_pickup, i - iStartPos, 4, cLineColor, "");

                    if (iCurrentLine == i) {
                        wprintz(w_auto_pickup, c_yellow, ">> ");
                    } else {
                        wprintz(w_auto_pickup, c_yellow, "   ");
                    }

                    wprintz(w_auto_pickup, (iCurrentLine == i && iCurrentCol == 1) ? hilite(cLineColor) : cLineColor, "%s", ((vAutoPickupRules[iCurrentPage][i].sRule == "") ? _("<empty rule>") : vAutoPickupRules[iCurrentPage][i].sRule).c_str());

                    mvwprintz(w_auto_pickup, i - iStartPos, 52, (iCurrentLine == i && iCurrentCol == 2) ? hilite(cLineColor) : cLineColor, "%s", ((vAutoPickupRules[iCurrentPage][i].bExclude) ? rm_prefix(_("<Exclude>E")).c_str() : rm_prefix(_("<Include>I")).c_str()));
                }
            }

            wrefresh(w_auto_pickup);

        } else if (iCurrentPage == 3) {
            wborder(w_auto_pickup_options, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX, LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX);

            mvwprintz(w_auto_pickup_options, 5, 10, c_white, _("Under construction!"));

            wrefresh(w_auto_pickup);
            wrefresh(w_auto_pickup_options);
        }

        ch = (char)input();

        if (iCurrentPage == 3) {
            switch(ch) {
                case '\t': //Switch to next Page
                    iCurrentPage++;
                    if (iCurrentPage > 3) {
                        iCurrentPage = 1;
                        iCurrentLine = 0;
                    }
                    break;
            }
        } else if (iCurrentPage == 1 || iCurrentPage == 2) {
            if (iCurrentPage == 2 && g->u.name == "" && ch != '\t') {
                //Only allow loaded games to use the char sheet
            } else if (vAutoPickupRules[iCurrentPage].size() > 0 || ch == 'a' || ch == '\t') {
                switch(ch) {
                    case 'j': //move down
                        iCurrentLine++;
                        iCurrentCol = 1;
                        if (iCurrentLine >= vAutoPickupRules[iCurrentPage].size()) {
                            iCurrentLine = 0;
                        }
                        break;
                    case 'k': //move up
                        iCurrentLine--;
                        iCurrentCol = 1;
                        if (iCurrentLine < 0) {
                            iCurrentLine = vAutoPickupRules[iCurrentPage].size()-1;
                        }
                        break;
                    case 'a': //add new rule
                    case 'A':
                        bStuffChanged = true;
                        vAutoPickupRules[iCurrentPage].push_back(cPickupRules("", true, false));
                        iCurrentLine = vAutoPickupRules[iCurrentPage].size()-1;
                        break;
                    case 'r': //remove rule
                    case 'R':
                        bStuffChanged = true;
                        vAutoPickupRules[iCurrentPage].erase(vAutoPickupRules[iCurrentPage].begin() + iCurrentLine);
                        if (iCurrentLine > vAutoPickupRules[iCurrentPage].size()-1) {
                            iCurrentLine--;
                        }
                        break;
                    case 'c': //copy rule
                    case 'C':
                        bStuffChanged = true;
                        vAutoPickupRules[iCurrentPage].push_back(cPickupRules(vAutoPickupRules[iCurrentPage][iCurrentLine].sRule, vAutoPickupRules[iCurrentPage][iCurrentLine].bActive, vAutoPickupRules[iCurrentPage][iCurrentLine].bExclude));
                        iCurrentLine = vAutoPickupRules[iCurrentPage].size()-1;
                        break;
                    case 'm': //move rule global <-> character
                    case 'M':
                        if ((iCurrentPage == 1 && g->u.name != "") || iCurrentPage == 2) {
                            bStuffChanged = true;
                            //copy over
                            vAutoPickupRules[(iCurrentPage == 1) ? 2 : 1].push_back(cPickupRules(vAutoPickupRules[iCurrentPage][iCurrentLine].sRule, vAutoPickupRules[iCurrentPage][iCurrentLine].bActive, vAutoPickupRules[iCurrentPage][iCurrentLine].bExclude));

                            //remove old
                            vAutoPickupRules[iCurrentPage].erase(vAutoPickupRules[iCurrentPage].begin() + iCurrentLine);
                            iCurrentLine = vAutoPickupRules[(iCurrentPage == 1) ? 2 : 1].size()-1;
                            iCurrentPage = (iCurrentPage == 1) ? 2 : 1;
                        }
                        break;
                    case '\t': //Switch to next Page
                        iCurrentPage++;
                        if (iCurrentPage > 2) {
                            iCurrentPage = 1;
                            iCurrentLine = 0;
                        }
                        break;
                    case '\n': //Edit Col in current line
                        bStuffChanged = true;
                        if (iCurrentCol == 1) {
                            fold_and_print(w_auto_pickup_help, 1, 1, 999, c_white,
                                _(
                                "* is used as a Wildcard. A few Examples:\n"
                                "\n"
                                "wood arrow    matches the itemname exactly\n"
                                "wood ar*      matches items beginning with wood ar\n"
                                "*rrow         matches items ending with rrow\n"
                                "*avy fle*fi*arrow     multible * are allowed\n"
                                "heAVY*woOD*arrOW      case insesitive search\n"
                                "")
                            );

                            wborder(w_auto_pickup_help, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX, LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX);
                            wrefresh(w_auto_pickup_help);
                            vAutoPickupRules[iCurrentPage][iCurrentLine].sRule = trim_rule(string_input_popup(_("Pickup Rule:"), 30, vAutoPickupRules[iCurrentPage][iCurrentLine].sRule));
                        } else if (iCurrentCol == 2) {
                            vAutoPickupRules[iCurrentPage][iCurrentLine].bExclude = !vAutoPickupRules[iCurrentPage][iCurrentLine].bExclude;
                        }
                        break;
                    case 'e': //enable rule
                    case 'E':
                        bStuffChanged = true;
                        vAutoPickupRules[iCurrentPage][iCurrentLine].bActive = true;
                        break;
                    case 'd': //disable rule
                    case 'D':
                        bStuffChanged = true;
                        vAutoPickupRules[iCurrentPage][iCurrentLine].bActive = false;
                        break;
                    case 'h': //move left
                        iCurrentCol--;
                        if (iCurrentCol < 1) {
                            iCurrentCol = iTotalCols;
                        }
                        break;
                    case 'l': //move right
                        iCurrentCol++;
                        if (iCurrentCol > iTotalCols) {
                            iCurrentCol = 1;
                        }
                        break;
                    case '+': //move rule up
                        bStuffChanged = true;
                        if (iCurrentLine < vAutoPickupRules[iCurrentPage].size()-1) {
                            std::swap(vAutoPickupRules[iCurrentPage][iCurrentLine], vAutoPickupRules[iCurrentPage][iCurrentLine+1]);
                            iCurrentLine++;
                            iCurrentCol = 1;
                        }
                        break;
                    case '-': //move rule down
                        bStuffChanged = true;
                        if (iCurrentLine > 0) {
                            std::swap(vAutoPickupRules[iCurrentPage][iCurrentLine], vAutoPickupRules[iCurrentPage][iCurrentLine-1]);
                            iCurrentLine--;
                            iCurrentCol = 1;
                        }
                        break;
                    case 't': //test rule
                    case 'T':
                        test_pattern(iCurrentPage, iCurrentLine);
                        break;
                }
            }
        }
    } while(ch != 'q' && ch != 'Q' && ch != KEY_ESCAPE);

    if (bStuffChanged) {
        if(query_yn(_("Save changes?"))) {
            save_auto_pickup(false);

            if (g->u.name != "") {
                save_auto_pickup(true);
            }
        } else {
            save_reset_changes(true);
        }
    }

    werase(w_auto_pickup);
    werase(w_auto_pickup_border);
    werase(w_auto_pickup_header);
    werase(w_auto_pickup_options);
    werase(w_auto_pickup_help);
}
Exemple #30
0
void input_context::display_help()
{
    inp_mngr.set_timeout(-1);
    // Shamelessly stolen from help.cpp
    WINDOW *w_help = newwin(FULL_SCREEN_HEIGHT - 2, FULL_SCREEN_WIDTH - 2,
                            1 + (int)((TERMY > FULL_SCREEN_HEIGHT) ? (TERMY - FULL_SCREEN_HEIGHT) / 2 : 0),
                            1 + (int)((TERMX > FULL_SCREEN_WIDTH) ? (TERMX - FULL_SCREEN_WIDTH) / 2 : 0));

    // has the user changed something?
    bool changed = false;
    // keybindings before the user changed anything.
    input_manager::t_action_contexts old_action_contexts(inp_mngr.action_contexts);
    // current status: adding/removing/showing keybindings
    enum { s_remove, s_add, s_add_global, s_show } status = s_show;
    // copy of registered_actions, but without the ANY_INPUT and COORDINATE, which should not be shown
    std::vector<std::string> org_registered_actions(registered_actions);
    std::vector<std::string>::iterator any_input = std::find(org_registered_actions.begin(),
            org_registered_actions.end(), ANY_INPUT);
    if (any_input != org_registered_actions.end()) {
        org_registered_actions.erase(any_input);
    }
    std::vector<std::string>::iterator coordinate = std::find(org_registered_actions.begin(),
            org_registered_actions.end(), COORDINATE);
    if (coordinate != org_registered_actions.end()) {
        org_registered_actions.erase(coordinate);
    }

    // colors of the keybindings
    static const nc_color global_key = c_ltgray;
    static const nc_color local_key = c_ltgreen;
    static const nc_color unbound_key = c_ltred;
    // (vertical) scroll offset
    size_t scroll_offset = 0;
    // height of the area usable for display of keybindings, excludes headers & borders
    const size_t display_height = FULL_SCREEN_HEIGHT - 9 - 2; // -2 for the border
    // width of the legend
    const size_t legwidth = FULL_SCREEN_WIDTH - 4 - 2;
    // keybindings help
    std::ostringstream legend;
    legend << "<color_" << string_from_color(unbound_key) << ">" << _("Unbound keys") << "</color>\n";
    legend << "<color_" << string_from_color(local_key) << ">" <<
           _("Keybinding active only on this screen") << "</color>\n";
    legend << "<color_" << string_from_color(global_key) << ">" << _("Keybinding active globally") <<
           "</color>\n";
    legend << _("Press - to remove keybinding\nPress + to add local keybinding\nPress = to add global keybinding\n");

    input_context ctxt("HELP_KEYBINDINGS");
    ctxt.register_action("UP", _("Scroll up"));
    ctxt.register_action("DOWN", _("Scroll down"));
    ctxt.register_action("PAGE_DOWN");
    ctxt.register_action("PAGE_UP");
    ctxt.register_action("REMOVE");
    ctxt.register_action("ADD_LOCAL");
    ctxt.register_action("ADD_GLOBAL");
    ctxt.register_action("QUIT");
    ctxt.register_action("ANY_INPUT");

    if (category != "HELP_KEYBINDINGS") {
        // avoiding inception!
        ctxt.register_action("HELP_KEYBINDINGS");
    }

    std::string hotkeys = ctxt.get_available_single_char_hotkeys(display_help_hotkeys);

    while(true) {
        werase(w_help);
        draw_border(w_help);
        draw_scrollbar(w_help, scroll_offset, display_height, org_registered_actions.size() - display_height, 8);
        mvwprintz(w_help, 0, (FULL_SCREEN_WIDTH - utf8_width(_("Keybindings"))) / 2 - 1,
                  c_ltred, " %s ", _("Keybindings"));

        fold_and_print(w_help, 1, 2, legwidth, c_white, legend.str());

        for (size_t i = 0; i + scroll_offset < org_registered_actions.size() && i < display_height; i++) {
            const std::string &action_id = org_registered_actions[i + scroll_offset];

            bool overwrite_default;
            const action_attributes &attributes = inp_mngr.get_action_attributes(action_id, category,
                                                  &overwrite_default);

            char invlet;
            if (i < hotkeys.size()) {
                invlet = hotkeys[i];
            } else {
                invlet = ' ';
            }

            if (status == s_add_global && overwrite_default) {
                // We're trying to add a global, but this action has a local
                // defined, so gray out the invlet.
                mvwprintz(w_help, i + 8, 2, c_dkgray, "%c ", invlet);
            } else if (status == s_add || status == s_add_global) {
                mvwprintz(w_help, i + 8, 2, c_blue, "%c ", invlet);
            } else if (status == s_remove) {
                mvwprintz(w_help, i + 8, 2, c_blue, "%c ", invlet);
            } else {
                mvwprintz(w_help, i + 8, 2, c_blue, "  ");
            }
            nc_color col;
            if (attributes.input_events.empty()) {
                col = unbound_key;
            } else if (overwrite_default) {
                col = local_key;
            } else {
                col = global_key;
            }
            mvwprintz(w_help, i + 8, 4, col, "%s: ", get_action_name(action_id).c_str());
            mvwprintz(w_help, i + 8, 52, col, "%s", get_desc(action_id).c_str());
        }
        wrefresh(w_help);
        refresh();

        // In addition to the modifiable hotkeys, we also check for hardcoded
        // keys, e.g. '+', '-', '=', in order to prevent the user from
        // entering an unrecoverable state.
        const std::string action = ctxt.handle_input();
        const long raw_input_char = ctxt.get_raw_input().get_first_input();
        if (action == "ADD_LOCAL" || raw_input_char == '+') {
            status = s_add;
        } else if (action == "ADD_GLOBAL" || raw_input_char == '=') {
            status = s_add_global;
        } else if (action == "REMOVE" || raw_input_char == '-') {
            status = s_remove;
        } else if (action == "ANY_INPUT") {
            const size_t hotkey_index = hotkeys.find_first_of(raw_input_char);
            if (status == s_show || hotkey_index == std::string::npos ) {
                continue;
            }
            const size_t action_index = hotkey_index + scroll_offset;
            if( action_index >= org_registered_actions.size() ) {
                continue;
            }
            const std::string &action_id = org_registered_actions[action_index];

            // Check if this entry is local or global.
            bool is_local = false;
            inp_mngr.get_action_attributes(action_id, category, &is_local);
            const std::string name = get_action_name(action_id);


            if (status == s_remove && (!OPTIONS["QUERY_KEYBIND_REMOVAL"] ||
                                       query_yn(_("Clear keys for %s?"), name.c_str()))) {

                // If it's global, reset the global actions.
                std::string category_to_access = category;
                if (!is_local) {
                    category_to_access = default_context_id;
                }

                inp_mngr.remove_input_for_action(action_id, category_to_access);
                changed = true;
            } else if (status == s_add_global && is_local) {
                // Disallow adding global actions to an action that already has a local defined.
                popup(_("There are already local keybindings defined for this action, please remove them first."));
            } else if (status == s_add || status == s_add_global) {
                const long newbind = popup_getkey(_("New key for %s:"), name.c_str());
                const input_event new_event(newbind, CATA_INPUT_KEYBOARD);
                const std::string conflicts = get_conflicts(new_event);
                const bool has_conflicts = !conflicts.empty();
                bool resolve_conflicts = false;

                if (has_conflicts) {
                    resolve_conflicts = query_yn(
                                            _("This key conflicts with %s. Remove this key from the conflicting command(s), and continue?"),
                                            conflicts.c_str());
                }

                if (!has_conflicts || resolve_conflicts) {
                    if (resolve_conflicts) {
                        clear_conflicting_keybindings(new_event);
                    }

                    // We might be adding a local or global action.
                    std::string category_to_access = category;
                    if (status == s_add_global) {
                        category_to_access = default_context_id;
                    }

                    inp_mngr.add_input_for_action(action_id, category_to_access, new_event);
                    changed = true;
                }
            }
            status = s_show;
        } else if (action == "DOWN") {
            if (scroll_offset < org_registered_actions.size() - display_height) {
                scroll_offset++;
            }
        } else if (action == "UP") {
            if (scroll_offset > 0) {
                scroll_offset--;
            }
        } else if (action == "PAGE_DOWN") {
            if( scroll_offset + display_height < org_registered_actions.size() ) {
                scroll_offset += std::min(display_height, org_registered_actions.size() -
                                          display_height - scroll_offset);
            } else if( org_registered_actions.size() > display_height ) {
                scroll_offset = 0;
            }
        } else if( action == "PAGE_UP" ) {
            if( scroll_offset >= display_height ) {
                scroll_offset -= display_height;
            } else if( scroll_offset > 0 ) {
                scroll_offset = 0;
            } else if( org_registered_actions.size() > display_height ) {
                scroll_offset = org_registered_actions.size() - display_height;
            }
        } else if (action == "QUIT") {
            if (status != s_show) {
                status = s_show;
            } else {
                break;
            }
        } else if (action == "HELP_KEYBINDINGS") {
            // update available hotkeys in case they've changed
            hotkeys = ctxt.get_available_single_char_hotkeys(display_help_hotkeys);
        }
    }

    if (changed && query_yn(_("Save changes?"))) {
        try {
            inp_mngr.save();
        } catch(std::exception &err) {
            popup(_("saving keybindings failed: %s"), err.what());
        } catch(std::string &err) {
            popup(_("saving keybindings failed: %s"), err.c_str());
        }
    } else if(changed) {
        inp_mngr.action_contexts.swap(old_action_contexts);
    }
    werase(w_help);
    wrefresh(w_help);
    delwin(w_help);
}