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 );
    }

    std::vector<std::string> options;
    options.push_back( _( "Yes" ) );
    options.push_back( _( "No" ) );

    // We NEED a copy.
    const std::string str = ss.str();
    int selection = menu_vec( true, str.c_str(), options );
    return selection == 1;
}
Beispiel #2
0
void consume_tools(game *g, std::vector<component> tools)
{
 bool found_nocharge = false;
 inventory map_inv;
 map_inv.form_from_map(g, point(g->u.posx, g->u.posy), PICKUP_RANGE);
 std::vector<component> player_has;
 std::vector<component> map_has;
// Use charges of any tools that require charges used
 for (int i = 0; i < tools.size() && !found_nocharge; i++) {
  itype_id type = tools[i].type;
  if (tools[i].count > 0) {
   int count = tools[i].count;
   if (g->u.has_charges(type, count))
    player_has.push_back(tools[i]);
   if (map_inv.has_charges(type, count))
    map_has.push_back(tools[i]);
  } else if (g->u.has_amount(type, 1) || map_inv.has_amount(type, 1))
   found_nocharge = true;
 }
 if (found_nocharge)
  return; // Default to using a tool that doesn't require charges

 if (player_has.size() == 1 && map_has.size() == 0)
  g->u.use_charges(player_has[0].type, player_has[0].count);
 else if (map_has.size() == 1 && player_has.size() == 0)
  g->m.use_charges(point(g->u.posx, g->u.posy), PICKUP_RANGE,
                   map_has[0].type, map_has[0].count);
 else { // Variety of options, list them and pick one
// Populate the list
  std::vector<std::string> options;
  for (int i = 0; i < map_has.size(); i++) {
   std::string tmpStr = g->itypes[map_has[i].type]->name + " (nearby)";
   options.push_back(tmpStr);
  }
  for (int i = 0; i < player_has.size(); i++)
   options.push_back(g->itypes[player_has[i].type]->name);

  if (options.size() == 0) // This SHOULD only happen if cooking with a fire,
   return;                 // and the fire goes out.

// Get selection via a popup menu
  int selection = menu_vec("Use which tool?", options) - 1;
  if (selection < map_has.size())
   g->m.use_charges(point(g->u.posx, g->u.posy), PICKUP_RANGE,
                    map_has[selection].type, map_has[selection].count);
  else {
   selection -= map_has.size();
   g->u.use_charges(player_has[selection].type, player_has[selection].count);
  }
 }
}
Beispiel #3
0
void add_transformation(terrain_type* type)
{
  std::vector<std::string> transform_names;
  transform_names.push_back("Cancel");
  for (int i = 1; i < TRANS_MAX; i++) {
    transform_names.push_back( get_transformation_name( transform_type(i) ) );
  }

  int picked = menu_vec("Transformation type:", transform_names);
  if (picked == 0)
    return;

  std::vector<std::string> terrain_names;
  terrain_names.push_back("Cancel");
  for (int i = 1; i < TERRAIN_POOL.size(); i++) {
    terrain_names.push_back(TERRAIN_POOL[i]->name);
  }
  int result = menu_vec("Transform to:", terrain_names);
  if (result == 0)
    return;

  int resistance = menu(
"Amount required:",
"Miniscule",    //  1
"Small",        //  4
"Moderate",     //  9
"Large",        // 16
"Huge",         // 25
"Incredible",   // 36
NULL);
  resistance++;
  resistance *= resistance;

  type->transformations[picked].result = result;
  type->transformations[picked].resistance = resistance;
}
Beispiel #4
0
int menu(const char *mes, ...)
{
 va_list ap;
 va_start(ap, mes);
 char* tmp;
 std::vector<std::string> options;
 bool done = false;
 while (!done) {
  tmp = va_arg(ap, char*);
  if (tmp != NULL) {
   std::string strtmp = tmp;
   options.push_back(strtmp);
  } else
   done = true;
 }
 return (menu_vec(mes, options));
}
Beispiel #5
0
void add_damagetype(element* ele)
{
  if (!ele) {
    return;
  }
  std::vector<std::string> options;
  options.push_back("Cancel");
  for (int i = 1; i < DAMTYPE_MAX; i++) {
    options.push_back( get_damage_type_name( damage_type(i) ) );
  }

  int sel = menu_vec("Damage Type:", options);
  if (sel == 0) {
    return;
  }
  ele->damages.push_back( damage_type(sel) );
}
Beispiel #6
0
void add_transformation(element* ele)
{
  if (!ele) {
    return;
  }
  std::vector<std::string> options;
  options.push_back("Cancel");
  for (int i = 1; i < TRANS_MAX; i++) {
    options.push_back( get_transformation_name( transform_type(i) ) );
  }

  int sel = menu_vec("Transformation:", options);
  if (sel == 0) {
    return;
  }
  ele->transformations.push_back( transform_type(sel) );
}
Beispiel #7
0
void add_flag(terrain_type* type)
{
  std::vector<std::string> flag_names;
  flag_names.push_back("Cancel");
  std::vector<int> flag_indices;
  for (int i = 1; i < TF_MAX; i++) {
    if (!type->flags[i]) {
      flag_names.push_back( get_flag_name( terrain_flag(i) ) );
      flag_indices.push_back(i);
    }
  }

  if (flag_names.size() == 1) {
    popup("All flags are turned on.");
    return;
  }

  int picked = menu_vec("Apply flag:", flag_names);
  if (picked != 0) {
    picked--;
    type->flags[ flag_indices[picked] ] = true;
  }
}
/**
 * Given a vpart id, gives the choice of inventory and nearby items to consume
 * for install/repair/etc. Doesn't use consume_items in crafting.cpp, as it got
 * into weird cases and doesn't consider properties like HP and bigness. The
 * item will be removed by this function.
 * @param vpid The id of the vpart type to look for.
 * @return The item that was consumed.
 */
item consume_vpart_item (game *g, std::string vpid)
{
    std::vector<candidate_vpart> candidates;
    const itype_id itid = vehicle_part_types[vpid].item;
    for (int x = g->u.posx - PICKUP_RANGE; x <= g->u.posx + PICKUP_RANGE; x++)
    {
        for (int y = g->u.posy - PICKUP_RANGE; y <= g->u.posy + PICKUP_RANGE; y++)
        {
            for(int i=0; i < g->m.i_at(x,y).size(); i++)
            {
                item* ith_item = &(g->m.i_at(x,y)[i]);
                if (ith_item->type->id == itid)
                {
                    candidates.push_back (candidate_vpart(x,y,i,*ith_item));
                }
            }
        }
    }

    std::vector<item*> cand_from_inv = g->u.inv.all_items_by_type(itid);
    for (int i=0; i < cand_from_inv.size(); i++)
    {
        item* ith_item = cand_from_inv[i];
        if (ith_item->type->id  == itid)
        {
            candidates.push_back (candidate_vpart(ith_item->invlet,*ith_item));
        }
    }
    if (g->u.weapon.type->id == itid) {
        candidates.push_back (candidate_vpart(-1,g->u.weapon));
    }

    // bug?
    if(candidates.size() == 0)
    {
        debugmsg("part not found");
        return item();
    }

    int selection;
    // no choice?
    if(candidates.size() == 1) {
        selection = 0;
    } else {
        // popup menu!?
        std::vector<std::string> options;
        for(int i=0;i<candidates.size(); i++)
        {
            if(candidates[i].in_inventory)
            {
                if (candidates[i].invlet == -1)
                {
                    options.push_back(candidates[i].vpart_item.tname() + _(" (wielded)"));
                }
                else
                {
                    options.push_back(candidates[i].vpart_item.tname());
                }
            }
            else
            { //nearby.
                options.push_back(candidates[i].vpart_item.tname() + _(" (nearby)"));
            }
        }
        selection = menu_vec(false, _("Use which gizmo?"), options);
        selection -= 1;
    }
    //remove item from inventory. or map.
    if(candidates[selection].in_inventory)
    {
        if(candidates[selection].invlet == -1) //weapon
        {
            g->u.remove_weapon();
        }
        else //non-weapon inventory
        {
            g->u.inv.remove_item_by_letter(candidates[selection].invlet);
        }
    } 
    else
    { //map.
        int x = candidates[selection].mapx;
        int y = candidates[selection].mapy;
        int i = candidates[selection].index;
        g->m.i_rem(x,y,i);
    }
    return candidates[selection].vpart_item;
}
// given vpart type, give a choice from inventory items & nearby items.
// not using consume_items in crafting.cpp
// because it got into weird cases, & it doesn't consider
// characteristics like item hp & bigness.
item consume_vpart_item (game *g, vpart_id vpid){
    std::vector<candidate_vpart> candidates;
    const itype_id itid = vpart_list[vpid].item;
    for (int x = g->u.posx - PICKUP_RANGE; x <= g->u.posx + PICKUP_RANGE; x++)
       for (int y = g->u.posy - PICKUP_RANGE; y <= g->u.posy + PICKUP_RANGE; y++)
          for(int i=0; i < g->m.i_at(x,y).size(); i++){
             item* ith_item = &(g->m.i_at(x,y)[i]);
             if (ith_item->type->id == itid)
                candidates.push_back (candidate_vpart(x,y,i,*ith_item));
          }

    for (int i=0; i<g->u.inv.size(); i++){
       item* ith_item = &(g->u.inv[i]);
       if (ith_item->type->id  == itid)
          candidates.push_back (candidate_vpart(i,*ith_item));
    }
    if (g->u.weapon.type->id == itid) {
       candidates.push_back (candidate_vpart(-1,g->u.weapon));
    }

    // bug?
    if(candidates.size() == 0){
       debugmsg("part not found");
       return item();
    }

    int selection;
    // no choice?
    if(candidates.size() == 1) {
       selection = 0;
    } else {
       // popup menu!?
       std::vector<std::string> options;
       for(int i=0;i<candidates.size(); i++){
          if(candidates[i].in_inventory){
             if (candidates[i].index == -1)
                options.push_back(candidates[i].vpart_item.tname() + " (wielded)");
             else
                options.push_back(candidates[i].vpart_item.tname());
          }
          else { //nearby.
             options.push_back(candidates[i].vpart_item.tname() + " (nearby)");
          }
       }
       selection = menu_vec("Use which gizmo?", options);
       selection -= 1;
    }
    //remove item from inventory. or map.
    if(candidates[selection].in_inventory){
       if(candidates[selection].index == -1) //weapon
          g->u.remove_weapon();
       else //non-weapon inventory
          g->u.inv.remove_item (candidates[selection].index);
    } else { //map.
       int x = candidates[selection].mapx;
       int y = candidates[selection].mapy;
       int i = candidates[selection].index;
       g->m.i_rem(x,y,i);
    }
    return candidates[selection].vpart_item;
    //item ret = candidates[selection].vpart_item;
    //return ret;
}
Beispiel #10
0
void consume_items(game *g, std::vector<component> components)
{
// For each set of components in the recipe, fill you_have with the list of all
// matching ingredients the player has.
 std::vector<component> player_has;
 std::vector<component> map_has;
 std::vector<component> mixed;
 std::vector<component> player_use;
 std::vector<component> map_use;
 std::vector<component> mixed_use;
 inventory map_inv;
 map_inv.form_from_map(g, point(g->u.posx, g->u.posy), PICKUP_RANGE);

 for (int i = 0; i < components.size(); i++) {
  itype_id type = components[i].type;
  int count = abs(components[i].count);
  bool pl = false, mp = false;

  if (g->itypes[type]->count_by_charges() && count > 0) {

   if (g->u.has_charges(type, count)) {
    player_has.push_back(components[i]);
    pl = true;
   }
   if (map_inv.has_charges(type, count)) {
    map_has.push_back(components[i]);
    mp = true;
   }
   if (!pl && !mp && g->u.charges_of(type) + map_inv.charges_of(type) >= count)
    mixed.push_back(components[i]);

  } else { // Counting by units, not charges

   if (g->u.has_amount(type, count)) {
    player_has.push_back(components[i]);
    pl = true;
   }
   if (map_inv.has_amount(type, count)) {
    map_has.push_back(components[i]);
    mp = true;
   }
   if (!pl && !mp && g->u.amount_of(type) + map_inv.amount_of(type) >= count)
    mixed.push_back(components[i]);

  }
 }

 if (player_has.size() + map_has.size() + mixed.size() == 1) { // Only 1 choice

  if (player_has.size() == 1)
   player_use.push_back(player_has[0]);
  else if (map_has.size() == 1)
   map_use.push_back(map_has[0]);
  else
   mixed_use.push_back(mixed[0]);

 } else { // Let the player pick which component they want to use
  std::vector<std::string> options; // List for the menu_vec below
// Populate options with the names of the items
  for (int i = 0; i < map_has.size(); i++) {
   std::string tmpStr = g->itypes[map_has[i].type]->name + " (nearby)";
   options.push_back(tmpStr);
  }
  for (int i = 0; i < player_has.size(); i++)
   options.push_back(g->itypes[player_has[i].type]->name);
  for (int i = 0; i < mixed.size(); i++) {
   std::string tmpStr = g->itypes[mixed[i].type]->name +" (on person & nearby)";
   options.push_back(tmpStr);
  }

  if (options.size() == 0) // This SHOULD only happen if cooking with a fire,
   return;                 // and the fire goes out.

// Get the selection via a menu popup
  int selection = menu_vec("Use which component?", options) - 1;
  if (selection < map_has.size())
   map_use.push_back(map_has[selection]);
  else if (selection < map_has.size() + player_has.size()) {
   selection -= map_has.size();
   player_use.push_back(player_has[selection]);
  } else {
   selection -= map_has.size() + player_has.size();
   mixed_use.push_back(mixed[selection]);
  }
 }

 for (int i = 0; i < player_use.size(); i++) {
  if (g->itypes[player_use[i].type]->count_by_charges() &&
      player_use[i].count > 0)
   g->u.use_charges(player_use[i].type, player_use[i].count);
  else
   g->u.use_amount(player_use[i].type, abs(player_use[i].count),
                   (player_use[i].count < 0));
 }
 for (int i = 0; i < map_use.size(); i++) {
  if (g->itypes[map_use[i].type]->count_by_charges() &&
      map_use[i].count > 0)
   g->m.use_charges(point(g->u.posx, g->u.posy), PICKUP_RANGE,
                    map_use[i].type, map_use[i].count);
  else
   g->m.use_amount(point(g->u.posx, g->u.posy), PICKUP_RANGE,
                   map_use[i].type, abs(map_use[i].count),
                   (map_use[i].count < 0));
 }
 for (int i = 0; i < mixed_use.size(); i++) {
  if (g->itypes[mixed_use[i].type]->count_by_charges() &&
      mixed_use[i].count > 0) {
   int from_map = mixed_use[i].count - g->u.charges_of(mixed_use[i].type);
   g->u.use_charges(mixed_use[i].type, g->u.charges_of(mixed_use[i].type));
   g->m.use_charges(point(g->u.posx, g->u.posy), PICKUP_RANGE,
                    mixed_use[i].type, from_map);
  } else {
   bool in_container = (mixed_use[i].count < 0);
   int from_map = abs(mixed_use[i].count) - g->u.amount_of(mixed_use[i].type);
   g->u.use_amount(mixed_use[i].type, g->u.amount_of(mixed_use[i].type),
                   in_container);
   g->m.use_amount(point(g->u.posx, g->u.posy), PICKUP_RANGE,
                   mixed_use[i].type, from_map, in_container);
  }
 }
}