const std::function<bool( const item & )> recipe::get_component_filter() const
{
    const item result = create_result();

    // Disallow crafting of non-perishables with rotten components
    // Make an exception for seeds
    // TODO: move seed extraction recipes to uncraft
    std::function<bool( const item & )> rotten_filter = return_true<item>;
    if( result.is_food() && !result.goes_bad() && !has_flag( "ALLOW_ROTTEN" ) ) {
        rotten_filter = []( const item & component ) {
            return !component.rotten();
        };
    }

    // If the result is made hot, we can allow frozen components.
    // EDIBLE_FROZEN components ( e.g. flour, chocolate ) are allowed as well
    // Otherwise forbid them
    std::function<bool( const item & )> frozen_filter = return_true<item>;
    if( result.is_food() && !hot_result() ) {
        frozen_filter = []( const item & component ) {
            return !component.has_flag( "FROZEN" ) || component.has_flag( "EDIBLE_FROZEN" );
        };
    }

    return [ rotten_filter, frozen_filter ]( const item & component ) {
        return is_crafting_component( component ) && rotten_filter( component ) &&
               frozen_filter( component );
    };
}
Beispiel #2
0
void finalize_crafted_item( item &newit, float used_age_tally, int used_age_count )
{
    if( newit.is_food() ) {
        set_item_food( newit );
    }
    if( used_age_count > 0 && newit.goes_bad() ) {
        set_item_spoilage( newit, used_age_tally, used_age_count );
    }
}
        int rate_freshness( const item &it, const item &container ) const {
            if( p.will_eat( it ).value() == edible_rating::ROTTEN ) {
                return -1;
            } else if( !container.type->container || !container.type->container->preserves ) {
                if( it.is_fresh() ) {
                    return 1;
                } else if( it.is_going_bad() ) {
                    return 3;
                } else if( it.goes_bad() ) {
                    return 2;
                }
            }

            return 0;
        }
Beispiel #4
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;
}