From d94245983324bbedff384a23e7113715fa1da63f Mon Sep 17 00:00:00 2001 From: dshaligram Date: Tue, 18 Nov 2008 21:55:39 +0000 Subject: Fixed crawl -mapstat segfaulting. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7485 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/chardump.cc | 50 ++++++++++++++++++++++++++--------------- crawl-ref/source/chardump.h | 4 ++-- crawl-ref/source/dat/layout.des | 2 +- crawl-ref/source/debug.cc | 24 +++++++++----------- crawl-ref/source/dungeon.cc | 40 ++++++++++++++++++++++++++++----- crawl-ref/source/view.cc | 9 ++++++++ crawl-ref/source/view.h | 1 + 7 files changed, 91 insertions(+), 39 deletions(-) (limited to 'crawl-ref') diff --git a/crawl-ref/source/chardump.cc b/crawl-ref/source/chardump.cc index 714f282234..c02ecac128 100644 --- a/crawl-ref/source/chardump.cc +++ b/crawl-ref/source/chardump.cc @@ -1125,7 +1125,7 @@ static std::string morgue_directory() return (dir); } -void dump_map(FILE *fp) +void dump_map(FILE *fp, bool debug) { // Duplicate the screenshot() trick. FixedVector char_table_bk; @@ -1134,24 +1134,38 @@ void dump_map(FILE *fp) init_char_table(CSET_ASCII); init_feature_table(); - int min_x = GXM-1, max_x = 0, min_y = GYM-1, max_y = 0; + if (debug) + { + // Write the whole map out without checking for mappedness. Handy + // for debugging level-generation issues. + for (int y = 0; y < GYM; ++y) + { + for (int x = 0; x < GXM; ++x) + fputc(grid_character_at(coord_def(x,y)), fp); + fputc('\n', fp); + } + } + else + { + int min_x = GXM-1, max_x = 0, min_y = GYM-1, max_y = 0; - for (int i = X_BOUND_1; i <= X_BOUND_2; i++) - for (int j = Y_BOUND_1; j <= Y_BOUND_2; j++) - if (env.map[i][j].known()) - { - if (i > max_x) max_x = i; - if (i < min_x) min_x = i; - if (j > max_y) max_y = j; - if (j < min_y) min_y = j; - } + for (int i = X_BOUND_1; i <= X_BOUND_2; i++) + for (int j = Y_BOUND_1; j <= Y_BOUND_2; j++) + if (env.map[i][j].known()) + { + if (i > max_x) max_x = i; + if (i < min_x) min_x = i; + if (j > max_y) max_y = j; + if (j < min_y) min_y = j; + } - for (int y = min_y; y <= max_y; ++y) - { - for (int x = min_x; x <= max_x; ++x) - fputc( env.map[x][y].glyph(), fp ); + for (int y = min_y; y <= max_y; ++y) + { + for (int x = min_x; x <= max_x; ++x) + fputc( env.map[x][y].glyph(), fp ); - fputc('\n', fp); + fputc('\n', fp); + } } // Restore char and feature tables @@ -1159,13 +1173,13 @@ void dump_map(FILE *fp) init_feature_table(); } -void dump_map(const char* fname) +void dump_map(const char* fname, bool debug) { FILE* fp = fopen(fname, "w"); if (!fp) return; - dump_map(fp); + dump_map(fp, debug); fclose(fp); } diff --git a/crawl-ref/source/chardump.h b/crawl-ref/source/chardump.h index f0ba9cfd66..ef5bc5f6f4 100644 --- a/crawl-ref/source/chardump.h +++ b/crawl-ref/source/chardump.h @@ -32,8 +32,8 @@ bool dump_char(const std::string &fname, bool show_prices, bool full_id = false, const scorefile_entry *se = NULL); -void dump_map(const char* fname); -void dump_map(FILE *fp); +void dump_map(const char* fname, bool debug = false); +void dump_map(FILE *fp, bool debug = false); void display_notes(); std::string munge_description(const std::string &inStr); const char *hunger_level(void); diff --git a/crawl-ref/source/dat/layout.des b/crawl-ref/source/dat/layout.des index 3fa39f1141..6bd5fb4a86 100644 --- a/crawl-ref/source/dat/layout.des +++ b/crawl-ref/source/dat/layout.des @@ -147,7 +147,7 @@ TAGS: layout allow_dup local oblique = 10 + crawl.random2(20) dgn.fill_area(0, 0, gxm - 1, gym - 1, "rock_wall") - dgn.octa_room(10, 10, gxm - 10, gym - 10, oblique, "floor") + dgn.octa_room(1, 1, gxm - 2, gym - 2, oblique, "floor") local smear = crawl.coinflip() if smear then diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc index 1cb95ba97c..c2a27f013f 100644 --- a/crawl-ref/source/debug.cc +++ b/crawl-ref/source/debug.cc @@ -4614,19 +4614,16 @@ static bool _mg_is_disconnected_level() static bool mg_do_build_level(int niters) { - if (niters > 1) - { - mesclr(); - mprf("On %s (%d); %d g, %d fail, %d err%s, %d uniq, " - "%d try, %d (%.2lf%%) vetos", - level_id::current().describe().c_str(), niters, - mg_levels_tried, mg_levels_failed, mapgen_errors.size(), - mapgen_last_error.empty()? "" - : (" (" + mapgen_last_error + ")").c_str(), - mapgen_use_count.size(), - mg_build_attempts, mg_vetoes, - mg_build_attempts? mg_vetoes * 100.0 / mg_build_attempts : 0.0); - } + mesclr(); + mprf("On %s (%d); %d g, %d fail, %d err%s, %d uniq, " + "%d try, %d (%.2lf%%) vetos", + level_id::current().describe().c_str(), niters, + mg_levels_tried, mg_levels_failed, mapgen_errors.size(), + mapgen_last_error.empty()? "" + : (" (" + mapgen_last_error + ")").c_str(), + mapgen_use_count.size(), + mg_build_attempts, mg_vetoes, + mg_build_attempts? mg_vetoes * 100.0 / mg_build_attempts : 0.0); no_messages mx; for (int i = 0; i < niters; ++i) @@ -4757,6 +4754,7 @@ static void mg_build_levels(int niters) you.uniq_map_tags.clear(); you.uniq_map_names.clear(); + init_level_connectivity(); if (!mg_build_dungeon()) break; } diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 7869655cd8..a004341c0c 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -17,6 +17,7 @@ #include "AppHdr.h" #include "abyss.h" #include "branch.h" +#include "chardump.h" #include "cloud.h" #include "defines.h" #include "enum.h" @@ -478,6 +479,11 @@ static bool _is_passable_ignore_vault(const coord_def &c) bool dgn_square_is_passable(const coord_def &c) { // [enne] Why does this function check MMT_OPAQUE? + // + // Don't peek inside MMT_OPAQUE vaults (all vaults are opaque by + // default) because vaults may choose to create isolated regions, + // or otherwise cause connectivity issues even if the map terrain + // is travel-passable. return (!(dgn_Map_Mask(c) & MMT_OPAQUE) && (is_travelsafe_square(c.x, c.y, false, true) || grd(c) == DNGN_SECRET_DOOR)); @@ -1283,16 +1289,21 @@ static bool _add_feat_if_missing(bool (*iswanted)(const coord_def &), for (int y = 0; y < GYM; ++y) for (int x = 0; x < GXM; ++x) { + // [ds] Use dgn_square_is_passable instead of + // _is_passable_ignore_vault here, for we'll otherwise + // fail on floorless isolated pocket in vaults (like the + // altar surrounded by deep water), and trigger the assert + // downstairs. const coord_def gc(x, y); if (!map_bounds(x, y) || travel_point_distance[x][y] - || !_is_passable_ignore_vault(gc)) + || !dgn_square_is_passable(gc)) { continue; } if (_dgn_fill_zone(gc, ++nzones, _dgn_point_record_stub, - _is_passable_ignore_vault, iswanted)) + dgn_square_is_passable, iswanted)) { continue; } @@ -1336,6 +1347,9 @@ static bool _add_feat_if_missing(bool (*iswanted)(const coord_def &), return (true); } +#ifdef DEBUG_DIAGNOSTICS + dump_map("debug.map", true); +#endif ASSERT(!"Couldn't find region."); return (false); } @@ -4668,14 +4682,30 @@ static bool _build_vaults(int level_number, int force_vault, int rune_subst, if (stair_exist[stair - DNGN_STONE_STAIRS_DOWN_I] == 1) continue; + int tries = 10000; do { pos_x = random_range(X_BOUND_1 + 1, X_BOUND_2 - 1); pos_y = random_range(Y_BOUND_1 + 1, Y_BOUND_2 - 1); } - while (grd[pos_x][pos_y] != DNGN_FLOOR - || (pos_x >= v1x && pos_x <= v2x && pos_y >= v1y - && pos_y <= v2y)); + while ((grd[pos_x][pos_y] != DNGN_FLOOR + || (!is_layout && pos_x >= v1x && pos_x <= v2x + && pos_y >= v1y && pos_y <= v2y)) + && tries-- > 0); + + + if (tries <= 0) + { +#ifdef DEBUG_DIAGNOSTICS + dump_map("debug.map", true); + end(1, false, + "Failed to create level: vault stairs for %s " + "(layout: %s) failed", + place.map.name.c_str(), is_layout? "yes" : "no"); +#endif + pos_x = you.pos().x; + pos_y = you.pos().y; + } grd[pos_x][pos_y] = stair; } diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index 25b4bac322..ce36cd6568 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -503,6 +503,15 @@ static void _get_symbol( const coord_def& where, *colour = real_colour(*colour); } +unsigned grid_character_at(const coord_def &c) +{ + unsigned glych; + unsigned short glycol = 0; + + _get_symbol(c, grd(c), &glych, &glycol ); + return glych; +} + void get_item_symbol(unsigned int object, unsigned *ch, unsigned short *colour) { diff --git a/crawl-ref/source/view.h b/crawl-ref/source/view.h index 502e987887..1337f2f54f 100644 --- a/crawl-ref/source/view.h +++ b/crawl-ref/source/view.h @@ -220,6 +220,7 @@ bool see_grid_no_trans( const coord_def &p ); bool trans_wall_blocking( const coord_def &p ); bool grid_see_grid(const coord_def& p1, const coord_def& p2, dungeon_feature_type allowed = DNGN_UNSEEN); +unsigned grid_character_at(const coord_def &c); inline bool see_grid( int grx, int gry ) { -- cgit v1.2.3-54-g00ecf