summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-02-07 12:56:34 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-02-07 12:56:34 +0000
commitc30b530266ee87b352f98e54287bc3c054c88060 (patch)
tree0fb03ae79580117eb5be9ff5767b1f078e5d3a6d /crawl-ref
parent9a5dd81c99d8cd33c826d47f61eded48494a484e (diff)
downloadcrawl-ref-c30b530266ee87b352f98e54287bc3c054c88060.tar.gz
crawl-ref-c30b530266ee87b352f98e54287bc3c054c88060.zip
[1638394] Added support for portal vaults.
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
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/dat/splev.des143
-rw-r--r--crawl-ref/source/dat/vaults.des2
-rw-r--r--crawl-ref/source/direct.cc3
-rw-r--r--crawl-ref/source/dungeon.cc270
-rw-r--r--crawl-ref/source/makefile.unix1
-rw-r--r--crawl-ref/source/maps.cc96
-rw-r--r--crawl-ref/source/maps.h12
-rw-r--r--crawl-ref/source/view.cc6
8 files changed, 442 insertions, 91 deletions
diff --git a/crawl-ref/source/dat/splev.des b/crawl-ref/source/dat/splev.des
index d6b2e5bac7..f41f624111 100644
--- a/crawl-ref/source/dat/splev.des
+++ b/crawl-ref/source/dat/splev.des
@@ -43,7 +43,8 @@
# % - normal item
# * - higher level item (good)
# | - acquirement-level item (almost guaranteed excellent)
-# O - place an appropriate rune here
+# O - place an appropriate rune here. In portal vaults, place the portal or
+# branch stair here.
# P - maybe place a rune here (50%)
# R - honeycomb (2/3) or royal jelly (1/3)
# Z - the Orb of Zot
@@ -2230,3 +2231,143 @@ ENDMAP
MONS: swamp dragon, swamp drake, hydra
MONS: random, random, random, random
+
+
+##############################################################################
+# 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 \ No newline at end of file
diff --git a/crawl-ref/source/dat/vaults.des b/crawl-ref/source/dat/vaults.des
index d6120a354d..ee8d0b81a3 100644
--- a/crawl-ref/source/dat/vaults.des
+++ b/crawl-ref/source/dat/vaults.des
@@ -48,7 +48,7 @@
# % - normal item
# * - higher level item (good)
# | - acquirement-level item (almost guaranteed excellent)
-# O - place an appropriate rune here
+# O - place an appropriate rune here. For portal vaults, place the portal here.
# P - maybe place a rune here (50%)
# R - honeycomb (2/3) or royal jelly (1/3)
# Z - the Orb of Zot
diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc
index f8e77fcc8b..040d109f40 100644
--- a/crawl-ref/source/direct.cc
+++ b/crawl-ref/source/direct.cc
@@ -289,7 +289,8 @@ void direction(struct dist& moves, targeting_type restricts,
// Prompts might get scrolled off if you have too few lines available.
// We'll live with that.
if ( !just_looking )
- mpr("Aim (press '?' for help, Shift-Dir to shoot in a straight line.)", MSGCH_PROMPT);
+ mpr("Aim (press '?' for help, Shift-Dir to shoot in a straight line.)",
+ MSGCH_PROMPT);
while (1)
{
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index ba8baac296..e63d6c3533 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -62,7 +62,7 @@ struct pit_mons_def
int rare;
};
-struct spec_t
+struct spec_room
{
bool created;
bool hooked_up;
@@ -70,9 +70,11 @@ struct spec_t
int y1;
int x2;
int y2;
-};
-typedef struct spec_t spec_room;
+ spec_room() : created(false), hooked_up(false), x1(0), y1(0), x2(0), y2(0)
+ {
+ }
+};
// DUNGEON BUILDERS
static void build_dungeon_level(int level_number, int level_type);
@@ -90,7 +92,7 @@ static int builder_basic(int level_number);
static void builder_extras(int level_number, int level_type);
static void builder_items(int level_number, char level_type, int items_wanted);
static void builder_monsters(int level_number, char level_type, int mon_wanted);
-static void place_specific_stair(unsigned char stair);
+static void place_specific_stair(int stair, const std::string &tag = "", int dl = 0);
static void place_branch_entrances(int dlevel, char level_type);
static void place_special_minivaults(int level_number, int level_type);
static void place_traps( int level_number );
@@ -108,7 +110,8 @@ static void many_pools(unsigned char pool_type);
static bool join_the_dots(
const coord_def &from,
const coord_def &to,
- const dgn_region_list &forbidden);
+ const dgn_region_list &forbidden,
+ bool early_exit = false);
static void build_river(unsigned char river_type); //mv
static void build_lake(unsigned char lake_type); //mv
@@ -151,13 +154,15 @@ static void beehive(spec_room &sr);
static void jelly_pit(int level_number, spec_room &sr);
// VAULT FUNCTIONS
-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 void build_minivaults(int level_number, int force_vault);
static int vault_grid( vault_placement &,
int level_number, int vx, int vy, int altar_count,
FixedVector < char, 7 > &acq_item_class,
char vgrid, std::vector<coord_def> &targets,
- int &num_runes );
+ int &num_runes, int rune_subst = -1);
// ALTAR FUNCTIONS
static int pick_an_altar(void);
@@ -339,35 +344,32 @@ static bool valid_dungeon_level(int level_number, int level_type)
return (true);
}
-static void build_dungeon_level(int level_number, int level_type)
+static void reset_level()
{
- int i; // generic loop variable
- int x,y; // generic map loop variables
-
level_vaults.clear();
no_monster_zones.clear();
no_pool_fixup_zones.clear();
no_door_fixup_zones.clear();
// blank level with DNGN_ROCK_WALL
- make_box(0,0,GXM-1,GYM-1,DNGN_ROCK_WALL,DNGN_ROCK_WALL);
+ make_box(0, 0, GXM - 1, GYM - 1, DNGN_ROCK_WALL, DNGN_ROCK_WALL);
// delete all traps
- for (i = 0; i < MAX_TRAPS; i++)
+ for (int i = 0; i < MAX_TRAPS; i++)
env.trap[i].type = TRAP_UNASSIGNED;
// initialize all items
- for (i = 0; i < MAX_ITEMS; i++)
+ for (int i = 0; i < MAX_ITEMS; i++)
init_item( i );
// reset all monsters
- for (i = 0; i < MAX_MONSTERS; i++)
+ for (int i = 0; i < MAX_MONSTERS; i++)
menv[i].type = -1;
// unlink all monsters and items from the grid
- for(x=0; x<GXM; x++)
+ for(int x=0; x<GXM; x++)
{
- for(y=0; y<GYM; y++)
+ for(int y=0; y<GYM; y++)
{
mgrd[x][y] = NON_MONSTER;
igrd[x][y] = NON_ITEM;
@@ -377,10 +379,12 @@ static void build_dungeon_level(int level_number, int level_type)
// reset all shops
for (unsigned char shcount = 0; shcount < 5; shcount++)
env.shop[shcount].type = SHOP_UNASSIGNED;
+}
- int skip_build;
-
- skip_build = builder_by_type(level_number, level_type);
+static void build_layout_skeleton(int level_number, int level_type,
+ spec_room &sr)
+{
+ int skip_build = builder_by_type(level_number, level_type);
if (skip_build < 0)
return;
@@ -392,8 +396,6 @@ static void build_dungeon_level(int level_number, int level_type)
return;
}
- spec_room sr = { false, false, 0, 0, 0, 0 };
-
if (skip_build == 0)
{
// do 'normal' building. Well, except for the swamp.
@@ -407,6 +409,14 @@ static void build_dungeon_level(int level_number, int level_type)
builder_extras(level_number, level_type);
}
}
+}
+
+static void build_dungeon_level(int level_number, int level_type)
+{
+ spec_room sr;
+
+ reset_level();
+ build_layout_skeleton(level_number, level_type, sr);
// Try to place minivaults that really badly want to be placed. Still
// no guarantees, seeing this is a minivault.
@@ -521,8 +531,8 @@ static void build_dungeon_level(int level_number, int level_type)
player_branch_depth() == 1 &&
you.level_type == LEVEL_DUNGEON )
{
- for (x = 1; x < GXM; x++)
- for (y = 1; y < GYM; y++)
+ for (int x = 1; x < GXM; x++)
+ for (int y = 1; y < GYM; y++)
if (grd[x][y] >= DNGN_STONE_STAIRS_UP_I
&& grd[x][y] <= DNGN_ROCK_STAIRS_UP)
grd[x][y] = branches[(int)you.where_are_you].exit_stairs;
@@ -532,8 +542,8 @@ static void build_dungeon_level(int level_number, int level_type)
if ( player_branch_depth() == branches[(int)you.where_are_you].depth &&
you.level_type == LEVEL_DUNGEON)
{
- for (x = 1; x < GXM; x++)
- for (y = 1; y < GYM; y++)
+ for (int x = 1; x < GXM; x++)
+ for (int y = 1; y < GYM; y++)
if (grd[x][y] >= DNGN_STONE_STAIRS_DOWN_I
&& grd[x][y] <= DNGN_ROCK_STAIRS_DOWN)
grd[x][y] = DNGN_ROCK_STAIRS_UP;
@@ -553,9 +563,9 @@ static void build_dungeon_level(int level_number, int level_type)
// hall of blades (1 level deal) - no down staircases, thanks!
if (player_in_branch( BRANCH_HALL_OF_BLADES ))
{
- for (x = 1; x < GXM; x++)
+ for (int x = 1; x < GXM; x++)
{
- for (y = 1; y < GYM; y++)
+ for (int y = 1; y < GYM; y++)
{
if (grd[x][y] >= DNGN_STONE_STAIRS_DOWN_I
&& grd[x][y] <= DNGN_ROCK_STAIRS_UP)
@@ -3876,6 +3886,20 @@ static int builder_by_type(int level_number, char level_type)
return 0;
}
+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 int random_map_for_dlevel(int level_number, bool wantmini = false)
{
int subdepth = subdungeon_depth(you.where_are_you, level_number);
@@ -4309,7 +4333,7 @@ static void place_traps(int level_number)
} // end "for i"
} // end place_traps()
-static void place_specific_stair(unsigned char stair)
+static void place_specific_feature(int feat)
{
int sx, sy;
@@ -4320,9 +4344,14 @@ static void place_specific_stair(unsigned char stair)
}
while(grd[sx][sy] != DNGN_FLOOR || mgrd[sx][sy] != NON_MONSTER);
- grd[sx][sy] = stair;
+ grd[sx][sy] = feat;
}
+static void place_specific_stair(int stair, const std::string &tag, int dlevel)
+{
+ if (tag.empty() || !place_portal_vault(stair, tag, dlevel))
+ place_specific_feature(stair);
+}
static void place_branch_entrances(int dlevel, char level_type)
{
@@ -4335,15 +4364,15 @@ static void place_branch_entrances(int dlevel, char level_type)
{
// stair to HELL
if (dlevel >= 20 && dlevel <= 27)
- place_specific_stair(DNGN_ENTER_HELL);
+ place_specific_stair(DNGN_ENTER_HELL, "hell_entry", dlevel);
// stair to PANDEMONIUM
if (dlevel >= 20 && dlevel <= 50 && (dlevel == 23 || one_chance_in(4)))
- place_specific_stair(DNGN_ENTER_PANDEMONIUM);
+ place_specific_stair(DNGN_ENTER_PANDEMONIUM, "pan_entry", dlevel);
// stairs to ABYSS
if (dlevel >= 20 && dlevel <= 30 && (dlevel == 24 || one_chance_in(3)))
- place_specific_stair(DNGN_ENTER_ABYSS);
+ place_specific_stair(DNGN_ENTER_ABYSS, "abyss_entry", dlevel);
// level 26: replaces all down stairs with staircases to Zot:
if (dlevel == 26)
@@ -4374,7 +4403,15 @@ static void place_branch_entrances(int dlevel, char level_type)
mprf(MSGCH_DIAGNOSTICS, "Placing stair to %s",
branches[i].shortname);
#endif
- place_specific_stair(branches[i].entry_stairs);
+
+ std::string entry_tag = std::string(branches[i].abbrevname);
+ entry_tag += "_entry";
+ lowercase(entry_tag);
+
+ place_specific_stair(
+ branches[i].entry_stairs,
+ entry_tag,
+ dlevel);
}
}
}
@@ -5323,7 +5360,7 @@ static void build_minivaults(int level_number, int force_vault)
map_type vgrid;
vault_placement place;
- vault_main(vgrid, place, force_vault, level_number);
+ vault_main(vgrid, place, force_vault, &level_vaults);
level_vaults.push_back(place);
@@ -5498,7 +5535,7 @@ static void build_rooms(const dgn_region_list &excluded,
}
}
-static coord_def dig_away_dir(vault_placement &place,
+static coord_def dig_away_dir(const vault_placement &place,
const coord_def &pos)
{
// Figure out which way we need to go to dig our way out of the vault.
@@ -5602,14 +5639,94 @@ static void pick_float_exits(vault_placement &place,
}
}
-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)
{
// for some weird reason can't put a vault on level 1, because monster equip
// isn't generated.
int altar_count = 0;
FixedVector < char, 10 > stair_exist;
char stx, sty;
- std::vector<coord_def> target_connections;
FixedVector < char, 7 > acq_item_class;
// hack - passing chars through '...' promotes them to ints, which
@@ -5624,26 +5741,33 @@ static void build_vaults(int level_number, int force_vault)
map_type vgrid;
vault_placement place;
+ std::vector<coord_def> &target_connections = place.exits;
- int gluggy = vault_main(vgrid, place, force_vault, level_number);
+ const int gluggy = vault_main(vgrid, place, force_vault, &level_vaults);
- level_vaults.push_back(place);
+ if (gluggy == MAP_NONE)
+ return (false);
int vx, vy;
int num_runes = 0;
+ dgn_region this_vault(place.x, place.y, place.width, place.height);
// note: assumes *no* previous item (I think) or monster (definitely)
// placement
for (vx = 0; vx < GXM; vx++)
{
for (vy = 0; vy < GYM; vy++)
{
+ if (!this_vault.contains( coord_def(vx, vy) ))
+ continue;
+
altar_count = vault_grid( place,
level_number, vx, vy, altar_count,
acq_item_class,
vgrid[vy][vx],
target_connections,
- num_runes );
+ num_runes,
+ rune_subst );
}
}
@@ -5658,13 +5782,18 @@ static void build_vaults(int level_number, int force_vault)
no_pool_fixup_zones.push_back(
dgn_region( place.x, place.y, place.width, place.height ) );
- // If the map takes the whole screen, our work is done.
- if (gluggy == MAP_ENCOMPASS)
- return;
-
if (gluggy == MAP_FLOAT && target_connections.empty())
pick_float_exits(place, target_connections);
+ // 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);
+
// Does this level require Dis treatment (metal wallification)?
// XXX: Change this so the level definition can explicitly state what
// kind of wallification it wants.
@@ -5699,16 +5828,8 @@ static void build_vaults(int level_number, int force_vault)
if (gluggy == MAP_FLOAT)
nrooms += 10;
- 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);
build_rooms(excluded_regions, ex_connection_points, nrooms);
@@ -5728,7 +5849,7 @@ static void build_vaults(int level_number, int force_vault)
if (grd[stx][sty] >= DNGN_STONE_STAIRS_DOWN_I
&& grd[stx][sty] <= DNGN_ROCK_STAIRS_UP)
{
- stair_exist[grd[stx][sty] - 82] = 1;
+ stair_exist[grd[stx][sty] - DNGN_STONE_STAIRS_DOWN_I] = 1;
}
}
}
@@ -5746,8 +5867,10 @@ static void build_vaults(int level_number, int force_vault)
{
for (int i = 0; i < 2; i++)
{
- // does this look funny to *you*? {dlb}
- if (stair_exist[(82 + j + (i * 4)) - 82] == 1)
+ const int stair = j + ((i == 0) ? DNGN_STONE_STAIRS_DOWN_I
+ : DNGN_STONE_STAIRS_UP_I);
+
+ if (stair_exist[stair - DNGN_STONE_STAIRS_DOWN_I] == 1)
continue;
do
@@ -5759,10 +5882,11 @@ static void build_vaults(int level_number, int force_vault)
|| (pos_x >= v1x && pos_x <= v2x && pos_y >= v1y
&& pos_y <= v2y));
- grd[pos_x][pos_y] = j + ((i == 0) ? DNGN_STONE_STAIRS_DOWN_I
- : DNGN_STONE_STAIRS_UP_I);
+ grd[pos_x][pos_y] = stair;
}
}
+
+ return (true);
} // end build_vaults()
static void dngn_place_item_explicit(int index, int x, int y,
@@ -5810,7 +5934,8 @@ static int vault_grid( vault_placement &place,
FixedVector < char, 7 > &acq_item_class,
char vgrid,
std::vector<coord_def> &targets,
- int &num_runes)
+ int &num_runes,
+ int rune_subst )
{
int not_used;
@@ -5920,6 +6045,12 @@ static int vault_grid( vault_placement &place,
}
else // for 'P' (1 out of 3 times) {dlb}
{
+ if (rune_subst != -1)
+ {
+ grd[vx][vy] = rune_subst;
+ break;
+ }
+
which_class = OBJ_MISCELLANY;
which_type = MISC_RUNE_OF_ZOT;
num_runes++;
@@ -6034,7 +6165,8 @@ bool unforbidden(const coord_def &c, const dgn_region_list &forbidden)
static bool join_the_dots(
const coord_def &from,
const coord_def &to,
- const dgn_region_list &forbidden)
+ const dgn_region_list &forbidden,
+ bool early_exit)
{
if (from == to)
return (true);
@@ -6045,6 +6177,10 @@ static bool join_the_dots(
do
{
join_count++;
+
+ if (early_exit && at != from && grd(at) == DNGN_FLOOR)
+ return (true);
+
grd(at) = DNGN_FLOOR;
if (join_count > 10000) // just insurance
@@ -7349,7 +7485,7 @@ static char plan_1(void)
if (temp_rand > 7) // 7 in 15 odds {dlb}
{
- spec_room sr = { false, false, 0,0,0,0 };
+ spec_room sr;
sr.x1 = 25;
sr.y1 = 25;
sr.x2 = (GXM - 25);
@@ -7576,7 +7712,7 @@ static char plan_4(char forbid_x1, char forbid_y1, char forbid_x2,
if (forbid_x1 == 0 && one_chance_in(4)) // a market square
{
- spec_room sr = { false, false, 0, 0, 0, 0 };
+ spec_room sr;
sr.x1 = 25;
sr.y1 = 25;
sr.x2 = 55;
@@ -7616,7 +7752,7 @@ static char plan_5(void)
static char plan_6(int level_number)
{
- spec_room sr = { false, false, 0,0,0,0 };
+ spec_room sr;
// circle of standing stones (well, kind of)
sr.x1 = 10;
@@ -8208,7 +8344,7 @@ static void diamond_rooms(int level_number)
for (i = 0; i < numb_diam; i++)
{
- spec_room sr = { false, false, 0, 0, 0, 0 };
+ spec_room sr;
sr.x1 = 8 + random2(43);
sr.y1 = 8 + random2(35);
@@ -8239,7 +8375,7 @@ static void big_room(int level_number)
unsigned char type_2 = DNGN_FLOOR;
int i, j, k, l;
- spec_room sr = { false, false, 0, 0, 0, 0 };
+ spec_room sr;
int oblique;
if (one_chance_in(4))
diff --git a/crawl-ref/source/makefile.unix b/crawl-ref/source/makefile.unix
index b8f3784aae..1b3f63d8eb 100644
--- a/crawl-ref/source/makefile.unix
+++ b/crawl-ref/source/makefile.unix
@@ -186,7 +186,6 @@ distclean: clean
$(GAME): $(GAME_DEPENDS)
${CXX} ${LDFLAGS} $(CFLAGS) $(OBJECTS) -o $(GAME) $(LIB)
- chmod ${MCHMOD} $(GAME)
debug: $(GAME_DEPENDS)
${CXX} ${LDFLAGS} $(CFLAGS) $(OBJECTS) -o $(GAME) $(LIB)
diff --git a/crawl-ref/source/maps.cc b/crawl-ref/source/maps.cc
index 201090910d..f38314b8d8 100644
--- a/crawl-ref/source/maps.cc
+++ b/crawl-ref/source/maps.cc
@@ -24,16 +24,19 @@
#include "files.h"
#include "monplace.h"
#include "mapdef.h"
+#include "misc.h"
#include "stuff.h"
#include "levcomp.h"
static int write_vault(const map_def &mdef, map_type mt,
- vault_placement &);
+ vault_placement &,
+ std::vector<vault_placement> *);
static int apply_vault_definition(
map_def &def,
map_type map,
- vault_placement &);
+ vault_placement &,
+ std::vector<vault_placement> *);
static void resolve_map(map_def &def);
@@ -55,8 +58,8 @@ static std::vector<map_def> vdefs;
int vault_main(
map_type vgrid,
vault_placement &place,
- int which_vault,
- int many_many )
+ int which_vault,
+ std::vector<vault_placement> *avoid)
{
#ifdef DEBUG_DIAGNOSTICS
mprf(MSGCH_DIAGNOSTICS, "Generating level: %s",
@@ -74,18 +77,26 @@ int vault_main(
}
// NB - a return value of zero is not handled well by dungeon.cc (but there it is) 10mar2000 {dlb}
- return write_vault( vdefs[which_vault], vgrid, place );
+ return write_vault( vdefs[which_vault], vgrid, place, avoid );
} // end vault_main()
static int write_vault(const map_def &mdef, map_type map,
- vault_placement &place)
+ vault_placement &place,
+ std::vector<vault_placement> *avoid)
{
// Copy the map so we can monkey with it.
place.map = mdef;
- resolve_map(place.map);
- 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);
}
// Mirror the map if appropriate, resolve substitutable symbols (?),
@@ -106,8 +117,53 @@ static void resolve_map(map_def &map)
map.rotate( coinflip() );
}
-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)
{
const map_lines &ml = def.map;
const int orient = def.orient;
@@ -146,6 +202,15 @@ static void apply_vault_grid(map_def &def, map_type map,
starty = where.y;
}
+ if (bad_map_place(startx, starty, width, height, avoid))
+ {
+#ifdef DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS, "Bad vault place: (%d,%d) dim (%d,%d)",
+ startx, starty, width, height);
+#endif
+ return (false);
+ }
+
const std::vector<std::string> &lines = ml.get_lines();
#ifdef DEBUG_DIAGNOSTICS
mprf(MSGCH_DIAGNOSTICS, "Applying %s at (%d,%d), dimensions (%d,%d)",
@@ -162,18 +227,23 @@ static void apply_vault_grid(map_def &def, map_type map,
place.y = starty;
place.width = width;
place.height = height;
+
+ return (true);
}
static int apply_vault_definition(
map_def &def,
map_type map,
- vault_placement &place)
+ vault_placement &place,
+ std::vector<vault_placement> *avoid)
{
- apply_vault_grid(def, map, place);
+ if (!apply_vault_grid(def, map, place, avoid))
+ return (MAP_NONE);
int orient = def.orient;
if (orient == MAP_NONE)
orient = MAP_NORTH;
+
return (orient);
}
diff --git a/crawl-ref/source/maps.h b/crawl-ref/source/maps.h
index 676d468190..6c098d11c4 100644
--- a/crawl-ref/source/maps.h
+++ b/crawl-ref/source/maps.h
@@ -16,6 +16,8 @@
#include "dungeon.h"
#include "mapdef.h"
+#include <vector>
+
class map_def;
struct vault_placement
{
@@ -23,17 +25,19 @@ struct vault_placement
int width, height;
int orient;
map_def map;
+ std::vector<coord_def> exits;
vault_placement()
- : x(-1), y(-1), width(0), height(0), map()
+ : x(-1), y(-1), width(0), height(0), map(),
+ exits()
{
}
};
int vault_main(map_type vgrid,
- vault_placement &vp,
- int vault_force,
- int many_many);
+ vault_placement &vp,
+ int vault_force,
+ std::vector<vault_placement> *avoid_vaults = NULL);
const map_def *map_by_index(int index);
int random_map_for_place(const std::string &place, bool mini = false);
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index cd5d9fcc56..b23ae18f15 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -2521,7 +2521,7 @@ void magic_mapping(int map_radius, int proportion)
continue;
}
- if (grid_is_solid( grd[i + k][j + l] )
+ if (grid_is_opaque( grd[i + k][j + l] )
&& grd[i + k][j + l] != DNGN_CLOSED_DOOR)
empty_count--;
}
@@ -2535,7 +2535,7 @@ void magic_mapping(int map_radius, int proportion)
set_envmap_char(i, j, get_magicmap_char(grd[i][j]));
#ifdef WIZARD
- if (map_radius == 1000)
+ if (map_radius == 1000 && you.wizard)
set_envmap_char(i, j, get_sightmap_char(grd[i][j]));
#endif
}
@@ -2545,7 +2545,7 @@ void magic_mapping(int map_radius, int proportion)
if ((you.mutation[MUT_PANDEMONIUM] > 1
&& grd[i][j] == DNGN_EXIT_PANDEMONIUM)
#ifdef WIZARD
- || map_radius == 1000
+ || (map_radius == 1000 && you.wizard)
#endif
)
{