Included David's portal vaults for the Mines, Lair and Vaults.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@930 c06c8d41-db1a-0410-9941-cceddc491573
KCHX2F3JFEWOZT3WMJVZAAQUU2QSZ5Q7RDCD7WUJ7VE65J52JFUQC
6QWZDCP5HGYLTJO3WWYJJGRRT7QFY6IG64TC7TUB553Z7GAA2HIQC
AKIBZESMWXUYTAKI3YEWHXDX7M3XM2Q72RQYNGYT4IBXC3R3JWAQC
SCWXQW5H65OXUP2MEJ2MEEAVPSRJDT3RQGKYCMKVTORS2334PQSQC
77H4BWWPPGLM3PLZH4QTAJRXIZTSDVNCOKZE223I437FN2UJ34RQC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
RC6L3CIBLJEH4GWRFD7UQNGI6PZT74FRUVOYHSAN2XCC74NZUASQC
A3CO4KBFTFU3ZSHWRY2OPPX3MMTFV7OUCZGL7Q4Y2FU7JO4AP7MAC
MSQI3TH6T62JAXQGLL52QZCWAMC372TGB6ZNNRDGUGMJKBNNV2VAC
34C4U6EQWERY75GZJKUCM5KVGU2OUICETS5LGZF6RMKMZT4R5SQAC
5UVDIVD4NSXA52U4QMQIVST3GSZJ2A2YZK3RUEXKPM43YVQ7LI5AC
7J3H7JY6AUO2UHNF6DAHDZI4O33JMTUUTYTPRM3CKNPUOF2RQOGAC
XAFFD52IHN6FWFR2TT5F2KCUS7HAVCBI5CWTFMKPQG77GGTGAHLAC
LW4N5EHKL776DURXZMAM6JEW3JPWWX5BSNP7TCZHTLCDOQTTGFCAC
TJRYL3NXPW5IUGEV3YOC7JYWEXCZDBFPLT4AUG4P227WVKVB72ZAC
return (place.orient =
apply_vault_definition(place.map, map, place));
// Try so many times to place the map. This will always succeed
// unless there are conflicting map placements in 'avoid'.
int tries = 10;
do
resolve_map(place.map);
while ((place.orient =
apply_vault_definition(place.map, map, place, avoid)) == MAP_NONE
&& tries-- > 0);
return (place.orient);
static void apply_vault_grid(map_def &def, map_type map,
vault_placement &place)
static bool is_grid_clobbered(int sx, int sy, int width, int height)
{
for (int y = sy; y < sy + height; ++y)
{
for (int x = sx; x < sx + width; ++x)
{
int grid = grd[x][y];
if (!grid_is_opaque(grid)
&& grid != DNGN_FLOOR
&& grid != DNGN_CLOSED_DOOR
&& grid != DNGN_OPEN_DOOR
&& grid != DNGN_SECRET_DOOR)
{
return (true);
}
}
}
return (false);
}
// Determines if the region specified by (x, y, x + width - 1, y + height - 1)
// is a bad place to build a vault.
static bool bad_map_place(int x, int y, int width, int height,
std::vector<vault_placement> *avoid)
{
if (!avoid)
return (false);
const dgn_region thisvault(x, y, width, height);
for (int i = 0, size = avoid->size(); i < size; ++i)
{
const vault_placement &vp = (*avoid)[i];
const dgn_region vault(vp.x, vp.y, vp.width, vp.height);
if (thisvault.overlaps(vault))
return (true);
}
return (is_grid_clobbered(x, y, width, height));
}
static bool apply_vault_grid(map_def &def, map_type map,
vault_placement &place,
std::vector<vault_placement> *avoid)
static void build_vaults(int level_number, int vault_number);
static bool build_secondary_vault(int level_number, int vault, int rune_subst = -1);
static bool build_vaults(int level_number, int vault_number, int rune_subst = -1,
bool build_only = false);
static int random_portal_vault(const std::string &tag)
{
return random_map_for_tag(tag, false);
}
static bool place_portal_vault(int stair, const std::string &tag, int dlevel)
{
const int vault = random_portal_vault(tag);
if (vault == -1)
return (false);
return build_secondary_vault(dlevel, vault, stair);
}
static void build_vaults(int level_number, int force_vault)
static std::vector<coord_def> external_connection_points(
const vault_placement &place,
const std::vector<coord_def> &target_connections)
{
std::vector<coord_def> ex_connection_points;
// Giving target_connections directly to build_rooms causes
// problems with long, skinny vaults where paths to the exit
// tend to cut through the vault. By backing out of the vault
// one square, we improve connectibility.
for (int i = 0, size = target_connections.size(); i < size; ++i)
{
const coord_def &p = target_connections[i];
ex_connection_points.push_back(p + dig_away_dir(place, p));
}
return (ex_connection_points);
}
static dgn_region_list get_vault_regions()
{
dgn_region_list vaults;
for (int i = 0, size = level_vaults.size(); i < size; ++i)
{
const vault_placement &vp = level_vaults[i];
vaults.push_back(dgn_region(vp.x, vp.y, vp.width, vp.height));
}
return (vaults);
}
static coord_def find_random_grid(int grid, const dgn_region_list &excluded)
{
for (int i = 0; i < 100; ++i)
{
coord_def c( random_range(MAPGEN_BORDER + 1,
GXM - MAPGEN_BORDER - 1),
random_range(MAPGEN_BORDER + 1,
GYM - MAPGEN_BORDER - 1) );
if (unforbidden(c, excluded) && grd(c) == grid)
return c;
}
return coord_def(0, 0);
}
static void connect_vault(const vault_placement &vp)
{
std::vector<coord_def> exc = external_connection_points(vp, vp.exits);
dgn_region_list vaults = get_vault_regions();
for (int i = 0, size = exc.size(); i < size; ++i)
{
const coord_def &p = exc[i];
const coord_def floor = find_random_grid(DNGN_FLOOR, vaults);
if (!floor.x && !floor.y)
continue;
join_the_dots(p, floor, vaults, true);
}
}
/*
* Places a vault somewhere in an already built level if possible.
* Returns true if the vault was successfully placed.
*/
static bool build_secondary_vault(int level_number, int vault, int rune_subst)
{
if (build_vaults(level_number, vault, rune_subst, true))
{
const vault_placement &vp = level_vaults[ level_vaults.size() - 1 ];
connect_vault(vp);
return (true);
}
return (false);
}
static bool build_vaults(int level_number, int force_vault, int rune_subst,
bool build_only)
// Must do this only after target_connections is finalised, or the vault
// exits will not be correctly set.
level_vaults.push_back(place);
// If the map takes the whole screen or we were only requested to
// build, our work is done.
if (gluggy == MAP_ENCOMPASS || build_only)
return (true);
std::vector<coord_def> ex_connection_points;
// Giving target_connections directly to build_rooms causes
// problems with long, skinny vaults where paths to the exit
// tend to cut through the vault. By backing out of the vault
// one square, we improve connectability.
for (int i = 0, size = target_connections.size(); i < size; ++i)
{
const coord_def &p = target_connections[i];
ex_connection_points.push_back(p + dig_away_dir(place, p));
}
std::vector<coord_def> ex_connection_points =
external_connection_points(place, target_connections);
##############################################################################
# Portal vaults
##############################################################################
# These vaults are used when the dungeon builder tries to place a portal/stair
# to a branch. There's no guarantee that one of these will be used because
# portal vaults are placed last, after the rest of the level is generated, and
# will not be placed if they can't fit on the level without clobbering
# something.
#
# With portal vaults (as with minivaults), smaller is better, since the dungeon
# builder will frequently not be able to fit large vaults in anywhere (it
# doesn't try very hard).
#
# Note that the rune symbol (O) is used for the portal in portal vaults. If you
# do not put an O anywhere in the vault, there will be no portal for that
# branch!
#
##############################################################################
# Freedom of Choice (Orc entry)
NAME: david_orc_choice
TAGS: orc_entry
MONS: hobgoblin, orc sorcerer, orc warrior, orc
ITEM: scroll of blinking / scroll of recharging / scroll of fear
ITEM: scroll of teleport / scroll of remove curse / scroll of identify
ORIENT: float
MAP
xxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxx.........xxxxxxxx
xxxxx.......O.......xxxxx
xxxx.................xxxx
xxxx....x.......x....xxxx
xxx....xxx.....xxx....xxx
xxx...xxxxx...xxxxx...xxx
xx.....xxx.....xxx.....xx
xx.....xxx.....xxx.....xx
x.......x..I.I..x...I...x
x.......x.......x.......x
x..x.x..x..x=x..x..x+x..x
x.xx.xx.x.xx=xx.x.xx~xx.x
x.x.%.x.x.x.d.x.x.x.4.x.x
x.x.1.x.x.x.2.x.x.x.4.x.x
x.x.%.x.x.x.3.x.x.x.e.x.x
x.xx.xx.x.xx=xx.x.xx~xx.x
x..x.x..x..x=x..x..x+x..x
x.......x.......x.......x
x.......x..I.I..x...I...x
xx.....xxx.....xxx.....xx
xx.....+.+.....+.+.....xx
xxx...xxxxx...xxxxx...xxx
xxx.@.xxxxxxxxxxxxx.@.xxx
ENDMAP
##############################################################################
# Generic Orc entry
NAME: david_orc_1
TAGS: orc_entry
MONS: orc
ORIENT: float
FLAGS: no_rotate
MAP
xxxx..@..xxxx
x.....I.....x
x...........x
.....111.....
@I...1O1...I@
.....111.....
x...........x
x.....I.....x
xxxx..@..xxxx
ENDMAP
##############################################################################
# Generic Vaults entry
NAME: david_vaults_1
TAGS: vault_entry
MONS: human
ORIENT: float
FLAGS: no_rotate
MAP
xxxxx.@.xxxxx
x...+...x...x
x...x...x...x
xxx=x111x...x
@.x.x111+.O.x
x.x.x111x...x
x.x.x...x...x
x.+.x...x...x
xxxxx.@.xxxxx
ENDMAP
##############################################################################
# Generic Lair entry
NAME: david_lair_1
TAGS: lair_entry
MONS: giant lizard, giant snail, yak, plant
ORIENT: float
FLAGS: no_rotate
CHANCE: 5000
MAP
xxxx..@..xxxx
xx.........xx
x...2...44..x
...4..1......
@....1O3....@
..........4..
x...4..2....x
xx.........xx
xxxx..@..xxxx
ENDMAP
##############################################################################
# Shrubbed Lair entry
NAME: david_lair_2
TAGS: lair_entry
MONS: plant, lindwurm
ORIENT: float
FLAGS: no_rotate
MAP
xxxxxxxxxxxxx
xx111111111xx
x112..111111x
x11.O..111...
x11...111...@
x111111......
x1..11......x
xx.........xx
xxxx..@..xxxx
ENDMAP