diff options
-rw-r--r-- | crawl-ref/source/dat/vaults.des | 2 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.cc | 133 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/misc.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/misc.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/travel.cc | 38 | ||||
-rw-r--r-- | crawl-ref/source/travel.h | 13 |
7 files changed, 175 insertions, 20 deletions
diff --git a/crawl-ref/source/dat/vaults.des b/crawl-ref/source/dat/vaults.des index 462daef33c..d6120a354d 100644 --- a/crawl-ref/source/dat/vaults.des +++ b/crawl-ref/source/dat/vaults.des @@ -2323,6 +2323,7 @@ TAGS: entry no_monster_gen # damn those fish! ORIENT: float ITEM: ring of levitation, potion of levitation +FLAGS: no_rotate MAP xxxxccccccccwwwww..wwww..wwwwwww....wwwwwww..wwww...wccccxxxxxx @@ -2535,6 +2536,7 @@ ENDMAP NAME: erik_entry_18 TAGS: entry ORIENT: float +FLAGS: no_rotate MONS: giant bat, small snake, worm, gnoll, imp, orc ITEM: stone, scroll of paper, banana, potion of healing diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 3c246cb906..34e1b81903 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -52,6 +52,7 @@ #include "randart.h" #include "spl-book.h" #include "stuff.h" +#include "travel.h" #define MAX_PIT_MONSTERS 10 @@ -72,6 +73,9 @@ struct spec_t { typedef struct spec_t spec_room; // DUNGEON BUILDERS +static void build_dungeon_level(int level_number, int level_type); +static bool valid_dungeon_level(int level_number, int level_type); + static bool find_in_area(int sx, int sy, int ex, int ey, unsigned char feature); static bool make_box(int room_x1, int room_y1, int room_x2, int room_y2, unsigned char floor=0, unsigned char wall=0, unsigned char avoid=0); @@ -165,6 +169,8 @@ static dgn_region_list no_monster_zones; static dgn_region_list no_pool_fixup_zones; static dgn_region_list no_door_fixup_zones; +static std::vector<vault_placement> level_vaults; + static std::string level_name(int subdepth) { return place_name( @@ -211,11 +217,132 @@ static void place_altars() /********************************************************************** * builder() - kickoff for the dungeon generator. *********************************************************************/ -void builder(int level_number, char level_type) +void builder(int level_number, int level_type) +{ + do + build_dungeon_level(level_number, level_type); + while (!valid_dungeon_level(level_number, level_type)); +} + +static coord_def find_level_feature(int feat) +{ + for (int y = 1; y < GYM; ++y) + { + for (int x = 1; x < GXM; ++x) + { + if (grd[x][y] == feat) + return coord_def(x, y); + } + } + return coord_def(0, 0); +} + +class feature_find : public travel_pathfind +{ +public: + feature_find(); + + void add_feat(int feat); + coord_def find_first_from(const coord_def &c); + + bool did_leave_vault() const { return left_vault; } + +protected: + bool path_flood(const coord_def &c, const coord_def &dc); +protected: + bool needed_features[NUM_FEATURES]; + bool left_vault; + dgn_region_list vaults; +}; + +feature_find::feature_find() + : travel_pathfind(), needed_features(), left_vault(false), vaults() +{ + memset(needed_features, false, sizeof needed_features); +} + +void feature_find::add_feat(int feat) +{ + if (feat >= 0 && feat < NUM_FEATURES) + needed_features[feat] = true; +} + +coord_def feature_find::find_first_from(const coord_def &c) +{ + set_floodseed(c); + + for (int i = 0, size = level_vaults.size(); i < size; ++i) + { + const vault_placement &p = level_vaults[i]; + vaults.push_back( dgn_region(p.x, p.y, p.width, p.height) ); + } + + return pathfind(RMODE_EXPLORE); +} + +bool feature_find::path_flood(const coord_def &c, const coord_def &dc) +{ + if (!in_bounds(dc)) + return (false); + + const int grid = grd(dc); + if (needed_features[ grid ]) + { + unexplored_place = dc; + unexplored_dist = traveled_distance; + return (true); + } + + if (!is_travelsafe_square(dc.x, dc.y, false, true) + && grid != DNGN_SECRET_DOOR + && !grid_is_trap(grid)) + { + return (false); + } + + if (unforbidden(dc, vaults)) + left_vault = true; + + good_square(dc); + + return (false); +} + +static bool has_connected_downstairs_from(const coord_def &c) +{ + feature_find ff; + ff.add_feat(DNGN_STONE_STAIRS_DOWN_I); + ff.add_feat(DNGN_STONE_STAIRS_DOWN_II); + ff.add_feat(DNGN_STONE_STAIRS_DOWN_III); + ff.add_feat(DNGN_ROCK_STAIRS_DOWN); + + coord_def where = ff.find_first_from(c); + return (where.x || !ff.did_leave_vault()); +} + +static bool is_level_stair_connected() +{ + coord_def up = find_level_feature(DNGN_STONE_STAIRS_UP_I); + if (up.x && up.y) + return has_connected_downstairs_from(up); + + return (false); +} + +static bool valid_dungeon_level(int level_number, int level_type) +{ + if (level_number == 0 && level_type == LEVEL_DUNGEON) + return is_level_stair_connected(); + + return (true); +} + +static void build_dungeon_level(int level_number, int level_type) { int i; // generic loop variable int x,y; // generic map loop variables + level_vaults.clear(); no_monster_zones.clear(); no_pool_fixup_zones.clear(); no_door_fixup_zones.clear(); @@ -5192,6 +5319,8 @@ static void build_minivaults(int level_number, int force_vault) vault_placement place; vault_main(vgrid, place, force_vault, level_number); + level_vaults.push_back(place); + int vx, vy; int v1x, v1y; @@ -5492,6 +5621,8 @@ static void build_vaults(int level_number, int force_vault) int gluggy = vault_main(vgrid, place, force_vault, level_number); + level_vaults.push_back(place); + int vx, vy; int num_runes = 0; diff --git a/crawl-ref/source/dungeon.h b/crawl-ref/source/dungeon.h index c2122f8c37..2e06159615 100644 --- a/crawl-ref/source/dungeon.h +++ b/crawl-ref/source/dungeon.h @@ -33,7 +33,7 @@ void item_colour( item_def &item ); /* *********************************************************************** * called from: files * *********************************************************************** */ -void builder(int level_number, char level_type); +void builder(int level_number, int level_type); // last updated 12may2000 {dlb} diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index af5174d97f..3c9f0755fa 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -173,6 +173,12 @@ bool grid_is_solid(const coord_def &c) return (grid_is_solid(grd(c))); } +bool grid_is_trap(int grid) +{ + return (grid == DNGN_TRAP_MECHANICAL || grid == DNGN_TRAP_MAGICAL + || grid == DNGN_TRAP_III); +} + bool grid_is_water( int grid ) { return (grid == DNGN_SHALLOW_WATER || grid == DNGN_DEEP_WATER); diff --git a/crawl-ref/source/misc.h b/crawl-ref/source/misc.h index 4106ee231a..10d168a06c 100644 --- a/crawl-ref/source/misc.h +++ b/crawl-ref/source/misc.h @@ -136,6 +136,7 @@ bool grid_is_opaque(int grid); bool grid_is_solid(int grid); bool grid_is_solid(int x, int y); bool grid_is_solid(const coord_def &c); +bool grid_is_trap(int grid); bool grid_is_water(int grid); bool grid_is_watery( int grid ); diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc index 57cc5d0d60..a3983a4145 100644 --- a/crawl-ref/source/travel.cc +++ b/crawl-ref/source/travel.cc @@ -128,25 +128,19 @@ bool is_player_mapped(unsigned char envch) return envch && envch != get_magicmap_char(DNGN_FLOOR) && envch != '~'; } -inline bool is_trap(unsigned char grid) -{ - return (grid == DNGN_TRAP_MECHANICAL || grid == DNGN_TRAP_MAGICAL - || grid == DNGN_TRAP_III); -} - // Returns true if there is a known trap at (x,y). Returns false for non-trap // squares as also for undiscovered traps. // inline bool is_trap(int x, int y) { - return is_trap( grd[x][y] ); + return grid_is_trap( grd[x][y] ); } // Returns true if this feature takes extra time to cross. inline int feature_traverse_cost(unsigned char feature) { return (feature == DNGN_SHALLOW_WATER || feature == DNGN_CLOSED_DOOR? 2 : - is_trap(feature) ? 3 : 1); + grid_is_trap(feature) ? 3 : 1); } // Returns true if the dungeon feature supplied is an altar. @@ -362,9 +356,10 @@ static bool is_reseedable(int x, int y) * is true, returns true even for dungeon features the character can normally * not cross safely (deep water, lava, traps). */ -static bool is_travel_ok(int x, int y, bool ignore_hostile) +bool is_travelsafe_square(int x, int y, bool ignore_hostile, + bool ignore_terrain_knowledge) { - if (!is_terrain_known(x, y)) + if (!ignore_terrain_knowledge && !is_terrain_known(x, y)) return (false); const int grid = grd[x][y]; @@ -1110,6 +1105,10 @@ travel_pathfind::travel_pathfind() { } +travel_pathfind::~travel_pathfind() +{ +} + static bool is_greed_inducing_square(const LevelStashes *ls, const coord_def &c) { if (ls && ls->needs_visit(c.x, c.y)) @@ -1249,7 +1248,7 @@ const coord_def travel_pathfind::pathfind(run_mode_type rmode) // Abort run if we're trying to go someplace evil. Travel to traps is // specifically allowed here if the player insists on it. if (!floodout - && !is_travel_ok(start.x, start.y, false) + && !is_travelsafe_square(start.x, start.y, false) && !is_trap(start.x, start.y)) // The player likes pain { return coord_def(0, 0); @@ -1367,7 +1366,7 @@ void travel_pathfind::check_square_greed(const coord_def &c) { if (greedy_dist == UNFOUND_DIST && is_greed_inducing_square(c) - && is_travel_ok(c.x, c.y, ignore_hostile)) + && is_travelsafe_square(c.x, c.y, ignore_hostile)) { greedy_place = c; greedy_dist = traveled_distance; @@ -1429,7 +1428,7 @@ bool travel_pathfind::path_flood(const coord_def &c, const coord_def &dc) return (true); } - if (dc != dest && !is_travel_ok(dc.x, dc.y, ignore_hostile)) + if (dc != dest && !is_travelsafe_square(dc.x, dc.y, ignore_hostile)) { // This point is not okay to travel on, but if this is a // trap, we'll want to put it on the feature vector anyway. @@ -1504,6 +1503,17 @@ bool travel_pathfind::path_flood(const coord_def &c, const coord_def &dc) return (false); } +void travel_pathfind::good_square(const coord_def &c) +{ + if (!point_distance[c.x][c.y]) + { + // This point is going to be on the agenda for the next + // iteration + circumference[!circ_index][next_iter_points++] = c; + point_distance[c.x][c.y] = traveled_distance; + } +} + bool travel_pathfind::path_examine_point(const coord_def &c) { if (square_slows_movement(c)) @@ -2411,7 +2421,7 @@ void start_travel(int x, int y) if (travel_point_distance[x][y] == 0 && (x != you.x_pos || you.running.y != you.y_pos) - && is_travel_ok(x, y, false) + && is_travelsafe_square(x, y, false) && can_travel_interlevel()) { // We'll need interlevel travel to get here. diff --git a/crawl-ref/source/travel.h b/crawl-ref/source/travel.h index 6493e37209..97491884c1 100644 --- a/crawl-ref/source/travel.h +++ b/crawl-ref/source/travel.h @@ -42,6 +42,9 @@ bool is_player_mapped(int grid_x, int grid_y); void find_travel_pos(int you_x, int you_y, char *move_x, char *move_y, std::vector<coord_def>* coords = NULL); +bool is_travelsafe_square(int x, int y, bool ignore_hostile = false, + bool ignore_terrain_knowledge = false); + /* *********************************************************************** * Initiates explore - the character runs around the level to map it. Note * that the caller has to ensure that the level is mappable before calling @@ -423,6 +426,7 @@ class travel_pathfind { public: travel_pathfind(); + virtual ~travel_pathfind(); // Finds travel direction or explore target. const coord_def pathfind(run_mode_type rt); @@ -461,18 +465,19 @@ public: // RMODE_EXPLORE_GREEDY. const coord_def unexplored_square() const; -private: +protected: bool is_greed_inducing_square(const coord_def &c) const; bool path_examine_point(const coord_def &c); - bool path_flood(const coord_def &c, const coord_def &dc); + virtual bool path_flood(const coord_def &c, const coord_def &dc); bool square_slows_movement(const coord_def &c); void check_square_greed(const coord_def &c); + void good_square(const coord_def &c); -private: +protected: static const int UNFOUND_DIST = -10000; static const int INFINITE_DIST = 10000; -private: +protected: run_mode_type runmode; // Where pathfinding starts, and the destination. Note that dest is not |