git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1616 c06c8d41-db1a-0410-9941-cceddc491573
56C44YMFHZ62GXAAOLYSLLGBVGRWXB53W2VI37Q26ZECEK2XG5SQC
KXUQB3WNWC5IFL6VFWADEPQMMU3VV3NDI5FLA666PGOEWFYUHCLQC
ILOED4VB4I6VPAUTR75ZWX6MXDYXB5DO2EDK2UH67O3HNKWV23RQC
RRADDS444JWSL4KOJKNZFAIMWMZRLFR4KZPC2MJBCJPEPINC5CPQC
OY7KHQPESOUHPBXRZ2JSNUKPAC7DCDY73TAUHCSJG5V6TPAHBVYQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
MSQI3TH6T62JAXQGLL52QZCWAMC372TGB6ZNNRDGUGMJKBNNV2VAC
3XZOL3FFQZITUJIGDD6B6V6ZYMBN524JKNN6ZPJAXEC7RY433I3QC
KCHX2F3JFEWOZT3WMJVZAAQUU2QSZ5Q7RDCD7WUJ7VE65J52JFUQC
A3CO4KBFTFU3ZSHWRY2OPPX3MMTFV7OUCZGL7Q4Y2FU7JO4AP7MAC
SCWXQW5H65OXUP2MEJ2MEEAVPSRJDT3RQGKYCMKVTORS2334PQSQC
L6O4LGZRKBURVWEY7XRVCSQLJ5RULNBEWMQJ6I2UYVWWB66FM3MQC
KFM2ARORBIJ6BGX456VFW7EAVRIYBVFUV53JH63GSKNOKVPJWQ2QC
static void build_minivaults(int level_number, int force_vault)
static bool safe_minivault_place(int v1x, int v1y,
const vault_placement &place)
{
for (int vx = v1x; vx < v1x + place.width; vx++)
{
for (int vy = v1y; vy < v1y + place.height; vy++)
{
if ((grd[vx][vy] != DNGN_FLOOR
&& grd[vx][vy] != DNGN_ROCK_WALL
&& grd[vx][vy] != DNGN_CLOSED_DOOR
&& grd[vx][vy] != DNGN_SECRET_DOOR)
|| igrd[vx][vy] != NON_ITEM
|| mgrd[vx][vy] != NON_MONSTER)
{
return (false);
}
}
}
return (true);
}
static bool connected_minivault_place(int v1x, int v1y,
const vault_placement &place)
{
/* must not be completely isolated: */
for (int vx = v1x; vx < v1x + place.width; vx++)
{
// if (vx != v1x && vx != v1x + 12) continue;
for (int vy = v1y; vy < v1y + place.height; vy++)
{
if (grd[vx][vy] == DNGN_FLOOR
|| grd[vx][vy] == DNGN_CLOSED_DOOR
|| grd[vx][vy] == DNGN_SECRET_DOOR)
return (true);
}
}
return (false);
}
static bool find_minivault_place(const vault_placement &place,
int &v1x, int &v1y)
{
// [ds] The margin around the edges of the map where the minivault
// won't be placed. Purely arbitrary as far as I can see.
const int margin = MAPGEN_BORDER * 2;
/* find a target area which can be safely overwritten: */
for (int tries = 0; tries < 600; ++tries)
{
v1x = random_range( margin, GXM - margin - place.width );
v1y = random_range( margin, GYM - margin - place.height );
if (!safe_minivault_place( v1x, v1y, place ))
continue;
if (connected_minivault_place(v1x, v1y, place))
return (true);
}
return (false);
}
static bool build_minivaults(int level_number, int force_vault)
// [ds] The margin around the edges of the map where the minivault won't be
// placed. Purely arbitrary as far as I can see.
const int margin = 12;
/* find a target area which can be safely overwritten: */
while(1)
{
v1x = random_range( margin, GXM - margin - place.width );
v1y = random_range( margin, GYM - margin - place.height );
for (vx = v1x; vx < v1x + place.width; vx++)
{
for (vy = v1y; vy < v1y + place.height; vy++)
{
// [ds] An escape hatch to keep from hanging forever looking
// for a good place.
if (one_chance_in(2000))
return;
if ((grd[vx][vy] != DNGN_FLOOR
&& grd[vx][vy] != DNGN_ROCK_WALL
&& grd[vx][vy] != DNGN_CLOSED_DOOR
&& grd[vx][vy] != DNGN_SECRET_DOOR)
|| igrd[vx][vy] != NON_ITEM
|| mgrd[vx][vy] != NON_MONSTER)
{
goto out_of_check;
}
}
}
/* must not be completely isolated: */
for (vx = v1x; vx < v1x + place.width; vx++)
{
// if (vx != v1x && vx != v1x + 12) continue;
for (vy = v1y; vy < v1y + place.height; vy++)
{
if (grd[vx][vy] == DNGN_FLOOR
|| grd[vx][vy] == DNGN_CLOSED_DOOR
|| grd[vx][vy] == DNGN_SECRET_DOOR)
goto break_out;
}
}
out_of_check:
continue;
if (grd(nc) == DNGN_ROCK_WALL)
{
grd(nc) = DNGN_FLOOR;
grd(c + (nc - c) / 2) = DNGN_FLOOR;
if (!one_chance_in(3))
labyrinth_maze_recurse(nc);
else
deferred.push_back(nc);
}
if (grd(nc) != DNGN_ROCK_WALL)
continue;
grd(nc) = DNGN_FLOOR;
grd(c + (nc - c) / 2) = DNGN_FLOOR;
if (!one_chance_in(5))
labyrinth_maze_recurse(nc, where);
else
deferred.push_back(nc);
dgn_region lab =
dgn_region::absolute( MAPGEN_BORDER * 5 / 2, MAPGEN_BORDER * 5 / 2,
GXM - MAPGEN_BORDER * 5 / 2 - 1,
GYM - MAPGEN_BORDER * 5 / 2 - 1 );
// First decide if we're going to use a Lab minivault.
int vault = random_map_for_tag("lab", true, false);
vault_placement place;
if (vault != -1)
{
init_minivault_placement(vault, place);
int ex = place.width / 4, ey = place.height / 4;
labyrinth_dimension_adjust(ex, lab.pos.x, lab.size.x);
labyrinth_dimension_adjust(ey, lab.pos.y, lab.size.y);
}
// turn rock walls into undiggable stone or metal:
if (vault == -1 || !build_minivaults(level_number, vault))
{
vault = -1;
labyrinth_place_exit(end);
}
else
{
const vault_placement &rplace = *(level_vaults.end() - 1);
if (rplace.map.has_tag("generate_loot"))
{
for (int y = rplace.y; y <= rplace.y + rplace.height - 1; ++y)
{
for (int x = rplace.x; x <= rplace.x + rplace.height - 1; ++x)
{
if (grd[x][y] == DNGN_ROCK_STAIRS_UP)
{
labyrinth_place_items(coord_def(x, y));
break;
}
}
}
}
place.x = rplace.x;
place.y = rplace.y;
place.width = rplace.width;
place.height = rplace.height;
}
// turn rock walls into undiggable stone or metal:
#############################################################################
# Labyrinth minivaults
#############################################################################
# One layer of floor space *must* surround the minivault, or the player could
# be trapped in the labyrinth (the dummy is exempt from this requirement).
#
# You can use the "generate_loot" tag to indicate that you're not explicitly
# placing the loot and that the dungeon builder should generate random loot
# (on the upstair). Note that this is not the default, and if you neither use
# this tag nor provide loot in the map definition, the player will be
# disappointed.
#
# You *must* place the minotaur(s) yourself!
#############################################################################
# Dummy balancer
NAME: labyrinth_0
TAGS: lab dummy
CHANCE: 20
MAP
x
ENDMAP
#############################################################################
# A simple lair.
NAME: labyrinth_1
TAGS: lab generate_loot no_pool_fixup
MONS: minotaur
SHUFFLE: def
SUBST: d=^, e=^, f=.
MAP
.........
.ccccccc.
.cwwwwwc.
.cww<wwc.
.cwdefwc.
.ccc1ccc.
.c.....c.
.ccc+ccc.
.........
ENDMAP