summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2008-05-26 07:45:18 +0000
committerzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2008-05-26 07:45:18 +0000
commitf910f85b74d9dae832f8d3422f51d87565ea3a08 (patch)
tree5b10f62736e875a57e0380e4dc477af5774cc661
parentf7f652ac0f4c5a193ee4ad5471a85cf723466e24 (diff)
downloadcrawl-ref-f910f85b74d9dae832f8d3422f51d87565ea3a08.tar.gz
crawl-ref-f910f85b74d9dae832f8d3422f51d87565ea3a08.zip
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
-rw-r--r--crawl-ref/docs/level_design.txt12
-rw-r--r--crawl-ref/source/dungeon.cc38
-rw-r--r--crawl-ref/source/dungeon.h1
-rw-r--r--crawl-ref/source/maps.cc13
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<vault_placement> 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 &region,
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<unsigned short, GXM, GYM> 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;