summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-10-25 12:19:25 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-10-25 12:19:25 +0000
commitdd4158d514297586e5fa76269dd6f6f6df5c3c2c (patch)
tree8b4eebe389bcb9427d832e46e00c09aa6573e90f /crawl-ref
parentfe973ee1c8d4069d19fe9b393d98b3db65556e24 (diff)
downloadcrawl-ref-dd4158d514297586e5fa76269dd6f6f6df5c3c2c.tar.gz
crawl-ref-dd4158d514297586e5fa76269dd6f6f6df5c3c2c.zip
dgn_place_map takes a coord_def to specify the centre of the map for minivaults and floating vaults. This placement can be activated using an asterisk (mapname*) when entering the name of the map in the &L command.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2559 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/debug.cc14
-rw-r--r--crawl-ref/source/dungeon.cc156
-rw-r--r--crawl-ref/source/dungeon.h8
-rw-r--r--crawl-ref/source/externs.h5
-rw-r--r--crawl-ref/source/mapdef.cc4
-rw-r--r--crawl-ref/source/mapdef.h2
-rw-r--r--crawl-ref/source/maps.cc58
-rw-r--r--crawl-ref/source/maps.h11
8 files changed, 157 insertions, 101 deletions
diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc
index b41a91c53f..60fe8dfa7f 100644
--- a/crawl-ref/source/debug.cc
+++ b/crawl-ref/source/debug.cc
@@ -2842,8 +2842,10 @@ void debug_set_xl()
debug_uptick_xl(newxl);
}
-static void debug_load_map_by_name(const std::string &name)
+static void debug_load_map_by_name(std::string name)
{
+ const bool place_on_us = strip_tag(name, "*", true);
+
level_clear_vault_memory();
int map = find_map_by_name(name);
if (map == -1)
@@ -2875,7 +2877,15 @@ static void debug_load_map_by_name(const std::string &name)
}
}
- if (dgn_place_map(map, false, true))
+ const map_def *toplace = map_by_index(map);
+ coord_def where(-1, -1);
+ if ((toplace->orient == MAP_FLOAT || toplace->orient == MAP_NONE)
+ && place_on_us)
+ {
+ where = you.pos();
+ }
+
+ if (dgn_place_map(map, false, true, where))
mprf("Successfully placed %s.", map_by_index(map)->name.c_str());
else
mprf("Failed to place %s.", map_by_index(map)->name.c_str());
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index 17116e79f2..a919e4b268 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -208,11 +208,13 @@ static void jelly_pit(int level_number, spec_room &sr);
static bool build_secondary_vault(int level_number, int vault,
int rune_subst = -1,
bool generating_level = true,
- bool clobber = false);
+ bool clobber = false,
+ const coord_def &where = coord_def(-1, -1));
static bool build_vaults(int level_number, int vault_number,
int rune_subst = -1, bool build_only = false,
bool check_vault_place = false,
- bool generating_level = true, bool clobber = false);
+ bool generating_level = true, bool clobber = false,
+ const coord_def &where = coord_def(-1, -1));
static bool build_minivaults(int level_number, int force_vault,
bool level_builder = true, bool clobber = false,
coord_def where = coord_def() );
@@ -504,9 +506,9 @@ static void fixup_pandemonium_stairs()
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)))
+ for (int y = place.pos.y + place.size.y - 1; y >= place.pos.y; --y)
+ for (int x = place.pos.x + place.size.x - 1; x >= place.pos.x; --x)
+ if (place.map.in_map(coord_def(x - place.pos.x, y - place.pos.y)))
dgn_map_mask[x][y] |= mask;
}
@@ -528,11 +530,11 @@ static void register_place(const vault_placement &place)
mask_vault(place, MMT_OPAQUE);
// Now do per-square by-symbol masking
- 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)))
+ for (int y = place.pos.y + place.size.y - 1; y >= place.pos.y; --y)
+ for (int x = place.pos.x + place.size.x - 1; x >= place.pos.x; --x)
+ if (place.map.in_map(coord_def(x - place.pos.x, y - place.pos.y)))
{
- int key = place.map.map.glyph(x - place.x, y - place.y);
+ int key = place.map.map.glyph(x - place.pos.x, y - place.pos.y);
const keyed_mapspec* spec = place.map.mapspec_for_key(key);
if (spec != NULL)
@@ -3098,9 +3100,9 @@ static bool safe_minivault_place(int v1x, int v1y,
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++)
+ for (int vx = v1x; vx < v1x + place.size.x; vx++)
{
- for (int vy = v1y; vy < v1y + place.height; vy++)
+ for (int vy = v1y; vy < v1y + place.size.y; vy++)
{
if (lines[vy - v1y][vx - v1x] == ' ')
continue;
@@ -3133,9 +3135,9 @@ static bool connected_minivault_place(int v1x, int v1y,
/* must not be completely isolated: */
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++)
+ for (int vx = v1x; vx < v1x + place.size.x; vx++)
{
- for (int vy = v1y; vy < v1y + place.height; vy++)
+ for (int vy = v1y; vy < v1y + place.size.y; vy++)
{
if (lines[vy - v1y][vx - v1x] == ' ')
continue;
@@ -3162,8 +3164,8 @@ static bool find_minivault_place(const vault_placement &place,
/* 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 );
+ v1x = random_range( margin, GXM - margin - place.size.x );
+ v1y = random_range( margin, GYM - margin - place.size.y );
if (!safe_minivault_place( v1x, v1y, place, clobber ))
continue;
@@ -3202,16 +3204,17 @@ static bool build_minivaults(int level_number, int force_vault,
int v1x, v1y;
- if ( where.x > 0 && where.y > 0 )
+ if (in_bounds(where)) // not map_bounds, minivaults should never touch edge
{
- v1x = where.x;
- v1y = where.y;
+ coord_def tl(where - place.size / 2);
+ fit_region_into_map_bounds(tl, place.size);
+ v1x = tl.x;
+ v1y = tl.y;
}
else if (!find_minivault_place(place, v1x, v1y, clobber))
return (false);
- place.x = v1x;
- place.y = v1y;
+ place.pos = coord_def(v1x, v1y);
level_vaults.push_back(place);
@@ -3228,9 +3231,9 @@ static bool build_minivaults(int level_number, int force_vault,
std::vector<coord_def> &target_connections = place.exits;
// paint the minivault onto the grid
- for (int vx = v1x; vx < v1x + place.width; vx++)
+ for (int vx = v1x; vx < v1x + place.size.x; vx++)
{
- for (int vy = v1y; vy < v1y + place.height; vy++)
+ for (int vy = v1y; vy < v1y + place.size.y; vy++)
{
const int feat = vgrid[vy - v1y][vx - v1x];
if (feat == ' ')
@@ -3363,14 +3366,14 @@ static coord_def dig_away_dir(const vault_placement &place,
{
// Figure out which way we need to go to dig our way out of the vault.
bool x_edge =
- pos.x == place.x || pos.x == place.x + place.width - 1;
+ pos.x == place.pos.x || pos.x == place.pos.x + place.size.x - 1;
bool y_edge =
- pos.y == place.y || pos.y == place.y + place.height - 1;
+ pos.y == place.pos.y || pos.y == place.pos.y + place.size.y - 1;
// Handle exits in non-rectangular areas.
if (!x_edge && !y_edge)
{
- const coord_def rel = pos - coord_def(place.x, place.y);
+ const coord_def rel = pos - place.pos;
for (int yi = -1; yi <= 1; ++yi)
for (int xi = -1; xi <= 1; ++xi)
{
@@ -3394,24 +3397,24 @@ static coord_def dig_away_dir(const vault_placement &place,
coord_def dig_dir;
if (x_edge)
{
- if (place.width == 1)
+ if (place.size.x == 1)
dig_dir.x =
away_from_edge(pos.x,
MAPGEN_BORDER * 2,
GXM - MAPGEN_BORDER * 2);
else
- dig_dir.x = pos.x == place.x? -1 : 1;
+ dig_dir.x = pos.x == place.pos.x? -1 : 1;
}
if (y_edge)
{
- if (place.height == 1)
+ if (place.size.y == 1)
dig_dir.y =
away_from_edge(pos.y,
MAPGEN_BORDER * 2,
GYM - MAPGEN_BORDER * 2);
else
- dig_dir.y = pos.y == place.y? -1 : 1;
+ dig_dir.y = pos.y == place.pos.y? -1 : 1;
}
return (dig_dir);
@@ -3481,7 +3484,7 @@ static bool map_grid_is_on_edge(const vault_placement &place,
{
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 - place.x, yi - place.y)))
+ if (!place.map.in_map(coord_def(xi, yi) - place.pos))
return (true);
return (false);
}
@@ -3489,8 +3492,8 @@ static bool map_grid_is_on_edge(const vault_placement &place,
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)
+ for (int y = place.pos.y + 1; y < place.pos.y + place.size.y - 1; ++y)
+ for (int x = place.pos.x + 1; x < place.pos.x + place.size.x - 1; ++x)
if (grid_needs_exit(x, y)
&& map_grid_is_on_edge(place, coord_def(x, y)))
{
@@ -3502,21 +3505,22 @@ static void pick_float_exits(vault_placement &place,
std::vector<coord_def> &targets)
{
std::vector<coord_def> possible_exits;
- for (int y = place.y; y < place.y + place.height; ++y)
+ for (int y = place.pos.y; y < place.pos.y + place.size.y; ++y)
{
- if (grid_needs_exit(place.x, y))
- possible_exits.push_back( coord_def(place.x, y) );
- if (grid_needs_exit(place.x + place.width - 1, y))
- possible_exits.push_back( coord_def(place.x + place.width - 1, y) );
+ if (grid_needs_exit(place.pos.x, y))
+ possible_exits.push_back( coord_def(place.pos.x, y) );
+ if (grid_needs_exit(place.pos.x + place.size.x - 1, y))
+ possible_exits.push_back(
+ coord_def(place.pos.x + place.size.x - 1, y) );
}
- for (int x = place.x + 1; x < place.x + place.width - 1; ++x)
+ for (int x = place.pos.x + 1; x < place.pos.x + place.size.x - 1; ++x)
{
- if (grid_needs_exit(x, place.y))
- possible_exits.push_back( coord_def(x, place.y) );
- if (grid_needs_exit(x, place.y + place.height - 1))
+ if (grid_needs_exit(x, place.pos.y))
+ possible_exits.push_back( coord_def(x, place.pos.y) );
+ if (grid_needs_exit(x, place.pos.y + place.size.y - 1))
possible_exits.push_back(
- coord_def(x, place.y + place.height - 1) );
+ coord_def(x, place.pos.y + place.size.y - 1) );
}
pick_internal_float_exits(place, possible_exits);
@@ -3634,6 +3638,11 @@ static dungeon_feature_type dgn_find_rune_subst_tags(const std::string &tags)
}
// Places a map on the current level (minivault or regular vault).
+//
+// You can specify the centre of the map using "where" for floating vaults
+// and minivaults. "where" is ignored for other vaults. XXX: it might be
+// nice to specify a square that is not the centre, but is identified by
+// a marker in the vault to be placed.
//
// NOTE: encompass maps will destroy the existing level!
//
@@ -3643,7 +3652,8 @@ static dungeon_feature_type dgn_find_rune_subst_tags(const std::string &tags)
// clobber: If true, assumes the newly placed vault can clobber existing
// items and monsters (items may be destroyed, monsters may be
// teleported).
-bool dgn_place_map(int map, bool generating_level, bool clobber)
+bool dgn_place_map(int map, bool generating_level, bool clobber,
+ const coord_def &where)
{
const map_def *mdef = map_by_index(map);
bool did_map = false;
@@ -3670,23 +3680,24 @@ bool dgn_place_map(int map, bool generating_level, bool clobber)
if (mdef->is_minivault())
did_map =
- build_minivaults(you.your_level, map, generating_level, clobber);
+ build_minivaults(you.your_level, map, generating_level, clobber,
+ where);
else
{
dungeon_feature_type rune_subst = DNGN_FLOOR;
if (mdef->has_tag_suffix("_entry"))
rune_subst = dgn_find_rune_subst_tags(mdef->tags);
did_map = build_secondary_vault(you.your_level, map, rune_subst,
- generating_level, clobber);
+ generating_level, clobber, where);
}
// Activate any markers within the map.
if (did_map && !generating_level)
{
const vault_placement &vp = level_vaults[level_vaults.size() - 1];
- for (int y = vp.y; y < vp.y + vp.height; ++y)
+ for (int y = vp.pos.y; y < vp.pos.y + vp.size.y; ++y)
{
- for (int x = vp.x; x < vp.x + vp.width; ++x)
+ for (int x = vp.pos.x; x < vp.pos.x + vp.size.x; ++x)
{
std::vector<map_marker *> markers =
env.markers.get_markers_at(coord_def(x, y));
@@ -3719,10 +3730,10 @@ bool dgn_place_map(int map, bool generating_level, bool clobber)
*/
static bool build_secondary_vault(int level_number, int vault,
int rune_subst, bool generating_level,
- bool clobber)
+ bool clobber, const coord_def &where)
{
if (build_vaults(level_number, vault, rune_subst, true, true,
- generating_level, clobber))
+ generating_level, clobber, where))
{
const vault_placement &vp = level_vaults[ level_vaults.size() - 1 ];
connect_vault(vp);
@@ -3734,7 +3745,8 @@ static bool build_secondary_vault(int level_number, int vault,
static bool build_vaults(int level_number, int force_vault, int rune_subst,
bool build_only, bool check_collisions,
- bool generating_level, bool clobber)
+ bool generating_level, bool clobber,
+ const coord_def &where)
{
int altar_count = 0;
FixedVector < char, 10 > stair_exist;
@@ -3758,6 +3770,9 @@ static bool build_vaults(int level_number, int force_vault, int rune_subst,
vault_placement place;
std::vector<coord_def> &target_connections = place.exits;
+ if (map_bounds(where))
+ place.pos = where;
+
const int gluggy = vault_main(vgrid, place, force_vault,
check_collisions, clobber);
@@ -3767,12 +3782,12 @@ static bool build_vaults(int level_number, int force_vault, int rune_subst,
int vx, vy;
int num_runes = 0;
- dgn_region this_vault(place.x, place.y, place.width, place.height);
+ dgn_region this_vault(place.pos, place.size);
// note: assumes *no* previous item (I think) or monster (definitely)
// placement
- for (vx = place.x; vx < place.x + place.width; vx++)
+ for (vx = place.pos.x; vx < place.pos.x + place.size.x; vx++)
{
- for (vy = place.y; vy < place.y + place.height; vy++)
+ for (vy = place.pos.y; vy < place.pos.y + place.size.y; vy++)
{
if (vgrid[vy][vx] == ' ')
continue;
@@ -3799,7 +3814,7 @@ static bool build_vaults(int level_number, int force_vault, int rune_subst,
}
}
- place.map.map.apply_overlays(coord_def(place.x, place.y));
+ place.map.map.apply_overlays(place.pos);
register_place(place);
if (gluggy == MAP_FLOAT && target_connections.empty())
@@ -3824,10 +3839,10 @@ static bool build_vaults(int level_number, int force_vault, int rune_subst,
// kind of wallification it wants.
const bool dis_wallify = place.map.has_tag("dis");
- const int v1x = place.x;
- const int v1y = place.y;
- const int v2x = place.x + place.width - 1;
- const int v2y = place.y + place.height - 1;
+ const int v1x = place.pos.x;
+ const int v1y = place.pos.y;
+ const int v2x = place.pos.x + place.size.x - 1;
+ const int v2y = place.pos.y + place.size.y - 1;
#ifdef DEBUG_DIAGNOSTICS
mprf(MSGCH_DIAGNOSTICS,
@@ -4243,8 +4258,9 @@ static int vault_grid( vault_placement &place,
}
if ((vgrid == '=' || vgrid == '+')
- && (vx == place.x || vy == place.y || vx == place.x + place.width - 1
- || vy == place.y + place.height - 1))
+ && (vx == place.pos.x || vy == place.pos.y
+ || vx == place.pos.x + place.size.x - 1
+ || vy == place.pos.y + place.size.y - 1))
{
targets.push_back( coord_def(vx, vy) );
}
@@ -5947,7 +5963,7 @@ static void labyrinth_level(int level_number)
{
init_minivault_placement(vault, place);
- int ex = place.width / 4, ey = place.height / 4;
+ int ex = place.size.x / 4, ey = place.size.y / 4;
labyrinth_dimension_adjust(ex, lab.pos.x, lab.size.x);
labyrinth_dimension_adjust(ey, lab.pos.y, lab.size.y);
@@ -5966,9 +5982,11 @@ static void labyrinth_level(int level_number)
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 y = rplace.pos.y;
+ y <= rplace.pos.y + rplace.size.y - 1; ++y)
{
- for (int x = rplace.x; x <= rplace.x + rplace.height - 1; ++x)
+ for (int x = rplace.pos.x;
+ x <= rplace.pos.x + rplace.size.x - 1; ++x)
{
if (grd[x][y] == DNGN_ROCK_STAIRS_UP)
{
@@ -5978,18 +5996,14 @@ static void labyrinth_level(int level_number)
}
}
}
- place.x = rplace.x;
- place.y = rplace.y;
- place.width = rplace.width;
- place.height = rplace.height;
+ place.pos = rplace.pos;
+ place.size = rplace.size;
- pad_region(dgn_region(place.x, place.y, place.width, place.height),
- 1, DNGN_FLOOR);
+ pad_region(dgn_region(place.pos, place.size), 1, DNGN_FLOOR);
}
if (vault != -1)
- end = coord_def(place.x + place.width / 2,
- place.y + place.height / 2);
+ end = place.pos + place.size / 2;
place_extra_lab_minivaults(level_number);
diff --git a/crawl-ref/source/dungeon.h b/crawl-ref/source/dungeon.h
index fe5d4d1fac..c6095128aa 100644
--- a/crawl-ref/source/dungeon.h
+++ b/crawl-ref/source/dungeon.h
@@ -82,6 +82,11 @@ struct dgn_region
{
}
+ dgn_region(const coord_def &_pos, const coord_def &_size)
+ : pos(_pos), size(_size)
+ {
+ }
+
dgn_region() : pos(-1, -1), size()
{
}
@@ -298,7 +303,8 @@ bool builder(int level_number, int level_type);
// Abyss and Pan.
void dgn_set_colours_from_monsters();
-bool dgn_place_map(int map, bool generating_level, bool clobber);
+bool dgn_place_map(int map, bool generating_level, bool clobber,
+ const coord_def &pos = coord_def(-1, -1));
void level_clear_vault_memory();
void level_welcome_messages();
void define_zombie(int mid, int ztype, int cs, int power);
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index fe0cb906f9..6edf258b14 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -311,6 +311,11 @@ struct coord_def
{
return (std::max(std::abs(x), std::abs(y)));
}
+
+ bool origin() const
+ {
+ return (!x && !y);
+ }
};
typedef bool (*coord_predicate)(const coord_def &c);
diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc
index 44e487afd3..47971f4191 100644
--- a/crawl-ref/source/mapdef.cc
+++ b/crawl-ref/source/mapdef.cc
@@ -1304,7 +1304,7 @@ void map_def::read_index(FILE *inf)
void map_def::write_depth_ranges(FILE *outf) const
{
writeShort(outf, depths.size());
- for (int i = 0, size = depths.size(); i < size; ++i)
+ for (int i = 0, sz = depths.size(); i < sz; ++i)
depths[i].write(outf);
}
@@ -1477,7 +1477,7 @@ std::string map_def::validate_map_def()
bool map_def::is_usable_in(const level_id &lid) const
{
bool any_matched = false;
- for (int i = 0, size = depths.size(); i < size; ++i)
+ for (int i = 0, sz = depths.size(); i < sz; ++i)
{
const level_range &lr = depths[i];
if (lr.matches(lid))
diff --git a/crawl-ref/source/mapdef.h b/crawl-ref/source/mapdef.h
index de6ead6047..cb0488b325 100644
--- a/crawl-ref/source/mapdef.h
+++ b/crawl-ref/source/mapdef.h
@@ -598,6 +598,8 @@ public:
void load();
bool in_map(const coord_def &p) const;
+
+ coord_def size() const { return coord_def(map.width(), map.height()); }
std::vector<coord_def> find_glyph(int glyph) const;
coord_def find_first_glyph(int glyph) const;
diff --git a/crawl-ref/source/maps.cc b/crawl-ref/source/maps.cc
index 7b01a4971f..dc1d66155d 100644
--- a/crawl-ref/source/maps.cc
+++ b/crawl-ref/source/maps.cc
@@ -64,8 +64,9 @@ int vault_main(
bool clobber)
{
#ifdef DEBUG_DIAGNOSTICS
- mprf(MSGCH_DIAGNOSTICS, "Generating level: %s",
- vdefs[which_vault].name.c_str());
+ mprf(MSGCH_DIAGNOSTICS, "Generating level: %s (%d,%d)",
+ vdefs[which_vault].name.c_str(),
+ place.pos.x, place.pos.y);
if (crawl_state.map_stat_gen)
mapgen_report_map_try(vdefs[which_vault]);
#endif
@@ -203,6 +204,19 @@ static bool bad_map_place(const map_def &map,
return (false);
}
+void fit_region_into_map_bounds(coord_def &pos, const coord_def &size)
+{
+ ASSERT(size.x <= GXM && size.y <= GYM);
+ if (pos.x < X_BOUND_1)
+ pos.x = X_BOUND_1;
+ if (pos.y < Y_BOUND_1)
+ pos.y = Y_BOUND_1;
+ if (pos.x + size.x - 1 > X_BOUND_2)
+ pos.x = X_BOUND_2 - size.x + 1;
+ if (pos.y + size.y - 1 > Y_BOUND_2)
+ pos.y = Y_BOUND_2 - size.y + 1;
+}
+
static bool apply_vault_grid(map_def &def, map_type map,
vault_placement &place,
bool check_place, bool clobber)
@@ -212,44 +226,46 @@ static bool apply_vault_grid(map_def &def, map_type map,
const int width = ml.width();
const int height = ml.height();
- int startx = 0, starty = 0;
+ coord_def start(0, 0);
if (orient == MAP_SOUTH || orient == MAP_SOUTHEAST
|| orient == MAP_SOUTHWEST)
- starty = GYM - height;
+ start.y = GYM - height;
if (orient == MAP_EAST || orient == MAP_NORTHEAST
|| orient == MAP_SOUTHEAST)
- startx = GXM - width;
+ start.x = GXM - width;
// Handle maps aligned along cardinals that are smaller than
// the corresponding map dimension.
if ((orient == MAP_NORTH || orient == MAP_SOUTH
|| orient == MAP_ENCOMPASS)
&& width < GXM)
- startx = (GXM - width) / 2;
+ start.x = (GXM - width) / 2;
if ((orient == MAP_EAST || orient == MAP_WEST
|| orient == MAP_ENCOMPASS)
&& height < GYM)
- starty = (GYM - height) / 2;
+ start.y = (GYM - height) / 2;
// Floating maps can go anywhere, ask the map_def to suggest a place.
if (orient == MAP_FLOAT)
{
- coord_def where = def.float_place();
-
- // No further sanity checks.
- startx = where.x;
- starty = where.y;
+ if (map_bounds(place.pos))
+ {
+ start = place.pos - coord_def(width, height) / 2;
+ fit_region_into_map_bounds(start, coord_def(width, height));
+ }
+ else
+ start = def.float_place();
}
- if (bad_map_place(def, startx, starty, width, height, check_place,
+ if (bad_map_place(def, start.x, start.y, width, height, check_place,
clobber))
{
#ifdef DEBUG_DIAGNOSTICS
mprf(MSGCH_DIAGNOSTICS, "Bad vault place: (%d,%d) dim (%d,%d)",
- startx, starty, width, height);
+ start.x, start.y, width, height);
#endif
return (false);
}
@@ -257,19 +273,17 @@ static bool apply_vault_grid(map_def &def, map_type map,
const std::vector<std::string> &lines = ml.get_lines();
#ifdef DEBUG_DIAGNOSTICS
mprf(MSGCH_DIAGNOSTICS, "Applying %s at (%d,%d), dimensions (%d,%d)",
- def.name.c_str(), startx, starty, width, height);
+ def.name.c_str(), start.x, start.y, width, height);
#endif
- for (int y = starty; y < starty + height; ++y)
+ for (int y = start.y; y < start.y + height; ++y)
{
- const std::string &s = lines[y - starty];
- strncpy(&map[y][startx], s.c_str(), s.length());
+ const std::string &s = lines[y - start.y];
+ strncpy(&map[y][start.x], s.c_str(), s.length());
}
- place.x = startx;
- place.y = starty;
- place.width = width;
- place.height = height;
+ place.pos = start;
+ place.size = coord_def(width, height);
return (true);
}
diff --git a/crawl-ref/source/maps.h b/crawl-ref/source/maps.h
index 174349da58..e5ce87220d 100644
--- a/crawl-ref/source/maps.h
+++ b/crawl-ref/source/maps.h
@@ -21,14 +21,15 @@
class map_def;
struct vault_placement
{
- int x, y;
- int width, height;
+ coord_def pos;
+ coord_def size;
+
int orient;
map_def map;
std::vector<coord_def> exits;
vault_placement()
- : x(-1), y(-1), width(0), height(0), orient(0), map(),
+ : pos(-1, -1), size(0, 0), orient(0), map(),
exits()
{
}
@@ -40,6 +41,10 @@ int vault_main(map_type vgrid,
bool check_place = false,
bool clobber = false);
+// Given a rectangular region, slides it to fit into the map. size must be
+// smaller than (GXM,GYM).
+void fit_region_into_map_bounds(coord_def &pos, const coord_def &size);
+
const map_def *map_by_index(int index);
int map_count();
int find_map_by_name(const std::string &name);