Attached Files |
0001-Reimplemented-LUA-dgn_make_box_doors-more-options.patch [^] (6,694 bytes) 2013-06-04 08:56 [Show Content] [Hide Content]From d7a07175f5486f869be81ba11c222687c0e52844 Mon Sep 17 00:00:00 2001
From: infiniplex <infiniplex@hotmail.com>
Date: Wed, 29 May 2013 18:14:56 -0600
Subject: [PATCH 1/4] Reimplemented LUA dgn_make_box_doors: more options
---
crawl-ref/source/l_dgnbld.cc | 153 ++++++++++++++++++++++++-------------------
1 file changed, 87 insertions(+), 66 deletions(-)
diff --git a/crawl-ref/source/l_dgnbld.cc b/crawl-ref/source/l_dgnbld.cc
index 7e60e9b..0dcde51 100644
--- a/crawl-ref/source/l_dgnbld.cc
+++ b/crawl-ref/source/l_dgnbld.cc
@@ -167,38 +167,6 @@ static void _border_area(map_lines &lines, int x1, int y1, int x2, int y2, char
lines(x1, y) = border, lines(x2, y) = border;
}
-// Specifically only deals with horizontal lines.
-static vector<coord_def> _box_side(int x1, int y1, int x2, int y2, int side)
-{
- vector<coord_def> line;
-
- int start_x, start_y, stop_x, stop_y, x, y;
-
- switch (side)
- {
- case 0: start_x = x1; start_y = y1; stop_x = x2; stop_y = y1; break;
- case 1: start_x = x2; start_y = y1; stop_x = x2; stop_y = y2; break;
- case 2: start_x = x1; start_y = y2; stop_x = x2; stop_y = y2; break;
- case 3: start_x = x1; start_y = y1; stop_x = x1; stop_y = y2; break;
- default: die("invalid _box_side");
- }
-
- x = start_x; y = start_y;
-
- if (start_x == stop_x)
- {
- for (y = start_y+1; y < stop_y; y++)
- line.push_back(coord_def(x, y));
- }
- else
- {
- for (x = start_x+1; x < stop_x; x++)
- line.push_back(coord_def(x, y));
- }
-
- return line;
-}
-
// Does what count_passable_neighbors does, but in C++ form.
static int _count_passable_neighbors(lua_State *ls, map_lines &lines, int x,
int y, const char *passable = traversable_glyphs)
@@ -216,12 +184,6 @@ static int _count_passable_neighbors(lua_State *ls, map_lines &lines, int x,
return count;
}
-static int _count_passable_neighbors(lua_State *ls, map_lines &lines, coord_def point,
- const char *passable = traversable_glyphs)
-{
- return _count_passable_neighbors(ls, lines, point.x, point.y, passable);
-}
-
static vector<coord_def> _get_pool_seed_positions(
vector<vector<int> > pool_index,
int pool_size,
@@ -754,10 +716,11 @@ LUAFN(dgn_make_box)
TABLE_CHAR(ls, floor, '.');
TABLE_CHAR(ls, wall, 'x');
- TABLE_INT(ls, width, 1);
+ TABLE_INT(ls, thickness, 1);
_fill_area(ls, lines, x1, y1, x2, y2, wall);
- _fill_area(ls, lines, x1+width, y1+width, x2-width, y2-width, floor);
+ _fill_area(ls, lines, x1+thickness, y1+thickness,
+ x2-thickness, y2-thickness, floor);
return 0;
}
@@ -771,42 +734,100 @@ LUAFN(dgn_make_box_doors)
return 0;
TABLE_INT(ls, number, 1);
+ TABLE_INT(ls, thickness, 1);
+ TABLE_CHAR(ls, door, '+');
+ TABLE_CHAR(ls, inner_door, '.');
+ TABLE_CHAR(ls, between_doors, '.');
+ TABLE_BOOL(ls, veto_gates, false);
+ TABLE_STR(ls, passable, traversable_glyphs);
- int sides[4] = {0, 0, 0, 0};
+ // size doesn't include corners
+ int size_x = x2 - x1 + 1 - thickness * 2;
+ int size_y = y2 - y1 + 1 - thickness * 2;
+ int position_count = size_x * 2 + size_y * 2;
- int door_count;
+ int max_sanity = number * 100;
+ int sanity = 0;
- for (door_count = 0; door_count < number; door_count++)
+ int door_count = 0;
+ while (door_count < number)
{
- int current_side = random2(4);
- if (sides[current_side] >= 2)
- current_side = random2(4);
-
- vector<coord_def> points = _box_side(x1, y1, x2, y2, current_side);
-
- int total_points = int(points.size());
-
- int index = random2avg(total_points, 2 + random2(number));
-
- int tries = 50;
-
- while (_count_passable_neighbors(ls, lines, points[index]) <= 3)
+ int position = random2(position_count);
+ int side;
+ int x, y;
+ if(position < size_x)
{
- tries--;
- index = random2(total_points);
-
- if (tries == 0)
- break;
+ side = 0;
+ x = x1 + thickness + position;
+ y = y1;
+ }
+ else if(position < size_x * 2)
+ {
+ side = 1;
+ x = x1 + thickness + (position - size_x);
+ y = y2;
+ }
+ else if(position < size_x * 2 + size_y)
+ {
+ side = 2;
+ x = x1;
+ y = y1 + thickness + (position - size_x * 2);
+ }
+ else
+ {
+ side = 3;
+ x = x2;
+ y = y1 + thickness + (position - size_x * 2 - size_y);
}
- if (tries == 0)
+ // We veto a position if:
+ // -> The cell outside the box is not passible
+ // -> The cell (however far) inside the box is not passible
+ // -> There is a door to the left or right and we are vetoing gates
+ bool good = true;
+ if(side < 2)
{
- door_count--;
- continue;
+ if(!strchr(passable, lines(x, y - (side == 0 ? 1 : thickness))))
+ good = false;
+ if(!strchr(passable, lines(x, y + (side == 1 ? 1 : thickness))))
+ good = false;
+ if(veto_gates && (lines(x-1, y) == door || lines(x+1, y) == door))
+ good = false;
+ }
+ else
+ {
+ if(!strchr(passable, lines(x - (side == 2 ? 1 : thickness), y)))
+ good = false;
+ if(!strchr(passable, lines(x + (side == 3 ? 1 : thickness), y)))
+ good = false;
+ if(veto_gates && (lines(x, y-1) == door || lines(x, y+1) == door))
+ good = false;
}
- sides[current_side]++;
- lines(points[index]) = '+';
+ if(good)
+ {
+ door_count++;
+ lines(x, y) = door;
+ for(int i = 1; i < thickness; i++)
+ {
+ switch(side)
+ {
+ case 0: y++; break;
+ case 1: y--; break;
+ case 2: x++; break;
+ case 3: x--; break;
+ }
+ lines(x, y) = between_doors;
+ }
+ if(thickness > 1)
+ lines(x, y) = inner_door;
+ }
+ else
+ {
+ sanity++;
+ if(sanity >= max_sanity)
+ break;
+ }
}
lua_pushnumber(ls, door_count);
--
1.8.1.2
0002-Added-LUA-you.depth_fraction-function.patch [^] (1,297 bytes) 2013-06-04 08:57 [Show Content] [Hide Content]From 05dbbf8fe1744641ca51f92ac0b66099103dfaa4 Mon Sep 17 00:00:00 2001
From: infiniplex <infiniplex@hotmail.com>
Date: Tue, 4 Jun 2013 00:07:22 -0600
Subject: [PATCH 2/4] Added LUA you.depth_fraction function
---
crawl-ref/source/l_you.cc | 3 +++
1 file changed, 3 insertions(+)
diff --git a/crawl-ref/source/l_you.cc b/crawl-ref/source/l_you.cc
index 3fd1b2b..01647f4 100644
--- a/crawl-ref/source/l_you.cc
+++ b/crawl-ref/source/l_you.cc
@@ -160,6 +160,8 @@ LUARET1(you_lives, number, you.lives)
LUARET1(you_where, string, level_id::current().describe().c_str())
LUARET1(you_branch, string, level_id::current().describe(false, false).c_str())
LUARET1(you_depth, number, you.depth)
+LUARET1(you_depth_fraction, number,
+ (float)you.depth / brdepth[you.where_are_you])
// [ds] Absolute depth is 1-based for Lua to match things like DEPTH:
// which are also 1-based. Yes, this is confusing. FIXME: eventually
// change you.absdepth0 to be 1-based as well.
@@ -458,6 +460,7 @@ static const struct luaL_reg you_clib[] =
{ "where", you_where },
{ "branch", you_branch },
{ "depth", you_depth },
+ { "depth_fraction", you_depth_fraction },
{ "absdepth", you_absdepth },
{ "is_level_on_stack", you_is_level_on_stack },
--
1.8.1.2
0003-Added-rooms-to-Gehenna-pools-layouts.patch [^] (7,942 bytes) 2013-06-04 08:57 [Show Content] [Hide Content]From 62fc50eb556fbf15897bdcbb3154c0094afcc566 Mon Sep 17 00:00:00 2001
From: infiniplex <infiniplex@hotmail.com>
Date: Tue, 4 Jun 2013 00:09:42 -0600
Subject: [PATCH 3/4] Added rooms to Gehenna pools layouts
---
crawl-ref/source/dat/des/builder/layout_pools.des | 106 +++++++++++++++++++---
1 file changed, 92 insertions(+), 14 deletions(-)
diff --git a/crawl-ref/source/dat/des/builder/layout_pools.des b/crawl-ref/source/dat/des/builder/layout_pools.des
index feae7cc..3f2241f 100644
--- a/crawl-ref/source/dat/des/builder/layout_pools.des
+++ b/crawl-ref/source/dat/des/builder/layout_pools.des
@@ -36,6 +36,9 @@
-- longer and thus harder
STAIRS_PLACE_PERCENT = 20
+ -- The minimum floor area for a layout
+ FLOOR_AREA_MINIMUM = 750
+
-- The width of the path before the caves are grown is 1 + 2 * size
PATH_SIZE_BASIC = 2
PATH_SIZE_TRIPLE = 1
@@ -59,25 +62,70 @@
function gehenna_layout_epilogue (e)
-- you.depth() is the depth in the current branch
local branch_depth = dgn.br_depth(you.branch())
- local depth_fraction = (you.depth() / branch_depth)
+ local depth_fraction = you.depth_fraction()
+
+ e.widen_paths { find = "x", percent = 10 }
+ -- add the lava and rock pools
local pool_contents = {}
- pool_contents["c"] = branch_depth * 2 - you.depth()
- pool_contents["l"] = branch_depth + you.depth()
+ pool_contents["v"] = branch_depth * 2 - you.depth()
+ pool_contents["l"] = branch_depth * 2
pool_contents["."] = branch_depth
- if pool_contents["."] <= 0 then
- pool_contents["."] = nil
- end
-
- e.widen_paths { find = "x", percent = 10 }
e.add_pools { replace = ".",
- pool_size = 60 - 25 * depth_fraction,
+ pool_size = 40 + 40 * depth_fraction,
contents = pool_contents }
- e.widen_paths { find = "c", percent = 90 }
- e.subst("c = x")
+
+ -- add some random rooms
+ local border = 4
+ local gxm, gym = dgn.max_bounds()
+ local right = gxm - 1 - border
+ local bottom = gym - 1 - border
+ local size_min = crawl.random_range(3, 5)
+ local size_max = crawl.random_range(5, 9)
+ local overlap_wall_min = crawl.random_real() * 0.4 + 0.1
+ local seperation_min = crawl.random_range(1, border - depth_fraction*2)
+
+ local room_count_min = (25 + depth_fraction * 475) / size_max
+ local room_count_max = (50 + depth_fraction * 950) / size_max
+ for i = 1, crawl.random_range(room_count_min, room_count_max) do
+ local size_x = crawl.random_range(size_min, size_max)
+ local size_y = crawl.random_range(size_min, size_max)
+ local min_x = crawl.random_range(border, right - size_x)
+ local min_y = crawl.random_range(border, bottom - size_y)
+ local max_x = min_x + size_x
+ local max_y = min_y + size_y
+
+ local cell_count = size_x * size_y
+ local wall_count = e.count_feature_in_box {x1 = min_x, x2 = max_x,
+ y1 = min_y, y2 = max_y,
+ feat = "xv" }
+ local blocked = e.find_in_area {x1 = min_x - seperation_min,
+ x2 = max_x + seperation_min,
+ y1 = min_y - seperation_min,
+ y2 = max_y + seperation_min,
+ find = "c", find_vault = true }
+ if not blocked and wall_count < cell_count
+ and wall_count >= cell_count * overlap_wall_min then
+ local wall_length = (size_x + size_y) * 2
+ local door_count = crawl.random_range(1, 1 + wall_length / 12)
+ e.make_box {x1 = min_x, x2 = max_x,
+ y1 = min_y, y2 = max_y,
+ floor = '.', wall = 'c' }
+ e.make_box_doors {x1 = min_x, x2 = max_x,
+ y1 = min_y, y2 = max_y, veto_gates=true,
+ number = door_count }
+ end
+ end
+
+ -- clean up the map
+ e.widen_paths { find = "v", percent = 90 }
+ e.subst("v = x")
e.remove_isolated_glyphs { find = "x", percent = 75 }
e.widen_paths { find = "l", percent = 60 }
e.remove_isolated_glyphs { find = "l", percent = 90, boxy = true }
+
+ -- THIS LEAVES ISOLATED LAVA POOLS
+ zonify.map_fill_zones(e, 1, 'x')
end
}}
@@ -188,10 +236,12 @@ ENDMAP
# NOTE: There are other Gehenna layouts in other files.
#
# These layouts are long canyons with lava pools in them and
-# rock "pools" to provide cover. The up stairs may be placed
+# rock "pools" to provide cover. After this, a number of
+# box-shaped rooms are added. The up stairs may be placed
# randomly or at one end of the canyon, while the down stairs
# are always placed randomly. Deeper maps have fewer, larger
-# pools, of which more are lava and fewer are rock.
+# pools, of which more are lava and fewer are rock, and have
+# more rooms.
#
# The approximate shape the each canyon is shown above the
# layout vault.
@@ -201,7 +251,8 @@ ENDMAP
# 2. Grow a cave map with spotty_map
# 3. Add the stairs (pools must go around these)
# 4. Add the lava and rock pools with add_pools
-# 5. Fix up lava and rock pools to look good and have wider
+# 5. Add some box-shaped rooms that overlap the rock
+# 6. Fix up lava and rock pools to look good and have wider
# paths
#
@@ -255,6 +306,9 @@ TAGS: overwritable layout allow_dup unrand no_rotate layout_type_caves
gehenna_layout_epilogue(_G)
}}
+validate {{
+ return count_feature_in_box { feat="." } >= FLOOR_AREA_MINIMUM
+}}
# +
# ( / \ )
@@ -321,6 +375,9 @@ TAGS: overwritable layout allow_dup unrand no_rotate layout_type_caves
gehenna_layout_epilogue(_G)
}}
+validate {{
+ return count_feature_in_box { feat="." } >= FLOOR_AREA_MINIMUM
+}}
# (
# {+-------+
@@ -380,6 +437,9 @@ TAGS: overwritable layout allow_dup unrand no_rotate layout_type_caves
gehenna_layout_epilogue(_G)
}}
+validate {{
+ return count_feature_in_box { feat="." } >= FLOOR_AREA_MINIMUM
+}}
# (
# {+-------+
@@ -443,6 +503,9 @@ TAGS: overwritable layout allow_dup unrand no_rotate layout_type_caves
gehenna_layout_epilogue(_G)
}}
+validate {{
+ return count_feature_in_box { feat="." } >= FLOOR_AREA_MINIMUM
+}}
# )
# ( |
@@ -500,6 +563,9 @@ TAGS: overwritable layout allow_dup unrand no_rotate layout_type_caves
gehenna_layout_epilogue(_G)
}}
+validate {{
+ return count_feature_in_box { feat="." } >= FLOOR_AREA_MINIMUM
+}}
# ( )
# | |
@@ -551,6 +617,9 @@ TAGS: overwritable layout allow_dup unrand no_rotate layout_type_caves
gehenna_layout_epilogue(_G)
}}
+validate {{
+ return count_feature_in_box { feat="." } >= FLOOR_AREA_MINIMUM
+}}
# (---------)
# | |
@@ -605,6 +674,9 @@ TAGS: overwritable layout allow_dup unrand no_rotate layout_type_caves
gehenna_layout_epilogue(_G)
}}
+validate {{
+ return count_feature_in_box { feat="." } >= FLOOR_AREA_MINIMUM
+}}
# (-----+---)
# |
@@ -671,6 +743,9 @@ TAGS: overwritable layout allow_dup unrand no_rotate layout_type_caves
gehenna_layout_epilogue(_G)
}}
+validate {{
+ return count_feature_in_box { feat="." } >= FLOOR_AREA_MINIMUM
+}}
# +----)
# ( |
@@ -739,3 +814,6 @@ TAGS: overwritable layout allow_dup unrand no_rotate layout_type_caves
gehenna_layout_epilogue(_G)
}}
+validate {{
+ return count_feature_in_box { feat="." } >= FLOOR_AREA_MINIMUM
+}}
--
1.8.1.2
0004-Added-thick-walls-to-some-layout_city-rooms.patch [^] (9,109 bytes) 2013-06-04 08:57 [Show Content] [Hide Content]From f0b2f7185e8f8c661fc733e5079c934ea090f46c Mon Sep 17 00:00:00 2001
From: infiniplex <infiniplex@hotmail.com>
Date: Tue, 4 Jun 2013 00:10:53 -0600
Subject: [PATCH 4/4] Added thick walls to some layout_city rooms
---
crawl-ref/source/dat/des/builder/layout.des | 124 ++++++++++++++++++++--------
1 file changed, 88 insertions(+), 36 deletions(-)
diff --git a/crawl-ref/source/dat/des/builder/layout.des b/crawl-ref/source/dat/des/builder/layout.des
index b09bf51..a34d5e5 100644
--- a/crawl-ref/source/dat/des/builder/layout.des
+++ b/crawl-ref/source/dat/des/builder/layout.des
@@ -95,8 +95,10 @@ TAGS: overwritable layout no_primary_vault allow_dup unrand layout_type_open
if crawl.coinflip() then
local width2 = 1 + crawl.random2(5)
- fill_area{x1=10, y1=gym/2-width2, x2=gxm-10, y2=gym/2+width2, fill=floor}
- fill_area{x1=gxm/2-width2, y1=10, x2=gxm/2+width2, y2=gym-10, fill=floor}
+ fill_area{x1=10, y1=gym/2-width2,
+ x2=gxm-10, y2=gym/2+width2, fill=floor}
+ fill_area{x1=gxm/2-width2, y1=10,
+ x2=gxm/2+width2, y2=gym-10, fill=floor}
-- sometimes add a small octagon room
if crawl.coinflip() then
@@ -110,7 +112,8 @@ TAGS: overwritable layout no_primary_vault allow_dup unrand layout_type_open
["w"] = 5,
["l"] = 1,
})
- octa_room{x1=25, y1=25, x2=gxm-25, y2=gym-25, oblique=obl, replace='x', inside=fill}
+ octa_room{x1=25, y1=25, x2=gxm-25, y2=gym-25,
+ oblique=obl, replace='x', inside=fill}
-- decrease spotty chance
spotty = crawl.one_chance_in(5)
@@ -469,21 +472,37 @@ TAGS: layout_type_city
x2 = x2 + 1
y2 = y2 + 1
- if x2 <= x2 or y2 <= y2 then
+ if x2 <= x1 or y2 <= y1 then
return false
end
- if (x2 - x1) * (y2 - y1) >= 40 then
+ local area = (x2 - x1) * (y2 - y1)
+ if area >= 40 then
return false
end
+ -- for bigger rooms, use less valuable loot
+ local loot = { }
+ if area <= 4 then
+ loot['|'] = 1
+ elseif area <= 10 then
+ loot['|'] = 10 - area
+ loot['*'] = area - 4
+ elseif area < 25 then
+ loot['*'] = 25 - area
+ loot['%'] = area - 10
+ else
+ loot['%'] = 1
+ end
+
local tl = dgn.point(x1, y1)
local br = dgn.point(x2 - 1, y2 - 1)
for point in iter.rect_iterator(tl, br) do
if is_valid_coord {x = point.x, y = point.y } then
- if is_passable_coord { x=point.x, y=point.y } or crawl.coinflip() then
- mapgrd[point.x][point.y] = "|"
+ if is_passable_coord { x=point.x, y=point.y }
+ or crawl.coinflip() then
+ mapgrd[point.x][point.y] = crawl.random_element (loot)
end
end
end
@@ -495,16 +514,8 @@ TAGS: layout_type_city
extend_map{width = gxm, height = gym, fill = 'x'}
- local wall_type_room
local wall_type
local rooms = {}
-
- local xs = 0
- local ys = 0
- local ax1 = 0
- local bx2 = 0
- local ay1 = 0
- local by2 = 0
local i, j
if you.branch() == "Dis" then
@@ -519,29 +530,56 @@ TAGS: layout_type_city
for i = 0, 5 do
for j = 0, 4 do
- xs = 8 + (i * 13)
- ys = 8 + (j * 14)
- a1 = xs + crawl.random2avg(5, 2);
- a2 = ys + crawl.random2avg(5, 2);
- b1 = xs + 11 - crawl.random2avg(5, 2);
- b2 = ys + 11 - crawl.random2avg(5, 2);
-
- if crawl.x_chance_in_y(6, 7) and is_valid_coord {x=a1, y=a2} and is_valid_coord{x=b1, y=b2}
+ local xs = 8 + (i * 13)
+ local ys = 8 + (j * 14)
+ local a1 = xs + crawl.random2avg(5, 2);
+ local a2 = ys + crawl.random2avg(5, 2);
+ local b1 = xs + 11 - crawl.random2avg(5, 2);
+ local b2 = ys + 11 - crawl.random2avg(5, 2);
+
+ if crawl.x_chance_in_y(6, 7)
+ and is_valid_coord {x=a1, y=a2}
+ and is_valid_coord{x=b1, y=b2}
and not find_in_area {x1 = a1 - 1, y1 = a2 - 1,
x2 = b1 + 1, y2 = b2 + 1,
find = "xcvb+", find_vault = true } then
- wall_type_room = theme.room_material(wall_type)
+ local wall_type_room = theme.room_material(wall_type)
- table.insert(rooms, {a1, a2, b1, b2})
- make_box { x1=a1, y1=a2, x2=b1, y2=b2, wall=wall_type_room }
+ local size_x = b1 - a1
+ local size_y = b2 - a2
+ local thickness = 1
+ if size_x > 6 and size_y > 6 and crawl.one_chance_in(8) then
+ thickness = 3
+ elseif size_x > 4 and size_y > 4
+ and crawl.one_chance_in(24) then
+ thickness = 2
+ end
- if b1 - a1 > 5 and b2 - a2 > 5 and crawl.one_chance_in(8) then
- table.insert(rooms, {a1+2, a2+2, b1-2, b2-2})
- make_box { x1=a1+2, y1=a2+2, x2=b1-2, y2=b2-2, wall=wall_type_room }
+ table.insert(rooms, {a1, a2, b1, b2, thickness})
+ make_box { x1=a1, y1=a2, x2=b1, y2=b2,
+ wall=wall_type_room, thickness=thickness }
+
+ if size_x > 3 + thickness * 2 and size_y > 3 + thickness * 2
+ and crawl.one_chance_in(8) then
+ local A1 = a1 + thickness + 1
+ local A2 = a2 + thickness + 1
+ local B1 = b1 - thickness - 1
+ local B2 = b2 - thickness - 1
+ local door_number = 1 + crawl.random2(2)*crawl.random2(2)
+
+ local wall_type_inner = wall_type_room
+ if crawl.one_chance_in(5) then
+ wall_type_inner = theme.room_material(wall_type)
+ end
+
+ make_box { x1=A1, y1=A2, x2=B1, y2=B2,
+ wall=wall_type_room }
+ make_box_doors { x1=A1, y1=A2, x2=B1, y2=B2,
+ number=door_number }
- if crawl.one_chance_in(3) then
- treasure_area(a1+3, a2+3, b1-3, b2-3)
+ if crawl.x_chance_in_y(thickness, 3) then
+ treasure_area(A1+1, A2+1, B1-1, B2-1)
end
end
end
@@ -558,11 +596,21 @@ TAGS: layout_type_city
doors = 2
end
- make_box_doors {x1=room[1], y1=room[2], x2=room[3], y2=room[4], number=doors}
+ local thickness = room[5]
+ local inner_door = '.'
+ if thickness == 2 and crawl.one_chance_in(8) then
+ inner_door = '+'
+ elseif thickness == 3 and crawl.x_chance_in_y(2, 3) then
+ inner_door = '+'
+ end
+
+ make_box_doors {x1=room[1], y1=room[2], x2=room[3], y2=room[4],
+ number=doors, thickness=room[5],
+ inner_door=inner_door, veto_gates=true}
end
-- Prevent treasure rooms being overwritten by vaults
- kmask('| = vault')
+ kmask('|*% = vault')
}}
MAP
ENDMAP
@@ -932,7 +980,9 @@ TAGS: overwritable layout no_primary_vault allow_dup unrand layout_type_rooms
and (you.in_branch("D") or you.in_branch("Lair"))
and crawl.x_chance_in_y(you.absdepth() - 9, 450)
then
- local feat = crawl.random_element { ['v'] = 2, ['c'] = 3, ['x'] = 3 }
+ local feat = crawl.random_element { ['v'] = 2,
+ ['c'] = 3,
+ ['x'] = 3 }
make_inner_room(room, feat, crawl.coinflip())
end
end
@@ -1207,7 +1257,8 @@ TAGS: overwritable layout allow_dup unrand layout_type_rooms
fill(x1, y1, x3, y2, 1)
fill(x3, y1, x2, y2, 1)
if not alt then
- replace_random { x1=x3, y1=y1+1, x2=x3, y2=y2-1, find='x', replace='+' }
+ replace_random { x1=x3, y1=y1+1, x2=x3, y2=y2-1,
+ find='x', replace='+' }
end
end
else
@@ -1222,7 +1273,8 @@ TAGS: overwritable layout allow_dup unrand layout_type_rooms
fill(x1, y1, x2, y3, 0)
fill(x1, y3, x2, y2, 0)
if not alt then
- replace_random { x1=x1+1, y1=y3, x2=x2-1, y2=y3, find='x', replace='+' }
+ replace_random { x1=x1+1, y1=y3, x2=x2-1, y2=y3,
+ find='x', replace='+' }
end
end
end
--
1.8.1.2
GehennaRooms1.png [^] (28,641 bytes) 2013-06-04 08:57
GehennaRooms2.png [^] (52,914 bytes) 2013-06-04 08:57
LayoutCityThickWalls.png [^] (37,939 bytes) 2013-06-04 08:57
layout_city2.des [^] (7,749 bytes) 2013-06-07 06:53 [Show Content] [Hide Content]##############################################################
# layout_city
#
# This replaces dungeon.cc:_city_level().
#
# Only available on upper Lair depths otherwise the high
# ruination makes it basically indistinguishable from a big
# open room
NAME: layout_city
DEPTH: D:15-, Lair:1-2, Snake, Dwarf, Crypt:1-4, Dis:1-6
WEIGHT: 10
ORIENT: encompass
TAGS: overwritable layout allow_dup unrand no_rotate no_vmirror no_hmirror
TAGS: layout_type_city
{{
function treasure_area (x1, y1, x2, y2)
x2 = x2 + 1
y2 = y2 + 1
if x2 <= x1 or y2 <= y1 then
return false
end
local area = (x2 - x1) * (y2 - y1)
if area >= 40 then
return false
end
-- for bigger rooms, use less valuable loot
local loot = { }
if area <= 4 then
loot['|'] = 1
elseif area <= 10 then
loot['|'] = 10 - area
loot['*'] = area - 4
elseif area < 25 then
loot['*'] = 25 - area
loot['%'] = area - 10
else
loot['%'] = 1
end
local tl = dgn.point(x1, y1)
local br = dgn.point(x2 - 1, y2 - 1)
for point in iter.rect_iterator(tl, br) do
if is_valid_coord {x = point.x, y = point.y } then
if is_passable_coord { x=point.x, y=point.y }
or crawl.coinflip() then
mapgrd[point.x][point.y] = crawl.random_element (loot)
end
end
end
return true
end
local gxm, gym = dgn.max_bounds()
extend_map{width = gxm, height = gym, fill = 'x'}
local wall_type
local rooms = {}
local i, j
if you.branch() == "Dis" then
wall_type = 'x'
elseif crawl.one_chance_in(100) then
wall_type = 'b'
else
wall_type = crawl.random_element { ['x'] = 3, ['c'] = 3, ['v'] = 2 }
end
local percent_thickness_2 = crawl.random_range(0, 8)
* crawl.random_range(0, 8)
local percent_thickness_3 = crawl.random_range(0, 7)
* crawl.random_range(0, 7)
local percent_inner_box = crawl.random_range(0, 25)
local percent_inner_new_wall = crawl.random_range(0, 100)
local percent_inner_split = crawl.random_range(0, 25)
if you.branch() == "Dis" then
percent_thickness_2 = 0
percent_thickness_3 = 0
percent_inner_box = percent_inner_box * 1.5
percent_inner_new_wall = 0
percent_inner_split = percent_inner_split * 2
end
fill_area { x1=8, y1=8, x2=gxm-9, y2=gym-9, fill="." }
for i = 0, 5 do
for j = 0, 4 do
local xs = 8 + (i * 13)
local ys = 8 + (j * 14)
local a1 = xs + crawl.random2avg(5, 2);
local a2 = ys + crawl.random2avg(5, 2);
local b1 = xs + 11 - crawl.random2avg(5, 2);
local b2 = ys + 11 - crawl.random2avg(5, 2);
if crawl.x_chance_in_y(6, 7)
and is_valid_coord {x=a1, y=a2}
and is_valid_coord{x=b1, y=b2}
and not find_in_area {x1 = a1 - 1, y1 = a2 - 1,
x2 = b1 + 1, y2 = b2 + 1,
find = "xcvb+", find_vault = true } then
local wall_type_room = theme.room_material(wall_type)
local size_x = b1 - a1
local size_y = b2 - a2
local thickness = 1
if size_x > 6 and size_y > 6
and crawl.x_chance_in_y(percent_thickness_3, 100) then
thickness = 3
elseif size_x > 4 and size_y > 4
and crawl.x_chance_in_y(percent_thickness_2, 100) then
thickness = 2
end
table.insert(rooms, {a1, a2, b1, b2, thickness})
make_box { x1=a1, y1=a2, x2=b1, y2=b2,
wall=wall_type_room, thickness=thickness }
local size_x_inner = size_x - thickness * 2
local size_y_inner = size_y - thickness * 2
if size_x_inner > 3 and size_y_inner > 3 then
if crawl.x_chance_in_y(percent_inner_box, 100) then
local A1 = a1 + thickness + 1
local A2 = a2 + thickness + 1
local B1 = b1 - thickness - 1
local B2 = b2 - thickness - 1
local door_number = 1 +
crawl.random2(2) * crawl.random2(2)
local wall_type_inner = wall_type_room
if crawl.x_chance_in_y(percent_inner_new_wall, 100) then
wall_type_inner = theme.room_material(wall_type)
end
make_box { x1=A1, y1=A2, x2=B1, y2=B2,
wall=wall_type_inner }
make_box_doors { x1=A1, y1=A2, x2=B1, y2=B2,
number=door_number }
if crawl.x_chance_in_y(thickness*4,
percent_inner_box) then
treasure_area(A1+1, A2+1, B1-1, B2-1)
end
elseif crawl.x_chance_in_y(percent_inner_split, 100) then
local door_x = a1 + thickness + 1
+ crawl.random2(size_x_inner - 2)
local door_y = a2 + thickness + 1
+ crawl.random2(size_y_inner - 2)
if crawl.coinflip() then
for x = a1 + thickness, b1 - thickness do
mapgrd[x][door_y] = wall_type_room
end
else
for y = a2 + thickness, b2 - thickness do
mapgrd[door_x][y] = wall_type_room
end
end
mapgrd[door_x][door_y] = '+'
end
end
end
end
end
for _, room in ipairs(rooms) do
local doors = 1 + crawl.random2(5) - crawl.random2(3)
if doors < 1 then
doors = 1
end
if doors > 3 and crawl.one_chance_in(3) then
doors = 2
end
local thickness = room[5]
local outer_door = '+'
local inner_door = '+'
if thickness == 2 then
outer_door = crawl.random_element { ['+'] = 1, ['.'] = 2 }
inner_door = crawl.random_element { ['+'] = 1, ['.'] = 3 }
elseif thickness == 3 then
outer_door = crawl.random_element { ['+'] = 2, ['.'] = 1 }
inner_door = crawl.random_element { ['+'] = 1, ['.'] = 2 }
end
if outer_door == '.' and crawl.coinflip() then
doors = doors + 1
end
if inner_door == '.' and crawl.coinflip() then
doors = doors + 1
end
make_box_doors {x1=room[1], y1=room[2], x2=room[3], y2=room[4],
number=doors, thickness=thickness,
door=outer_door, inner_door=inner_door,
veto_gates=true }
end
-- Prevent treasure rooms being overwritten by vaults
kmask('|*% = vault')
}}
MAP
ENDMAP
LayoutCityThickWalls2.png [^] (22,923 bytes) 2013-06-07 06:53
layout_pools.des [^] (21,257 bytes) 2013-06-14 06:23 [Show Content] [Hide Content]##############################################################
# layout_pools.des
#
# These layouts are based on the add_pools function. They
# divide the map into a bunch of irregular areas jammed aginst
# each other. The layout may use either the areas themsleves
# are the paths between them. These are not true vaults, in
# that the dungeon builder can add other vaults on top of them.
#
: require("dlua/layout/zonify.lua")
: require("dlua/layout/theme.lua")
##############################################################
#
# Gehenna layout constants and functions
#
# These are collected together here instead of in the layout
# vaults because they are each used in more than one.
#
# These maps have a small chance of placing the up stairs.
# This is handlied by always generating the layout as if
# the stairs were to be placed, but only sometimes adding
# them.
#
{{
-- Increasing this makes the caves bigger
CANYON_SIZE_FACTOR = 100
-- The distance stairs are placed from the edge of the map
STAIRS_FROM_MAP_EDGE = 15
-- The chance that the up stairs are deliberately placed,
-- usually at the canyon end: increasing this makes diving
-- longer and thus harder
STAIRS_PLACE_PERCENT = 20
-- The minimum floor area for a layout
FLOOR_AREA_MINIMUM = 750
-- The width of the path before the caves are grown is
-- 1 + 2 * PATH_SIZE_???
PATH_SIZE_BASIC = 2
PATH_SIZE_TRIPLE = 1
-- The spacing between 3 stairs placed together at the end
-- of a large path
STAIRS_SPACING_X = 3
STAIRS_SPACING_Y = 8
-- add and fix up the lava and rock pools
function gehenna_layout_epilogue (e)
-- you.depth() is the depth in the current branch
local branch_depth = dgn.br_depth(you.branch())
local depth_fraction = you.depth_fraction()
e.widen_paths { find = "x", percent = 10 }
-- add the lava and rock pools
local pool_contents = {}
pool_contents["v"] = branch_depth * 2 - you.depth()
pool_contents["l"] = branch_depth * 2
pool_contents["."] = branch_depth
e.add_pools { replace = ".",
pool_size = 40 + 40 * depth_fraction,
contents = pool_contents }
-- add some random rooms
local border = 4
local gxm, gym = dgn.max_bounds()
local right = gxm - 1 - border
local bottom = gym - 1 - border
local size_max = 6 + 4 * depth_fraction
local seperation_min = crawl.random_range(1, border - depth_fraction*2)
local room_count_min = ( 50 + depth_fraction * 950) / size_max
local room_count_max = (150 + depth_fraction * 1850) / size_max
for i = 1, crawl.random_range(room_count_min, room_count_max) do
local size = crawl.random_range(4, size_max)
local min_x = crawl.random_range(border, right - size)
local min_y = crawl.random_range(border, bottom - size)
local max_x = min_x + size
local max_y = min_y + size
local cell_count = size * size
local wall_count = e.count_feature_in_box {x1 = min_x, x2 = max_x,
y1 = min_y, y2 = max_y,
feat = "xv" }
local blocked = e.find_in_area {x1 = min_x - seperation_min,
x2 = max_x + seperation_min,
y1 = min_y - seperation_min,
y2 = max_y + seperation_min,
find = "c", find_vault = true }
if not blocked and wall_count < cell_count
and wall_count >= cell_count * 0.5 then
local door_count = crawl.random_range(1, 3)
e.make_round_box {x1 = min_x, x2 = max_x,
y1 = min_y, y2 = max_y,
floor = '.', wall = 'c',
door_count = door_count, veto_gates=true,
veto_if_no_doors=true }
end
end
-- clean up the map
e.widen_paths { find = "v", percent = 90 }
e.subst("v = x")
e.remove_isolated_glyphs { find = "x", percent = 75 }
e.widen_paths { find = "l", percent = 60 }
e.remove_isolated_glyphs { find = "l", percent = 90, boxy = true }
zonify.map_fill_zones(e, 1, 'x')
end
}}
##############################################################
# layout_pools
#
# This layout creates an irregular cave with clumps of rock and
# possibly a few pools of water. There are more pools at
# deeper depths. Starting at depth 19, there is an increasing
# chance of lava pools instead of water pools (never mixed).
#
NAME: layout_pools
DEPTH: D:9-
WEIGHT: 10
ORIENT: encompass
TAGS: overwritable layout allow_dup unrand no_rotate no_vmirror no_hmirror
TAGS: layout_type_caves
{{
local gxm, gym = dgn.max_bounds()
extend_map { width = gxm, height = gym, fill = 'x' }
-- without a starting floor patch, spotty_map will crash
mapgrd[gxm/2][gym/2] = '.'
spotty_map { boxy = false, iterations = 1000 }
remove_isolated_glyphs { find = "x", percent = 100 }
local pool_contents = {}
pool_contents["."] = 40
pool_contents["x"] = 40 - you.absdepth()
if crawl.coinflip() then
if you.absdepth() >= 19 + crawl.random2(8) then
pool_contents["l"] = you.absdepth() * crawl.random2(100) / 100
else
pool_contents["w"] = you.absdepth() * crawl.random2(100) / 100
end
end
add_pools { replace = ".",
pool_size = 10 + crawl.random2(15),
contents = pool_contents,
frequency = pool_frequency }
widen_paths { find = "x", percent = 30 }
remove_isolated_glyphs { find = "x", percent = 80 }
widen_paths { find = "l", percent = 30 }
remove_isolated_glyphs { find = "l", percent = 75, boxy = true }
theme.D.caves(_G)
}}
MAP
ENDMAP
#############################################################
# layout_honeycomb
#
# This layout is composed of a series of irregular rooms
# directly beside each other. They are sometimes connected
# by doors and sometimes just by holes in the wall.
#
NAME: layout_honeycomb
DEPTH: D:12-, Snake:1-4, Tar
WEIGHT: 10, 80(Tar)
ORIENT: encompass
TAGS: overwritable layout allow_dup unrand no_rotate no_vmirror no_hmirror
TAGS: layout_type_rooms
{{
local gxm, gym = dgn.max_bounds()
extend_map { width = gxm, height = gym, fill = 'x' }
make_circle { x = gxm/2, y = gym/2, radius = 10 }
mapgrd[gxm/2][gym/2] = '.'
spotty_map { boxy = true, iterations = 1500 }
widen_paths { find = "x", percent = 50 }
remove_isolated_glyphs { find = "x", percent = 100 }
local connection = {}
if you.in_branch("snake") then
connection = '.'
else
connection = crawl.random_element({['.'] = 1, ['+'] = 2})
end
add_pools { replace = ".",
contents = {['.'] = 1},
pool_size = 25 + crawl.random2(25),
border = 'x' }
connect_adjacent_rooms { wall = "x", floor = ".", replace = connection,
min = 900, max = 1300, check_empty = true }
connect_adjacent_rooms { wall = "x", floor = ".", replace = connection,
min = 100, max = 200, check_empty = false }
zonify.map_fill_zones(_G, 1, 'x')
if connection == '.' and you.in_branch("D") then
theme.D.caves(_G)
else
theme.level_material(_G)
end
}}
# Enforce minimum floor size - this is important
validate {{
return count_feature_in_box { feat="." } > 600
}}
MAP
ENDMAP
##############################################################
# Gehenna layouts
#
# NOTE: There are other Gehenna layouts in other files.
#
# These layouts are long canyons with lava pools in them and
# rock "pools" to provide cover. After this, a number of
# box-shaped rooms are added. The up stairs may be placed
# randomly or at one end of the canyon, while the down stairs
# are always placed randomly. Deeper maps have fewer, larger
# pools, of which more are lava and fewer are rock, and have
# more rooms.
#
# Simply put, the algorithm is:
# 1. Draw the rough layout shape with fill_area
# 2. Grow a cave map with spotty_map
# 3. Add the stairs (pools must go around these)
# 4. Add the lava and rock pools with add_pools
# 5. Add some box-shaped rooms that overlap the rock
# 6. Fix up lava and rock pools to look good and have wider
# paths
#
#
# This layout has a single main horizontal path. It may have
# large areas on either end and may have a large rooms at the
# middle.
#
NAME: layout_gehenna_pools_basic
DEPTH: Geh
WEIGHT: 20
ORIENT: encompass
TAGS: overwritable layout allow_dup unrand no_rotate no_vmirror no_hmirror
TAGS: layout_type_caves
{{
local gxm, gym = dgn.max_bounds()
extend_map{width = gxm, height = gym, fill = 'x'}
local STAIRS_X_UP = STAIRS_FROM_MAP_EDGE
local STAIRS_X_UP23 = STAIRS_FROM_MAP_EDGE + STAIRS_SPACING_X
local STAIRS_X_DOWN = gxm - STAIRS_FROM_MAP_EDGE
local STAIRS_X_DOWN23 = gxm - STAIRS_FROM_MAP_EDGE - STAIRS_SPACING_X
local STAIRS_Y1 = gym / 2
local STAIRS_Y_SMALL2 = STAIRS_Y1 - STAIRS_SPACING_Y
local STAIRS_Y_SMALL3 = STAIRS_Y1 + STAIRS_SPACING_Y
local STAIRS_Y_BIG2 = STAIRS_FROM_MAP_EDGE
local STAIRS_Y_BIG3 = gym - STAIRS_FROM_MAP_EDGE
local big_end_1 = crawl.one_chance_in(3)
local big_end_2 = crawl.one_chance_in(3)
local spotty_iterations = 4
if big_end_1 then
fill_area { x1 = STAIRS_X_UP - PATH_SIZE_BASIC, y1 = STAIRS_Y_BIG2,
x2 = STAIRS_X_UP + PATH_SIZE_BASIC, y2 = STAIRS_Y_BIG3,
fill = '.' }
spotty_iterations = spotty_iterations + 0.5
else
fill_area { x1 = STAIRS_X_UP23, y1 = STAIRS_Y_SMALL2,
x2 = STAIRS_X_UP23, y2 = STAIRS_Y_SMALL3,
fill = '.' }
end
fill_area { x1 = STAIRS_X_UP, y1 = STAIRS_Y1 - PATH_SIZE_BASIC,
x2 = STAIRS_X_DOWN, y2 = STAIRS_Y1 + PATH_SIZE_BASIC,
fill = '.' }
if big_end_2 then
fill_area { x1 = STAIRS_X_DOWN - PATH_SIZE_BASIC, y1 = STAIRS_Y_BIG2,
x2 = STAIRS_X_DOWN + PATH_SIZE_BASIC, y2 = STAIRS_Y_BIG3,
fill = '.' }
spotty_iterations = spotty_iterations + 0.5
else
fill_area { x1 = STAIRS_X_DOWN23, y1 = STAIRS_Y_SMALL2,
x2 = STAIRS_X_DOWN23, y2 = STAIRS_Y_SMALL3,
fill = '.' }
end
-- maybe add an open are in the middle
if crawl.one_chance_in(3) then
local big_room_x = gxm / 2 + crawl.random_range(-2, 2)
local big_room_y = gym / 2 + crawl.random_range(-5, 5)
local big_room_radius = crawl.random_range(15, 20)
make_diamond { x = big_room_x, y = big_room_y,
radius = big_room_radius, fill = '.' }
if crawl.coinflip() then
make_diamond { x = big_room_x, y = big_room_y,
radius = big_room_radius - PATH_SIZE_BASIC * 2,
fill = 'x' }
end
spotty_iterations = spotty_iterations + 1
end
spotty_iterations = spotty_iterations * CANYON_SIZE_FACTOR
spotty_map { boxy = false, iterations = spotty_iterations }
remove_isolated_glyphs { find = "x", percent = 100 }
if crawl.random2(100) < STAIRS_PLACE_PERCENT then
if big_end_1 then
mapgrd[STAIRS_X_UP][STAIRS_Y1] = '{'
mapgrd[STAIRS_X_UP][STAIRS_Y_BIG2] = '('
mapgrd[STAIRS_X_UP][STAIRS_Y_BIG3] = '['
else
mapgrd[STAIRS_X_UP ][STAIRS_Y1] = '{'
mapgrd[STAIRS_X_UP23][STAIRS_Y_SMALL2] = '('
mapgrd[STAIRS_X_UP23][STAIRS_Y_SMALL3] = '['
end
if big_end_2 then
mapgrd[STAIRS_X_DOWN][STAIRS_Y1] = '}'
mapgrd[STAIRS_X_DOWN][STAIRS_Y_BIG2] = ')'
mapgrd[STAIRS_X_DOWN][STAIRS_Y_BIG3] = ']'
else
mapgrd[STAIRS_X_DOWN ][STAIRS_Y1] = '}'
mapgrd[STAIRS_X_DOWN23][STAIRS_Y_SMALL2] = ')'
mapgrd[STAIRS_X_DOWN23][STAIRS_Y_SMALL3] = ']'
end
shuffle("{([")
shuffle("})]")
shuffle("{([/})]")
subst("})] = .")
end
gehenna_layout_epilogue(_G)
}}
validate {{
return count_feature_in_box { feat="." } >= FLOOR_AREA_MINIMUM
}}
#
# This layout draws a rough box which is often missing a
# horizontal and/or vertical side.
#
# Shape distribution:
# Complete box: 2/8 * 2/8 = 4/64 = 1/16 = 6.25%
# U-Shape: 2/8 * 6/8 * 2 = 24/64 = 3/8 = 37.5 %
# L-shape: 6/8 * 6/8 = 36/64 = 9/16 = 56.25%
#
NAME: layout_gehenna_pools_box
DEPTH: Geh
WEIGHT: 10
ORIENT: encompass
TAGS: overwritable layout allow_dup unrand no_rotate no_vmirror no_hmirror
TAGS: layout_type_caves
{{
local gxm, gym = dgn.max_bounds()
extend_map{width = gxm, height = gym, fill = 'x'}
local CORNER_X1 = STAIRS_FROM_MAP_EDGE
local CORNER_X2 = gxm - STAIRS_FROM_MAP_EDGE
local PATH_OFFSET_Y = 15
local CORNER_Y1 = gym / 2 - PATH_OFFSET_Y
local CORNER_Y2 = gym / 2 + PATH_OFFSET_Y
local ODDS_1_SIDE = 3
local ODDS_2_SIDES = 2
local ODDS_TOTAL = ODDS_1_SIDE * 2 + ODDS_2_SIDES
local which_paths_x = crawl.random2(ODDS_TOTAL)
local which_paths_y = crawl.random2(ODDS_TOTAL)
local spotty_iterations = 4
if which_paths_x < ODDS_TOTAL - ODDS_1_SIDE then
fill_area { x1 = CORNER_X1, y1 = CORNER_Y1 - PATH_SIZE_BASIC,
x2 = CORNER_X2, y2 = CORNER_Y1 + PATH_SIZE_BASIC,
fill = '.' }
spotty_iterations = spotty_iterations + 1
end
if which_paths_x >= ODDS_1_SIDE then
fill_area { x1 = CORNER_X1, y1 = CORNER_Y2 - PATH_SIZE_BASIC,
x2 = CORNER_X2, y2 = CORNER_Y2 + PATH_SIZE_BASIC,
fill = '.' }
spotty_iterations = spotty_iterations + 1
end
if which_paths_y < ODDS_TOTAL - ODDS_1_SIDE then
fill_area { x1 = CORNER_X1 - PATH_SIZE_BASIC, y1 = CORNER_Y1,
x2 = CORNER_X1 + PATH_SIZE_BASIC, y2 = CORNER_Y2,
fill = '.' }
spotty_iterations = spotty_iterations + 0.5
end
if which_paths_y >= ODDS_1_SIDE then
fill_area { x1 = CORNER_X2 - PATH_SIZE_BASIC, y1 = CORNER_Y1,
x2 = CORNER_X2 + PATH_SIZE_BASIC, y2 = CORNER_Y2,
fill = '.' }
spotty_iterations = spotty_iterations + 0.5
end
spotty_iterations = spotty_iterations * CANYON_SIZE_FACTOR
spotty_map { boxy = false, iterations = spotty_iterations }
remove_isolated_glyphs { find = "x", percent = 100 }
-- I am not even going to try to place stairs at the ends
-- of this mess
gehenna_layout_epilogue(_G)
}}
validate {{
return count_feature_in_box { feat="." } >= FLOOR_AREA_MINIMUM
}}
#
# This layout builds three parallel horizontal paths. The paths
# may continue the whole length of the map seperately, or may
# join up at one end. If the paths do not join up,
# connections are added so that all three paths are connected.
#
NAME: layout_gehenna_pools_triple
DEPTH: Geh
WEIGHT: 5
ORIENT: encompass
TAGS: overwritable layout allow_dup unrand no_rotate no_vmirror no_hmirror
TAGS: layout_type_caves
{{
local gxm, gym = dgn.max_bounds()
extend_map{width = gxm, height = gym, fill = 'x'}
local DIVISION_SPACING = 15
local PATH_SPACING = 22
local STAIRS_X_UP = STAIRS_FROM_MAP_EDGE
local STAIRS_X_UP23 = STAIRS_FROM_MAP_EDGE + STAIRS_SPACING_X
local STAIRS_X_DOWN = gxm - STAIRS_FROM_MAP_EDGE
local STAIRS_X_DOWN23 = gxm - STAIRS_FROM_MAP_EDGE - STAIRS_SPACING_X
local STAIRS_Y1 = gym / 2
local STAIRS_Y_SMALL2 = STAIRS_Y1 - STAIRS_SPACING_Y
local STAIRS_Y_SMALL3 = STAIRS_Y1 + STAIRS_SPACING_Y
local STAIRS_Y_BIG2 = STAIRS_Y1 - PATH_SPACING
local STAIRS_Y_BIG3 = STAIRS_Y1 + PATH_SPACING
local ODDS_1_SIDE = 2
local ODDS_2_SIDES = 3
local ODDS_TOTAL = ODDS_1_SIDE * 2 + ODDS_2_SIDES
local division_x = crawl.random_range(STAIRS_X_UP23 + DIVISION_SPACING,
STAIRS_X_DOWN23 - DIVISION_SPACING)
local open_end = crawl.random2(ODDS_TOTAL)
local spotty_iterations
if open_end < ODDS_1_SIDE then
fill_area { x1 = STAIRS_X_UP23, y1 = STAIRS_Y_SMALL2,
x2 = STAIRS_X_UP23, y2 = STAIRS_Y_SMALL3,
fill = '.' }
fill_area { x1 = STAIRS_X_UP, y1 = STAIRS_Y1 - PATH_SIZE_BASIC,
x2 = division_x, y2 = STAIRS_Y1 + PATH_SIZE_BASIC,
fill = '.' }
else
fill_area { x1 = STAIRS_X_UP, y1 = STAIRS_Y1 - PATH_SIZE_TRIPLE,
x2 = division_x, y2 = STAIRS_Y1 + PATH_SIZE_TRIPLE,
fill = '.' }
fill_area { x1 = STAIRS_X_UP, y1 = STAIRS_Y_BIG2 - PATH_SIZE_TRIPLE,
x2 = division_x, y2 = STAIRS_Y_BIG2 + PATH_SIZE_TRIPLE,
fill = '.' }
fill_area { x1 = STAIRS_X_UP, y1 = STAIRS_Y_BIG3 - PATH_SIZE_TRIPLE,
x2 = division_x, y2 = STAIRS_Y_BIG3 + PATH_SIZE_TRIPLE,
fill = '.' }
end
if open_end < ODDS_1_SIDE or open_end >= ODDS_TOTAL - ODDS_1_SIDE then
fill_area { x1 = division_x - PATH_SIZE_TRIPLE, y1 = STAIRS_Y_BIG2,
x2 = division_x + PATH_SIZE_TRIPLE, y2 = STAIRS_Y_BIG3,
fill = '.' }
spotty_iterations = 5.5
else
fill_area { x1 = division_x - PATH_SIZE_TRIPLE, y1 = STAIRS_Y_BIG2,
x2 = division_x + PATH_SIZE_TRIPLE, y2 = STAIRS_Y1,
fill = '.' }
division_x = crawl.random_range(STAIRS_X_UP23 + DIVISION_SPACING,
STAIRS_X_DOWN23 - DIVISION_SPACING)
fill_area { x1 = division_x - PATH_SIZE_TRIPLE, y1 = STAIRS_Y1,
x2 = division_x + PATH_SIZE_TRIPLE, y2 = STAIRS_Y_BIG3,
fill = '.' }
spotty_iterations = 6
end
if open_end >= ODDS_TOTAL - ODDS_1_SIDE then
fill_area { x1 = STAIRS_X_DOWN23, y1 = STAIRS_Y_SMALL2,
x2 = STAIRS_X_DOWN23, y2 = STAIRS_Y_SMALL3,
fill = '.' }
fill_area { x1 = division_x, y1 = STAIRS_Y1 - PATH_SIZE_BASIC,
x2 = STAIRS_X_DOWN, y2 = STAIRS_Y1 + PATH_SIZE_BASIC,
fill = '.' }
else
fill_area { x1 = division_x, y1 = STAIRS_Y1 - PATH_SIZE_TRIPLE,
x2 = STAIRS_X_DOWN, y2 = STAIRS_Y1 + PATH_SIZE_TRIPLE,
fill = '.' }
fill_area { x1 = division_x, y1 = STAIRS_Y_BIG2 - PATH_SIZE_TRIPLE,
x2 = STAIRS_X_DOWN, y2 = STAIRS_Y_BIG2 + PATH_SIZE_TRIPLE,
fill = '.' }
fill_area { x1 = division_x, y1 = STAIRS_Y_BIG3 - PATH_SIZE_TRIPLE,
x2 = STAIRS_X_DOWN, y2 = STAIRS_Y_BIG3 + PATH_SIZE_TRIPLE,
fill = '.' }
end
spotty_iterations = spotty_iterations * CANYON_SIZE_FACTOR
spotty_map { boxy = false, iterations = spotty_iterations }
remove_isolated_glyphs { find = "x", percent = 100 }
if crawl.random2(100) < STAIRS_PLACE_PERCENT then
if open_end < ODDS_1_SIDE then
mapgrd[STAIRS_X_UP ][STAIRS_Y1] = '{'
mapgrd[STAIRS_X_UP23][STAIRS_Y_SMALL2] = '('
mapgrd[STAIRS_X_UP23][STAIRS_Y_SMALL3] = '['
else
mapgrd[STAIRS_X_UP][STAIRS_Y1] = '{'
mapgrd[STAIRS_X_UP][STAIRS_Y_BIG2] = '('
mapgrd[STAIRS_X_UP][STAIRS_Y_BIG3] = '['
end
if open_end >= ODDS_TOTAL - ODDS_1_SIDE then
mapgrd[STAIRS_X_DOWN ][STAIRS_Y1] = '}'
mapgrd[STAIRS_X_DOWN23][STAIRS_Y_SMALL2] = ')'
mapgrd[STAIRS_X_DOWN23][STAIRS_Y_SMALL3] = ']'
else
mapgrd[STAIRS_X_DOWN][STAIRS_Y1] = '}'
mapgrd[STAIRS_X_DOWN][STAIRS_Y_BIG2] = ')'
mapgrd[STAIRS_X_DOWN][STAIRS_Y_BIG3] = ']'
end
shuffle("{([")
shuffle("})]")
shuffle("{([/})]")
subst("})] = .")
end
gehenna_layout_epilogue(_G)
}}
validate {{
return count_feature_in_box { feat="." } >= FLOOR_AREA_MINIMUM
}}
GehennaCircularRooms.png [^] (82,562 bytes) 2013-06-14 06:23
0001-Added-LUA-make_round_box-function.patch [^] (8,953 bytes) 2013-06-15 19:48 [Show Content] [Hide Content]From 11b4e102e59e17a785d0739221019306d6213a5e Mon Sep 17 00:00:00 2001
From: infiniplex <infiniplex@hotmail.com>
Date: Thu, 13 Jun 2013 21:43:18 -0600
Subject: [PATCH] Added LUA make_round_box function
---
crawl-ref/source/l_dgnbld.cc | 208 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 208 insertions(+)
diff --git a/crawl-ref/source/l_dgnbld.cc b/crawl-ref/source/l_dgnbld.cc
index 0dcde51..0e60983 100644
--- a/crawl-ref/source/l_dgnbld.cc
+++ b/crawl-ref/source/l_dgnbld.cc
@@ -857,6 +857,213 @@ LUAFN(dgn_make_irregular_box)
return 0;
}
+LUAFN(dgn_make_round_box)
+{
+ LINES(ls, 1, lines);
+
+ int x1, y1, x2, y2;
+ if (!_coords(ls, lines, x1, y1, x2, y2))
+ return 0;
+
+ TABLE_CHAR(ls, floor, '.');
+ TABLE_CHAR(ls, wall, 'x');
+ TABLE_CHAR(ls, door, '+');
+ TABLE_INT(ls, door_count, 1);
+ TABLE_STR(ls, passable, traversable_glyphs);
+ TABLE_BOOL(ls, veto_gates, false);
+ TABLE_BOOL(ls, veto_if_no_doors, false);
+
+ const int OUTSIDE = 0;
+ const int WALL = 1;
+ const int FLOOR = 2;
+ const int DOOR = 3;
+
+ int size_x = x2 - x1 + 1;
+ int size_y = y2 - y1 + 1;
+
+ //
+ // The basic idea here is we draw a filled circle, hollow
+ // out the middle, and then place doors on straight walls
+ // until we have enough.
+ //
+ // We do not know for sure whether we want to actually draw
+ // anything until the end, so we will draw out tower onto
+ // our own seperate array (actually a vector of vectors
+ // so we can set the size at runtime). Then, if
+ // everything goes well, we will copy it to the world with
+ // the appropriate glyphs.
+ //
+ // Note that each of these steps has to be completed before
+ // we can do the next one, so all the loops over the same
+ // area are required.
+ //
+
+ // 1. Fill with OUTSIDE glyphs.
+ vector<vector<int> > new_glyphs(size_x, vector<int>(size_y, OUTSIDE));
+
+ // 2. Draw wall glyphs for filled circle.
+ // -> This is a formula for an ellipse in case we get a
+ // non-circular room to make
+ // -> we add an extra 0.5 to the radius so that we don't
+ // get wall isolated cells on the outside
+ float radius_x = (size_x - 1.0f) * 0.5f;
+ float radius_y = (size_y - 1.0f) * 0.5f;
+ for (int x = 0; x < size_x; x++)
+ for (int y = 0; y < size_y; y++)
+ {
+ float fraction_x = (x - radius_x) / (radius_x + 0.5f);
+ float fraction_y = (y - radius_y) / (radius_y + 0.5f);
+ if (fraction_x * fraction_x + fraction_y * fraction_y <= 1.0f)
+ new_glyphs[x][y] = WALL;
+ }
+
+ // 3. Replace all wall glypyhs that don't touch outside the
+ // circle with floor glyphs.
+ for (int x = 0; x < size_x; x++)
+ for (int y = 0; y < size_y; y++)
+ {
+ // we can't use adjacent_iterator it doesn't
+ // report neighbours with negative coordinates
+ if (new_glyphs[x][y] == WALL
+ && x > 0 && x < size_x - 1
+ && y > 0 && y < size_y - 1
+ && new_glyphs[x - 1][y - 1] != OUTSIDE
+ && new_glyphs[x ][y - 1] != OUTSIDE
+ && new_glyphs[x + 1][y - 1] != OUTSIDE
+ && new_glyphs[x - 1][y ] != OUTSIDE
+ && new_glyphs[x + 1][y ] != OUTSIDE
+ && new_glyphs[x - 1][y + 1] != OUTSIDE
+ && new_glyphs[x ][y + 1] != OUTSIDE
+ && new_glyphs[x + 1][y + 1] != OUTSIDE)
+ {
+ new_glyphs[x][y] = FLOOR;
+ }
+ }
+
+ // 4. Find all potential door positions.
+ vector<coord_def> door_positions;
+ for (int x = 0; x < size_x; x++)
+ for (int y = 0; y < size_y; y++)
+ if (new_glyphs[x][y] == WALL)
+ {
+ // check for wall in each direction
+ bool xm = (x - 1 >= 0 && new_glyphs[x - 1][y] == WALL);
+ bool xp = (x + 1 < size_x && new_glyphs[x + 1][y] == WALL);
+ bool ym = (y - 1 >= 0 && new_glyphs[x][y - 1] == WALL);
+ bool yp = (y + 1 < size_y && new_glyphs[x][y + 1] == WALL);
+
+ int real_x = x1 + x;
+ int real_y = y1 + y;
+
+ // We are on an X-aligned wall
+ if (xm && xp && !ym && !yp)
+ {
+ //
+ // Check for passable glyphs in real map
+ // and outside the tower. The check
+ // order is:
+ // -> in real map
+ // -> passable
+ // -> outside temporary array
+ // or array has OUTSIDE glyph
+ //
+ // If we can find one on at least one side,
+ // we can put a door here.
+ // -> we will only get two on rooms only
+ // 1 cell wide including walls
+ //
+
+ if (real_y - 1 >= 0
+ && strchr(passable, lines(real_x, real_y - 1))
+ && (y - 1 < 0
+ || new_glyphs[x][y - 1] == OUTSIDE))
+ {
+ door_positions.push_back(coord_def(x, y));
+ }
+ else if (real_y + 1 < lines.height()
+ && strchr(passable, lines(real_x, real_y + 1))
+ && (y + 1 >= size_y
+ || new_glyphs[x][y + 1] == OUTSIDE))
+ {
+ door_positions.push_back(coord_def(x, y));
+ }
+ }
+
+ // We are on an Y-aligned wall
+ if (!xm && !xp && ym && yp)
+ {
+ // Same checks as above, but the other axis
+ if (real_x - 1 >= 0
+ && strchr(passable, lines(real_x - 1, real_y))
+ && (x - 1 < 0
+ || new_glyphs[x - 1][y] == OUTSIDE))
+ {
+ door_positions.push_back(coord_def(x, y));
+ }
+ else if (real_x + 1 < lines.width()
+ && strchr(passable, lines(real_x + 1, real_y))
+ && (x + 1 >= size_x
+ || new_glyphs[x + 1][y] == OUTSIDE))
+ {
+ door_positions.push_back(coord_def(x, y));
+ }
+ }
+ }
+
+ // 5. Add doors
+ int doors_placed = 0;
+ while (doors_placed < door_count && !door_positions.empty())
+ {
+ int index = random2(door_positions.size());
+ coord_def pos = door_positions[index];
+ door_positions[index] = door_positions[door_positions.size() - 1];
+ door_positions.pop_back();
+
+ bool good_spot = true;
+ if (veto_gates)
+ {
+ if (pos.x - 1 >= 0 && new_glyphs[pos.x - 1][pos.y] == DOOR)
+ good_spot = false;
+ if (pos.x + 1 < size_x && new_glyphs[pos.x + 1][pos.y] == DOOR)
+ good_spot = false;
+ if (pos.y - 1 >= 0 && new_glyphs[pos.x][pos.y - 1] == DOOR)
+ good_spot = false;
+ if (pos.y + 1 < size_y && new_glyphs[pos.x][pos.y + 1] == DOOR)
+ good_spot = false;
+ }
+
+ if (good_spot)
+ {
+ new_glyphs[pos.x][pos.y] = DOOR;
+ doors_placed++;
+ }
+ }
+
+ // 6. Add tower to map (if not vetoed)
+ if(doors_placed > 0 || !veto_if_no_doors)
+ {
+ for (int x = 0; x < size_x; x++)
+ for (int y = 0; y < size_y; y++)
+ {
+ switch(new_glyphs[x][y])
+ {
+ // leave existing glyphs on OUTSIDE
+ case WALL: lines(x1 + x, y1 + y) = wall; break;
+ case FLOOR: lines(x1 + x, y1 + y) = floor; break;
+ case DOOR: lines(x1 + x, y1 + y) = door; break;
+ }
+ }
+
+ lua_pushboolean(ls, true);
+ }
+ else
+ {
+ lua_pushboolean(ls, false);
+ }
+
+ return 1;
+}
+
// Return a metatable for a point on the map_lines grid.
LUAFN(dgn_mapgrd_table)
{
@@ -1649,6 +1856,7 @@ const struct luaL_reg dgn_build_dlib[] =
{ "make_box", &dgn_make_box },
{ "make_box_doors", &dgn_make_box_doors },
{ "make_irregular_box", &dgn_make_irregular_box },
+ { "make_round_box", &dgn_make_round_box },
{ "mapgrd_table", dgn_mapgrd_table },
{ "octa_room", &dgn_octa_room },
{ "remove_isolated_glyphs", &dgn_remove_isolated_glyphs },
--
1.8.1.2
|