Example #1
0
void board_up( map &m, int sx, int sy, int dx, int dy )
{
    std::vector<point> furnitures1;
    std::vector<point> furnitures2;
    std::vector<point> boardables;
    for( int x = sx; x < sx + dx; x++ ) {
        for( int y = sy; y < sy + dy; y++ ) {
            bool must_board_around = false;
            const ter_id t = m.ter( x, y );
            if( t == t_window_domestic || t == t_window ) {
                // Windows are always to the outside and must be boarded
                must_board_around = true;
                m.ter_set( x, y, t_window_boarded );
            } else if( t == t_door_c || t == t_door_locked || t == t_door_c_peep ) {
                // Only board up doors that lead to the outside
                if( m.is_outside( x + 1, y ) || m.is_outside( x - 1, y ) ||
                    m.is_outside( x, y + 1 ) || m.is_outside( x, y - 1 ) ) {
                    m.ter_set( x, y, t_door_boarded );
                    must_board_around = true;
                } else {
                    // internal doors are opened instead
                    m.ter_set( x, y, t_door_o );
                }
            }
            if( must_board_around ) {
                // Board up the surroundings of the door/window
                add_boardable( m, point( x + 1, y ), boardables );
                add_boardable( m, point( x - 1, y ), boardables );
                add_boardable( m, point( x, y + 1 ), boardables );
                add_boardable( m, point( x, y - 1 ), boardables );
                add_boardable( m, point( x + 1, y + 1 ), boardables );
                add_boardable( m, point( x - 1, y + 1 ), boardables );
                add_boardable( m, point( x + 1, y - 1 ), boardables );
                add_boardable( m, point( x - 1, y - 1 ), boardables );
            }
        }
    }
    // Find all furniture that can be used to board up some place
    for( int x = sx; x < sx + dx; x++ ) {
        for( int y = sy; y < sy + dy; y++ ) {
            if( std::find( boardables.begin(), boardables.end(), point( x, y ) ) != boardables.end() ) {
                continue;
            }
            if( !m.has_furn( x, y ) ) {
                continue;
            }
            // If the furniture is movable and the character can move it, use it to barricade
            // g->u is workable here as NPCs by definition are not starting the game.  (Let's hope.)
            if( (m.furn_at( x, y ).move_str_req > 0) && (m.furn_at( x, y ).move_str_req < g->u.get_str() )) {
                if( m.furn_at( x, y ).movecost == 0 ) {
                    // Obstacles are better, prefer them
                    furnitures1.push_back( point( x, y ) );
                } else {
                    furnitures2.push_back( point( x, y ) );
                }
            }
        }
    }
    while( ( !furnitures1.empty() || !furnitures2.empty() ) && !boardables.empty() ) {
        const point fp = furnitures1.empty() ?
            get_random_from_vec( furnitures2 ) : get_random_from_vec( furnitures1 );
        const point bp = get_random_from_vec( boardables );
        m.furn_set( bp.x, bp.y, m.furn( fp.x, fp.y ) );
        m.furn_set( fp.x, fp.y, f_null );
        auto destination_items = m.i_at(bp.x, bp.y);
        for( auto moved_item : m.i_at(fp.x, fp.y) ) {
            destination_items.push_back( moved_item );
        }
        m.i_clear( fp.x, fp.y );
    }
}
void board_up( map &m, const tripoint &start, const tripoint &end )
{
    std::vector<tripoint> furnitures1;
    std::vector<tripoint> furnitures2;
    std::vector<tripoint> boardables;
    tripoint p;
    p.z = m.get_abs_sub().z;
    int &x = p.x;
    int &y = p.y;
    int &z = p.z;
    for( x = start.x; x < end.x; x++ ) {
        for( y = start.y; y < end.y; y++ ) {
            bool must_board_around = false;
            const ter_id t = m.ter( x, y );
            if( t == t_window_domestic || t == t_window || t == t_window_no_curtains ) {
                // Windows are always to the outside and must be boarded
                must_board_around = true;
                m.ter_set( p, t_window_boarded );
            } else if( t == t_door_c || t == t_door_locked || t == t_door_c_peep ) {
                // Only board up doors that lead to the outside
                if( m.is_outside( tripoint( x + 1, y, z ) ) ||
                    m.is_outside( tripoint( x - 1, y, z ) ) ||
                    m.is_outside( tripoint( x, y + 1, z ) ) ||
                    m.is_outside( tripoint( x, y - 1, z ) ) ) {
                    m.ter_set( p, t_door_boarded );
                    must_board_around = true;
                } else {
                    // internal doors are opened instead
                    m.ter_set( p, t_door_o );
                }
            }
            if( must_board_around ) {
                // Board up the surroundings of the door/window
                add_boardable( m, tripoint( x + 1, y, z ), boardables );
                add_boardable( m, tripoint( x - 1, y, z ), boardables );
                add_boardable( m, tripoint( x, y + 1, z ), boardables );
                add_boardable( m, tripoint( x, y - 1, z ), boardables );
                add_boardable( m, tripoint( x + 1, y + 1, z ), boardables );
                add_boardable( m, tripoint( x - 1, y + 1, z ), boardables );
                add_boardable( m, tripoint( x + 1, y - 1, z ), boardables );
                add_boardable( m, tripoint( x - 1, y - 1, z ), boardables );
            }
        }
    }
    // Find all furniture that can be used to board up some place
    for( x = start.x; x < end.x; x++ ) {
        for( y = start.y; y < end.y; y++ ) {
            if( std::find( boardables.begin(), boardables.end(), p ) != boardables.end() ) {
                continue;
            }
            if( !m.has_furn( p ) ) {
                continue;
            }
            // If the furniture is movable and the character can move it, use it to barricade
            // g->u is workable here as NPCs by definition are not starting the game.  (Let's hope.)
            ///\EFFECT_STR determines what furniture might be used as a starting area barricade
            if( m.furn( p ).obj().move_str_req > 0 && m.furn( p ).obj().move_str_req < g->u.get_str() ) {
                if( m.furn( p ).obj().movecost == 0 ) {
                    // Obstacles are better, prefer them
                    furnitures1.push_back( p );
                } else {
                    furnitures2.push_back( p );
                }
            }
        }
    }
    while( ( !furnitures1.empty() || !furnitures2.empty() ) && !boardables.empty() ) {
        const tripoint fp = random_entry_removed( furnitures1.empty() ? furnitures2 : furnitures1 );
        const tripoint bp = random_entry_removed( boardables );
        m.furn_set( bp, m.furn( fp ) );
        m.furn_set( fp, f_null );
        auto destination_items = m.i_at( bp );
        for( auto moved_item : m.i_at( fp ) ) {
            destination_items.push_back( moved_item );
        }
        m.i_clear( fp );
    }
}
void inventory::form_from_map( map &m, const tripoint &origin, int range, bool assign_invlet,
                               bool clear_path )
{
    items.clear();
    for( const tripoint &p : m.points_in_radius( origin, range ) ) {
        // can not reach this -> can not access its contents
        if( clear_path ) {
            if( origin != p && !m.clear_path( origin, p, range, 1, 100 ) ) {
                continue;
            }
        }
        if( m.has_furn( p ) ) {
            const furn_t &f = m.furn( p ).obj();
            const itype *type = f.crafting_pseudo_item_type();
            if( type != nullptr ) {
                const itype *ammo = f.crafting_ammo_item_type();
                item furn_item( type, calendar::turn, 0 );
                furn_item.item_tags.insert( "PSEUDO" );
                furn_item.charges = ammo ? count_charges_in_list( ammo, m.i_at( p ) ) : 0;
                add_item( furn_item );
            }
        }
        if( m.accessible_items( p ) ) {
            for( auto &i : m.i_at( p ) ) {
                if( !i.made_of( LIQUID ) ) {
                    add_item( i, false, assign_invlet );
                }
            }
        }
        // Kludges for now!
        if( m.has_nearby_fire( p, 0 ) ) {
            item fire( "fire", 0 );
            fire.charges = 1;
            add_item( fire );
        }
        // Handle any water from infinite map sources.
        item water = m.water_from( p );
        if( !water.is_null() ) {
            add_item( water );
        }
        // kludge that can probably be done better to check specifically for toilet water to use in
        // crafting
        if( m.furn( p ).obj().examine == &iexamine::toilet ) {
            // get water charges at location
            auto toilet = m.i_at( p );
            auto water = toilet.end();
            for( auto candidate = toilet.begin(); candidate != toilet.end(); ++candidate ) {
                if( candidate->typeId() == "water" ) {
                    water = candidate;
                    break;
                }
            }
            if( water != toilet.end() && water->charges > 0 ) {
                add_item( *water );
            }
        }

        // keg-kludge
        if( m.furn( p ).obj().examine == &iexamine::keg ) {
            auto liq_contained = m.i_at( p );
            for( auto &i : liq_contained ) {
                if( i.made_of( LIQUID ) ) {
                    add_item( i );
                }
            }
        }

        // WARNING: The part below has a bug that's currently quite minor
        // When a vehicle has multiple faucets in range, available water is
        //  multiplied by the number of faucets.
        // Same thing happens for all other tools and resources, but not cargo
        const optional_vpart_position vp = m.veh_at( p );
        if( !vp ) {
            continue;
        }
        vehicle *const veh = &vp->vehicle();

        //Adds faucet to kitchen stuff; may be horribly wrong to do such....
        //ShouldBreak into own variable
        const cata::optional<vpart_reference> kpart = vp.part_with_feature( "KITCHEN", true );
        const cata::optional<vpart_reference> faupart = vp.part_with_feature( "FAUCET", true );
        const cata::optional<vpart_reference> weldpart = vp.part_with_feature( "WELDRIG", true );
        const cata::optional<vpart_reference> craftpart = vp.part_with_feature( "CRAFTRIG", true );
        const cata::optional<vpart_reference> forgepart = vp.part_with_feature( "FORGE", true );
        const cata::optional<vpart_reference> kilnpart = vp.part_with_feature( "KILN", true );
        const cata::optional<vpart_reference> chempart = vp.part_with_feature( "CHEMLAB", true );
        const cata::optional<vpart_reference> cargo = vp.part_with_feature( "CARGO", true );

        if( cargo ) {
            const auto items = veh->get_items( cargo->part_index() );
            *this += std::list<item>( items.begin(), items.end() );
        }

        if( faupart ) {
            for( const auto &it : veh->fuels_left() ) {
                item fuel( it.first, 0 );
                if( fuel.made_of( LIQUID ) ) {
                    fuel.charges = it.second;
                    add_item( fuel );
                }
            }
        }

        if( kpart ) {
            item hotplate( "hotplate", 0 );
            hotplate.charges = veh->fuel_left( "battery", true );
            hotplate.item_tags.insert( "PSEUDO" );
            add_item( hotplate );

            item pot( "pot", 0 );
            pot.item_tags.insert( "PSEUDO" );
            add_item( pot );
            item pan( "pan", 0 );
            pan.item_tags.insert( "PSEUDO" );
            add_item( pan );
        }
        if( weldpart ) {
            item welder( "welder", 0 );
            welder.charges = veh->fuel_left( "battery", true );
            welder.item_tags.insert( "PSEUDO" );
            add_item( welder );

            item soldering_iron( "soldering_iron", 0 );
            soldering_iron.charges = veh->fuel_left( "battery", true );
            soldering_iron.item_tags.insert( "PSEUDO" );
            add_item( soldering_iron );
        }
        if( craftpart ) {
            item vac_sealer( "vac_sealer", 0 );
            vac_sealer.charges = veh->fuel_left( "battery", true );
            vac_sealer.item_tags.insert( "PSEUDO" );
            add_item( vac_sealer );

            item dehydrator( "dehydrator", 0 );
            dehydrator.charges = veh->fuel_left( "battery", true );
            dehydrator.item_tags.insert( "PSEUDO" );
            add_item( dehydrator );

            item food_processor( "food_processor", 0 );
            food_processor.charges = veh->fuel_left( "battery", true );
            food_processor.item_tags.insert( "PSEUDO" );
            add_item( food_processor );

            item press( "press", 0 );
            press.charges = veh->fuel_left( "battery", true );
            press.item_tags.insert( "PSEUDO" );
            add_item( press );
        }
        if( forgepart ) {
            item forge( "forge", 0 );
            forge.charges = veh->fuel_left( "battery", true );
            forge.item_tags.insert( "PSEUDO" );
            add_item( forge );
        }
        if( kilnpart ) {
            item kiln( "kiln", 0 );
            kiln.charges = veh->fuel_left( "battery", true );
            kiln.item_tags.insert( "PSEUDO" );
            add_item( kiln );
        }
        if( chempart ) {
            item hotplate( "hotplate", 0 );
            hotplate.charges = veh->fuel_left( "battery", true );
            hotplate.item_tags.insert( "PSEUDO" );
            add_item( hotplate );

            item chemistry_set( "chemistry_set", 0 );
            chemistry_set.charges = veh->fuel_left( "battery", true );
            chemistry_set.item_tags.insert( "PSEUDO" );
            add_item( chemistry_set );
        }
    }
}