Пример #1
0
 public bool PlaceShape(Dungeon room_to_be_placed,bool force_connection,bool force_cardinal_direction_connection,bool allow_room_placement_under_features,params CellType[] allowed_to_overwrite)
 {
     int first_row = H+1;
     int first_col = W+1; //todo: this doesn't respect the map boundaries yet - it can overwrite the edge walls with the room.
     int last_row = -1;
     int last_col = -1;
     for(int i=0;i<room_to_be_placed.H;++i){
         for(int j=0;j<room_to_be_placed.W;++j){
             if(!room_to_be_placed[i,j].IsWall()){
                 if(i < first_row){
                     first_row = i;
                 }
                 if(i > last_row){
                     last_row = i;
                 }
                 if(j < first_col){
                     first_col = j;
                 }
                 if(j > last_col){
                     last_col = j;
                 }
             }
         }
     }
     Dungeon room = new Dungeon((last_row - first_row) + 1,(last_col - first_col) + 1);
     int rh = room.H;
     int rw = room.W; //'force connection' means that the added room must connect somehow to the existing passable tiles of the map.
     for(int i=0;i<rh;++i){
         for(int j=0;j<rw;++j){
             room[i,j] = room_to_be_placed[i+first_row,j+first_col];
         }
     }
     List<pos> positions = map.AllPositions().Where(x=>x.row < H-rh && x.col < W-rw).Randomize(); //'allow room placement under features' means, if the room has a floor and the map has a feature in the same location, that won't disqualify placement - instead, if the room passes, the feature will appear instead of the floor.
     Dungeon connected = new Dungeon(rh,rw);
     for(int num=0;num<positions.Count;++num){
         pos p = positions[num];
         bool bad_connection = force_connection;
         for(int i=0;i<rh;++i){
             for(int j=0;j<rw;++j){
                 if(room[i,j].IsPassable()){
                     foreach(pos neighbor in new pos(i,j).PositionsWithinDistance(1)){
                         pos neighbor_offset = new pos(p.row + neighbor.row,p.col + neighbor.col);
                         if(!force_cardinal_direction_connection){ //if this bool is set, check later.
                             if(map.BoundsCheck(neighbor_offset) && map[neighbor_offset].IsPassable()){
                                 bad_connection = false;
                             }
                         }
                         if(connected.BoundsCheck(neighbor)){
                             connected[neighbor] = map[neighbor_offset];
                         }
                     }
                     if(force_cardinal_direction_connection){
                         foreach(pos neighbor in new pos(i,j).CardinalAdjacentPositions()){
                             if(connected.BoundsCheck(neighbor) && map[p.row+neighbor.row,p.col+neighbor.col].IsPassable()){
                                 bad_connection = false;
                             }
                         }
                     }
                 }
             }
         }
         if(!bad_connection && connected.IsFullyConnected()){
             bool valid = true;
             for(int i=0;i<rh && valid;++i){
                 for(int j=0;j<rw && valid;++j){
                     if(room[i,j] != CellType.Wall){
                         bool this_position_valid = false;
                         if(map[p.row+i,p.col+j].IsWall()){
                             this_position_valid = true;
                         }
                         if(map[p.row+i,p.col+j].Is(allowed_to_overwrite)){
                             this_position_valid = true;
                         }
                         if(map[p.row+i,p.col+j] == room[i,j]){
                             this_position_valid = true;
                         }
                         if(map[p.row+i,p.col+j].IsFloor() && room[i,j].IsFloor()){
                             this_position_valid = true;
                         }
                         if(room[i,j].IsFloor() && allow_room_placement_under_features){
                             this_position_valid = true;
                         }
                         if(!this_position_valid){
                             valid = false;
                         }
                     }
                 }
             }
             if(valid){
                 for(int i=0;i<rh;++i){
                     for(int j=0;j<rw;++j){
                         if(room[i,j] != CellType.Wall){
                             if(map[p.row+i,p.col+j].IsWall() || map[p.row+i,p.col+j].Is(allowed_to_overwrite)){
                                 map[p.row+i,p.col+j] = room[i,j];
                             }
                         }
                     }
                 }
                 return true;
             }
         }
     }
     return false;
 }