Example #1
0
bool vehicle_part::fill_with( item &liquid, long qty )
{
    if( !is_tank() || !can_reload( liquid ) ) {
        return false;
    }

    base.fill_with( liquid, qty );
    return true;
}
Example #2
0
// Handles interactions with a vehicle in the examine menu.
interact_results interact_with_vehicle( vehicle *veh, const tripoint &pos,
                                        int veh_root_part )
{
    if( veh == nullptr ) {
        return ITEMS_FROM_GROUND;
    }

    std::vector<std::string> menu_items;
    std::vector<uimenu_entry> options_message;
    const bool has_items_on_ground = g->m.sees_some_items( pos, g->u );
    const bool items_are_sealed = g->m.has_flag( "SEALED", pos );

    auto turret = veh->turret_query( pos );

    const bool has_kitchen = ( veh->part_with_feature( veh_root_part, "KITCHEN" ) >= 0 );
    const bool has_faucet = ( veh->part_with_feature( veh_root_part, "FAUCET" ) >= 0 );
    const bool has_weldrig = ( veh->part_with_feature( veh_root_part, "WELDRIG" ) >= 0 );
    const bool has_chemlab = ( veh->part_with_feature( veh_root_part, "CHEMLAB" ) >= 0 );
    const bool has_purify = ( veh->part_with_feature( veh_root_part, "WATER_PURIFIER" ) >= 0 );
    const bool has_controls = ( ( veh->part_with_feature( veh_root_part, "CONTROLS" ) >= 0 ) ||
                                ( veh->part_with_feature( veh_root_part, "CTRL_ELECTRONIC" ) >= 0 ) );
    const int cargo_part = veh->part_with_feature( veh_root_part, "CARGO", false );
    const bool from_vehicle = veh && cargo_part >= 0 && !veh->get_items( cargo_part ).empty();
    const bool can_be_folded = veh->is_foldable();
    const bool is_convertible = ( veh->tags.count( "convertible" ) > 0 );
    const bool remotely_controlled = g->remoteveh() == veh;
    typedef enum {
        EXAMINE, CONTROL, GET_ITEMS, GET_ITEMS_ON_GROUND, FOLD_VEHICLE, UNLOAD_TURRET, RELOAD_TURRET,
        USE_HOTPLATE, FILL_CONTAINER, DRINK, USE_WELDER, USE_PURIFIER, PURIFY_TANK
    } options;
    uimenu selectmenu;

    selectmenu.addentry( EXAMINE, true, 'e', _( "Examine vehicle" ) );

    if( has_controls ) {
        selectmenu.addentry( CONTROL, true, 'v', _( "Control vehicle" ) );
    }

    if( from_vehicle ) {
        selectmenu.addentry( GET_ITEMS, true, 'g', _( "Get items" ) );
    }

    if( has_items_on_ground && !items_are_sealed ) {
        selectmenu.addentry( GET_ITEMS_ON_GROUND, true, 'i', _( "Get items on the ground" ) );
    }

    if( ( can_be_folded || is_convertible ) && !remotely_controlled ) {
        selectmenu.addentry( FOLD_VEHICLE, true, 'f', _( "Fold vehicle" ) );
    }

    if( turret.can_unload() ) {
        selectmenu.addentry( UNLOAD_TURRET, true, 'u', _( "Unload %s" ), turret.name().c_str() );
    }

    if( turret.can_reload() ) {
        selectmenu.addentry( RELOAD_TURRET, true, 'r', _( "Reload %s" ), turret.name().c_str() );
    }

    if( ( has_kitchen || has_chemlab ) && veh->fuel_left( "battery" ) > 0 ) {
        selectmenu.addentry( USE_HOTPLATE, true, 'h', _( "Use the hotplate" ) );
    }

    if( has_faucet && veh->fuel_left( "water_clean" ) > 0 ) {
        selectmenu.addentry( FILL_CONTAINER, true, 'c', _( "Fill a container with water" ) );

        selectmenu.addentry( DRINK, true, 'd', _( "Have a drink" ) );
    }

    if( has_weldrig && veh->fuel_left( "battery" ) > 0 ) {
        selectmenu.addentry( USE_WELDER, true, 'w', _( "Use the welding rig?" ) );
    }

    if( has_purify && veh->fuel_left( "battery" ) > 0 ) {
        selectmenu.addentry( USE_PURIFIER, true, 'p', _( "Purify water in carried container" ) );
    }

    if( has_purify && veh->fuel_left( "battery" ) > 0 &&
        veh->fuel_left( "water" ) > 0 &&
        veh->fuel_capacity( "water_clean" ) > veh->fuel_left( "water_clean" ) ) {
        selectmenu.addentry( PURIFY_TANK, true, 'P', _( "Purify water in vehicle's tank" ) );
    }

    int choice;
    if( selectmenu.entries.size() == 1 ) {
        choice = selectmenu.entries.front().retval;
    } else {
        selectmenu.return_invalid = true;
        selectmenu.text = _( "Select an action" );
        selectmenu.selected = 0;
        selectmenu.query();
        choice = selectmenu.ret;
    }

    switch( static_cast<options>( choice ) ) {

        case USE_HOTPLATE: {
            item pseudo( "hotplate" );
            itype_id ammo = pseudo.ammo_default();
            pseudo.ammo_set( ammo, veh->drain( ammo, pseudo.ammo_capacity() ) );

            if( pseudo.ammo_sufficient() ) {
                g->u.invoke_item( &pseudo );
                pseudo.ammo_consume( pseudo.ammo_required(), g->u.pos() );
                veh->refill( ammo, pseudo.ammo_remaining() );
            }
            return DONE;
        }

        case FILL_CONTAINER:
            g->u.siphon( *veh, "water_clean" );
            return DONE;

        case DRINK: {
            veh->drain( "water_clean", 1 );
            item water( "water_clean", 0 );
            g->u.eat( water );
            g->u.moves -= 250;
            return DONE;
        }

        case USE_WELDER: {
            item pseudo( "welder" );
            itype_id ammo = pseudo.ammo_default();
            pseudo.ammo_set( ammo, veh->drain( ammo, pseudo.ammo_capacity() ) );

            if( pseudo.ammo_sufficient() ) {
                g->u.invoke_item( &pseudo );
                pseudo.ammo_consume( pseudo.ammo_required(), g->u.pos() );
                veh->refill( ammo, pseudo.ammo_remaining() );

                // Evil hack incoming
                auto &act = g->u.activity;
                if( act.type == ACT_REPAIR_ITEM ) {
                    // Magic: first tell activity the item doesn't really exist
                    act.index = INT_MIN;
                    // Then tell it to search it on `pos`
                    act.coords.push_back( pos );
                    // Finally tell it it is the vehicle part with weldrig
                    act.values.resize( 2 );
                    act.values[1] = veh->part_with_feature( veh_root_part, "WELDRIG" );
                }
            }
            return DONE;
        }

        case USE_PURIFIER: {
            item pseudo( "water_purifier" );
            itype_id ammo = pseudo.ammo_default();
            pseudo.ammo_set( ammo, veh->drain( ammo, pseudo.ammo_capacity() ) );

            if( pseudo.ammo_sufficient() ) {
                g->u.invoke_item( &pseudo );
            }

            veh->refill( ammo, pseudo.ammo_remaining() );
            return DONE;
        }

        case PURIFY_TANK: {
            const int max_water = std::min( veh->fuel_left( "water" ),
                                            veh->fuel_capacity( "water_clean" ) - veh->fuel_left( "water_clean" ) );
            const int purify_amount = std::min( veh->fuel_left( "battery" ), max_water );
            veh->drain( "battery", purify_amount );
            veh->drain( "water", purify_amount );
            veh->refill( "water_clean", purify_amount );
            return DONE;
        }

        case UNLOAD_TURRET: {
            g->unload( *turret.base() );
            return DONE;
        }

        case RELOAD_TURRET: {
            item::reload_option opt = g->u.select_ammo( *turret.base(), true );
            if( opt ) {
                g->u.assign_activity( ACT_RELOAD, opt.moves(), opt.qty() );
                g->u.activity.targets.emplace_back( turret.base() );
                g->u.activity.targets.push_back( std::move( opt.ammo ) );
            }
            return DONE;
        }

        case FOLD_VEHICLE:
            veh->fold_up();
            return DONE;

        case CONTROL:
            if( veh->interact_vehicle_locked() ) {
                veh->use_controls( pos );
            }
            return DONE;

        case EXAMINE:
            g->exam_vehicle( *veh );
            return DONE;

        case GET_ITEMS_ON_GROUND:
            return ITEMS_FROM_GROUND;

        case GET_ITEMS:
            return from_vehicle ? ITEMS_FROM_CARGO : ITEMS_FROM_GROUND;
    }

    return DONE;
}
Example #3
0
// Handles interactions with a vehicle in the examine menu.
interact_results interact_with_vehicle( vehicle *veh, const tripoint &pos,
                                        int veh_root_part )
{
    if( veh == nullptr ) {
        return ITEMS_FROM_GROUND;
    }

    std::vector<std::string> menu_items;
    std::vector<uimenu_entry> options_message;
    const bool has_items_on_ground = g->m.sees_some_items( pos, g->u );
    const bool items_are_sealed = g->m.has_flag( "SEALED", pos );

    auto turret = veh->turret_query( pos );

    const bool has_kitchen = ( veh->part_with_feature( veh_root_part, "KITCHEN" ) >= 0 );
    const bool has_faucet = ( veh->part_with_feature( veh_root_part, "FAUCET" ) >= 0 );
    const bool has_weldrig = ( veh->part_with_feature( veh_root_part, "WELDRIG" ) >= 0 );
    const bool has_chemlab = ( veh->part_with_feature( veh_root_part, "CHEMLAB" ) >= 0 );
    const bool has_purify = ( veh->part_with_feature( veh_root_part, "WATER_PURIFIER" ) >= 0 );
    const bool has_controls = ( ( veh->part_with_feature( veh_root_part, "CONTROLS" ) >= 0 ) ||
                                ( veh->part_with_feature( veh_root_part, "CTRL_ELECTRONIC" ) >= 0 ) );
    const int cargo_part = veh->part_with_feature( veh_root_part, "CARGO", false );
    const bool from_vehicle = cargo_part >= 0 && !veh->get_items( cargo_part ).empty();
    const bool can_be_folded = veh->is_foldable();
    const bool is_convertible = ( veh->tags.count( "convertible" ) > 0 );
    const bool remotely_controlled = g->remoteveh() == veh;
    const int washing_machine_part = veh->part_with_feature( veh_root_part, "WASHING_MACHINE" );
    const bool has_washmachine = washing_machine_part >= 0;
    bool washing_machine_on = ( washing_machine_part == -1 ) ? false :
                              veh->parts[washing_machine_part].enabled;
    const bool has_monster_capture = ( veh->part_with_feature( veh_root_part,
                                       "CAPTURE_MONSTER_VEH" ) >= 0 );
    const int monster_capture_part = veh->part_with_feature( veh_root_part, "CAPTURE_MONSTER_VEH" );

    typedef enum {
        EXAMINE, TRACK, CONTROL, CONTROL_ELECTRONICS, GET_ITEMS, GET_ITEMS_ON_GROUND, FOLD_VEHICLE, UNLOAD_TURRET, RELOAD_TURRET,
        USE_HOTPLATE, FILL_CONTAINER, DRINK, USE_WELDER, USE_PURIFIER, PURIFY_TANK, USE_WASHMACHINE, USE_MONSTER_CAPTURE
    } options;
    uimenu selectmenu;

    selectmenu.addentry( EXAMINE, true, 'e', _( "Examine vehicle" ) );
    selectmenu.addentry( TRACK, true, keybind( "TOGGLE_TRACKING" ), veh->tracking_toggle_string() );

    if( has_controls ) {
        selectmenu.addentry( CONTROL, true, 'v', _( "Control vehicle" ) );
        selectmenu.addentry( CONTROL_ELECTRONICS, true, keybind( "CONTROL_MANY_ELECTRONICS" ),
                             _( "Control multiple electronics" ) );
    }

    if( has_washmachine ) {
        selectmenu.addentry( USE_WASHMACHINE, true, 'W',
                             washing_machine_on ? _( "Deactivate the washing machine" ) :
                             _( "Activate the washing machine (1.5 hours)" ) );
    }

    if( from_vehicle && !washing_machine_on ) {
        selectmenu.addentry( GET_ITEMS, true, 'g', _( "Get items" ) );
    }

    if( has_items_on_ground && !items_are_sealed ) {
        selectmenu.addentry( GET_ITEMS_ON_GROUND, true, 'i', _( "Get items on the ground" ) );
    }

    if( ( can_be_folded || is_convertible ) && !remotely_controlled ) {
        selectmenu.addentry( FOLD_VEHICLE, true, 'f', _( "Fold vehicle" ) );
    }

    if( turret.can_unload() ) {
        selectmenu.addentry( UNLOAD_TURRET, true, 'u', _( "Unload %s" ), turret.name().c_str() );
    }

    if( turret.can_reload() ) {
        selectmenu.addentry( RELOAD_TURRET, true, 'r', _( "Reload %s" ), turret.name().c_str() );
    }

    if( ( has_kitchen || has_chemlab ) && veh->fuel_left( "battery" ) > 0 ) {
        selectmenu.addentry( USE_HOTPLATE, true, 'h', _( "Use the hotplate" ) );
    }

    if( has_faucet && veh->fuel_left( "water_clean" ) > 0 ) {
        selectmenu.addentry( FILL_CONTAINER, true, 'c', _( "Fill a container with water" ) );

        selectmenu.addentry( DRINK, true, 'd', _( "Have a drink" ) );
    }

    if( has_weldrig && veh->fuel_left( "battery" ) > 0 ) {
        selectmenu.addentry( USE_WELDER, true, 'w', _( "Use the welding rig?" ) );
    }

    if( has_purify ) {
        bool can_purify = veh->fuel_left( "battery" ) >=
                          item::find_type( "water_purifier" )->charges_to_use();

        selectmenu.addentry( USE_PURIFIER, can_purify,
                             'p', _( "Purify water in carried container" ) );

        selectmenu.addentry( PURIFY_TANK, can_purify && veh->fuel_left( "water" ),
                             'P', _( "Purify water in vehicle tank" ) );
    }
    if( has_monster_capture ) {
        selectmenu.addentry( USE_MONSTER_CAPTURE, true, 'G', _( "Capture or release a creature" ) );
    }

    int choice;
    if( selectmenu.entries.size() == 1 ) {
        choice = selectmenu.entries.front().retval;
    } else {
        selectmenu.return_invalid = true;
        selectmenu.text = _( "Select an action" );
        selectmenu.selected = 0;
        selectmenu.query();
        choice = selectmenu.ret;
    }

    auto veh_tool = [&]( const itype_id & obj ) {
        item pseudo( obj );
        if( veh->fuel_left( "battery" ) < pseudo.ammo_required() ) {
            return false;
        }
        auto qty = pseudo.ammo_capacity() - veh->discharge_battery( pseudo.ammo_capacity() );
        pseudo.ammo_set( "battery", qty );
        g->u.invoke_item( &pseudo );
        veh->charge_battery( pseudo.ammo_remaining() );
        return true;
    };

    switch( static_cast<options>( choice ) ) {
        case USE_MONSTER_CAPTURE: {
            veh->use_monster_capture( monster_capture_part, pos );
            return DONE;
        }

        case USE_HOTPLATE:
            veh_tool( "hotplate" );
            return DONE;

        case USE_WASHMACHINE: {
            veh->use_washing_machine( washing_machine_part );
            return DONE;
        }

        case FILL_CONTAINER:
            g->u.siphon( *veh, "water_clean" );
            return DONE;

        case DRINK: {
            item water( "water_clean", 0 );
            if( g->u.eat( water ) ) {
                veh->drain( "water_clean", 1 );
                g->u.moves -= 250;
            }
            return DONE;
        }

        case USE_WELDER: {
            if( veh_tool( "welder" ) ) {
                // Evil hack incoming
                auto &act = g->u.activity;
                if( act.id() == activity_id( "ACT_REPAIR_ITEM" ) ) {
                    // Magic: first tell activity the item doesn't really exist
                    act.index = INT_MIN;
                    // Then tell it to search it on `pos`
                    act.coords.push_back( pos );
                    // Finally tell if it is the vehicle part with welding rig
                    act.values.resize( 2 );
                    act.values[1] = veh->part_with_feature( veh_root_part, "WELDRIG" );
                }
            }
            return DONE;
        }

        case USE_PURIFIER:
            veh_tool( "water_purifier" );
            return DONE;

        case PURIFY_TANK: {
            auto sel = []( const vehicle_part & pt ) {
                return pt.is_tank() && pt.ammo_current() == "water";
            };

            auto title = string_format( _( "Purify <color_%s>water</color> in tank" ),
                                        get_all_colors().get_name( item::find_type( "water" )->color ).c_str() );

            auto &tank = veh_interact::select_part( *veh, sel, title );

            if( tank ) {
                double cost = item::find_type( "water_purifier" )->charges_to_use();

                if( veh->fuel_left( "battery" ) < tank.ammo_remaining() * cost ) {
                    //~ $1 - vehicle name, $2 - part name
                    add_msg( m_bad, _( "Insufficient power to purify the contents of the %1$s's %2$s" ),
                             veh->name.c_str(), tank.name().c_str() );

                } else {
                    //~ $1 - vehicle name, $2 - part name
                    add_msg( m_good, _( "You purify the contents of the %1$s's %2$s" ),
                             veh->name.c_str(), tank.name().c_str() );

                    veh->discharge_battery( tank.ammo_remaining() * cost );
                    tank.ammo_set( "water_clean", tank.ammo_remaining() );
                }
            }
            return DONE;
        }

        case UNLOAD_TURRET: {
            g->unload( *turret.base() );
            return DONE;
        }

        case RELOAD_TURRET: {
            item::reload_option opt = g->u.select_ammo( *turret.base(), true );
            if( opt ) {
                g->u.assign_activity( activity_id( "ACT_RELOAD" ), opt.moves(), opt.qty() );
                g->u.activity.targets.emplace_back( turret.base() );
                g->u.activity.targets.push_back( std::move( opt.ammo ) );
            }
            return DONE;
        }

        case FOLD_VEHICLE:
            veh->fold_up();
            return DONE;

        case CONTROL:
            veh->use_controls( pos );
            return DONE;

        case CONTROL_ELECTRONICS:
            veh->control_electronics();
            return DONE;

        case EXAMINE:
            g->exam_vehicle( *veh );
            return DONE;

        case TRACK:
            veh->toggle_tracking( );
            return DONE;

        case GET_ITEMS_ON_GROUND:
            return ITEMS_FROM_GROUND;

        case GET_ITEMS:
            return from_vehicle ? ITEMS_FROM_CARGO : ITEMS_FROM_GROUND;
    }

    return DONE;
}