// check if tile at p should be boarded with some kind of furniture. void add_boardable( map &m, const tripoint &p, std::vector<tripoint> &vec ) { if( m.has_furn( p ) ) { // Don't need to board this up, is already occupied return; } if( m.ter( p ) != t_floor ) { // Other terrain (door, wall, ...), not boarded either return; } if( m.is_outside( p ) ) { // Don't board up the outside return; } if( std::find( vec.begin(), vec.end(), p ) != vec.end() ) { // Already registered to be boarded return; } vec.push_back( p ); }
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 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 ); } }