// // Digging map generator (third) // By Jim Babcock // // This program is part of the article 'Digging Features' and may be // distributed under the same terms as that article. // // www.jimrandomh.org/rldev // #include #include #include #include #include using namespace std; // // Some handy things about vectors: // // point + direction = one step away from (point) in (direction) // point + direction*num = (num) steps in (direction) away from (point) // dir.right() = 90 degrees clockwise from dir // dir.left() = 90 degrees counter-clockwise from dir // class Vector { public: int x, y; inline Vector() { x=y=0; } inline Vector(int x, int y) { this->x=x; this->y=y; } inline Vector operator+(const Vector &vec) { return Vector(x+vec.x, y+vec.y); } inline Vector operator-(const Vector &vec) { return Vector(x-vec.x, y-vec.y); } inline Vector& operator+=(const Vector &vec) { x += vec.x; y += vec.y; return *this; } inline Vector& operator-=(const Vector &vec) { x -= vec.x; y -= vec.y; return *this; } inline Vector operator*(int scalar) { return Vector(x*scalar, y*scalar); } inline friend Vector operator*(int scalar, Vector vec) { return Vector(vec.x*scalar, vec.y*scalar); } inline bool operator==(const Vector &vec) { return x==vec.x && y==vec.y; } inline bool operator!=(const Vector &vec) { return x!=vec.x || y!=vec.y; } inline Vector left() { return Vector(y, -x); } inline Vector right() { return Vector(-y, x); } }; int dig_random(Vector pos, Vector heading); int dig_room(Vector entrance, Vector heading); int dig_corridor(Vector entrance, Vector heading); int is_in_bounds(Vector v); int is_in_bounds_or_border(Vector v); int is_known(Vector v); int is_floor(Vector v); int is_wall(Vector v); int is_permawall(Vector v); void dig_tile(Vector v); void door_tile(Vector v); void fill_tile(Vector v); void permawall_tile(Vector v); int rand_range(int Min, int Max); enum { TILE_UNKNOWN, TILE_FLOOR, TILE_WALL, TILE_PERMAWALL, TILE_DOOR }; int **grid; int size_x, size_y; const int max_tries = 5; class Doorway { public: Doorway(Vector l, Vector h, bool door) { location=l; heading=h; has_door=door; } Vector location, heading; bool has_door; }; std::vector doorways; void dig_loop(void) { Vector entrance = Vector(size_x/2, size_y-1); doorways.push_back(Doorway(entrance, Vector(0, -1), true)); door_tile(entrance); fill_tile(entrance+Vector(1, 0)); fill_tile(entrance-Vector(1, 0)); while(doorways.size() > 0) { int which = rand_range(0, doorways.size()-1); Doorway door = doorways[which]; doorways.erase(doorways.begin()+which); if(dig_random(door.location, door.heading)) { if(door.has_door) door_tile(door.location); else if(is_wall(door.location)) dig_tile(door.location); } } } // Dig either a room or a corridor. Retry until something fits, or max_tries // times total. int dig_random(Vector pos, Vector heading) { int success = 0; int tries; for(tries=0; tries // size.x // <----> // entrance_offset size.x = rand_range(3, 6); size.y = rand_range(3, 6); entrance_offset = rand_range(1, size.x); corner = entrance + (heading.left()*entrance_offset); // Check the area to see if any of it has already been dug pos=corner; for(int yi=0; yi=1 && v.y>=1 && v.x=0 && v.y>=0 && v.x