diff options
-rw-r--r-- | crawl-ref/source/abyss.cc | 5 | ||||
-rw-r--r-- | crawl-ref/source/debug.cc | 114 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.cc | 130 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.h | 9 |
4 files changed, 184 insertions, 74 deletions
diff --git a/crawl-ref/source/abyss.cc b/crawl-ref/source/abyss.cc index 76ce4be6b9..38c9c782bd 100644 --- a/crawl-ref/source/abyss.cc +++ b/crawl-ref/source/abyss.cc @@ -81,6 +81,11 @@ static bool _place_feature_near( const coord_def ¢re, // Public for abyss generation. void generate_abyss() { + extern std::string dgn_Build_Method; + + dgn_Build_Method += " abyss"; + dgn_Layout_Type = "abyss"; + #ifdef DEBUG_ABYSS mprf(MSGCH_DIAGNOSTICS, "generate_abyss(); turn_on_level: %d", env.turns_on_level); diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc index 0a98fdafda..1e5a347694 100644 --- a/crawl-ref/source/debug.cc +++ b/crawl-ref/source/debug.cc @@ -4866,7 +4866,7 @@ void wizard_give_monster_item(monsters *mon) } item_def &item = you.inv[player_slot]; - mon_inv_type mon_slot; + mon_inv_type mon_slot = NUM_MONSTER_SLOTS; switch (item.base_type) { @@ -5013,6 +5013,7 @@ void wizard_give_monster_item(monsters *mon) int old_eq = NON_ITEM; bool unequipped = false; if (item.base_type != OBJ_CORPSES + && mon_slot != NUM_MONSTER_SLOTS && mon->inv[mon_slot] != NON_ITEM && !items_stack(item, mitm[mon->inv[mon_slot]])) { @@ -5037,7 +5038,7 @@ void wizard_give_monster_item(monsters *mon) if (!mon->pickup_item(mitm[index], false, true)) { mpr("Monster wouldn't take item."); - if (old_eq != NON_ITEM) + if (old_eq != NON_ITEM && mon_slot != NUM_MONSTER_SLOTS) { mon->inv[mon_slot] = old_eq; if (unequipped) @@ -5524,58 +5525,103 @@ void debug_miscast( int target_index ) static void _dump_levgen() { - if (!Generating_Level) - return; + CrawlHashTable &props = env.properties; - extern std::string dgn_Build_Method; + std::string method; + std::string type; - mprf("dgn_Build_Method = %s", dgn_Build_Method.c_str()); - mprf("dgn_Layout_Type = %s", dgn_Layout_Type.c_str()); + if (Generating_Level) + { + mpr("Currently generating level."); + extern std::string dgn_Build_Method; + method = dgn_Build_Method; + type = dgn_Layout_Type; + } + else + { + if (!props.exists(BUILD_METHOD_KEY)) + method = "ABSENT"; + else + method = props[BUILD_METHOD_KEY].get_string(); - extern bool river_level, lake_level, many_pools_level; + if (!props.exists(LAYOUT_TYPE_KEY)) + type = "ABSENT"; + else + type = props[LAYOUT_TYPE_KEY].get_string(); + } - if (river_level) - mpr("river level"); - if (lake_level) - mpr("lake level"); - if (many_pools_level) - mpr("many pools level"); + mprf("dgn_Build_Method = %s", method.c_str()); + mprf("dgn_Layout_Type = %s", type.c_str()); - std::vector<std::string> vault_names; + std::string extra; - for (unsigned int i = 0; i < Level_Vaults.size(); i++) - vault_names.push_back(Level_Vaults[i].map.name); + if (!props.exists(LEVEL_EXTRAS_KEY)) + extra = "ABSENT"; + else + { + const CrawlVector &vec = props[LEVEL_EXTRAS_KEY].get_vector(); - if (Level_Vaults.size() > 0) - mpr_comma_separated_list("Level_Vaults: ", vault_names, - " and ", ", ", MSGCH_WARN); - vault_names.clear(); + for (unsigned int i = 0; i < vec.size(); i++) + extra += vec[i].get_string() + ", "; + } - for (unsigned int i = 0; i < Temp_Vaults.size(); i++) - vault_names.push_back(Temp_Vaults[i].map.name); + mprf("Level extras: %s", extra.c_str()); + + mpr("Level vaults:"); + if (!props.exists(LEVEL_VAULTS_KEY)) + mpr("ABSENT"); + else + { + const CrawlHashTable &vaults = props[LEVEL_VAULTS_KEY].get_table(); + CrawlHashTable::const_iterator i = vaults.begin(); - if (Temp_Vaults.size() > 0) - mpr_comma_separated_list("Temp_Vaults: ", vault_names, - " and ", ", ", MSGCH_WARN); + for (; i != vaults.end(); i++) + mprf(" %s: %s", i->first.c_str(), + i->second.get_string().c_str()); + } + mpr(""); + + mpr("Temp vaults:"); + if (!props.exists(TEMP_VAULTS_KEY)) + mpr("ABSENT"); + else + { + const CrawlHashTable &vaults = props[TEMP_VAULTS_KEY].get_table(); + CrawlHashTable::const_iterator i = vaults.begin(); + + for (; i != vaults.end(); i++) + mprf(" %s: %s", i->first.c_str(), + i->second.get_string().c_str()); + } + mpr(""); } static void _dump_level_info(FILE* file) { + CrawlHashTable &props = env.properties; + fprintf(file, "Place info:" EOL); + fprintf(file, "your_level = %d, branch = %d, level_type = %d, " "type_name = %s" EOL EOL, you.your_level, (int) you.where_are_you, (int) you.level_type, you.level_type_name.c_str()); - if (Generating_Level) - { - fprintf(file, EOL "Crashed while generating level." EOL); + std::string place = level_id::current().describe(); + std::string orig_place; - _dump_levgen(); - fprintf(file, EOL); - } -} + if (!props.exists(LEVEL_ID_KEY)) + orig_place = "ABSENT"; + else + orig_place = props[LEVEL_ID_KEY].get_string(); + fprintf(file, "Level id: %s" EOL, place.c_str()); + if (place != orig_place) + fprintf(file, "Level id when level was generated: %s" EOL, + orig_place.c_str()); + + _dump_levgen(); +} static void _dump_player(FILE *file) { @@ -5866,7 +5912,7 @@ static void _debug_marker_scan() for (unsigned int j = 0; j < at_pos.size(); j++) { - map_marker* tmp = at_pos[i]; + map_marker* tmp = at_pos[j]; if (tmp == NULL) continue; diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index bb2bff14fc..923cd14248 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -231,10 +231,6 @@ std::set<std::string> Level_Unique_Tags; std::string dgn_Build_Method; std::string dgn_Layout_Type; -// Used by debug_mons_scan() when announcing that a just generated level -// has floating/detached monsters. -bool river_level, lake_level, many_pools_level; - bool Generating_Level = false; static int can_create_vault = true; @@ -310,12 +306,19 @@ bool builder(int level_number, int level_type) if (!dgn_level_vetoed && _valid_dungeon_level(level_number, level_type)) { #if DEBUG_MONS_SCAN - // If debug_mons_scan() find a problem while Generating_Level is + // If debug_mons_scan() finds a problem while Generating_Level is // still true then it will announce that a problem was caused // during level generation. debug_mons_scan(); #endif + if (dgn_Build_Method.size() > 0 && dgn_Build_Method[0] == ' ') + dgn_Build_Method = dgn_Build_Method.substr(1); + + env.properties[BUILD_METHOD_KEY] = dgn_Build_Method; + env.properties[LAYOUT_TYPE_KEY] = dgn_Layout_Type; + env.properties[LEVEL_ID_KEY] = level_id::current().describe(); + dgn_Layout_Type.clear(); Level_Unique_Maps.clear(); Level_Unique_Tags.clear(); @@ -895,10 +898,6 @@ void dgn_reset_level() level_clear_vault_memory(); dgn_colour_grid.reset(NULL); - river_level = false; - lake_level = false; - many_pools_level = false; - can_create_vault = true; use_random_maps = true; dgn_check_connectivity = false; @@ -907,6 +906,11 @@ void dgn_reset_level() // Forget level properties. env.properties.clear(); + // Set up containers for storing some level generation info. + env.properties[LEVEL_VAULTS_KEY].new_table(SV_STR); + env.properties[TEMP_VAULTS_KEY].new_table(SV_STR); + env.properties[LEVEL_EXTRAS_KEY].new_vector(SV_STR); + // Blank level with DNGN_ROCK_WALL. grd.init(DNGN_ROCK_WALL); env.grid_colours.init(BLACK); @@ -1561,15 +1565,12 @@ static void _build_dungeon_level(int level_number, int level_type) { spec_room sr; - dgn_Layout_Type = "rooms"; - _build_layout_skeleton(level_number, level_type, sr); if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_PORTAL_VAULT || dgn_level_vetoed) { - dgn_Layout_Type.clear(); return; } @@ -1943,7 +1944,8 @@ static void _prepare_shoals(int level_number) // Don't destroy portals, etc. const located_feature_list lfl = _save_critical_features(); - dgn_Layout_Type = "shoals"; + dgn_Build_Method += make_stringf(" shoals [%d]", level_number); + dgn_Layout_Type = "shoals"; // dpeg's algorithm. // We could have just used spotty_level() and changed rock to @@ -2114,7 +2116,8 @@ static void _prepare_shoals(int level_number) static void _prepare_swamp() { - dgn_Layout_Type = "swamp"; + dgn_Build_Method += " swamp"; + dgn_Layout_Type = "swamp"; const int margin = 5; @@ -2323,6 +2326,10 @@ static builder_rc_type _builder_by_type(int level_number, char level_type) static void _portal_vault_level(int level_number) { + dgn_Build_Method += make_stringf(" portal_vault_level [%d]", + level_number); + dgn_Layout_Type = "portal vault"; + // level_type_tag may contain spaces for human readability, but the // corresponding vault tag name cannot use spaces, so force spaces to // _ when searching for the tag. @@ -2435,6 +2442,7 @@ static builder_rc_type _builder_by_branch(int level_number) if (vault) { + dgn_Build_Method += " random_map_for_place"; _ensure_vault_placed( _build_vaults(level_number, vault) ); return BUILD_SKIP; } @@ -2527,6 +2535,7 @@ static builder_rc_type _builder_normal(int level_number, char level_type, if (vault) { + dgn_Build_Method += " normal_random_map_for_place"; _ensure_vault_placed( _build_vaults(level_number, vault) ); return BUILD_SKIP; } @@ -2618,6 +2627,9 @@ static builder_rc_type _builder_normal(int level_number, char level_type, // Returns 1 if we should skip extras(), otherwise 0. static builder_rc_type _builder_basic(int level_number) { + dgn_Build_Method += make_stringf(" basic [%d]", level_number); + dgn_Layout_Type = "basic"; + int temp_rand; int doorlevel = random2(11); int corrlength = 2 + random2(14); @@ -3676,6 +3688,10 @@ static void _special_room(int level_number, spec_room &sr, { ASSERT(vault); + std::string extra = make_stringf("special room [%s %d]", + vault->name.c_str(), level_number); + env.properties[LEVEL_EXTRAS_KEY].get_vector().push_back(extra); + // Overwrites anything: this function better be called early on during // creation. int room_x1 = 8 + random2(55); @@ -4232,6 +4248,7 @@ static bool _build_vaults(int level_number, const map_def *vault, // Must do this only after target_connections is finalised, or the vault // exits will not be correctly set. Level_Vaults.push_back(place); + remember_vault_placement(LEVEL_VAULTS_KEY, place); #ifdef DEBUG_DIAGNOSTICS if (crawl_state.map_stat_gen) @@ -5273,8 +5290,6 @@ static void _place_pool(dungeon_feature_type pool_type, unsigned char pool_x1, static void _many_pools(dungeon_feature_type pool_type) { - many_pools_level = true; - if (player_in_branch( BRANCH_COCYTUS )) pool_type = DNGN_DEEP_WATER; else if (player_in_branch( BRANCH_GEHENNA )) @@ -5283,6 +5298,10 @@ static void _many_pools(dungeon_feature_type pool_type) const int num_pools = 20 + random2avg(9, 2); int pools = 0; + std::string extra = make_stringf("many pools [%d %d]", (int) pool_type, + num_pools); + env.properties[LEVEL_EXTRAS_KEY].get_vector().push_back(extra); + for (int timeout = 0; pools < num_pools && timeout < 30000; ++timeout) { const int i = random_range(X_BOUND_1 + 1, X_BOUND_2 - 21); @@ -5714,11 +5733,15 @@ static object_class_type _item_in_shop(unsigned char shop_type) void spotty_level(bool seeded, int iterations, bool boxy) { - dgn_Build_Method = "spotty_level"; + dgn_Build_Method += make_stringf(" spotty_level [%d%s%s]", + iterations, seeded ? " seeeded" : "", + boxy ? " boxy" : ""); if (dgn_Layout_Type == "open" || dgn_Layout_Type == "cross") dgn_Layout_Type = "open"; else if (iterations >= 100) dgn_Layout_Type = "caves"; + else if (dgn_Layout_Type.empty()) + dgn_Layout_Type = "spotty"; else dgn_Layout_Type += "_spotty"; @@ -5842,8 +5865,8 @@ void smear_feature(int iterations, bool boxy, dungeon_feature_type feature, static void _bigger_room() { - dgn_Build_Method = "bigger_room"; - dgn_Layout_Type = "open"; + dgn_Build_Method += " bigger_room"; + dgn_Layout_Type = "open"; unsigned char i, j; @@ -5878,8 +5901,9 @@ static void _bigger_room() // Various plan_xxx functions. static void _plan_main(int level_number, int force_plan) { - dgn_Build_Method = "plan_main"; - dgn_Layout_Type = "rooms"; + dgn_Build_Method += make_stringf(" plan_main [%d%s]", level_number, + force_plan ? " force_plan" : ""); + dgn_Layout_Type = "rooms"; // possible values for do_stairs: // 0 - stairs already done @@ -5925,8 +5949,8 @@ static void _plan_main(int level_number, int force_plan) static char _plan_1(int level_number) { - dgn_Build_Method = "plan_1"; - dgn_Layout_Type = "open"; + dgn_Build_Method += make_stringf(" plan_1 [%d]", level_number); + dgn_Layout_Type = "open"; const map_def *vault = find_map_by_name("layout_forbidden_donut"); ASSERT(vault); @@ -5939,8 +5963,8 @@ static char _plan_1(int level_number) static char _plan_2(int level_number) { - dgn_Build_Method = "plan_2"; - dgn_Layout_Type = "cross"; + dgn_Build_Method += " plan_2"; + dgn_Layout_Type = "cross"; const map_def *vault = find_map_by_name("layout_cross"); ASSERT(vault); @@ -5953,8 +5977,8 @@ static char _plan_2(int level_number) static char _plan_3() { - dgn_Build_Method = "plan_3"; - dgn_Layout_Type = "rooms"; + dgn_Build_Method += " plan_3"; + dgn_Layout_Type = "rooms"; // Draws a room, then another and links them together, then another and etc. // Of course, this can easily end up looking just like a make_trail level. @@ -6046,8 +6070,11 @@ static char _plan_3() static char _plan_4(char forbid_x1, char forbid_y1, char forbid_x2, char forbid_y2, dungeon_feature_type force_wall) { - dgn_Build_Method = "plan_4"; - dgn_Layout_Type = "city"; + dgn_Build_Method += make_stringf(" plan_4 [%d,%d %d,%d %d]", + (int) forbid_x1, (int) forbid_y1, + (int) forbid_x2, (int) forbid_y2, + (int) force_wall); + dgn_Layout_Type = "city"; int temp_rand; // req'd for probability checking @@ -6148,8 +6175,8 @@ static char _plan_4(char forbid_x1, char forbid_y1, char forbid_x2, static char _plan_5() { - dgn_Build_Method = "plan_5"; - dgn_Layout_Type = "misc"; // XXX: What type of layout is this? + dgn_Build_Method += " plan_5"; + dgn_Layout_Type = "misc"; // XXX: What type of layout is this? unsigned char imax = 5 + random2(20); // value range of [5,24] {dlb} @@ -6170,8 +6197,8 @@ static char _plan_5() // Octagon with pillars in middle. static char _plan_6(int level_number) { - dgn_Build_Method = "plan_6"; - dgn_Layout_Type = "open"; + dgn_Build_Method += make_stringf(" plan_6 [%d]", level_number); + dgn_Layout_Type = "open"; const map_def *vault = find_map_by_name("layout_big_octagon"); ASSERT(vault); @@ -6199,7 +6226,8 @@ static char _plan_6(int level_number) bool octa_room(spec_room &sr, int oblique_max, dungeon_feature_type type_floor) { - dgn_Build_Method = "octa_room"; + dgn_Build_Method += make_stringf(" octa_room [%d %d]", oblique_max, + (int) type_floor); int x,y; @@ -6354,6 +6382,7 @@ static void _init_minivault_placement(const map_def *vault, vault_placement &place) { vault_main(place, vault); + remember_vault_placement(LEVEL_VAULTS_KEY, place); } // Checks whether a given grid has at least one neighbour surrounded @@ -6739,7 +6768,8 @@ static void _labyrinth_add_glass_walls(const dgn_region ®ion) static void _labyrinth_level(int level_number) { - dgn_Layout_Type = "labyrinth"; + dgn_Build_Method += make_stringf(" labyrinth [%d]", level_number); + dgn_Layout_Type = "labyrinth"; dgn_region lab = dgn_region::absolute( LABYRINTH_BORDER, LABYRINTH_BORDER, @@ -6970,8 +7000,8 @@ static void _box_room(int bx1, int bx2, int by1, int by2, static void _city_level(int level_number) { - dgn_Build_Method = "city_level"; - dgn_Layout_Type = "city"; + dgn_Build_Method += make_stringf(" city_level [%d]", level_number); + dgn_Layout_Type = "city"; int temp_rand; // probability determination {dlb} // Remember, can have many wall types in one level. @@ -7252,6 +7282,9 @@ static void _chequerboard( spec_room &sr, dungeon_feature_type target, static void _roguey_level(int level_number, spec_room &sr, bool make_stairs) { + dgn_Build_Method += make_stringf(" roguey_level [%d%s]", level_number, + make_stairs ? " make_stairs" : ""); + int bcount_x, bcount_y; int cn = 0; int i; @@ -7490,7 +7523,8 @@ static void _build_river( dungeon_feature_type river_type ) //mv if (player_in_branch( BRANCH_CRYPT ) || player_in_branch( BRANCH_TOMB )) return; - river_level = true; + std::string extra = make_stringf("river [%d]", (int) river_type); + env.properties[LEVEL_EXTRAS_KEY].get_vector().push_back(extra); // if (one_chance_in(10)) // _build_river(river_type); @@ -7540,7 +7574,8 @@ static void _build_lake(dungeon_feature_type lake_type) //mv if (player_in_branch(BRANCH_CRYPT) || player_in_branch(BRANCH_TOMB)) return; - lake_level = true; + std::string extra = make_stringf("lake [%d]", (int) lake_type); + env.properties[LEVEL_EXTRAS_KEY].get_vector().push_back(extra); // if (one_chance_in (10)) // _build_lake(lake_type); @@ -8336,3 +8371,20 @@ void vault_placement::draw_at(const coord_def &c) pos = c; apply_grid(); } + +void remember_vault_placement(std::string key, vault_placement &place) +{ + CrawlHashTable &table = env.properties[key].get_table(); + + std::string name = make_stringf("%s [%d]", place.map.name.c_str(), + table.size() + 1); + + std::string place_str + = make_stringf("(%d,%d) (%d,%d) orient: %d lev: %d alt: %d rune: %d " + "subst: %d", + place.pos.x, place.pos.y, place.size.x, place.size.y, + place.orient, place.level_number, place.altar_count, + place.num_runes, place.rune_subst); + + table[name] = place_str; +} diff --git a/crawl-ref/source/dungeon.h b/crawl-ref/source/dungeon.h index 02d5c05fac..e73eff36a9 100644 --- a/crawl-ref/source/dungeon.h +++ b/crawl-ref/source/dungeon.h @@ -22,6 +22,13 @@ #include <set> #include <algorithm> +#define BUILD_METHOD_KEY "build_method_key" +#define LAYOUT_TYPE_KEY "layout_type_key" +#define LEVEL_VAULTS_KEY "level_vaults_key" +#define TEMP_VAULTS_KEY "temp_vaults_key" +#define LEVEL_EXTRAS_KEY "level_extras_key" +#define LEVEL_ID_KEY "level_id_key" + enum portal_type { PORTAL_NONE = 0, @@ -411,5 +418,5 @@ int count_antifeature_in_box(int x0, int y0, int x1, int y1, dungeon_feature_type feat); int count_neighbours(int x, int y, dungeon_feature_type feat); - +void remember_vault_placement(std::string key, vault_placement &place); #endif |