void activity_handlers::washing_finish( player_activity *act, player *p )
{
    auto items = reorder_for_dropping( *p, convert_to_indexes( *act ) );

    // Check again that we have enough water and soap incase the amount in our inventory changed somehow
    // Consume the water and soap
    units::volume total_volume = 0_ml;

    for( const act_item &filthy_item : items ) {
        total_volume += filthy_item.it->volume();
    }
    washing_requirements required = washing_requirements_for_volume( total_volume );

    const auto is_liquid_crafting_component = []( const item & it ) {
        return is_crafting_component( it ) && ( !it.count_by_charges() || it.made_of( LIQUID ) ||
                                                it.contents_made_of( LIQUID ) );
    };
    const inventory &crafting_inv = p->crafting_inventory();
    if( !crafting_inv.has_charges( "water", required.water, is_liquid_crafting_component ) &&
        !crafting_inv.has_charges( "water_clean", required.water, is_liquid_crafting_component ) ) {
        p->add_msg_if_player( _( "You need %1$i charges of water or clean water to wash these items." ),
                              required.water );
        act->set_to_null();
        return;
    } else if( !crafting_inv.has_charges( "soap", required.cleanser ) &&
               !crafting_inv.has_charges( "detergent", required.cleanser ) ) {
        p->add_msg_if_player( _( "You need %1$i charges of cleansing agent to wash these items." ),
                              required.cleanser );
        act->set_to_null();
        return;
    }

    for( const auto &ait : items ) {
        item *filthy_item = const_cast<item *>( ait.it );
        filthy_item->item_tags.erase( "FILTHY" );
        p->on_worn_item_washed( *filthy_item );
    }

    std::vector<item_comp> comps;
    comps.push_back( item_comp( "water", required.water ) );
    comps.push_back( item_comp( "water_clean", required.water ) );
    p->consume_items( comps, 1, is_liquid_crafting_component );

    std::vector<item_comp> comps1;
    comps1.push_back( item_comp( "soap", required.cleanser ) );
    comps1.push_back( item_comp( "detergent", required.cleanser ) );
    p->consume_items( comps1 );

    p->add_msg_if_player( m_good, _( "You washed your clothing." ) );

    // Make sure newly washed components show up as available if player attempts to craft immediately
    p->invalidate_crafting_inventory();

    act->set_to_null();
}
void activity_handlers::washing_finish( player_activity *act, player *p )
{
    auto items = reorder_for_dropping( *p, convert_to_indexes( *act ) );

    // Check again that we have enough water and soap incase the amount in our inventory changed somehow
    // Consume the water and soap
    int required_water = 0;
    int required_cleanser = 0;

    for( const act_item &filthy_item : items ) {
        required_water += filthy_item.it->volume() / 125_ml;
        required_cleanser += filthy_item.it->volume() / 1000_ml;
    }
    if( required_cleanser < 1 ) {
        required_cleanser = 1;
    }

    const inventory &crafting_inv = p->crafting_inventory();
    if( !crafting_inv.has_charges( "water", required_water ) &&
        !crafting_inv.has_charges( "water_clean", required_water ) ) {
        p->add_msg_if_player( _( "You need %1$i charges of water or clean water to wash these items." ),
                              required_water );
        act->set_to_null();
        return;
    } else if( !crafting_inv.has_charges( "soap", required_cleanser ) &&
               !crafting_inv.has_charges( "detergent", required_cleanser ) ) {
        p->add_msg_if_player( _( "You need %1$i charges of cleansing agent to wash these items." ),
                              required_cleanser );
        act->set_to_null();
        return;
    }

    for( const auto &ait : items ) {
        item *filthy_item = const_cast<item *>( ait.it );
        filthy_item->item_tags.erase( "FILTHY" );
    }

    std::vector<item_comp> comps;
    comps.push_back( item_comp( "water", required_water ) );
    comps.push_back( item_comp( "water_clean", required_water ) );
    p->consume_items( comps );

    std::vector<item_comp> comps1;
    comps1.push_back( item_comp( "soap", required_cleanser ) );
    comps1.push_back( item_comp( "detergent", required_cleanser ) );
    p->consume_items( comps1 );

    p->add_msg_if_player( m_good, _( "You washed your clothing." ) );

    act->set_to_null();
}
void mission::wrap_up()
{
    auto &u = g->u;
    if( u.getID() != player_id ) {
        // This is called from npctalk.cpp, the npc should only offer the option to wrap up mission
        // that have been assigned to the current player.
        debugmsg( "mission::wrap_up called, player %d was assigned, but current player is %d", player_id, u.getID() );
    }

    status = mission_status::success;
    u.on_mission_finished( *this );
    std::vector<item_comp> comps;
    switch( type->goal ) {
        case MGOAL_FIND_ITEM:
            comps.push_back(item_comp(type->item_id, item_count));
            u.consume_items(comps);
            break;
        case MGOAL_FIND_ANY_ITEM:
            u.remove_mission_items( uid );
            break;
        default:
            //Suppress warnings
            break;
    }

    type->end( this );
}
Exemple #4
0
void finalize_constructions()
{
    std::vector<item_comp> frame_items;
    for( const auto &e : vpart_info::all() ) {
        const vpart_info &vp = e.second;
        if( !vp.has_flag( "INITIAL_PART" ) ) {
            continue;
        }
        frame_items.push_back( item_comp( vp.item, 1 ) );
    }

    if( frame_items.empty() ) {
        debugmsg( "No valid frames detected for vehicle construction" );
    }

    for( construction &con : constructions ) {
        if( con.post_special == &construct::done_vehicle ) {
            const_cast<requirement_data &>( con.requirements.obj() ).get_components().push_back( frame_items );
        }
    }

    constructions.erase( std::remove_if( constructions.begin(), constructions.end(),
        [&]( const construction &c ) {
            return c.requirements->is_blacklisted();
    } ), constructions.end() );

    for( size_t i = 0; i < constructions.size(); i++ ) {
        constructions[ i ].id = i;
    }
}
void talk_function::bionic_install( npc &p )
{
    std::vector<item *> bionic_inv = g->u.items_with( []( const item & itm ) {
        return itm.is_bionic();
    } );
    if( bionic_inv.empty() ) {
        popup( _( "You have no bionics to install!" ) );
        return;
    }

    std::vector<itype_id> bionic_types;
    std::vector<std::string> bionic_names;
    for( auto &bio : bionic_inv ) {
        if( std::find( bionic_types.begin(), bionic_types.end(), bio->typeId() ) == bionic_types.end() ) {
            if( !g->u.has_bionic( bionic_id( bio->typeId() ) ) || bio->typeId() ==  "bio_power_storage" ||
                bio->typeId() ==  "bio_power_storage_mkII" ) {

                bionic_types.push_back( bio->typeId() );
                bionic_names.push_back( bio->tname() + " - " + format_money( bio->price( true ) * 2 ) );
            }
        }
    }
    // Choose bionic if applicable
    int bionic_index = uilist( _( "Which bionic do you wish to have installed?" ),
                               bionic_names );
    // Did we cancel?
    if( bionic_index < 0 ) {
        popup( _( "You decide to hold off..." ) );
        return;
    }

    const item tmp = item( bionic_types[bionic_index], 0 );
    const itype &it = *tmp.type;
    unsigned int price = tmp.price( true ) * 2;

    if( price > g->u.cash ) {
        popup( _( "You can't afford the procedure..." ) );
        return;
    }

    //Makes the doctor awesome at installing but not perfect
    if( g->u.install_bionics( it, p, false, 20 ) ) {
        g->u.cash -= price;
        p.cash += price;
        g->u.amount_of( bionic_types[bionic_index] );
        std::vector<item_comp> comps;
        comps.push_back( item_comp( tmp.typeId(), 1 ) );
        g->u.consume_items( comps, 1 );
    }
}
void mission::wrap_up()
{
    auto &u = g->u;
    if( u.getID() != player_id ) {
        // This is called from npctalk.cpp, the npc should only offer the option to wrap up mission
        // that have been assigned to the current player.
        debugmsg( "mission::wrap_up called, player %d was assigned, but current player is %d", player_id,
                  u.getID() );
    }

    status = mission_status::success;
    u.on_mission_finished( *this );
    std::vector<item_comp> comps;
    switch( type->goal ) {
        case MGOAL_FIND_ITEM_GROUP: {
            inventory tmp_inv = u.crafting_inventory();
            std::vector<item *> items = std::vector<item *>();
            tmp_inv.dump( items );
            Group_tag grp_type = type->group_id;
            itype_id container = type->container_id;
            bool specific_container_required = container != "null";
            bool remove_container = type->remove_container;
            itype_id empty_container = type->empty_container;

            std::map<itype_id, int> matches = std::map<itype_id, int>();
            get_all_item_group_matches(
                items, grp_type, matches,
                container, itype_id( "null" ), specific_container_required );

            std::map<std::string, int>::iterator cnt_it;
            for( cnt_it = matches.begin(); cnt_it != matches.end(); cnt_it++ ) {
                comps.push_back( item_comp( cnt_it->first, cnt_it->second ) );

            }

            u.consume_items( comps );

            if( remove_container ) {
                std::vector<item_comp> container_comp = std::vector<item_comp>();
                if( empty_container != "null" ) {
                    container_comp.push_back( item_comp( empty_container, type->item_count ) );
                    u.consume_items( container_comp );
                } else {
                    container_comp.push_back( item_comp( container, type->item_count ) );
                    u.consume_items( container_comp );
                }
            }
        }
        break;

        case MGOAL_FIND_ITEM:
            comps.push_back( item_comp( type->item_id, item_count ) );
            u.consume_items( comps );
            break;
        case MGOAL_FIND_ANY_ITEM:
            u.remove_mission_items( uid );
            break;
        default:
            //Suppress warnings
            break;
    }

    type->end( this );
}