diff options
author | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2008-11-19 21:23:25 +0000 |
---|---|---|
committer | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2008-11-19 21:23:25 +0000 |
commit | 9726d74a32cd63e2d7e317d8ae592c4b05773f3d (patch) | |
tree | 9b93e1eac9d7319735aa8518682c1add7e4f1db3 | |
parent | 74d429f39c7b29c023d920e5eb994154d6e980f0 (diff) | |
download | crawl-ref-9726d74a32cd63e2d7e317d8ae592c4b05773f3d.tar.gz crawl-ref-9726d74a32cd63e2d7e317d8ae592c4b05773f3d.zip |
Remove labyrinth entry placement from dungeon.cc, added support for "luniq" and "extra" tags.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7511 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r-- | crawl-ref/docs/level_design.txt | 35 | ||||
-rw-r--r-- | crawl-ref/source/dat/lab.des | 10 | ||||
-rw-r--r-- | crawl-ref/source/dat/lair.des | 3 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.cc | 89 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.h | 4 | ||||
-rw-r--r-- | crawl-ref/source/maps.cc | 15 |
6 files changed, 102 insertions, 54 deletions
diff --git a/crawl-ref/docs/level_design.txt b/crawl-ref/docs/level_design.txt index f8c9932d1d..9f8fa277f9 100644 --- a/crawl-ref/docs/level_design.txt +++ b/crawl-ref/docs/level_design.txt @@ -348,6 +348,26 @@ CHANCE: <priority>:<roll> or <roll> CHANCE: 0 : 500 : chance(0, 500) + A common case when using CHANCE is to assign a CHANCE to a + set of maps. For instance, if you have a set of portal vault + entries, and you want one of the set to be used on 5% of all + levels, you can do this: + + NAME: portal_a + CHANCE: 50 : 5% + TAGS: chance_portal_group + ... + + NAME: portal_b + CHANCE: 50 : 5% + TAGS: chance_portal_group + ... + + That is, if you have a set of maps that use CHANCE and are + tagged chance_xxx, then one map of that set will be used + when the chance is met. + + WEIGHT: (number with 10 being default) For entry vaults and any other vaults randomly picked from among a set, this type of line affects the likelihood of the given vault @@ -372,12 +392,22 @@ TAGS: Tags go an a TAGS: line and are space-separated. You can have several * "allow_dup": Vaults are normally used only once per game. If you have a vault that can be used more than once, use allow_dup to tell the dungeon builder that the vault can be reused. + * "chance_FOO": Maps can be tagged chance_ with any unique suffix + to indicate that if the map's CHANCE roll is made, one of the maps + tagged chance_FOO should be picked. * "dummy": this tag indicates that the vault is a stub; if the dungeon builder picks a dummy vault, it pretends no vault was selected. Dummies are used to reduce the probability of other vaults at the same depth / place. * "entry": this tag MUST be there for a vault to be pickable as an entry vault. + * "extra": requests that the dungeon builder treat this as + an extra vault and try to immediately place another vault of the + same type it was trying to place when it placed this vault. + "extra" is good to use for things like labyrinth entries + that should not affect the chance of other minivaults on the level. + If you use "extra", you probably want to use one of the + "luniq" tags as well if your map is tagged "allow_dup". * "generate_awake": Monsters placed (using MONS, KMONS) in this vault will be generated awake. * "patrolling": Monsters placed (using MONS, KMONS) in this vault @@ -398,6 +428,11 @@ TAGS: Tags go an a TAGS: line and are space-separated. You can have several randomly converted from deep water (the default) to shallow. * "uniq_BAR": (uniq_ with any suffix) specifies that only one of the vaults with this tag can be used in a game. + * "luniq": specifies that this vault can be used only once on a + given level. "luniq" is only relevant when used with "allow_dup". + * "luniq_BAR": (luniq_ with any suffix) specifies that only one + of the vaults with this tag can be used on any given level. + "luniq_BAR" is only relevant when used with "allow_dup". * "branch_entry" eg. "orc_entry", "lair_entry" etc. If chosen, these maps will contain the stairs for that branch. Use "O" to place the stairs. If a branch has very few entries, diff --git a/crawl-ref/source/dat/lab.des b/crawl-ref/source/dat/lab.des index 9e40008913..5a08bf57cd 100644 --- a/crawl-ref/source/dat/lab.des +++ b/crawl-ref/source/dat/lab.des @@ -9,13 +9,17 @@ # Labyrinth entry vaults NAME: lab_entry_generic -TAGS: lab_entry transparent trowel_portal allow_dup -DEPTH: 12-26 -ORIENT: float +TAGS: luniq_lab chance_lab transparent trowel_portal allow_dup +# Nominal chance for labs was 1 chance in 15, but making it eligible as a +# random vault gives this vault more opportunities to be placed, so dropping +# chance to 2.85%. +CHANCE: 50 : 285 +DEPTH: 12-27 : messager = bell_clock_msg { initmsg="You hear a distant snort." } MARKER: O = lua: timed_marker { \ low=400, high=600, msg=messager, floor = 'stone_arch' \ } +KFEAT: O = enter_labyrinth MAP O ENDMAP diff --git a/crawl-ref/source/dat/lair.des b/crawl-ref/source/dat/lair.des index 7588ea89f5..31fb59e2de 100644 --- a/crawl-ref/source/dat/lair.des +++ b/crawl-ref/source/dat/lair.des @@ -765,8 +765,7 @@ ENDMAP # # Shoal:$ is hand-hacked to force lots of minivaults. NAME: shoalhut_rune -PLACE: Shoal:$ -TAGS: has_rune +TAGS: shoal_rune SHUFFLE: ABCD SUBST: A:x, B:x, C:x=, D=+ MAP diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 6ec32e4d3f..8263cb69a2 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -238,6 +238,8 @@ static bool _fixup_interlevel_connectivity(); // A mask of vaults and vault-specific flags. map_mask dgn_Map_Mask; std::vector<vault_placement> Level_Vaults; +std::set<std::string> Level_Unique_Maps; +std::set<std::string> Level_Unique_Tags; std::string dgn_Build_Method; std::string dgn_Layout_Type; @@ -295,6 +297,8 @@ bool builder(int level_number, int level_type) #endif dgn_level_vetoed = false; + Level_Unique_Maps.clear(); + Level_Unique_Tags.clear(); _reset_level(); @@ -314,7 +318,8 @@ bool builder(int level_number, int level_type) if (!dgn_level_vetoed && _valid_dungeon_level(level_number, level_type)) { dgn_Layout_Type.clear(); - + Level_Unique_Maps.clear(); + Level_Unique_Tags.clear(); _dgn_map_colour_fixup(); return (true); } @@ -460,12 +465,17 @@ static void _dgn_register_vault(const map_def &map) if (!map.has_tag("allow_dup")) you.uniq_map_names.insert(map.name); + if (map.has_tag("uniq")) + Level_Unique_Maps.insert(map.name); + std::vector<std::string> tags = split_string(" ", map.tags); for (int t = 0, ntags = tags.size(); t < ntags; ++t) { const std::string &tag = tags[t]; if (tag.find("uniq_") == 0) you.uniq_map_tags.insert(tag); + else if (tag.find("luniq_") == 0) + Level_Unique_Tags.insert(tag); } } @@ -1349,7 +1359,9 @@ static bool _add_feat_if_missing(bool (*iswanted)(const coord_def &), #ifdef DEBUG_DIAGNOSTICS dump_map("debug.map", true); #endif - ASSERT(!"Couldn't find region."); + // [ds] Too many normal cases trigger this ASSERT, including + // rivers that surround a stair with deep water. + // ASSERT(!"Couldn't find region."); return (false); } @@ -1531,8 +1543,8 @@ static void _build_dungeon_level(int level_number, int level_type) // Try to place minivaults that really badly want to be placed. Still // no guarantees, seeing this is a minivault. - if (!player_in_branch(BRANCH_SHOALS)) - _place_minivaults(); + + _place_minivaults(); _place_branch_entrances( level_number, level_type ); _place_extra_vaults(); @@ -1987,13 +1999,7 @@ static void _prepare_shoals(int level_number) grd[centres[j].x-1][centres[j].y] = DNGN_STONE_STAIRS_UP_III; // Place the rune - int vaultidx; - do - { - vaultidx = _dgn_random_map_for_place(true); - } - while ( vaultidx == -1 - || !map_by_index(vaultidx)->has_tag("has_rune") ); + int vaultidx = random_map_for_tag("shoal_rune", true); _build_minivaults( level_number, vaultidx, true, false, false, centres[1] ); @@ -2005,8 +2011,7 @@ static void _prepare_shoals(int level_number) { vaultidx = _dgn_random_map_for_place(true); } - while ( vaultidx == -1 - || map_by_index(vaultidx)->has_tag("has_rune") ); + while ( vaultidx == -1 ); _build_minivaults( level_number, vaultidx, true, false, false, centres[i] ); @@ -2392,7 +2397,8 @@ static builder_rc_type _builder_by_branch(int level_number) return BUILD_CONTINUE; } -static void _place_minivaults(const std::string &tag, int lo, int hi, bool force) +static void _place_minivaults(const std::string &tag, int lo, int hi, + bool force) { const level_id curr = level_id::current(); // Dungeon-style branches only, thankyouverymuch. @@ -2416,15 +2422,15 @@ static void _place_minivaults(const std::string &tag, int lo, int hi, bool force return; } - std::set<int> used; if (use_random_maps) { - const int vault = random_map_in_depth(level_id::current(), true); - if (vault != -1) + int vault = -1; + do { - _build_minivaults(you.your_level, vault); - used.insert(vault); - } + vault = random_map_in_depth(level_id::current(), true); + if (vault != -1) + _build_minivaults(you.your_level, vault); + } while (vault != -1 && map_by_index(vault)->has_tag("extra")); } int chance = you.your_level == 0? 50 : 100; @@ -2434,16 +2440,7 @@ static void _place_minivaults(const std::string &tag, int lo, int hi, bool force if (vault == -1) break; - // If we've already used this minivault and it doesn't want duplicates, - // break. - if (used.find(vault) != used.end() - && !map_by_index(vault)->has_tag("allow_dup")) - { - break; - } - _build_minivaults(you.your_level, vault); - used.insert(vault); chance /= 4; } } @@ -2658,12 +2655,6 @@ static void _builder_extras( int level_number, int level_type ) { UNUSED( level_type ); - if (one_chance_in(15)) - { - _place_specific_stair(DNGN_ENTER_LABYRINTH, "lab_entry", - level_number, true); - } - if (level_number > 6 && one_chance_in(10)) { _many_pools( level_number < 11 || coinflip() ? @@ -2834,18 +2825,28 @@ static void _place_specific_stair(dungeon_feature_type stair, static void _place_extra_vaults() { - if (!player_in_branch(BRANCH_MAIN_DUNGEON) - && use_random_maps - && can_create_vault) + for ( ; ; ) { - int vault = random_map_in_depth(level_id::current()); + if (!player_in_branch(BRANCH_MAIN_DUNGEON) + && use_random_maps + && can_create_vault) + { + int vault = random_map_in_depth(level_id::current()); - // ORIENT: encompass maps are unsuitable as secondary vaults. - if (vault != -1 && map_by_index(vault)->orient == MAP_ENCOMPASS) - vault = -1; + // ORIENT: encompass maps are unsuitable as secondary vaults. + if (vault != -1 && map_by_index(vault)->orient == MAP_ENCOMPASS) + vault = -1; - if (vault != -1 && _build_secondary_vault(you.your_level, vault, -1)) - can_create_vault = false; + if (vault != -1 + && _build_secondary_vault(you.your_level, vault, -1)) + { + const map_def &map(*map_by_index(vault)); + if (map.has_tag("extra")) + continue; + can_create_vault = false; + } + } + break; } } diff --git a/crawl-ref/source/dungeon.h b/crawl-ref/source/dungeon.h index a515ebdf5c..756c431ab3 100644 --- a/crawl-ref/source/dungeon.h +++ b/crawl-ref/source/dungeon.h @@ -17,6 +17,7 @@ #include "travel.h" #include "stuff.h" #include <vector> +#include <set> #include <algorithm> enum portal_type @@ -54,6 +55,9 @@ typedef FixedArray<unsigned short, GXM, GYM> map_mask; extern map_mask dgn_Map_Mask; extern std::string dgn_Layout_Type; +extern std::set<std::string> Level_Unique_Maps; +extern std::set<std::string> Level_Unique_Tags; + // Map mask constants. enum map_mask_type diff --git a/crawl-ref/source/maps.cc b/crawl-ref/source/maps.cc index e0b0909c44..31386ff2e3 100644 --- a/crawl-ref/source/maps.cc +++ b/crawl-ref/source/maps.cc @@ -327,8 +327,11 @@ static bool map_has_no_tags(const map_def &map, I begin, I end) static bool vault_unforbidden(const map_def &map) { return (you.uniq_map_names.find(map.name) == you.uniq_map_names.end() + && Level_Unique_Maps.find(map.name) == Level_Unique_Maps.end() && map_has_no_tags(map, you.uniq_map_tags.begin(), - you.uniq_map_tags.end())); + you.uniq_map_tags.end()) + && map_has_no_tags(map, Level_Unique_Tags.begin(), + Level_Unique_Tags.end())); } static bool map_matches_layout_type(const map_def &map) @@ -387,9 +390,10 @@ public: } static map_selector by_tag(const std::string &tag, bool mini, - bool check_depth) + bool check_depth, + const level_id &place = level_id::current()) { - return map_selector(map_selector::TAG, level_id::current(), tag, + return map_selector(map_selector::TAG, place, tag, mini, check_depth); } @@ -558,8 +562,9 @@ static int _random_map_in_list(const map_selector &sel, // a lookup for that tag. if (!chance_tag.empty()) { - map_selector msel = map_selector::by_tag(sel.tag, sel.mini, - sel.check_depth); + map_selector msel = map_selector::by_tag(chance_tag, sel.mini, + sel.check_depth, + sel.place); msel.ignore_chance = true; return _random_map_by_selector(msel); } |