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