Exemplo n.º 1
1
std::vector<comp_selection<tool_comp>> craft_command::check_tool_components_missing(
                                        const inventory &map_inv ) const
{
    std::vector<comp_selection<tool_comp>> missing;

    for( const auto &tool_sel : tool_selections ) {
        itype_id type = tool_sel.comp.type;
        if( tool_sel.comp.count > 0 ) {
            long count = tool_sel.comp.count * batch_size;
            switch( tool_sel.use_from ) {
                case use_from_player:
                    if( !crafter->has_charges( type, count ) ) {
                        missing.push_back( tool_sel );
                    }
                    break;
                case use_from_map:
                    if( !map_inv.has_charges( type, count ) ) {
                        missing.push_back( tool_sel );
                    }
                    break;
                case use_from_both:
                case use_from_none:
                case cancel:
                    break;
            }
        } else if( !crafter->has_amount( type, 1 ) && !map_inv.has_tools( type, 1 ) ) {
            missing.push_back( tool_sel );
        }
    }

    return missing;
}
Exemplo n.º 2
0
bool tool_comp::has( const inventory &crafting_inv, int batch ) const
{
    if( !by_charges() ) {
        return crafting_inv.has_tools( type, std::abs( count ) );
    } else {
        return crafting_inv.has_charges( type, count * batch );
    }
}
Exemplo n.º 3
0
std::vector<comp_selection<item_comp>> craft_command::check_item_components_missing(
                                        const inventory &map_inv ) const
{
    std::vector<comp_selection<item_comp>> missing;

    for( const auto &item_sel : item_selections ) {
        itype_id type = item_sel.comp.type;
        item_comp component = item_sel.comp;
        long count = ( component.count > 0 ) ? component.count * batch_size : abs( component.count );

        if( item::count_by_charges( type ) && count > 0 ) {
            switch( item_sel.use_from ) {
                case use_from_player:
                    if( !crafter->has_charges( type, count ) ) {
                        missing.push_back( item_sel );
                    }
                    break;
                case use_from_map:
                    if( !map_inv.has_charges( type, count ) ) {
                        missing.push_back( item_sel );
                    }
                    break;
                case use_from_both:
                    if( !( crafter->charges_of( type ) + map_inv.charges_of( type ) >= count ) ) {
                        missing.push_back( item_sel );
                    }
                    break;
                case use_from_none:
                case cancel:
                    break;
            }
        } else {
            // Counting by units, not charges.
            switch( item_sel.use_from ) {
                case use_from_player:
                    if( !crafter->has_amount( type, count ) ) {
                        missing.push_back( item_sel );
                    }
                    break;
                case use_from_map:
                    if( !map_inv.has_components( type, count ) ) {
                        missing.push_back( item_sel );
                    }
                    break;
                case use_from_both:
                    if( !( crafter->amount_of( type ) + map_inv.amount_of( type ) >= count ) ) {
                        missing.push_back( item_sel );
                    }
                    break;
                case use_from_none:
                case cancel:
                    break;
            }
        }
    }

    return missing;
}
Exemplo n.º 4
0
bool player_can_build(player &p, inventory pinv, construction *con)
{
    if (p.skillLevel("carpentry") < con->difficulty) {
        return false;
    }

    bool has_tool = false;
    bool has_component = false;
    bool tools_required = false;
    bool components_required = false;

    for (int j = 0; j < con->tools.size(); j++) {
        if (con->tools[j].size() > 0) {
            tools_required = true;
            has_tool = false;
            for (unsigned k = 0; k < con->tools[j].size(); k++) {
                if (pinv.has_amount(con->tools[j][k].type, 1)) {
                    has_tool = true;
                    con->tools[j][k].available = 1;
                } else {
                    con->tools[j][k].available = -1;
                }
            }
            if (!has_tool) { // missing one of the tools for this stage
                break;
            }
        }
    }

    for (int j = 0; j < con->components.size(); ++j) {
        if (con->components[j].size() > 0) {
            components_required = true;
            has_component = false;
            for (unsigned k = 0; k < con->components[j].size(); k++) {
                if (( item_controller->find_template(con->components[j][k].type)->is_ammo() &&
                      pinv.has_charges(con->components[j][k].type,
                                       con->components[j][k].count)    ) ||
                    (!item_controller->find_template(con->components[j][k].type)->is_ammo() &&
                      pinv.has_amount (con->components[j][k].type,
                                       con->components[j][k].count)    ))
                {
                    has_component = true;
                    con->components[j][k].available = 1;
                } else {
                    con->components[j][k].available = -1;
                }
            }
            if (!has_component) { // missing one of the comps for this stage
                break;
            }
        }
    }

    return (has_component || !components_required) &&
           (has_tool || !tools_required);
}
Exemplo n.º 5
0
std::string tool_comp::get_color( bool has_one, const inventory &crafting_inv, int batch ) const
{
    if( available == a_insufficent ) {
        return "brown";
    } else if( !by_charges() && crafting_inv.has_tools( type, std::abs( count ) ) ) {
        return "green";
    } else if( by_charges() && crafting_inv.has_charges( type, count * batch ) ) {
        return "green";
    }
    return has_one ? "dkgray" : "red";
}
Exemplo n.º 6
0
bool tool_comp::has( const inventory &crafting_inv, int batch ) const
{
    if( g->u.has_trait( "DEBUG_HS" ) ) {
        return true;
    }

    if( !by_charges() ) {
        return crafting_inv.has_tools( type, std::abs( count ) );
    } else {
        return crafting_inv.has_charges( type, count * batch );
    }
}
Exemplo n.º 7
0
bool item_comp::has( const inventory &crafting_inv, int batch ) const
{
    if( g->u.has_trait( "DEBUG_HS" ) ) {
        return true;
    }

    const int cnt = std::abs( count ) * batch;
    if( item::count_by_charges( type ) ) {
        return crafting_inv.has_charges( type, cnt );
    } else {
        return crafting_inv.has_components( type, cnt );
    }
}
Exemplo n.º 8
0
bool tool_comp::has( const inventory &crafting_inv, int batch ) const
{
    if( type == "goggles_welding" ) {
        if( g->u.has_bionic( "bio_sunglasses" ) || g->u.is_wearing( "rm13_armor_on" ) ) {
            return true;
        }
    }
    if( !by_charges() ) {
        return crafting_inv.has_tools( type, std::abs( count ) );
    } else {
        return crafting_inv.has_charges( type, count * batch );
    }
}
Exemplo n.º 9
0
int get_remaining_charges( const std::string &tool_id )
{
    const inventory crafting_inv = g->u.crafting_inventory();
    std::vector<const item *> items =
    crafting_inv.items_with( [tool_id]( const item & i ) {
        return i.typeId() == tool_id;
    } );
    int remaining_charges = 0;
    for( const item *instance : items ) {
        remaining_charges += instance->charges;
    }
    return remaining_charges;
}
Exemplo n.º 10
0
std::string item_comp::get_color( bool has_one, const inventory &crafting_inv, int batch ) const
{
    const int cnt = std::abs( count ) * batch;
    if( available == a_insufficent ) {
        return "brown";
    } else if( item::count_by_charges( type ) ) {
        if( crafting_inv.has_charges( type, cnt ) ) {
            return "green";
        }
    } else if( crafting_inv.has_components( type, cnt ) ) {
        return "green";
    }
    return has_one ? "dkgray" : "red";
}
Exemplo n.º 11
0
bool game::player_can_build(player &p, inventory inv, constructable* con,
                            int level, bool specific)
// defaults: level==0,  specific==false
{
 if (level < 0) // used as escape value in place_construction()
  return false;

 int stop = (specific ? level : con->stages.size());
 do {
  construction_stage stage = con->stages[level];
  int number_of_tools = 0, number_of_components = 0;
  int number_of_req_tools = 0, number_of_req_components = 0;

  for (int j = 0; j < 3; j++) {
// counting available tools
   if (stage.tools[j].size() > 0) {
    number_of_req_tools++;
    for (int k = 0; k < stage.tools[j].size(); k++)
     if (inv.has_amount(stage.tools[j][k], 1)) {
      number_of_tools++;
      break;
     }
   }
// counting available components
   if (stage.components[j].size() > 0) {
    number_of_req_components++;
    for (int k = 0; k < stage.components[j].size(); k++)
     if (( itypes[stage.components[j][k].type]->is_ammo() &&
          inv.has_charges(stage.components[j][k].type,
                          stage.components[j][k].count)    ) ||
         (!itypes[stage.components[j][k].type]->is_ammo() &&
          inv.has_amount (stage.components[j][k].type,
                          stage.components[j][k].count)    )) {
      number_of_components++;
      break;
     }
   }
  }
// difficulty check + summary
  if (!(p.sklevel[sk_carpentry] < stage.difficulty) &&
      number_of_tools == number_of_req_tools &&
      number_of_components == number_of_req_components)
   return true;

  level++;
 } while (level < stop);
 return false;
}
Exemplo n.º 12
0
bool requirement_data::has_comps( const inventory &crafting_inv,
                                  const std::vector< std::vector<T> > &vec,
                                  int batch )
{
    bool retval = true;
    int total_UPS_charges_used = 0;
    for( const auto &set_of_tools : vec ) {
        bool has_tool_in_set = false;
        int UPS_charges_used = std::numeric_limits<int>::max();
        for( const auto &tool : set_of_tools ) {
            if( tool.has( crafting_inv, batch, [ &UPS_charges_used ]( int charges ) {
            UPS_charges_used = std::min( UPS_charges_used, charges );
            } ) ) {
                tool.available = a_true;
            } else {
                tool.available = a_false;
            }
            has_tool_in_set = has_tool_in_set || tool.available == a_true;
        }
        if( !has_tool_in_set ) {
            retval = false;
        }
        if( UPS_charges_used != std::numeric_limits<int>::max() ) {
            total_UPS_charges_used += UPS_charges_used;
        }
    }
    if( total_UPS_charges_used > 0 &&
        total_UPS_charges_used > crafting_inv.charges_of( "UPS" ) ) {
        return false;
    }
    return retval;
}
Exemplo n.º 13
0
std::string tool_comp::get_color( bool has_one, const inventory &crafting_inv, int batch ) const
{
    if( type == "goggles_welding" ) {
        if( g->u.has_bionic( "bio_sunglasses" ) || g->u.is_wearing( "rm13_armor_on" ) ) {
            return "cyan";
        }
    }
    if( available == a_insufficent ) {
        return "brown";
    } else if( !by_charges() && crafting_inv.has_tools( type, std::abs( count ) ) ) {
        return "green";
    } else if( by_charges() && crafting_inv.has_charges( type, count * batch ) ) {
        return "green";
    }
    return has_one ? "dkgray" : "red";
}
Exemplo n.º 14
0
bool requirements::check_enough_materials( const item_comp& comp, const inventory& crafting_inv ) const
{
    if( comp.available != a_true ) {
        return false;
    }
    const itype *it = item_controller->find_template( comp.type );
    const tool_comp *tq = find_by_type( tools, comp.type );
    if( tq != nullptr ) {
        // The very same item type is also needed as tool!
        // Use charges of it, or use it by count?
        const int tc = tq->count < 0 ? std::abs( tq->count ) : 1;
        // Check for components + tool count. Check item amount (excludes
        // pseudo items) and tool amount (includes pseudo items)
        // Imagine: required = 1 welder (component) + 1 welder (tool),
        // available = 1 welder (real item), 1 welding rig (creates
        // a pseudo welder item). has_components(welder,2) returns false
        // as there is only one real welder available, but has_tools(welder,2)
        // returns true.
        // Keep in mind that both requirements (tool+component) are checked
        // before this. That assures that one real item is actually available,
        // two welding rigs (and no real welder) would make this component
        // non-available even before this function is called.
        // Only ammo and (some) food is counted by charges, both are unlikely
        // to appear as tool, but it's possible /-:
        bool has_comps;
        if( it->count_by_charges() && comp.count > 0 ) {
            has_comps = crafting_inv.has_charges( comp.type, comp.count + tc );
        } else {
            has_comps = crafting_inv.has_components( comp.type, abs( comp.count ) + tc );
        }
        if( !has_comps && !crafting_inv.has_tools( comp.type, comp.count + tc ) ) {
            comp.available = a_insufficent;
        }
    }
    for( const auto &ql : it->qualities ) {
        const quality_requirement *qr = find_by_type( qualities, ql.first );
        if( qr == nullptr || qr->level > ql.second ) {
            continue;
        }
        // This item can be used for the quality requirement, same as above for specific
        // tools applies.
        if( !crafting_inv.has_items_with_quality( qr->type, qr->level, qr->count + abs(comp.count) ) ) {
            comp.available = a_insufficent;
        }
    }
    return comp.available == a_true;
}
Exemplo n.º 15
0
			void take_all(inventory &container)
			{
				for (item_ptr loot : container.m_items)
				{
					add(loot);
				}
				container.clear();
			}
Exemplo n.º 16
0
bool quality_requirement::has( const inventory &crafting_inv, int ) const
{
    if( g->u.has_trait( "DEBUG_HS" ) ) {
        return true;
    }

    return crafting_inv.has_quality( type, level, count );
}
Exemplo n.º 17
0
bool quality_requirement::has( const inventory &crafting_inv, int,
                               std::function<void( int )> ) const
{
    if( g->u.has_trait( trait_DEBUG_HS ) ) {
        return true;
    }

    return crafting_inv.has_quality( type, level, count );
}
Exemplo n.º 18
0
std::string item_comp::get_color( bool has_one, const inventory &crafting_inv, int batch ) const
{
    if( type == "rope_30" || type == "rope_6" ) {
        if( g->u.has_trait( "WEB_ROPE" ) && g->u.get_hunger() <= 300 ) {
            return "ltgreen"; // Show that WEB_ROPE is on the job!
        }
    }
    const int cnt = std::abs( count ) * batch;
    if( available == a_insufficent ) {
        return "brown";
    } else if( item::count_by_charges( type ) ) {
        if( crafting_inv.has_charges( type, cnt ) ) {
            return "green";
        }
    } else if( crafting_inv.has_components( type, cnt ) ) {
        return "green";
    }
    return has_one ? "dkgray" : "red";
}
Exemplo n.º 19
0
bool item_comp::has( const inventory &crafting_inv, int batch ) const
{
    // If you've Rope Webs, you can spin up the webbing to replace any amount of
    // rope your projects may require.  But you need to be somewhat nourished:
    // Famished or worse stops it.
    if( type == "rope_30" || type == "rope_6" ) {
        // NPC don't craft?
        // TODO: what about the amount of ropes vs the hunger?
        if( g->u.has_trait( "WEB_ROPE" ) && g->u.get_hunger() <= 300 ) {
            return true;
        }
    }
    const int cnt = std::abs( count ) * batch;
    if( item::count_by_charges( type ) ) {
        return crafting_inv.has_charges( type, cnt );
    } else {
        return crafting_inv.has_components( type, cnt );
    }
}
Exemplo n.º 20
0
std::string item_comp::get_color( bool has_one, const inventory &crafting_inv ) const
{
    if( type == "rope_30" || type == "rope_6" ) {
        if( g->u.has_trait( "WEB_ROPE" ) && g->u.hunger <= 300 ) {
            return "ltgreen"; // Show that WEB_ROPE is on the job!
        }
    }
    const itype *it = item_controller->find_template( type );
    if( available == a_insufficent ) {
        return "brown";
    } else if( it->count_by_charges() && count > 0 ) {
        if( crafting_inv.has_charges( type, count ) ) {
            return "green";
        }
    } else if( crafting_inv.has_components( type, abs( count ) ) ) {
        return "green";
    }
    return has_one ? "dkgray" : "red";
}
Exemplo n.º 21
0
bool item_comp::has( const inventory &crafting_inv ) const
{
    // If you've Rope Webs, you can spin up the webbing to replace any amount of
    // rope your projects may require.  But you need to be somewhat nourished:
    // Famished or worse stops it.
    if( type == "rope_30" || type == "rope_6" ) {
        // NPC don't craft?
        // TODO: what about the amount of ropes vs the hunger?
        if( g->u.has_trait( "WEB_ROPE" ) && g->u.hunger <= 300 ) {
            return true;
        }
    }
    const itype *it = item_controller->find_template( type );
    if( it->count_by_charges() && count > 0 ) {
        return crafting_inv.has_charges( type, count );
    } else {
        return crafting_inv.has_components( type, abs( count ) );
    }
}
Exemplo n.º 22
0
bool game::player_can_build(player &p, inventory inv, constructable* con,
                            int level, bool cont)
{
 if (p.sklevel[sk_carpentry] < con->difficulty)
  return false;

 if (level < 0)
  level = con->stages.size();

 int start = 0;
 if (cont)
  start = level;
 for (int i = start; i < con->stages.size() && i <= level; i++) {
  construction_stage stage = con->stages[i];
  for (int j = 0; j < 3; j++) {
   if (stage.tools[j].size() > 0) {
    bool has_tool = false;
    for (int k = 0; k < stage.tools[j].size() && !has_tool; k++) {
     if (inv.has_amount(stage.tools[j][k], 1))
      has_tool = true;
    }
    if (!has_tool)
     return false;
   }
   if (stage.components[j].size() > 0) {
    bool has_component = false;
    for (int k = 0; k < stage.components[j].size() && !has_component; k++) {
     if (( itypes[stage.components[j][k].type]->is_ammo() &&
          inv.has_charges(stage.components[j][k].type,
                          stage.components[j][k].count)    ) ||
         (!itypes[stage.components[j][k].type]->is_ammo() &&
          inv.has_amount (stage.components[j][k].type,
                          stage.components[j][k].count)    ))
      has_component = true;
    }
    if (!has_component)
     return false;
   }
  }
 }
 return true;
}
Exemplo n.º 23
0
void AddItem(inventory& inv,char* name,double weight)
{
	int len = strlen(name)+1;
	char* itemName = new char[len];
	strncpy(itemName,name,len);

	cout << "Adding " << itemName << " with a weight of " << weight << "." << endl;
	inv.AddItem(item(itemName,weight));

	delete [] itemName;
}
Exemplo n.º 24
0
bool tool_comp::has( const inventory &crafting_inv, int batch,
                     std::function<void( int )> visitor ) const
{
    if( g->u.has_trait( trait_DEBUG_HS ) ) {
        return true;
    }

    if( !by_charges() ) {
        return crafting_inv.has_tools( type, std::abs( count ) );
    } else {
        int charges_found = crafting_inv.charges_of( type, count * batch );
        if( charges_found == count * batch ) {
            return true;
        }
        const auto &binned = crafting_inv.get_binned_items();
        const auto iter = binned.find( type );
        if( iter == binned.end() ) {
            return false;
        }
        bool has_UPS = false;
        for( const item *it : iter->second ) {
            it->visit_items( [&has_UPS]( const item * e ) {
                if( e->has_flag( "USE_UPS" ) ) {
                    has_UPS = true;
                    return VisitResponse::ABORT;
                }
                return VisitResponse::NEXT;
            } );
        }
        if( has_UPS ) {
            int UPS_charges_used =
                crafting_inv.charges_of( "UPS", ( count * batch ) - charges_found );
            if( visitor && UPS_charges_used + charges_found >= ( count * batch ) ) {
                visitor( UPS_charges_used );
            }
            charges_found += UPS_charges_used;
        }
        return charges_found == count * batch;
    }
}
Exemplo n.º 25
0
void npc::init_buying(inventory you, std::vector<int> &indices,
                      std::vector<int> &prices)
{
 int val, price;
 for (int i = 0; i < you.size(); i++) {
  val = value(you[i]);
  if (val >= NPC_HI_VALUE) {
   indices.push_back(i);
   price = you[i].price();
   if (val >= NPC_VERY_HI_VALUE)
    price *= 2;
   price *= price_adjustment(sklevel[sk_barter]);
   prices.push_back(price);
  }
 }
}
Exemplo n.º 26
0
bool game::player_can_build(player &p, inventory pinv, constructable* con,
                            const int level, bool cont, bool exact_level)
{
 int last_level = level;

 // default behavior: return true if any of the stages up to L can be constr'd
 // if exact_level, require that this level be constructable
 if (p.skillLevel("carpentry") < con->difficulty)
  return false;

 if (level < 0)
  last_level = con->stages.size();

 int start = 0;
 if (cont)
  start = level;

 bool can_build_any = false;
 for (int i = start; i < con->stages.size() && i <= last_level; i++) {
  construction_stage* stage = &(con->stages[i]);
  bool has_tool = false;
  bool has_component = false;
  bool tools_required = false;
  bool components_required = false;

  for (int j = 0; j < 10; j++) {
   if (stage->tools[j].size() > 0) {
    tools_required = true;
    has_tool = false;
    for (int k = 0; k < stage->tools[j].size(); k++) {
     if (pinv.has_amount(stage->tools[j][k].type, 1))
     {
         has_tool = true;
         stage->tools[j][k].available = 1;
     }
     else
     {
         stage->tools[j][k].available = -1;
     }
    }
    if (!has_tool)  // missing one of the tools for this stage
     break;
   }
   if (stage->components[j].size() > 0) {
    components_required = true;
    has_component = false;
    for (int k = 0; k < stage->components[j].size(); k++) {
     if (( item_controller->find_template(stage->components[j][k].type)->is_ammo() &&
	   pinv.has_charges(stage->components[j][k].type,
			   stage->components[j][k].count)    ) ||
         (!item_controller->find_template(stage->components[j][k].type)->is_ammo() &&
          pinv.has_amount (stage->components[j][k].type,
                          stage->components[j][k].count)    ))
     {
         has_component = true;
         stage->components[j][k].available = 1;
     }
     else
     {
         stage->components[j][k].available = -1;
     }
    }
    if (!has_component)  // missing one of the comps for this stage
     break;
   }

  }  // j in [0,2]
  can_build_any |= (has_component || !components_required) &&
    (has_tool || !tools_required);
  if (exact_level && (i == level)) {
      return ((has_component || !components_required) &&
	      (has_tool || !tools_required));
  }
 }  // stage[i]
 return can_build_any;
}
Exemplo n.º 27
0
comp_selection<tool_comp>
player::select_tool_component( const std::vector<tool_comp> &tools, int batch, inventory &map_inv,
                               const std::string &hotkeys, bool can_cancel )
{

    comp_selection<tool_comp> selected;

    bool found_nocharge = false;
    std::vector<tool_comp> player_has;
    std::vector<tool_comp> map_has;
    // Use charges of any tools that require charges used
    for( auto it = tools.begin(); it != tools.end() && !found_nocharge; ++it ) {
        itype_id type = it->type;
        if( it->count > 0 ) {
            long count = it->count * batch;
            if( has_charges( type, count ) ) {
                player_has.push_back( *it );
            }
            if( map_inv.has_charges( type, count ) ) {
                map_has.push_back( *it );
            }
        } else if( has_amount( type, 1 ) || map_inv.has_tools( type, 1 ) ) {
            selected.comp = *it;
            found_nocharge = true;
        }
    }
    if( found_nocharge ) {
        selected.use_from = use_from_none;
        return selected;    // Default to using a tool that doesn't require charges
    }

    if( player_has.size() + map_has.size() == 1 ) {
        if( map_has.empty() ) {
            selected.use_from = use_from_player;
            selected.comp = player_has[0];
        } else {
            selected.use_from = use_from_map;
            selected.comp = map_has[0];
        }
    } else { // Variety of options, list them and pick one
        // Populate the list
        uimenu tmenu( hotkeys );
        for( auto &map_ha : map_has ) {
            std::string tmpStr = item::nname( map_ha.type ) + _( " (nearby)" );
            tmenu.addentry( tmpStr );
        }
        for( auto &player_ha : player_has ) {
            tmenu.addentry( item::nname( player_ha.type ) );
        }

        if( tmenu.entries.empty() ) {  // This SHOULD only happen if cooking with a fire,
            selected.use_from = use_from_none;
            return selected;    // and the fire goes out.
        }

        if( can_cancel ) {
            tmenu.addentry( -1, true, 'q', _( "Cancel" ) );
        }

        // Get selection via a popup menu
        tmenu.title = _( "Use which tool?" );
        tmenu.query();

        if( tmenu.ret == static_cast<int>( map_has.size() + player_has.size() ) ) {
            selected.use_from = cancel;
            return selected;
        }

        size_t uselection = static_cast<size_t>( tmenu.ret );
        if( uselection < map_has.size() ) {
            selected.use_from = use_from_map;
            selected.comp = map_has[uselection];
        } else {
            uselection -= map_has.size();
            selected.use_from = use_from_player;
            selected.comp = player_has[uselection];
        }
    }

    return selected;
}
Exemplo n.º 28
0
bool player::can_disassemble( const item &obj, const inventory &inv, std::string *err ) const
{
    const auto error = [&err]( const std::string & message ) {
        if( err != nullptr ) {
            *err = message;
        }
        return false;
    };

    const auto &r = recipe_dictionary::get_uncraft( obj.typeId() );

    if( !r ) {
        return error( string_format( _( "You cannot disassemble this." ) ) );
    }

    // check sufficient light
    if( lighting_craft_speed_multiplier( r ) == 0.0f ) {
        return error( _( "You can't see to craft!" ) );
    }
    // refuse to disassemble rotten items
    if( obj.goes_bad() || ( obj.is_food_container() && obj.contents.front().goes_bad() ) ) {
        if( obj.rotten() || ( obj.is_food_container() && obj.contents.front().rotten() ) ) {
            return error( _( "It's rotten, I'm not taking that apart." ) );
        }
    }

    if( obj.count_by_charges() && !r.has_flag( "UNCRAFT_SINGLE_CHARGE" ) ) {
        // Create a new item to get the default charges
        int qty = r.create_result().charges;
        if( obj.charges < qty ) {
            auto msg = ngettext( "You need at least %d charge of %s.",
                                 "You need at least %d charges of %s.", qty );
            return error( string_format( msg, qty, obj.tname().c_str() ) );
        }
    }

    const auto &dis = r.disassembly_requirements();

    for( const auto &opts : dis.get_qualities() ) {
        for( const auto &qual : opts ) {
            if( !qual.has( inv ) ) {
                // Here should be no dot at the end of the string as 'to_string()' provides it.
                return error( string_format( _( "You need %s" ), qual.to_string().c_str() ) );
            }
        }
    }

    for( const auto &opts : dis.get_tools() ) {
        const bool found = std::any_of( opts.begin(), opts.end(),
        [&]( const tool_comp & tool ) {
            return ( tool.count <= 0 && inv.has_tools( tool.type, 1 ) ) ||
                   ( tool.count >  0 && inv.has_charges( tool.type, tool.count ) );
        } );

        if( !found ) {
            if( opts.front().count <= 0 ) {
                return error( string_format( _( "You need %s." ),
                                             item::nname( opts.front().type ).c_str() ) );
            } else {
                return error( string_format( ngettext( "You need a %s with %d charge.",
                                                       "You need a %s with %d charges.",
                                                       opts.front().count ),
                                             item::nname( opts.front().type ).c_str(), opts.front().count ) );
            }
        }
    }

    return true;
}
Exemplo n.º 29
0
char game::inv(inventory& inv, std::string title)
{
    WINDOW* w_inv = newwin(TERRAIN_WINDOW_HEIGHT, TERRAIN_WINDOW_WIDTH + (use_narrow_sidebar() ? 45 : 55), VIEW_OFFSET_Y, VIEW_OFFSET_X);
    const int maxitems = TERRAIN_WINDOW_HEIGHT - 5;

 int ch = (int)'.';
 int start = 0, cur_it = 0, max_it;
 inv.sort();
 std::vector<char> null_vector;
 print_inv_statics(this, w_inv, title, null_vector);
// Gun, ammo, weapon, armor, food, tool, book, other

 invslice slice = inv.slice(0, inv.size());
 std::vector<int> firsts = find_firsts(slice);

 int selected =- 1;
 int selected_char = (int)' ';
 do {
  if (( ch == '<' || ch == KEY_PPAGE ) && start > 0) { // Clear lines and shift
   for (int i = 1; i < maxitems+4; i++)
    mvwprintz(w_inv, i, 0, c_black, "                                             ");
   start -= maxitems;
   if (start < 0)
    start = 0;
   mvwprintw(w_inv, maxitems + 4, 0, "         ");
   if ( selected > -1 ) selected = start; // oy, the cheese
  }
  if (( ch == '>' || ch == KEY_NPAGE ) && cur_it < inv.size()) { // Clear lines and shift
   start = cur_it;
   mvwprintw(w_inv, maxitems + 4, 12, "            ");
   for (int i = 1; i < maxitems+4; i++)
    mvwprintz(w_inv, i, 0, c_black, "                                             ");
   if ( selected < start && selected > -1 ) selected = start;
  }
  int cur_line = 2;
  max_it = 0;
  for (cur_it = start; cur_it < start + maxitems && cur_line < maxitems+3; cur_it++) {
// Clear the current line;
   mvwprintw(w_inv, cur_line, 0, "                                             ");

   for (int i = 1; i < iCategorieNum; i++) {
    if (cur_it == firsts[i-1]) {
     mvwprintz(w_inv, cur_line, 0, c_magenta, _(CATEGORIES[i].c_str()));
     cur_line++;
    }
   }

   if (cur_it < slice.size())
   {
    item& it = slice[cur_it]->front();
    if(cur_it==selected) selected_char=(int)it.invlet;
    mvwputch (w_inv, cur_line, 0, (cur_it == selected ? h_white : c_white), it.invlet);
    mvwprintz(w_inv, cur_line, 1, (cur_it == selected ? h_white : it.color_in_inventory(&u) ), " %s",
              it.tname(this).c_str());
    if (slice[cur_it]->size() > 1)
     wprintw(w_inv, " [%d]", slice[cur_it]->size());
    if (it.charges > 0)
     wprintw(w_inv, " (%d)", it.charges);
    else if (it.contents.size() == 1 &&
             it.contents[0].charges > 0)
     wprintw(w_inv, " (%d)", it.contents[0].charges);
    cur_line++;
    max_it=cur_it;
   }
//   cur_line++;
  }
  if (start > 0)
   mvwprintw(w_inv, maxitems + 4, 0, _("< Go Back"));
  if (cur_it < inv.size())
   mvwprintw(w_inv, maxitems + 4, 12, _("> More items"));
  wrefresh(w_inv);

  ch = getch();

  if ( ch == KEY_DOWN ) {
    if ( selected < 0 ) {
      selected = start;
    } else {
      selected++;
    }
    if ( selected > max_it ) {
      if( cur_it < u.inv.size() ) {
        ch='>';
      } else {
        selected = u.inv.size() - 1; // wraparound?
      }
    }
  } else if ( ch == KEY_UP ) {
    selected--;
    if ( selected < -1 ) {
      selected = -1; // wraparound?
    } else if ( selected < start ) {
      if ( start > 0 ) {
        for (int i = 1; i < maxitems+4; i++)
         mvwprintz(w_inv, i, 0, c_black, "                                             ");
        start -= maxitems;
        if (start < 0)
         start = 0;
        mvwprintw(w_inv, maxitems + 4, 0, "         ");
      }
    }
  } else if ( ch == '\n' || ch == KEY_RIGHT ) {
    ch = selected_char;
  }

 } while (ch == '<' || ch == '>' || ch == KEY_NPAGE || ch == KEY_PPAGE || ch == KEY_UP || ch == KEY_DOWN );
 werase(w_inv);
 delwin(w_inv);
 erase();
 refresh_all();
 return (char)ch;
}
Exemplo n.º 30
0
bool quality_requirement::has( const inventory &crafting_inv, int ) const
{
    return crafting_inv.has_quality( type, level, count );
}