summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-07-07 15:28:06 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-07-07 15:28:06 +0000
commitc25973abd006dc9584efc3ce3538758b30cf3a2a (patch)
tree573598a46d696ef31a20a486e92d5868ec15ed13 /crawl-ref
parent17b7bb3e2bab6f05a2e3000b11896f3987ed5a80 (diff)
downloadcrawl-ref-c25973abd006dc9584efc3ce3538758b30cf3a2a.tar.gz
crawl-ref-c25973abd006dc9584efc3ce3538758b30cf3a2a.zip
Extend rectangular vault support for regular vaults.
Vault collision checking is also non-rectangular now. Fixed Windows builds not reporting line numbers in .des file error messages. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1784 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/cio.cc19
-rw-r--r--crawl-ref/source/cio.h1
-rw-r--r--crawl-ref/source/dat/entry.des119
-rw-r--r--crawl-ref/source/dungeon.cc370
-rw-r--r--crawl-ref/source/dungeon.h33
-rw-r--r--crawl-ref/source/luadgn.cc17
-rw-r--r--crawl-ref/source/luadgn.h3
-rw-r--r--crawl-ref/source/makeitem.cc4
-rw-r--r--crawl-ref/source/makeitem.h2
-rw-r--r--crawl-ref/source/mapdef.cc10
-rw-r--r--crawl-ref/source/mapdef.h4
-rw-r--r--crawl-ref/source/maps.cc2
-rw-r--r--crawl-ref/source/monplace.cc4
-rw-r--r--crawl-ref/source/monplace.h3
14 files changed, 237 insertions, 354 deletions
diff --git a/crawl-ref/source/cio.cc b/crawl-ref/source/cio.cc
index d22729a7fa..23305e556c 100644
--- a/crawl-ref/source/cio.cc
+++ b/crawl-ref/source/cio.cc
@@ -386,6 +386,21 @@ bool line_reader::is_wordchar(int c)
return isalnum(c) || c == '_' || c == '-';
}
+void line_reader::kill_to_begin()
+{
+ if (!pos || cur == buffer)
+ return;
+
+ buffer[length] = 0;
+ cursorto(0);
+ wrapcprintf(wrapcol, "%s%*s", cur, cur - buffer, "");
+ memmove(buffer, cur, length - pos);
+ length -= pos;
+ pos = 0;
+ cur = buffer;
+ cursorto(pos);
+}
+
void line_reader::killword()
{
if (!pos || cur == buffer)
@@ -483,6 +498,10 @@ int line_reader::process_key(int ch)
killword();
break;
+ case CONTROL('U'):
+ kill_to_begin();
+ break;
+
case CK_LEFT:
if (pos)
{
diff --git a/crawl-ref/source/cio.h b/crawl-ref/source/cio.h
index 552ea1b699..376d806c72 100644
--- a/crawl-ref/source/cio.h
+++ b/crawl-ref/source/cio.h
@@ -206,6 +206,7 @@ protected:
int process_key(int ch);
void backspace();
void killword();
+ void kill_to_begin();
bool is_wordchar(int c);
diff --git a/crawl-ref/source/dat/entry.des b/crawl-ref/source/dat/entry.des
index 1ea158f233..6ebd11e5ae 100644
--- a/crawl-ref/source/dat/entry.des
+++ b/crawl-ref/source/dat/entry.des
@@ -15,15 +15,15 @@ ORIENT: float
SUBST: !:cvxGT
FLAGS: no_rotate
MAP
-xxxxxx.@.xxxxxx
-xxxxxx.!.xxxxxx
-xxxxxx...xxxxxx
-xxxxxx.!.xxxxxx
-xxxxxx...xxxxxx
-xxxxxx.!.xxxxxx
-xxxxxx...xxxxxx
-xxxxxx.!.xxxxxx
-xxxxxx...xxxxxx
+ x.@.x
+ x.!.x
+ x...x
+ x.!.x
+ x...x
+ x.!.x
+ x...x
+ x.!.x
+ x...x
xxxxxx...xxxxxx
x.............x
x.............x
@@ -42,11 +42,11 @@ ORIENT: float
SHUFFLE: {[, abc
SUBST: a:+=, b=x, c=x
MAP
-......x@x......
-....xax.xcx....
-...xx.....xx...
-..xb.......bx..
-.xx.........xx.
+ x@x
+ xax.xcx
+ xx.....xx
+ xb.......bx
+ xx.........xx
xc...........ax
x.............x
x......{......x
@@ -54,12 +54,12 @@ x.....[.(.....x
x......<......x
x.............x
xx...........xx
-.xc.........bx.
-..xx.......xx..
-...xa.....xc...
-....xx...xx....
-.....bx.xa.....
-......x@x......
+ xc.........bx
+ xx.......xx
+ xa.....xc
+ xx...xx
+ bx.xa
+ x@x
ENDMAP
##############################################################################
@@ -70,24 +70,23 @@ TAGS: entry
ORIENT: float
SHUFFLE: {[
MAP
-xxxxxxxxx
-xxxxxxx{x
-xxxxxxx.x
-xxxxxxx.x
-xxxxxxx.x
+ xxx
+ x{x
+ x.x
+ x.x
+ x.x
xxxxxxx.xxxxxxx
x[...........(x
xxxxxxx.xxxxxxx
-xxxxxxx.x
-xxxxxxx.x
-xxxxxxx.x
-xxxxxxx.xx
-xxxxxxG.Gx
-xxxxxxx.xx
-xxxxxxx.x
-xxxxxxx@x
+ x.x
+ x.x
+ x.x
+ xx.xx
+ xG.Gx
+ xx.xx
+ x.x
+ x@x
ENDMAP
-# padded to the right with 'x', unfortunately
##############################################################################
# lemuel_entry_004
@@ -182,24 +181,24 @@ ORIENT: float
SUBST: ? = x.
SHUFFLE: {[(
MAP
-xxxxxxxxxxxxxxxxxxx
-x{xxxxxxxxxxxxxxxxx
-x..xxxxxxxxxxxx[x?x
-xx.?xxxxx(xxxx?...x
-x?..xxxx..xxxx???.x
+xxx
+x{xx xxxxx
+x..xx xxx xx[x?x
+xx.?xxxxx(x x?...x
+x?..xxxx..x xx???.x
x..?x?..?xxxx?x??.x
x.?xx..xxxxx?.....x
x.?xx.?xxxx?x.x???x
xx..?.xxxx??..xxxxx
-xxx...?x??x..xxxxxx
-xxxxx.xx....xxxxxxx
-xxxxx..x.??xxxxxxxx
-xxxxxx.?.xxxxxxxxxx
-xxxxxx..??xxxxxxxxx
-xxxxxx?x.xxxxxxxxxx
-xxxxxxx?.?xxxxxxxxx
-xxxxxxxx..?xxxxxxxx
-xxxxxxxxxx@xxxxxxxx
+ xx...?x??x..xx
+ xxx.xx....xx
+ x..x.??xx
+ xx.?.xxx
+ x..??x
+ x?x.xx
+ xx?.?xx
+ xx..?x
+ xxx@x
ENDMAP
##############################################################################
@@ -214,18 +213,18 @@ xxxxxxxxxxxxxxx
x{.....(.....[x
x.............x
xx...ccccc...xx
-xx...ccccc...xx
-xxx...ccc...xxx
-xxx...ccc...xxx
-xxxx...c...xxxx
-xxxx...c...xxxx
-xxxxx.....xxxxx
-xxxxx.....xxxxx
-xxxxxx...xxxxxx
-xxxxxx...xxxxxx
-xxxxxx...xxxxxx
-xxxxxx+++xxxxxx
-xxxxxx.@.xxxxxx
+ x...ccccc...x
+ xx...ccc...xx
+ x...ccc...x
+ xx...c...xx
+ x...c...x
+ xx.....xx
+ x.....x
+ xx...xx
+ x...x
+ x...x
+ x+++x
+ x.@.x
ENDMAP
##############################################################################
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index 19399fd054..74763e5064 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -104,7 +104,7 @@ static bool make_box(int room_x1, int room_y1, int room_x2, int room_y2,
static void replace_area(int sx, int sy, int ex, int ey,
dungeon_feature_type replace,
dungeon_feature_type feature,
- const dgn_region_list &forbidden = dgn_region_list());
+ unsigned mmask = 0);
static builder_rc_type builder_by_type(int level_number, char level_type);
static builder_rc_type builder_by_branch(int level_number);
static builder_rc_type builder_normal(int level_number, char level_type, spec_room &s);
@@ -135,7 +135,7 @@ static void many_pools(dungeon_feature_type pool_type);
static bool join_the_dots(
const coord_def &from,
const coord_def &to,
- const dgn_region_list &forbidden,
+ unsigned mmask,
bool early_exit = false);
static void build_river(dungeon_feature_type river_type); //mv
@@ -200,10 +200,7 @@ typedef std::list<coord_def> coord_list;
// Static data
// Places where monsters should not be randomly generated.
-static dgn_region_list no_monster_zones;
-static dgn_region_list no_item_zones;
-static dgn_region_list no_pool_fixup_zones;
-static dgn_region_list no_door_fixup_zones;
+map_mask dgn_map_mask;
static dgn_region_list vault_zones;
static std::vector<vault_placement> level_vaults;
static int minivault_chance = 3;
@@ -255,6 +252,27 @@ void builder(int level_number, int level_type)
level_id::current().describe().c_str()).c_str());
}
+static void mask_vault(const vault_placement &place, unsigned mask)
+{
+ for (int y = place.y + place.height - 1; y >= place.y; --y)
+ for (int x = place.x + place.width - 1; x >= place.x; --x)
+ if (place.map.in_map(coord_def(x - place.x, y - place.y)))
+ dgn_map_mask[x][y] |= mask;
+}
+
+static void apply_place_masks(const vault_placement &place)
+{
+ mask_vault(place, MMT_VAULT | MMT_NO_DOOR);
+ if (place.map.has_tag("no_monster_gen"))
+ mask_vault(place, MMT_NO_MONS);
+
+ if (place.map.has_tag("no_item_gen"))
+ mask_vault(place, MMT_NO_ITEM);
+
+ if (place.map.has_tag("no_pool_fixup"))
+ mask_vault(place, MMT_NO_POOL);
+}
+
static bool ensure_vault_placed(bool vault_success)
{
if (!vault_success)
@@ -283,7 +301,7 @@ static bool has_connected_downstairs_from(const coord_def &c)
ff.add_feat(DNGN_STONE_STAIRS_DOWN_III);
ff.add_feat(DNGN_ROCK_STAIRS_DOWN);
- coord_def where = ff.find_first_from(c, vault_zones);
+ coord_def where = ff.find_first_from(c, dgn_map_mask);
return (where.x || !ff.did_leave_vault());
}
@@ -306,11 +324,8 @@ static bool valid_dungeon_level(int level_number, int level_type)
static void reset_level()
{
+ dgn_map_mask.init(0);
level_vaults.clear();
- no_monster_zones.clear();
- no_item_zones.clear();
- no_pool_fixup_zones.clear();
- no_door_fixup_zones.clear();
vault_zones.clear();
minivault_chance = 3;
@@ -600,7 +615,7 @@ static void hide_doors()
{
// only one out of four doors are candidates for hiding {gdl}:
if (grd[dx][dy] == DNGN_CLOSED_DOOR && one_chance_in(4)
- && unforbidden(coord_def(dx, dy), no_door_fixup_zones))
+ && unforbidden(coord_def(dx, dy), MMT_NO_DOOR))
{
wall_count = 0;
@@ -912,7 +927,7 @@ static void prepare_water( int level_number )
{
for (j = 10; j < (GYM - 10); j++)
{
- if (!unforbidden(coord_def(i, j), no_pool_fixup_zones))
+ if (!unforbidden(coord_def(i, j), MMT_NO_POOL))
continue;
if (grd[i][j] == DNGN_DEEP_WATER)
@@ -1923,7 +1938,7 @@ static int place_uniques(int level_number, char level_type)
// note: unique_creatures 40 + used by unique demons
if (place_monster( not_used, which_unique, level_number,
BEH_SLEEP, MHITNOT, false, 1, 1, true,
- PROX_ANYWHERE, 250, 0, no_monster_zones ))
+ PROX_ANYWHERE, 250, 0, MMT_NO_MONS ))
{
#ifdef DEBUG_DIAGNOSTICS
mprf(MSGCH_DIAGNOSTICS, "Placed %s",
@@ -1945,7 +1960,7 @@ static int place_monster_vector(std::vector<int> montypes,
if (place_monster( not_used, montypes[random2(montypes.size())],
level_number, BEH_SLEEP, MHITNOT,
false, 1, 1, true, PROX_ANYWHERE, 250, 0,
- no_monster_zones ))
+ MMT_NO_MONS ))
{
++result;
}
@@ -2017,7 +2032,7 @@ static void builder_monsters(int level_number, char level_type, int mon_wanted)
for (int i = 0; i < mon_wanted; i++)
place_monster( not_used, RANDOM_MONSTER, level_number, BEH_SLEEP,
MHITNOT, false, 1, 1, true, PROX_ANYWHERE, 250, 0,
- no_monster_zones );
+ MMT_NO_MONS );
place_uniques(level_number, level_type);
@@ -2065,7 +2080,7 @@ static void builder_items(int level_number, char level_type, int items_wanted)
{
for (i = 0; i < items_wanted; i++)
items( 1, specif_type, OBJ_RANDOM, false, items_levels, 250,
- no_item_zones );
+ MMT_NO_ITEM );
// Make sure there's a very good chance of a knife being placed
// in the first five levels, but not a guarantee of one. The
@@ -2075,7 +2090,7 @@ static void builder_items(int level_number, char level_type, int items_wanted)
&& level_number < 5 && coinflip())
{
item_no = items( 0, OBJ_WEAPONS, WPN_KNIFE, false, 0, 250,
- no_item_zones );
+ MMT_NO_ITEM );
// Guarantee that the knife is uncursed and non-special
if (item_no != NON_ITEM)
@@ -2535,8 +2550,10 @@ static bool safe_minivault_place(int v1x, int v1y,
const vault_placement &place)
{
dgn_region reg(v1x, v1y, place.width, place.height);
- if (reg.overlaps_any(vault_zones))
+
+ if (reg.overlaps(vault_zones, dgn_map_mask))
return (false);
+
const bool water_ok = place.map.has_tag("water_ok");
const std::vector<std::string> &lines = place.map.map.get_lines();
for (int vx = v1x; vx < v1x + place.width; vx++)
@@ -2645,6 +2662,8 @@ static bool build_minivaults(int level_number, int force_vault)
level_vaults.push_back(place);
vault_zones.push_back(
dgn_region(place.x, place.y, place.width, place.height));
+
+ apply_place_masks(place);
// these two are throwaways:
std::vector<coord_def> dummy;
@@ -2666,21 +2685,6 @@ static bool build_minivaults(int level_number, int force_vault)
}
}
- no_door_fixup_zones.push_back(
- dgn_region( place.x, place.y, place.width, place.height ) );
-
- if (place.map.has_tag("no_monster_gen"))
- no_monster_zones.push_back(
- dgn_region( place.x, place.y, place.width, place.height ) );
-
- if (place.map.has_tag("no_item_gen"))
- no_item_zones.push_back(
- dgn_region( place.x, place.y, place.width, place.height ) );
-
- if (place.map.has_tag("no_pool_fixup"))
- no_pool_fixup_zones.push_back(
- dgn_region( place.x, place.y, place.width, place.height ) );
-
return (true);
} // end build_minivaults()
@@ -2711,7 +2715,7 @@ static void build_rooms(const dgn_region_list &excluded,
random_range(MAPGEN_BORDER,
GYM - MAPGEN_BORDER - 1 - myroom.size.y));
}
- while (myroom.overlaps_any(excluded) && overlap_tries-- > 0);
+ while (myroom.overlaps(excluded, dgn_map_mask) && overlap_tries-- > 0);
if (overlap_tries < 0)
continue;
@@ -2719,7 +2723,7 @@ static void build_rooms(const dgn_region_list &excluded,
if (connections.size())
{
const coord_def c = connections[0];
- if (join_the_dots(c, myroom.random_edge_point(), excluded))
+ if (join_the_dots(c, myroom.random_edge_point(), MMT_VAULT))
connections.erase( connections.begin() );
}
@@ -2756,7 +2760,7 @@ static void build_rooms(const dgn_region_list &excluded,
join_the_dots(
myroom.random_edge_point(),
rom[which_room - 1].random_edge_point(),
- excluded );
+ MMT_VAULT );
}
which_room++;
@@ -2878,6 +2882,28 @@ static bool grid_needs_exit(int x, int y)
|| grd[x][y] == DNGN_SECRET_DOOR);
}
+static bool map_grid_is_on_edge(const vault_placement &place,
+ const coord_def &c)
+{
+ for (int xi = c.x - 1; xi <= c.x + 1; ++xi)
+ for (int yi = c.y - 1; yi <= c.y + 1; ++yi)
+ if (!place.map.in_map(coord_def(xi, yi)))
+ return (true);
+ return (false);
+}
+
+static void pick_internal_float_exits(const vault_placement &place,
+ std::vector<coord_def> &exits)
+{
+ for (int y = place.y + 1; y < place.y + place.height - 1; ++y)
+ for (int x = place.x + 1; x < place.x + place.width - 1; ++x)
+ if (grid_needs_exit(x, y)
+ && map_grid_is_on_edge(place, coord_def(x, y)))
+ {
+ exits.push_back( coord_def(x, y) );
+ }
+}
+
static void pick_float_exits(vault_placement &place,
std::vector<coord_def> &targets)
{
@@ -2899,6 +2925,8 @@ static void pick_float_exits(vault_placement &place,
coord_def(x, place.y + place.height - 1) );
}
+ pick_internal_float_exits(place, possible_exits);
+
if (possible_exits.empty())
return;
@@ -2930,20 +2958,7 @@ static std::vector<coord_def> external_connection_points(
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)
+static coord_def find_random_grid(int grid, unsigned mask)
{
for (int i = 0; i < 100; ++i)
{
@@ -2952,7 +2967,7 @@ static coord_def find_random_grid(int grid, const dgn_region_list &excluded)
random_range(MAPGEN_BORDER,
GYM - MAPGEN_BORDER - 1) );
- if (unforbidden(c, excluded) && grd(c) == grid)
+ if (unforbidden(c, mask) && grd(c) == grid)
return c;
}
return coord_def(0, 0);
@@ -2961,17 +2976,15 @@ static coord_def find_random_grid(int grid, const dgn_region_list &excluded)
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);
+ const coord_def floor = find_random_grid(DNGN_FLOOR, MMT_VAULT);
if (!floor.x && !floor.y)
continue;
- join_the_dots(p, floor, vaults, true);
+ join_the_dots(p, floor, MMT_VAULT, true);
}
}
@@ -3042,20 +3055,7 @@ static bool build_vaults(int level_number, int force_vault, int rune_subst,
}
}
- no_door_fixup_zones.push_back(
- dgn_region( place.x, place.y, place.width, place.height ) );
-
- if (place.map.has_tag("no_monster_gen"))
- no_monster_zones.push_back(
- dgn_region( place.x, place.y, place.width, place.height ) );
-
- if (place.map.has_tag("no_item_gen"))
- no_item_zones.push_back(
- dgn_region( place.x, place.y, place.width, place.height ) );
-
- if (place.map.has_tag("no_pool_fixup"))
- no_pool_fixup_zones.push_back(
- dgn_region( place.x, place.y, place.width, place.height ) );
+ apply_place_masks(place);
if (gluggy == MAP_FLOAT && target_connections.empty())
pick_float_exits(place, target_connections);
@@ -3625,32 +3625,25 @@ static int vault_grid( vault_placement &place,
static void replace_area(
int sx, int sy, int ex, int ey, dungeon_feature_type replace,
- dungeon_feature_type feature, const dgn_region_list &forbidden)
+ dungeon_feature_type feature, unsigned mapmask)
{
int x,y;
for(x=sx; x<=ex; x++)
for(y=sy; y<=ey; y++)
- if (grd[x][y] == replace && unforbidden(coord_def(x, y), forbidden))
+ if (grd[x][y] == replace && unforbidden(coord_def(x, y), mapmask))
grd[x][y] = feature;
}
// With apologies to Metallica.
-bool unforbidden(const coord_def &c, const dgn_region_list &forbidden)
+bool unforbidden(const coord_def &c, unsigned mask)
{
- for (dgn_region_list::const_iterator i = forbidden.begin();
- i != forbidden.end(); ++i)
- {
- if (i->contains(c))
- return (false);
- }
-
- return (true);
+ return (!mask || !(dgn_map_mask(c) & mask));
}
static bool join_the_dots(
const coord_def &from,
const coord_def &to,
- const dgn_region_list &forbidden,
+ unsigned mapmask,
bool early_exit)
{
if (from == to)
@@ -3672,28 +3665,28 @@ static bool join_the_dots(
return (false);
if (at.x < to.x
- && unforbidden(coord_def(at.x + 1, at.y), forbidden))
+ && unforbidden(coord_def(at.x + 1, at.y), mapmask))
{
at.x++;
continue;
}
if (at.x > to.x
- && unforbidden(coord_def(at.x - 1, at.y), forbidden))
+ && unforbidden(coord_def(at.x - 1, at.y), mapmask))
{
at.x--;
continue;
}
if (at.y > to.y
- && unforbidden(coord_def(at.x, at.y - 1), forbidden))
+ && unforbidden(coord_def(at.x, at.y - 1), mapmask))
{
at.y--;
continue;
}
if (at.y < to.y
- && unforbidden(coord_def(at.x, at.y + 1), forbidden))
+ && unforbidden(coord_def(at.x, at.y + 1), mapmask))
{
at.y++;
continue;
@@ -4422,7 +4415,7 @@ static char plan_3()
ry1 + random2( ry2 - ry1 )),
coord_def(prev_rx1 + random2(prev_rx2 - prev_rx1),
prev_ry1 + random2(prev_ry2 - prev_ry1)),
- dgn_region_list() );
+ MMT_VAULT );
}
which_room++;
@@ -4453,7 +4446,7 @@ static char plan_3()
coord_def(
prev_rx1 + random2( prev_rx2 - prev_rx1 ),
prev_ry1 + random2( prev_ry2 - prev_ry1 ) ),
- dgn_region_list() );
+ MMT_VAULT );
}
}
}
@@ -4570,7 +4563,7 @@ static char plan_5()
join_the_dots(
coord_def( random2(GXM - 20) + 10, random2(GYM - 20) + 10 ),
coord_def( random2(GXM - 20) + 10, random2(GYM - 20) + 10 ),
- dgn_region_list() );
+ MMT_VAULT );
}
if (!one_chance_in(4))
@@ -4850,7 +4843,7 @@ static void pad_region(const dgn_region &reg, int pad_depth,
static void change_walls_from_centre(const dgn_region &region,
const coord_def &centre,
bool rectangular,
- const dgn_region_list &forbidden,
+ unsigned mmask,
dungeon_feature_type wall,
const std::vector<dist_feat> &ldist)
{
@@ -4863,7 +4856,7 @@ static void change_walls_from_centre(const dgn_region &region,
for (int x = region.pos.x; x < end.x; ++x)
{
const coord_def c(x, y);
- if (grd(c) != wall || !unforbidden(c, forbidden))
+ if (grd(c) != wall || !unforbidden(c, mmask))
continue;
const int distance =
@@ -4895,7 +4888,6 @@ static void change_walls_from_centre(const dgn_region &region,
static void change_walls_from_centre(const dgn_region &region,
const coord_def &c,
bool rectangular,
- const dgn_region_list &forbidden,
dungeon_feature_type wall,
...)
{
@@ -4914,7 +4906,7 @@ static void change_walls_from_centre(const dgn_region &region,
ldist.push_back(dist_feat(dist, feat));
}
- change_walls_from_centre(region, c, rectangular, forbidden, wall, ldist);
+ change_walls_from_centre(region, c, rectangular, MMT_VAULT, wall, ldist);
}
static void place_extra_lab_minivaults(int level_number)
@@ -4992,7 +4984,8 @@ static void labyrinth_level(int level_number)
place_extra_lab_minivaults(level_number);
- change_walls_from_centre(lab, end, false, vault_zones, DNGN_ROCK_WALL,
+ change_walls_from_centre(lab, end, false,
+ DNGN_ROCK_WALL,
15 * 15, DNGN_METAL_WALL,
34 * 34, DNGN_STONE_WALL,
0);
@@ -5004,179 +4997,6 @@ static void labyrinth_level(int level_number)
//replace_area(0, 0, GXM - 1, GYM - 1, DNGN_ROCK_WALL, wall_xform, vaults);
link_items();
-
-
-#ifdef OBSOLETE_LABYRINTH
- int keep_lx = 0, keep_ly = 0;
- int keep_lx2 = 0, keep_ly2 = 0;
- char start_point_x = 10;
- char start_point_y = 10;
- char going_x = 1;
- char going_y = (coinflip() ? 0 : 1);
- bool do_2 = false;
- int clear_space = 1;
- unsigned char traps_put2 = 0;
-
- if (coinflip())
- {
- start_point_x = (GXM - 10);
- going_x = -1;
- }
-
- if (coinflip())
- {
- start_point_y = (GYM - 10);
-
- if (going_y == 1)
- going_y = -1;
- }
-
- int lx = start_point_x;
- int ly = start_point_y;
-
- if (going_y)
- goto do_y;
-
- do_x:
- traps_put2 = 0;
- clear_space = 0; // ( coinflip()? 3 : 2 );
-
- do
- {
- lx += going_x;
-
- if (grd[lx][ly] == DNGN_ROCK_WALL)
- grd[lx][ly] = DNGN_FLOOR;
- }
- while (lx < (GXM - 8) && lx > 8
- && grd[lx + going_x * (2 + clear_space)][ly] == DNGN_ROCK_WALL);
-
- going_x = 0;
-
- if (ly < 32)
- going_y = 1;
- else if (ly > 37)
- going_y = -1;
- else
- goto finishing;
-
- do_y: // if (going_y != 0)
- if (do_2)
- {
- lx = keep_lx2;
- ly = keep_ly2;
- }
-
- // do_2 = false is the problem
- if (coinflip())
- {
- clear_space = 0;
- do_2 = false;
- }
- else
- {
- clear_space = 2;
- do_2 = true;
- }
-
- do
- {
- ly += going_y;
-
- if (grd[lx][ly] == DNGN_ROCK_WALL)
- grd[lx][ly] = DNGN_FLOOR;
- }
- while (ly < (GYM - 8) && ly > 8
- && grd[lx][ly + going_y * (2 + clear_space)] == DNGN_ROCK_WALL);
-
- keep_lx = lx;
- keep_ly = ly;
-
- if (lx < 37)
- going_x = 1;
- else if (lx > 42)
- going_x = -1;
-
- if (ly < 33)
- ly += 2;
- else if (ly > 37)
- ly -= 2;
-
- clear_space = ((!do_2) ? 6 : 2);
-
- do
- {
- lx += going_x;
-
- if (grd[lx][ly] == DNGN_ROCK_WALL)
- grd[lx][ly] = DNGN_FLOOR;
- }
- while (lx < (GXM - 8) && lx > 8
- && grd[lx + going_x * (2 + clear_space)][ly] == DNGN_ROCK_WALL);
-
- if (do_2)
- {
- keep_lx2 = lx;
- keep_ly2 = ly;
- }
-
- lx = keep_lx;
- ly = keep_ly;
-
- going_y = 0;
-
- if (lx < 37)
- going_x = 1;
- else if (lx > 42)
- going_x = -1;
- else
- goto finishing;
-
- goto do_x;
-
- finishing:
- start_point_x = 10 + random2(GXM - 20);
-
- object_class_type glopop = OBJ_RANDOM; // used in calling items() {dlb}
-
- int num_items = 8 + random2avg(9, 2);
- for (int i = 0; i < num_items; i++)
- {
- int temp_rand = random2(11);
-
- glopop = ((temp_rand == 0 || temp_rand == 9) ? OBJ_WEAPONS :
- (temp_rand == 1 || temp_rand == 10) ? OBJ_ARMOUR :
- (temp_rand == 2) ? OBJ_MISSILES :
- (temp_rand == 3) ? OBJ_WANDS :
- (temp_rand == 4) ? OBJ_MISCELLANY :
- (temp_rand == 5) ? OBJ_SCROLLS :
- (temp_rand == 6) ? OBJ_JEWELLERY :
- (temp_rand == 7) ? OBJ_BOOKS
- /* (temp_rand == 8) */ : OBJ_STAVES);
-
- const int treasure_item = items( 1, glopop, OBJ_RANDOM, true,
- level_number * 3, MAKE_ITEM_RANDOM_RACE );
-
- if (treasure_item != NON_ITEM)
- {
- mitm[treasure_item].x = lx;
- mitm[treasure_item].y = ly;
- }
- }
-
- mons_place( MONS_MINOTAUR, BEH_SLEEP, MHITNOT, true, lx, ly );
-
- grd[lx][ly] = DNGN_ROCK_STAIRS_UP;
-
- link_items();
-
- // turn rock walls into undiggable stone or metal:
- dungeon_feature_type wall_xform =
- ((random2(50) > 10) ? DNGN_STONE_WALL // 78.0%
- : DNGN_METAL_WALL); // 22.0%
-
- replace_area(0,0,GXM-1,GYM-1,DNGN_ROCK_WALL,wall_xform);
-#endif
} // end labyrinth_level()
static bool is_wall(int x, int y)
@@ -6247,6 +6067,22 @@ bool dgn_region::overlaps_any(const dgn_region_list &regions) const
return (false);
}
+bool dgn_region::overlaps(const dgn_region_list &regions,
+ const map_mask &mask) const
+{
+ return overlaps_any(regions) && overlaps(mask);
+}
+
+bool dgn_region::overlaps(const map_mask &mask) const
+{
+ const coord_def endp = pos + size;
+ for (int y = pos.y; y < endp.y; ++y)
+ for (int x = pos.x; x < endp.x; ++x)
+ if (mask[x][y])
+ return (true);
+ return (false);
+}
+
coord_def dgn_region::random_edge_point() const
{
return random2(size.x + size.y) < size.x?
diff --git a/crawl-ref/source/dungeon.h b/crawl-ref/source/dungeon.h
index 9182de4d5d..60d953c931 100644
--- a/crawl-ref/source/dungeon.h
+++ b/crawl-ref/source/dungeon.h
@@ -15,6 +15,7 @@
#define DUNGEON_H
#include "FixVec.h"
+#include "FixAry.h"
#include "externs.h"
#include "misc.h"
#include "travel.h"
@@ -29,6 +30,21 @@ const int MAKE_GOOD_ITEM = 351;
// map_type[y][x] for large-scale vaults. Keep an eye out for the associated
// brain-damage. [dshaligram]
typedef char map_type[MAP_SIDE + 1][MAP_SIDE + 1];
+typedef FixedArray<unsigned short, GXM, GYM> map_mask;
+
+extern map_mask dgn_map_mask;
+
+// Map mask constants.
+
+enum map_mask_type
+{
+ MMT_NONE = 0x0,
+ MMT_VAULT = 0x01, // This is a square in a vault.
+ MMT_NO_ITEM = 0x02, // Random items should not be placed here.
+ MMT_NO_MONS = 0x04, // Random monsters should not be placed here.
+ MMT_NO_POOL = 0x08, // Pool fixup should not be applied here.
+ MMT_NO_DOOR = 0x10 // No secret-doorisation.
+};
class dgn_region;
typedef std::vector<dgn_region> dgn_region_list;
@@ -89,6 +105,9 @@ struct dgn_region
bool overlaps(const dgn_region &other) const;
bool overlaps_any(const dgn_region_list &others) const;
+ bool overlaps(const dgn_region_list &others,
+ const map_mask &dgn_map_mask) const;
+ bool overlaps(const map_mask &dgn_map_mask) const;
};
void builder(int level_number, int level_type);
@@ -97,7 +116,7 @@ bool is_wall(int feature);
bool place_specific_trap(int spec_x, int spec_y, trap_type spec_type);
void place_spec_shop(int level_number, int shop_x, int shop_y,
int force_s_type, bool representative = false);
-bool unforbidden(const coord_def &c, const dgn_region_list &forbidden);
+bool unforbidden(const coord_def &c, unsigned mask);
//////////////////////////////////////////////////////////////////////////
// Map markers
@@ -152,7 +171,7 @@ public:
void add_feat(int feat);
void add_point(const coord_def &pos);
- coord_def find_first_from(const coord_def &c, const dgn_region_list &vlts);
+ coord_def find_first_from(const coord_def &c, const map_mask &vlts);
bool points_connected_from(const coord_def &start);
bool any_point_connected_from(const coord_def &start);
bool has_exit_from(const coord_def &start);
@@ -166,7 +185,7 @@ protected:
bool needed_features[NUM_FEATURES];
std::vector<coord_def> needed_points;
bool left_vault;
- dgn_region_list vaults;
+ const map_mask *vaults;
const fgrd &fgrid;
const bound_check &bcheck;
@@ -175,7 +194,7 @@ protected:
template <typename fgrd, typename bound_check>
flood_find<fgrd, bound_check>::flood_find(const fgrd &f, const bound_check &bc)
: travel_pathfind(), point_hunt(false), want_exit(false),
- needed_features(), needed_points(), left_vault(true), vaults(),
+ needed_features(), needed_points(), left_vault(true), vaults(NULL),
fgrid(f), bcheck(bc)
{
memset(needed_features, false, sizeof needed_features);
@@ -192,10 +211,10 @@ template <typename fgrd, typename bound_check>
coord_def
flood_find<fgrd, bound_check>::find_first_from(
const coord_def &c,
- const dgn_region_list &vlts)
+ const map_mask &vlts)
{
set_floodseed(c);
- vaults = vlts;
+ vaults = &vlts;
return pathfind(RMODE_EXPLORE);
}
@@ -292,7 +311,7 @@ bool flood_find<fgrd, bound_check>::path_flood(
return (false);
}
- if (!left_vault && unforbidden(dc, vaults))
+ if (!left_vault && vaults && !(*vaults)(dc))
left_vault = true;
good_square(dc);
diff --git a/crawl-ref/source/luadgn.cc b/crawl-ref/source/luadgn.cc
index f50420b7ef..2bb9150d4f 100644
--- a/crawl-ref/source/luadgn.cc
+++ b/crawl-ref/source/luadgn.cc
@@ -227,7 +227,8 @@ bool dlua_chunk::rewrite_chunk_errors(std::string &s) const
return (true);
}
-std::string dlua_chunk::rewrite_chunk_prefix(const std::string &line) const
+std::string dlua_chunk::rewrite_chunk_prefix(const std::string &line,
+ bool skip_body) const
{
std::string s = line;
const std::string contextm = "[string \"" + context + "\"]:";
@@ -235,10 +236,10 @@ std::string dlua_chunk::rewrite_chunk_prefix(const std::string &line) const
if (ps == std::string::npos)
return (s);
+ const std::string::size_type lns = ps + contextm.length();
std::string::size_type pe = s.find(':', ps + contextm.length());
if (pe != std::string::npos)
{
- const std::string::size_type lns = ps + contextm.length();
const std::string line_num = s.substr(lns, pe - lns);
const int lnum = atoi(line_num.c_str());
s = s.substr(0, lns) + make_stringf("%d", lnum + first - 1)
@@ -246,19 +247,13 @@ std::string dlua_chunk::rewrite_chunk_prefix(const std::string &line) const
}
return s.substr(0, ps) + (file.empty()? context : file) + ":"
- + s.substr(ps + contextm.length());
+ + (skip_body? s.substr(lns, pe - lns)
+ : s.substr(lns));
}
std::string dlua_chunk::get_chunk_prefix(const std::string &sorig) const
{
- std::string s = rewrite_chunk_prefix(sorig);
- const std::string::size_type cpos = s.find(':');
- if (cpos == std::string::npos)
- return (s);
- const std::string::size_type cnpos = s.find(':', cpos + 1);
- if (cnpos == std::string::npos)
- return (s);
- return s.substr(0, cnpos);
+ return rewrite_chunk_prefix(sorig, true);
}
///////////////////////////////////////////////////////////////////////////
diff --git a/crawl-ref/source/luadgn.h b/crawl-ref/source/luadgn.h
index 102a4e87e7..d717f38f5f 100644
--- a/crawl-ref/source/luadgn.h
+++ b/crawl-ref/source/luadgn.h
@@ -34,7 +34,8 @@ private:
private:
int check_op(CLua &, int);
- std::string rewrite_chunk_prefix(const std::string &line) const;
+ std::string rewrite_chunk_prefix(const std::string &line,
+ bool skip_body = false) const;
std::string get_chunk_prefix(const std::string &s) const;
public:
diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc
index 6cc77176cc..5407b9f3be 100644
--- a/crawl-ref/source/makeitem.cc
+++ b/crawl-ref/source/makeitem.cc
@@ -855,7 +855,7 @@ int items( int allow_uniques, // not just true-false,
int item_level, // level of the item, can differ from global
int item_race, // weapon / armour racial categories
// item_race also gives type of rune!
- const dgn_region_list &forbidden)
+ unsigned mapmask)
{
const bool make_good_item = (item_level == MAKE_GOOD_ITEM);
@@ -2864,7 +2864,7 @@ int items( int allow_uniques, // not just true-false,
y_pos = random2(GYM);
}
while (grd[x_pos][y_pos] != DNGN_FLOOR
- || !unforbidden(coord_def(x_pos, y_pos), forbidden));
+ || !unforbidden(coord_def(x_pos, y_pos), mapmask));
move_item_to_grid( &p, x_pos, y_pos );
}
diff --git a/crawl-ref/source/makeitem.h b/crawl-ref/source/makeitem.h
index d74d572545..9dbf3a14fe 100644
--- a/crawl-ref/source/makeitem.h
+++ b/crawl-ref/source/makeitem.h
@@ -12,7 +12,7 @@
int items( int allow_uniques, object_class_type force_class, int force_type,
bool dont_place, int item_level, int item_race,
- const dgn_region_list &forbidden = dgn_region_list() );
+ unsigned mapmask = 0 );
void item_colour( item_def &item );
void init_rod_mp(item_def &item);
diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc
index fc6c0a62dc..4c957c3cc9 100644
--- a/crawl-ref/source/mapdef.cc
+++ b/crawl-ref/source/mapdef.cc
@@ -361,6 +361,11 @@ int map_lines::operator () (const coord_def &c) const
return lines[c.y][c.x];
}
+bool map_lines::in_map(const coord_def &c) const
+{
+ return (lines[c.y][c.x] != ' ');
+}
+
map_lines &map_lines::operator = (const map_lines &map)
{
if (this != &map)
@@ -1104,6 +1109,11 @@ void map_def::reinit()
mons.clear();
}
+bool map_def::in_map(const coord_def &c) const
+{
+ return map.in_map(c);
+}
+
int map_def::glyph_at(const coord_def &c) const
{
return map(c);
diff --git a/crawl-ref/source/mapdef.h b/crawl-ref/source/mapdef.h
index 2d4b95c0dc..79a9bb3a07 100644
--- a/crawl-ref/source/mapdef.h
+++ b/crawl-ref/source/mapdef.h
@@ -176,6 +176,8 @@ public:
map_lines &operator = (const map_lines &);
+ bool in_map(const coord_def &pos) const;
+
void add_line(const std::string &s);
std::string add_nsubst(const std::string &st);
std::string add_subst(const std::string &st);
@@ -500,6 +502,8 @@ public:
void load();
+ bool in_map(const coord_def &p) const;
+
std::vector<coord_def> find_glyph(int glyph) const;
coord_def find_first_glyph(int glyph) const;
coord_def find_first_glyph(const std::string &glyphs) const;
diff --git a/crawl-ref/source/maps.cc b/crawl-ref/source/maps.cc
index be6aa2f249..15d6bf5913 100644
--- a/crawl-ref/source/maps.cc
+++ b/crawl-ref/source/maps.cc
@@ -192,7 +192,7 @@ static bool bad_map_place(const map_def &map,
const vault_placement &vp = (*avoid)[i];
const dgn_region vault(vp.x, vp.y, vp.width, vp.height);
- if (thisvault.overlaps(vault))
+ if (thisvault.overlaps(vault) && thisvault.overlaps(dgn_map_mask))
return (true);
}
diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc
index 1e9b55aa44..20a7b2a4dc 100644
--- a/crawl-ref/source/monplace.cc
+++ b/crawl-ref/source/monplace.cc
@@ -144,7 +144,7 @@ static bool need_moderate_ood(int lev_mons)
bool place_monster(int &id, int mon_type, int power, beh_type behaviour,
int target, bool summoned, int px, int py, bool allow_bands,
proximity_type proximity, int extra, int dur,
- const dgn_region_list &forbidden)
+ unsigned mmask)
{
int band_size = 0;
int band_monsters[BIG_BAND]; // band monster types
@@ -315,7 +315,7 @@ bool place_monster(int &id, int mon_type, int power, beh_type behaviour,
continue;
// Is the grid verboten?
- if (!unforbidden( coord_def(px, py), forbidden ))
+ if (!unforbidden( coord_def(px, py), mmask ))
continue;
// don't generate monsters on top of teleport traps
diff --git a/crawl-ref/source/monplace.h b/crawl-ref/source/monplace.h
index 04eff7f9db..8f85014741 100644
--- a/crawl-ref/source/monplace.h
+++ b/crawl-ref/source/monplace.h
@@ -81,8 +81,7 @@ int summon_any_demon( demon_class_type demon_class );
bool place_monster( int &id, int mon_type, int power, beh_type behaviour,
int target, bool summoned, int px, int py, bool allow_bands,
proximity_type proximity = PROX_ANYWHERE, int extra = 250,
- int dur = 0,
- const dgn_region_list &proscribed = dgn_region_list() );
+ int dur = 0, unsigned mmask = 0 );
monster_type rand_dragon( dragon_class_type type );