diff options
author | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2007-07-07 15:28:06 +0000 |
---|---|---|
committer | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2007-07-07 15:28:06 +0000 |
commit | c25973abd006dc9584efc3ce3538758b30cf3a2a (patch) | |
tree | 573598a46d696ef31a20a486e92d5868ec15ed13 /crawl-ref | |
parent | 17b7bb3e2bab6f05a2e3000b11896f3987ed5a80 (diff) | |
download | crawl-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.cc | 19 | ||||
-rw-r--r-- | crawl-ref/source/cio.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/dat/entry.des | 119 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.cc | 370 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.h | 33 | ||||
-rw-r--r-- | crawl-ref/source/luadgn.cc | 17 | ||||
-rw-r--r-- | crawl-ref/source/luadgn.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/makeitem.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/makeitem.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/mapdef.cc | 10 | ||||
-rw-r--r-- | crawl-ref/source/mapdef.h | 4 | ||||
-rw-r--r-- | crawl-ref/source/maps.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/monplace.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/monplace.h | 3 |
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 ®, int pad_depth, static void change_walls_from_centre(const dgn_region ®ion, const coord_def ¢re, 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 ®ion, 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 ®ion, static void change_walls_from_centre(const dgn_region ®ion, 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 ®ion, 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 ®ions) const return (false); } +bool dgn_region::overlaps(const dgn_region_list ®ions, + 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 ); |