From f910f85b74d9dae832f8d3422f51d87565ea3a08 Mon Sep 17 00:00:00 2001 From: zelgadis Date: Mon, 26 May 2008 07:45:18 +0000 Subject: FR 1822931: Vaults can now include tags of the form "layout_foo" to indicate which level layout types it's compatible with, where "foo" can be: rooms, caves, open, city, or cross (plus swamp, shoals and labyrinth, even though random vaults aren't used in those places). Having no "layout_foo" tag means that the vault is compatible with all layout types, which is the current behavior. Also, fixed bug where layouts plan_1 (donut levels), plan_2 (cross levels) and plan_6 (octagon with circle of pillars) were choosing randomly from the three Lua defined layouts in dat/layout.des, rather than choosing exactly the chosen layout. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5251 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/docs/level_design.txt | 12 ++++++++++++ crawl-ref/source/dungeon.cc | 38 +++++++++++++++++++++++++++++++++++--- crawl-ref/source/dungeon.h | 1 + crawl-ref/source/maps.cc | 13 +++++++++++++ 4 files changed, 61 insertions(+), 3 deletions(-) diff --git a/crawl-ref/docs/level_design.txt b/crawl-ref/docs/level_design.txt index 6cce7c471e..8c062df940 100644 --- a/crawl-ref/docs/level_design.txt +++ b/crawl-ref/docs/level_design.txt @@ -32,6 +32,8 @@ are in use: lab.des - labyrinths exits and flavour vaults lair.des - lair entrances, Shoals:5, Swamp:5, Snake:5, Slime:6 large.des - all regular vaults which have ORIENT:encompass/northwest etc. + layout.des - Level layout code that has been moved from dungeon.cc and + rewritten in Lua. mini.des - minivaults (no ORIENT line at all) orc.des - orcish mine entrances, orc only vaults pan.des - vaults of the Pan demon lords, Pan minivaults @@ -386,6 +388,16 @@ TAGS: Tags go an a TAGS: line and are space-separated. Valid tags are: vault!" * "no_hmirror": Like no_rotate, but for horizontal mirroring. * "no_vmirror": Like no_rotate, but for vertical mirroring. + * "layout": Lua code that dungeon.cc uses for generating level + layouts. Do *NOT* use or mess with unlss you know what + you're doing. + * "layout_foo": Indicates what sort of level layouts this vault is + compatible with, for vaults that don't fit in with all layouts; + the absence of this type of tags means it can go with any layout. + Multiple layout_foo tags can be used if it can be used with + multiple layouts. Current values for "foo" are: rooms, city, + open, caves, cross, shoals, swamp, labyrithn (though currently + random vaults aren't palced in the last three). Pre-0.3 Crawl distinguished between TAGS and FLAGS. 0.3 and newer Crawls treat TAGS and FLAGS as synonyms. diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index c87f158c14..9a4677244a 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -233,6 +233,7 @@ static void _dgn_set_floor_colours(); map_mask dgn_Map_Mask; std::vector Level_Vaults; std::string dgn_Build_Method; +std::string dgn_Layout_Type; static int vault_chance = 9; static int minivault_chance = 3; @@ -307,6 +308,8 @@ bool builder(int level_number, int level_type) if (!dgn_level_vetoed && _valid_dungeon_level(level_number, level_type)) { + dgn_Layout_Type.clear(); + _dgn_map_colour_fixup(); return (true); } @@ -322,6 +325,8 @@ bool builder(int level_number, int level_type) make_stringf("Unable to generate level for '%s'!", level_id::current().describe().c_str()).c_str()); } + + dgn_Layout_Type.clear(); return (false); } @@ -716,6 +721,7 @@ static bool _valid_dungeon_level(int level_number, int level_type) static void _reset_level() { dgn_Build_Method.clear(); + dgn_Layout_Type.clear(); level_clear_vault_memory(); dgn_colour_grid.reset(NULL); @@ -1160,12 +1166,15 @@ 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; } @@ -1510,6 +1519,8 @@ static void _place_base_islands(int margin, int num_islands, int estradius, static void _prepare_shoals(int level_number) { + dgn_Layout_Type = "shaols"; + // dpeg's algorithm. // We could have just used spotty_level() and changed rock to // water, but this is much cooler. Right? @@ -1667,6 +1678,8 @@ static void _prepare_shoals(int level_number) static void _prepare_swamp() { + dgn_Layout_Type = "swamp"; + const int margin = 10; for (int i = margin; i < (GXM - margin); i++) @@ -5607,6 +5620,12 @@ 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"; + if (dgn_Layout_Type == "open" || dgn_Layout_Type == "cross") + dgn_Layout_Type = "open"; + else if (iterations >= 100) + dgn_Layout_Type = "caves"; + else + dgn_Layout_Type += "_spotty"; // assumes starting with a level full of rock walls (1) int i, j, k, l; @@ -5729,6 +5748,7 @@ void smear_feature(int iterations, bool boxy, dungeon_feature_type feature, static void _bigger_room() { dgn_Build_Method = "bigger_room"; + dgn_Layout_Type = "open"; unsigned char i, j; @@ -5764,6 +5784,7 @@ static void _bigger_room() static void _plan_main(int level_number, int force_plan) { dgn_Build_Method = "plan_main"; + dgn_Layout_Type = "rooms"; // possible values for do_stairs: // 0 - stairs already done @@ -5810,8 +5831,9 @@ 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"; - const int vault = random_map_for_tag("layout", false, true); + const int vault = find_map_by_name("layout_forbidden_donut"); ASSERT(vault != -1); bool success = _build_vaults(level_number, vault); @@ -5823,8 +5845,9 @@ static char _plan_1(int level_number) static char _plan_2(int level_number) { dgn_Build_Method = "plan_2"; + dgn_Layout_Type = "cross"; - const int vault = random_map_for_tag("layout", false, true); + const int vault = find_map_by_name("layout_cross"); ASSERT(vault != -1); bool success = _build_vaults(level_number, vault); @@ -5836,6 +5859,7 @@ static char _plan_2(int level_number) static char _plan_3() { 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. @@ -5928,6 +5952,7 @@ 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"; // a more chaotic version of city level int temp_rand; // req'd for probability checking @@ -6033,6 +6058,7 @@ 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? unsigned char imax = 5 + random2(20); // value range of [5,24] {dlb} @@ -6053,8 +6079,9 @@ static char _plan_5() static char _plan_6(int level_number) { dgn_Build_Method = "plan_6"; + dgn_Layout_Type = "open"; // Octagon with pillars in middle - const int vault = random_map_for_tag("layout", false, true); + const int vault = find_map_by_name("layout_big_octagon"); ASSERT(vault != -1); bool success = _build_vaults(level_number, vault); @@ -6376,6 +6403,8 @@ static void _labyrinth_place_entry_point(const dgn_region ®ion, static void _labyrinth_level(int level_number) { + dgn_Layout_Type = "labyrinth"; + dgn_region lab = dgn_region::absolute( LABYRINTH_BORDER, LABYRINTH_BORDER, GXM - LABYRINTH_BORDER - 1, @@ -6616,6 +6645,9 @@ 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"; + int temp_rand; // probability determination {dlb} // remember, can have many wall types in one level dungeon_feature_type wall_type; diff --git a/crawl-ref/source/dungeon.h b/crawl-ref/source/dungeon.h index 4644cd05fe..06755245f2 100644 --- a/crawl-ref/source/dungeon.h +++ b/crawl-ref/source/dungeon.h @@ -56,6 +56,7 @@ typedef char map_type[MAP_SIDE + 1][MAP_SIDE + 1]; typedef FixedArray map_mask; extern map_mask dgn_Map_Mask; +extern std::string dgn_Layout_Type; // Map mask constants. diff --git a/crawl-ref/source/maps.cc b/crawl-ref/source/maps.cc index 044ae2a47f..2aeadcf73d 100644 --- a/crawl-ref/source/maps.cc +++ b/crawl-ref/source/maps.cc @@ -329,6 +329,14 @@ static bool vault_unforbidden(const map_def &map) you.uniq_map_tags.end())); } +static bool map_matches_layout_type(const map_def &map) +{ + if (dgn_Layout_Type.empty() || !map.has_tag_prefix("layout_")) + return true; + + return map.has_tag("layout_" + dgn_Layout_Type); +} + int find_map_by_name(const std::string &name) { for (unsigned i = 0, size = vdefs.size(); i < size; ++i) @@ -362,6 +370,7 @@ int random_map_for_place(const level_id &place, bool want_minivault) if (vdefs[i].place == place && vdefs[i].is_minivault() == want_minivault && !vdefs[i].has_tag("layout") + && map_matches_layout_type(vdefs[i]) && vault_unforbidden(vdefs[i])) { rollsize += vdefs[i].chance; @@ -388,6 +397,8 @@ int random_map_in_depth(const level_id &place, bool want_minivault) int mapindex = -1; int rollsize = 0; + const bool check_layout = (place == level_id::current()); + for (unsigned i = 0, size = vdefs.size(); i < size; ++i) if (vdefs[i].is_minivault() == want_minivault && !vdefs[i].place.is_valid() @@ -400,6 +411,7 @@ int random_map_in_depth(const level_id &place, bool want_minivault) && !vdefs[i].has_tag("unrand") && !vdefs[i].has_tag("bazaar") && !vdefs[i].has_tag("layout") + && (!check_layout || map_matches_layout_type(vdefs[i])) && vault_unforbidden(vdefs[i])) { rollsize += vdefs[i].chance; @@ -426,6 +438,7 @@ int random_map_for_tag(const std::string &tag, if (vdefs[i].has_tag(tag) && vdefs[i].is_minivault() == want_minivault && (!check_depth || !vdefs[i].has_depth() || vdefs[i].is_usable_in(level_id::current())) + && map_matches_layout_type(vdefs[i]) && vault_unforbidden(vdefs[i])) { rollsize += vdefs[i].chance; -- cgit v1.2.3-54-g00ecf