diff options
author | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2007-10-26 16:02:15 +0000 |
---|---|---|
committer | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2007-10-26 16:02:15 +0000 |
commit | 2bccfd8a3ce5d589f5ba82697dbee17fe05e670c (patch) | |
tree | 04d9953f0e3327f9d1f58aeae95ca068c2578243 | |
parent | 4a6887aa3e43e069943e860d82fa531f8b676281 (diff) | |
download | crawl-ref-2bccfd8a3ce5d589f5ba82697dbee17fe05e670c.tar.gz crawl-ref-2bccfd8a3ce5d589f5ba82697dbee17fe05e670c.zip |
Trunk->0.3 merge (2559, 2566-2567): Trowel implementation.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/branches/stone_soup-0.3@2598 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r-- | crawl-ref/source/debug.cc | 14 | ||||
-rw-r--r-- | crawl-ref/source/decks.cc | 29 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.cc | 179 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.h | 9 | ||||
-rw-r--r-- | crawl-ref/source/externs.h | 5 | ||||
-rw-r--r-- | crawl-ref/source/mapdef.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/mapdef.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/maps.cc | 58 | ||||
-rw-r--r-- | crawl-ref/source/maps.h | 11 |
9 files changed, 202 insertions, 109 deletions
diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc index 5f2dd5294c..9b70a50930 100644 --- a/crawl-ref/source/debug.cc +++ b/crawl-ref/source/debug.cc @@ -2391,8 +2391,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) @@ -2424,7 +2426,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, false, 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/decks.cc b/crawl-ref/source/decks.cc index 42686771aa..3a356cf079 100644 --- a/crawl-ref/source/decks.cc +++ b/crawl-ref/source/decks.cc @@ -17,6 +17,7 @@ #include "externs.h" #include "beam.h" +#include "dungeon.h" #include "effects.h" #include "food.h" #include "invent.h" @@ -24,6 +25,7 @@ #include "item_use.h" #include "itemprop.h" #include "items.h" +#include "maps.h" #include "message.h" #include "misc.h" #include "monplace.h" @@ -1096,8 +1098,31 @@ static void trowel_card(int power, deck_rarity_type rarity) bool done_stuff = false; if ( power_level >= 2 ) { - // XXX FIXME Vaults not implemented - // generate a vault + // generate a portal to something + int mapidx = -1; + if ( coinflip() ) + { + // generate a bazaar portal + mapidx = find_map_by_name("bzr_entry_dummy"); + } + else + { + mapidx = find_map_by_name("lab_entry_generic"); + } + + if ( mapidx == -1 ) + { + mpr("A buggy portal flickers into view, then vanishes."); + } + else + { + { + no_messages n; + dgn_place_map(mapidx, false, true, true, you.pos()); + } + mpr("A mystic portal forms."); + } + done_stuff = true; } else if ( power_level == 1 ) { diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 01a4046de0..3ac9965657 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -208,14 +208,19 @@ 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, + bool make_no_exits = 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, + bool make_no_exits = 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() ); + bool make_no_exits = false, + const coord_def &where = coord_def() ); static int vault_grid( vault_placement &, int level_number, int vx, int vy, int altar_count, FixedVector < object_class_type, 7 > &acq_item_class, @@ -512,9 +517,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; } @@ -1254,8 +1259,8 @@ static void prepare_shoals(int level_number) } while ( vaultidx == -1 || !map_by_index(vaultidx)->has_tag("has_rune") ); - build_minivaults( level_number, vaultidx, true, false, - centres[1] - coord_def(3,3) ); + build_minivaults( level_number, vaultidx, true, false, false, + centres[1] ); for ( int i = 2; i < num_islands; ++i ) { @@ -1264,8 +1269,8 @@ static void prepare_shoals(int level_number) vaultidx = dgn_random_map_for_place(true); } while ( vaultidx == -1 || map_by_index(vaultidx)->has_tag("has_rune") ); - build_minivaults( level_number, vaultidx, true, false, - centres[i] - coord_def(3,3) ); + build_minivaults( level_number, vaultidx, true, false, false, + centres[i] ); } } else @@ -3089,9 +3094,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; @@ -3124,9 +3129,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; @@ -3153,8 +3158,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; @@ -3167,7 +3172,7 @@ static bool find_minivault_place(const vault_placement &place, static bool build_minivaults(int level_number, int force_vault, bool building_level, bool clobber, - coord_def where) + bool make_no_exits, const coord_def &where) { // for some weird reason can't put a vault on level 1, because monster equip // isn't generated. @@ -3193,16 +3198,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); @@ -3219,9 +3225,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 == ' ') @@ -3248,11 +3254,14 @@ static bool build_minivaults(int level_number, int force_vault, place.map.map.apply_overlays(coord_def(v1x, v1y)); - if (target_connections.empty() && place.map.has_tag("mini_float")) - pick_float_exits(place, target_connections); + if (!make_no_exits) + { + if (target_connections.empty() && place.map.has_tag("mini_float")) + pick_float_exits(place, target_connections); - if (!target_connections.empty()) - connect_vault(place); + if (!target_connections.empty()) + connect_vault(place); + } return (true); } // end build_minivaults() @@ -3354,14 +3363,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) { @@ -3385,24 +3394,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); @@ -3472,7 +3481,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); } @@ -3480,8 +3489,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))) { @@ -3493,21 +3502,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); @@ -3625,6 +3635,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! // @@ -3634,7 +3649,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, + bool make_no_exits, const coord_def &where) { const dgn_colour_override_manager colour_man; @@ -3663,23 +3679,25 @@ 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, + make_no_exits, 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, + make_no_exits, 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)); @@ -3712,10 +3730,11 @@ 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, bool no_exits, + const coord_def &where) { if (build_vaults(level_number, vault, rune_subst, true, true, - generating_level, clobber)) + generating_level, clobber, no_exits, where)) { const vault_placement &vp = level_vaults[ level_vaults.size() - 1 ]; connect_vault(vp); @@ -3727,7 +3746,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, + bool make_no_exits, const coord_def &where) { int altar_count = 0; FixedVector < char, 10 > stair_exist; @@ -3751,6 +3771,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); @@ -3760,12 +3783,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; @@ -3792,12 +3815,15 @@ 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()) pick_float_exits(place, target_connections); + if (make_no_exits) + target_connections.clear(); + // Must do this only after target_connections is finalised, or the vault // exits will not be correctly set. level_vaults.push_back(place); @@ -3817,10 +3843,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, @@ -4230,8 +4256,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) ); } @@ -5935,7 +5962,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); @@ -5954,9 +5981,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) { @@ -5966,18 +5995,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 5b507af77f..fc7f610f26 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() { } @@ -301,7 +306,9 @@ void dgn_set_colours_from_monsters(); void dgn_set_floor_colours(); void dgn_set_grid_colour_at(const coord_def &c, int colour); -bool dgn_place_map(int map, bool generating_level, bool clobber); +bool dgn_place_map(int map, bool generating_level, bool clobber, + bool make_no_exits, + 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 55b1ed5aaa..e8b2933ec4 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -294,6 +294,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 7d88ff9834..bc62c32151 100644 --- a/crawl-ref/source/mapdef.cc +++ b/crawl-ref/source/mapdef.cc @@ -1301,7 +1301,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); } @@ -1474,7 +1474,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 3ca2c03ca1..dead1f3744 100644 --- a/crawl-ref/source/mapdef.h +++ b/crawl-ref/source/mapdef.h @@ -580,6 +580,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); |