From f0dccf90776fe087a34b22d04e7125b8ce3842fc Mon Sep 17 00:00:00 2001 From: Darshan Shaligram Date: Sat, 26 Dec 2009 18:58:53 +0530 Subject: Experimental changes to Shoals level generation. Use more random Shoal island generation. Still needs work on placing Shoal:$ huts correctly and connectivity fixes. --- crawl-ref/source/dungeon.cc | 394 +++++++++++++++++--------------------------- 1 file changed, 149 insertions(+), 245 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index bef185979e..c7b1f9c88d 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -13,6 +13,7 @@ #include #include #include +#include #include "abyss.h" #include "artefact.h" @@ -1104,8 +1105,7 @@ static void _build_layout_skeleton(int level_number, int level_type, if (!dgn_level_vetoed && skip_build == BUILD_CONTINUE) { - if (!player_in_branch(BRANCH_SHOALS)) - skip_build = _builder_basic(level_number); + skip_build = _builder_basic(level_number); if (!dgn_level_vetoed && skip_build == BUILD_CONTINUE) _builder_extras(level_number, level_type); } @@ -1798,8 +1798,6 @@ static void _build_dungeon_level(int level_number, int level_type) // Time to make the swamp or shoals {dlb}: if (player_in_branch(BRANCH_SWAMP)) _prepare_swamp(); - else if (player_in_branch(BRANCH_SHOALS)) - _prepare_shoals(level_number); if (dgn_level_vetoed) return; @@ -2003,19 +2001,6 @@ static void _hide_doors() } } -// Places a randomised ellipse with centre (x, y) and half axes a and b. -static void _place_ellipse(int x, int y, int a, int b, - dungeon_feature_type feat, int margin) -{ - for (int i = std::max(x-a, margin); i < std::min(x+a, GXM-margin); ++i) - for (int j = std::max(y-b, margin); j < std::min(y+b, GYM-margin); ++j) - if ( (x-i)*(x-i)*b*b + (y-j)*(y-j)*a*a - <= a*a*b*b/2 + roll_dice(2, a*a*b*b)/4 + random2(3) ) - { - grd[i][j] = feat; - } -} - int count_feature_in_box(int x0, int y0, int x1, int y1, dungeon_feature_type feat) { @@ -2042,18 +2027,6 @@ int count_neighbours(int x, int y, dungeon_feature_type feat) return count_feature_in_box(x-1, y-1, x+2, y+2, feat); } -static void _replace_in_grid(int x1, int y1, int x2, int y2, - dungeon_feature_type oldfeat, - dungeon_feature_type newfeat) -{ - for (int x = x1; x < x2; ++x) - for (int y = y1; y < y2; ++y) - { - if (grd[x][y] == oldfeat) - grd[x][y] = newfeat; - } -} - static void _connected_flood(int margin, int i, int j, bool taken[GXM][GYM]) { if (i < margin || i >= GXM - margin || j < margin || j >= GYM - margin @@ -2068,270 +2041,182 @@ static void _connected_flood(int margin, int i, int j, bool taken[GXM][GYM]) _connected_flood(margin, i + idelta, j + jdelta, taken); } -// Yes, yes, this can probably use travel to avoid duplicating code. -static int _count_connected(int margin) -{ - bool taken[GXM][GYM]; +static int _shoals_heights[GYM][GXM]; +static std::vector _shoals_islands; - for (int i = margin; i < GXM - margin; ++i) - for (int j = margin; j < GYM - margin; ++j) - taken[i][j] = feat_is_water(grd[i][j]); +const int ISLAND_COLLIDE_DIST2 = 5 * 5; +const int N_PERTURB_ISLAND_CENTER = 50; +const int ISLAND_CENTER_RADIUS_LOW = 3; +const int ISLAND_CENTER_RADIUS_HIGH = 10; - int count = 0; +const int N_PERTURB_OFFSET_LOW = 25; +const int N_PERTURB_OFFSET_HIGH = 45; +const int PERTURB_OFFSET_RADIUS_LOW = 2; +const int PERTURB_OFFSET_RADIUS_HIGH = 7; - for (int i = margin; i < GXM - margin; ++i) - for (int j = margin; j < GYM - margin; ++j) - if (!taken[i][j]) - { - ++count; - _connected_flood(margin,i,j,taken); - } +const int _shoals_margin = 6; - return count; +static void _shoals_init_heights() +{ + for (int y = 0; y < GYM; ++y) + for (int x = 0; x < GXM; ++x) + _shoals_heights[y][x] = -17; } -static void _place_base_islands(int margin, int num_islands, int estradius, - coord_def centres[10]) +static coord_def _random_point_from(const coord_def &c, int radius) { - for (int i = 0; i < num_islands; ++i) - { - // smaller axis - int b = (2 * estradius + roll_dice(3, estradius)) / 4; - b = std::max(b, 4); - b = std::min(b, (GYM - 2*margin - 2) / 2); - - int a = b + roll_dice(2, b)/3; // more wide than tall - a = std::min(a, (GXM - 2*margin - 2) / 2); - - int island_distance = estradius*estradius * (2 + num_islands/3); - - // Make sure an island fits into the map without getting - // cut off on the edges, i.e. leave margin + radius space - // at each side. - const int rnd_x_size = GXM - 2*(margin+a) - 1; - const int rnd_y_size = GYM - 2*(margin+b) - 1; - ASSERT(rnd_x_size > 0); - ASSERT(rnd_y_size > 0); - - bool centre_ok = false; - int tries = 1000; - do + while (true) { + const double angle = random2(360) * M_PI / 180; + coord_def res = c + coord_def(radius * cos(angle), radius * sin(angle)); + if (res.x >= _shoals_margin && res.x < GXM - _shoals_margin + && res.y >= _shoals_margin && res.y < GYM - _shoals_margin) { - centre_ok = true; - - centres[i].x = margin + a + random2(rnd_x_size); - centres[i].y = margin + b + random2(rnd_y_size); - - for (int j = 0; j < i; ++j) - { - // Calculate the distance from the centers of - // previous islands. - if (distance(centres[i].x, centres[i].y, - centres[j].x, centres[j].y) < island_distance) - { - centre_ok = false; - break; - } - } - if (island_distance && !one_chance_in(num_islands)) - --island_distance; + return res; } - while (!centre_ok && --tries > 0); - -#ifdef DEBUG_DIAGNOSTICS - if (tries == 0) - mprf(MSGCH_ERROR, "Failure to place island #%d!", i); -#endif - // Eventually, place an ellipse around the new coordinate. - _place_ellipse( centres[i].x, centres[i].y, a, b, DNGN_FLOOR, margin); } } -typedef std::pair located_feature; -typedef std::list located_feature_list; - -bool _is_critical_feature(dungeon_feature_type feat) -{ - return (feat == DNGN_ENTER_PORTAL_VAULT - || feat == DNGN_ENTER_LABYRINTH - || feat == DNGN_ENTER_SHOP); +static coord_def _random_point(int offset = 0) { + return coord_def(random_range(offset, GXM - offset - 1), + random_range(offset, GYM - offset - 1)); } -static located_feature_list _save_critical_features() +static void _shoals_island_center(const coord_def &c, int n_perturb, int radius, + int bounce_low, int bounce_high) { - located_feature_list result; - - for (rectangle_iterator ri(1); ri; ++ri) - if (_is_critical_feature(grd(*ri))) - result.push_back(located_feature(*ri, grd(*ri))); - - return result; + for (int i = 0; i < n_perturb; ++i) { + coord_def p = _random_point_from(c, random2(1 + radius)); + _shoals_heights[p.y][p.x] += random_range(bounce_low, bounce_high); + } } -static void _restore_critical_features(const located_feature_list& lfl) +static coord_def _shoals_pick_island_spot() { - for (located_feature_list::const_iterator ci = lfl.begin(); - ci != lfl.end(); ++ci) + coord_def c; + for (int i = 0; i < 15; ++i) { - grd(ci->first) = ci->second; + c = _random_point(_shoals_margin * 2); + + bool collides = false; + for (int j = 0, size = _shoals_islands.size(); j < size; ++j) + { + const coord_def island = _shoals_islands[j]; + const coord_def dist = island - c; + if (dist.abs() < ISLAND_COLLIDE_DIST2) + { + collides = true; + break; + } + } + if (!collides) + break; } + _shoals_islands.push_back(c); + return c; } -static void _prepare_shoals(int level_number) +static void _shoals_build_island() { - // Don't destroy portals, etc. - const located_feature_list lfl = _save_critical_features(); - - dgn_Build_Method += make_stringf(" shoals [%d]", level_number); - dgn_Layout_Type = "shoals"; - - // dpeg's algorithm. - // We could have just used spotty_level() and changed rock to - // water, but this is much cooler. Right? - const int margin = 6; + coord_def c = _shoals_pick_island_spot(); + _shoals_island_center(c, N_PERTURB_ISLAND_CENTER, + random_range(ISLAND_CENTER_RADIUS_LOW, + ISLAND_CENTER_RADIUS_HIGH), + 40, 60); + const int additional_heights = random2(4); + for (int i = 0; i < additional_heights; ++i) { + const int addition_offset = random_range(2, 10); - int num_islands = player_branch_depth() + 1; - - if (at_branch_bottom()) - num_islands += random2(3); + coord_def offsetC = _random_point_from(c, addition_offset); - const int estradius = 50 / num_islands - (num_islands == 2 ? 5 : 0); - - int num_tries = 0; - coord_def centres[10]; - do - { - for (int x = margin; x < GXM-margin; ++x) - for (int y = margin; y < GYM-margin; ++y) - grd[x][y] = DNGN_DEEP_WATER; - - _place_base_islands(margin, num_islands, estradius, centres); + _shoals_island_center(offsetC, random_range(N_PERTURB_OFFSET_LOW, + N_PERTURB_OFFSET_HIGH), + random_range(PERTURB_OFFSET_RADIUS_LOW, + PERTURB_OFFSET_RADIUS_HIGH), + 25, 35); } - while (++num_tries < 100 && _count_connected(margin) != num_islands); - -#ifdef DEBUG_DIAGNOSTICS - mprf(MSGCH_DIAGNOSTICS, "Num tries: %d Connected components: %d", - num_tries, _count_connected(margin)); -#endif - - // Adding shallow water at deep water adjacent to floor. - // Randomisation: place shallow water if at least 1d(1d3) floor neighbours - for (int i = margin; i < GXM - margin; ++i) - for (int j = margin; j < GYM - margin; ++j) - if (grd[i][j] == DNGN_DEEP_WATER - && count_neighbours(i, j, DNGN_FLOOR) > random2(random2(3)+1)) - { - grd[i][j] = DNGN_SHALLOW_WATER; - } - - // Placing sandbanks. - for (int banks = 0; banks < 8; ++banks) - { - int xsize = 3 + random2(3); // random rectangle - int ysize = 3 + random2(3); - int xb = margin + 2 + random2(GXM - 2 * margin - xsize - 2); - int yb = margin + 2 + random2(GYM - 2 * margin - ysize - 2); +} - bool ok_place = true; - for (int i = xb; i < xb + xsize; ++i) - for (int j = yb; j < yb + ysize; ++j) - { - if (grd[i][j] != DNGN_DEEP_WATER) - { - ok_place = false; - break; - } - } +static void _shoals_init_islands(int depth) +{ + const int nislands = 25 - depth * 3; + for (int i = 0; i < nislands; ++i) + _shoals_build_island(); +} - if (ok_place) - { - for (int i = xb; i < xb + xsize; ++i) - for (int j = yb; j < yb + ysize; ++j) - { - if (!one_chance_in(3)) - grd[i][j] = DNGN_SHALLOW_WATER; - } +static void _shoals_smooth_at(const coord_def &c, int radius) +{ + int max_delta = radius * radius * 2 + 2; + int divisor = 0; + int total = 0; + for (int y = c.y - radius; y <= c.y + radius; ++y) { + for (int x = c.x - radius; x <= c.x + radius; ++x) { + const coord_def p(x, y); + if (!in_bounds(p)) + continue; + const coord_def off = c - p; + int weight = max_delta - off.abs(); + divisor += weight; + total += _shoals_heights[p.y][p.x] * weight; } } + _shoals_heights[c.y][c.x] = total / divisor; +} - // Fractalisation - - // LAVA is a placeholder for cells which will become shallow water - // at the end of the current iteration. - // WATER_RESERVED is a placeholder for last iteration's generated water. - _replace_in_grid(margin, margin, GXM-margin, GYM-margin, - DNGN_SHALLOW_WATER, DNGN_WATER_RESERVED); - - for (int iteration = 0; iteration < 6; ++iteration) - { - for (int x = margin; x < GXM - margin; ++x) - for (int y = margin; y < GYM - margin; ++y) - if (grd[x][y] == DNGN_DEEP_WATER) - { - int badness = count_neighbours(x, y, DNGN_WATER_RESERVED); - if (random2(badness) >= 2 && coinflip()) - grd[x][y] = DNGN_LAVA; - } - - _replace_in_grid(margin, margin, GXM-margin, GYM-margin, - DNGN_LAVA, DNGN_WATER_RESERVED); - } - _replace_in_grid(margin, margin, GXM-margin, GYM-margin, - DNGN_WATER_RESERVED, DNGN_SHALLOW_WATER); +static void _shoals_smooth() +{ + for (int y = 0; y < GYM; ++y) + for (int x = 0; x < GXM; ++x) + _shoals_smooth_at(coord_def(x, y), 1); +} - // Turn rock walls into deep water and "open sea". This must happen - // before vaults are placed as those may contain rock as well. - const int margin2 = margin - 1; - _replace_in_grid(margin2, margin2, GXM-margin2, GYM-margin2, - DNGN_ROCK_WALL, DNGN_DEEP_WATER); +static dungeon_feature_type _shoals_feature_at(int x, int y) +{ + const int height = _shoals_heights[y][x]; + return height >= 0? DNGN_FLOOR : + height >= -14? DNGN_SHALLOW_WATER : DNGN_DEEP_WATER; +} - _replace_area(0, 0, GXM-1, GYM-1, DNGN_BUILDER_SPECIAL_WALL, - DNGN_ROCK_WALL); - _replace_area(0, 0, GXM-1, GYM-1, DNGN_ROCK_WALL, DNGN_OPEN_SEA); +static void _shoals_apply_level() +{ + for (int y = 1; y < GYM - 1; ++y) + for (int x = 1; x < GXM - 1; ++x) + grd[x][y] = _shoals_feature_at(x, y); +} - // Put important things back. - _restore_critical_features(lfl); +static coord_def _pick_shoals_island() +{ + const int lucky_island = random2(_shoals_islands.size()); + const coord_def c = _shoals_islands[lucky_island]; + _shoals_islands.erase(_shoals_islands.begin() + lucky_island); + return c; +} +static void _shoals_furniture(int margin) +{ if (at_branch_bottom()) { - // Find an island to place the stairs up on. - int j; - const coord_def d1(1,0), d2(-1,0); - for (j = 0; j < num_islands; ++j) - { - if (!_is_critical_feature(grd(centres[j])) - && !_is_critical_feature(grd(centres[j] + d1)) - && !_is_critical_feature(grd(centres[j] + d2))) - { - break; - } - } - if (j == num_islands) - { - // Oh well. - j = 0; - mprf(MSGCH_ERROR, "Clobbering critical features: %d %d %d.", - grd(centres[j]), grd(centres[j] + d1), grd(centres[j] + d2)); - } + const coord_def c = _pick_shoals_island(); // Put all the stairs on one island. - grd[centres[j].x ][centres[j].y] = DNGN_STONE_STAIRS_UP_I; - grd[centres[j].x+1][centres[j].y] = DNGN_STONE_STAIRS_UP_II; - grd[centres[j].x-1][centres[j].y] = DNGN_STONE_STAIRS_UP_III; + grd(c) = DNGN_STONE_STAIRS_UP_I; + grd(c + coord_def(1, 0)) = DNGN_STONE_STAIRS_UP_II; + grd(c - coord_def(1, 0)) = DNGN_STONE_STAIRS_UP_III; + const coord_def p = _pick_shoals_island(); // Place the rune const map_def *vault = random_map_for_tag("shoal_rune"); - _build_secondary_vault(level_number, vault, -1, false, true, - centres[1]); + _build_secondary_vault(you.your_level, vault, -1, false, true, + p); - for (int i = 2; i < num_islands; ++i) + const int nhuts = std::min(8, int(_shoals_islands.size())); + for (int i = 2; i < nhuts; ++i) { // Place (non-rune) minivaults on the other islands do vault = random_map_for_tag("shoal"); while (!vault); - _build_secondary_vault(level_number, vault, -1, false, true, - centres[i]); + _build_secondary_vault(you.your_level, vault, -1, false, true, + _pick_shoals_island()); } } else @@ -2361,6 +2246,22 @@ static void _prepare_shoals(int level_number) = static_cast(DNGN_STONE_STAIRS_UP_I + i); } } + +} + +static void _prepare_shoals(int level_number) +{ + dgn_Build_Method += make_stringf(" shoals+ [%d]", level_number); + dgn_Layout_Type = "shoals"; + + const int shoals_depth = level_id::current().depth - 1; + _replace_area(0, 0, GXM-1, GYM-1, DNGN_ROCK_WALL, DNGN_OPEN_SEA); + _shoals_init_heights(); + _shoals_islands.clear(); + _shoals_init_islands(shoals_depth); + _shoals_smooth(); + _shoals_apply_level(); + _shoals_furniture(6); } static void _prepare_swamp() @@ -2755,6 +2656,9 @@ static builder_rc_type _builder_by_branch(int level_number) spotty_level(false, iterations, false); return BUILD_SKIP; } + case BRANCH_SHOALS: + _prepare_shoals(level_number); + return BUILD_SKIP; default: break; -- cgit v1.2.3-54-g00ecf From 14da0d8a05d8f7ca55d05a198733e9abf82208f1 Mon Sep 17 00:00:00 2001 From: Darshan Shaligram Date: Sat, 26 Dec 2009 19:17:44 +0530 Subject: Tweak placement of rune hut on Shoal:$. --- crawl-ref/source/dungeon.cc | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index c7b1f9c88d..88fdbddc67 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -2191,6 +2191,30 @@ static coord_def _pick_shoals_island() return c; } +struct point_sort_distance_from +{ + coord_def bad_place; + point_sort_distance_from(coord_def c) : bad_place(c) { } + bool operator () (coord_def a, coord_def b) const + { + const int dista = (a - bad_place).abs(), distb = (b - bad_place).abs(); + return dista >= distb; + } +}; + +static coord_def _pick_shoals_island_distant_from(coord_def bad_place) +{ + ASSERT(!_shoals_islands.empty()); + + std::sort(_shoals_islands.begin(), _shoals_islands.end(), + point_sort_distance_from(bad_place)); + const int top_picks = std::min(4, int(_shoals_islands.size())); + const int choice = random2(top_picks); + coord_def chosen = _shoals_islands[choice]; + _shoals_islands.erase(_shoals_islands.begin() + choice); + return chosen; +} + static void _shoals_furniture(int margin) { if (at_branch_bottom()) @@ -2201,7 +2225,7 @@ static void _shoals_furniture(int margin) grd(c + coord_def(1, 0)) = DNGN_STONE_STAIRS_UP_II; grd(c - coord_def(1, 0)) = DNGN_STONE_STAIRS_UP_III; - const coord_def p = _pick_shoals_island(); + const coord_def p = _pick_shoals_island_distant_from(c); // Place the rune const map_def *vault = random_map_for_tag("shoal_rune"); _build_secondary_vault(you.your_level, vault, -1, false, true, -- cgit v1.2.3-54-g00ecf From 7024702fd974bd3e993eec789237df0d4d29d1df Mon Sep 17 00:00:00 2001 From: Darshan Shaligram Date: Sat, 26 Dec 2009 19:36:52 +0530 Subject: Adjust number of islands per Shoal level. --- crawl-ref/source/dungeon.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 88fdbddc67..a0100ed3aa 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -2138,7 +2138,7 @@ static void _shoals_build_island() static void _shoals_init_islands(int depth) { - const int nislands = 25 - depth * 3; + const int nislands = 20 - depth * 2; for (int i = 0; i < nislands; ++i) _shoals_build_island(); } -- cgit v1.2.3-54-g00ecf From 61e082e6697779272d5f3503e2751a0ec91283c7 Mon Sep 17 00:00:00 2001 From: Darshan Shaligram Date: Sat, 26 Dec 2009 22:21:09 +0530 Subject: Move Shoals code out into its own file. --- crawl-ref/source/dgn-shoals.cc | 257 ++++++++++++++++++++++++++++ crawl-ref/source/dgn-shoals.h | 6 + crawl-ref/source/dungeon.cc | 370 +++++++---------------------------------- crawl-ref/source/dungeon.h | 12 ++ crawl-ref/source/makefile.obj | 1 + 5 files changed, 337 insertions(+), 309 deletions(-) create mode 100644 crawl-ref/source/dgn-shoals.cc create mode 100644 crawl-ref/source/dgn-shoals.h (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dgn-shoals.cc b/crawl-ref/source/dgn-shoals.cc new file mode 100644 index 0000000000..949812d05f --- /dev/null +++ b/crawl-ref/source/dgn-shoals.cc @@ -0,0 +1,257 @@ +#include "AppHdr.h" + +#include "branch.h" +#include "coord.h" +#include "dungeon.h" +#include "dgn-shoals.h" +#include "env.h" +#include "maps.h" +#include "random.h" + +#include +#include +#include + +static int _shoals_heights[GYM][GXM]; +static std::vector _shoals_islands; + +const int ISLAND_COLLIDE_DIST2 = 5 * 5; +const int N_PERTURB_ISLAND_CENTER = 50; +const int ISLAND_CENTER_RADIUS_LOW = 3; +const int ISLAND_CENTER_RADIUS_HIGH = 10; + +const int N_PERTURB_OFFSET_LOW = 25; +const int N_PERTURB_OFFSET_HIGH = 45; +const int PERTURB_OFFSET_RADIUS_LOW = 2; +const int PERTURB_OFFSET_RADIUS_HIGH = 7; + +const int _shoals_margin = 6; + +static void _shoals_init_heights() +{ + for (int y = 0; y < GYM; ++y) + for (int x = 0; x < GXM; ++x) + _shoals_heights[y][x] = -17; +} + +static coord_def _random_point_from(const coord_def &c, int radius) +{ + while (true) { + const double angle = random2(360) * M_PI / 180; + coord_def res = c + coord_def(radius * cos(angle), radius * sin(angle)); + if (res.x >= _shoals_margin && res.x < GXM - _shoals_margin + && res.y >= _shoals_margin && res.y < GYM - _shoals_margin) + { + return res; + } + } +} + +static coord_def _random_point(int offset = 0) { + return coord_def(random_range(offset, GXM - offset - 1), + random_range(offset, GYM - offset - 1)); +} + +static void _shoals_island_center(const coord_def &c, int n_perturb, int radius, + int bounce_low, int bounce_high) +{ + for (int i = 0; i < n_perturb; ++i) { + coord_def p = _random_point_from(c, random2(1 + radius)); + _shoals_heights[p.y][p.x] += random_range(bounce_low, bounce_high); + } +} + +static coord_def _shoals_pick_island_spot() +{ + coord_def c; + for (int i = 0; i < 15; ++i) + { + c = _random_point(_shoals_margin * 2); + + bool collides = false; + for (int j = 0, size = _shoals_islands.size(); j < size; ++j) + { + const coord_def island = _shoals_islands[j]; + const coord_def dist = island - c; + if (dist.abs() < ISLAND_COLLIDE_DIST2) + { + collides = true; + break; + } + } + if (!collides) + break; + } + _shoals_islands.push_back(c); + return c; +} + +static void _shoals_build_island() +{ + coord_def c = _shoals_pick_island_spot(); + _shoals_island_center(c, N_PERTURB_ISLAND_CENTER, + random_range(ISLAND_CENTER_RADIUS_LOW, + ISLAND_CENTER_RADIUS_HIGH), + 40, 60); + const int additional_heights = random2(4); + for (int i = 0; i < additional_heights; ++i) { + const int addition_offset = random_range(2, 10); + + coord_def offsetC = _random_point_from(c, addition_offset); + + _shoals_island_center(offsetC, random_range(N_PERTURB_OFFSET_LOW, + N_PERTURB_OFFSET_HIGH), + random_range(PERTURB_OFFSET_RADIUS_LOW, + PERTURB_OFFSET_RADIUS_HIGH), + 25, 35); + } +} + +static void _shoals_init_islands(int depth) +{ + const int nislands = 20 - depth * 2; + for (int i = 0; i < nislands; ++i) + _shoals_build_island(); +} + +static void _shoals_smooth_at(const coord_def &c, int radius) +{ + int max_delta = radius * radius * 2 + 2; + int divisor = 0; + int total = 0; + for (int y = c.y - radius; y <= c.y + radius; ++y) { + for (int x = c.x - radius; x <= c.x + radius; ++x) { + const coord_def p(x, y); + if (!in_bounds(p)) + continue; + const coord_def off = c - p; + int weight = max_delta - off.abs(); + divisor += weight; + total += _shoals_heights[p.y][p.x] * weight; + } + } + _shoals_heights[c.y][c.x] = total / divisor; +} + +static void _shoals_smooth() +{ + for (int y = 0; y < GYM; ++y) + for (int x = 0; x < GXM; ++x) + _shoals_smooth_at(coord_def(x, y), 1); +} + +static dungeon_feature_type _shoals_feature_at(int x, int y) +{ + const int height = _shoals_heights[y][x]; + return height >= 0? DNGN_FLOOR : + height >= -14? DNGN_SHALLOW_WATER : DNGN_DEEP_WATER; +} + +static void _shoals_apply_level() +{ + for (int y = 1; y < GYM - 1; ++y) + for (int x = 1; x < GXM - 1; ++x) + grd[x][y] = _shoals_feature_at(x, y); +} + +static coord_def _pick_shoals_island() +{ + const int lucky_island = random2(_shoals_islands.size()); + const coord_def c = _shoals_islands[lucky_island]; + _shoals_islands.erase(_shoals_islands.begin() + lucky_island); + return c; +} + +struct point_sort_distance_from +{ + coord_def bad_place; + point_sort_distance_from(coord_def c) : bad_place(c) { } + bool operator () (coord_def a, coord_def b) const + { + const int dista = (a - bad_place).abs(), distb = (b - bad_place).abs(); + return dista >= distb; + } +}; + +static coord_def _pick_shoals_island_distant_from(coord_def bad_place) +{ + ASSERT(!_shoals_islands.empty()); + + std::sort(_shoals_islands.begin(), _shoals_islands.end(), + point_sort_distance_from(bad_place)); + const int top_picks = std::min(4, int(_shoals_islands.size())); + const int choice = random2(top_picks); + coord_def chosen = _shoals_islands[choice]; + _shoals_islands.erase(_shoals_islands.begin() + choice); + return chosen; +} + +static void _shoals_furniture(int margin) +{ + if (at_branch_bottom()) + { + const coord_def c = _pick_shoals_island(); + // Put all the stairs on one island. + grd(c) = DNGN_STONE_STAIRS_UP_I; + grd(c + coord_def(1, 0)) = DNGN_STONE_STAIRS_UP_II; + grd(c - coord_def(1, 0)) = DNGN_STONE_STAIRS_UP_III; + + const coord_def p = _pick_shoals_island_distant_from(c); + // Place the rune + const map_def *vault = random_map_for_tag("shoal_rune"); + dgn_place_map(vault, false, true, p); + + const int nhuts = std::min(8, int(_shoals_islands.size())); + for (int i = 2; i < nhuts; ++i) + { + // Place (non-rune) minivaults on the other islands + do + vault = random_map_for_tag("shoal"); + while (!vault); + dgn_place_map(vault, false, true, _pick_shoals_island()); + } + } + else + { + // Place stairs randomly. No elevators. + for (int i = 0; i < 3; ++i) + { + int x, y; + do + { + x = margin + random2(GXM - 2*margin); + y = margin + random2(GYM - 2*margin); + } + while (grd[x][y] != DNGN_FLOOR); + + grd[x][y] + = static_cast(DNGN_STONE_STAIRS_DOWN_I + i); + + do + { + x = margin + random2(GXM - 2*margin); + y = margin + random2(GYM - 2*margin); + } + while (grd[x][y] != DNGN_FLOOR); + + grd[x][y] + = static_cast(DNGN_STONE_STAIRS_UP_I + i); + } + } + +} + +void prepare_shoals(int level_number) +{ + dgn_Build_Method += make_stringf(" shoals+ [%d]", level_number); + dgn_Layout_Type = "shoals"; + + const int shoals_depth = level_id::current().depth - 1; + dgn_replace_area(0, 0, GXM-1, GYM-1, DNGN_ROCK_WALL, DNGN_OPEN_SEA); + _shoals_init_heights(); + _shoals_islands.clear(); + _shoals_init_islands(shoals_depth); + _shoals_smooth(); + _shoals_apply_level(); + _shoals_furniture(6); +} diff --git a/crawl-ref/source/dgn-shoals.h b/crawl-ref/source/dgn-shoals.h new file mode 100644 index 0000000000..023f321fe6 --- /dev/null +++ b/crawl-ref/source/dgn-shoals.h @@ -0,0 +1,6 @@ +#ifndef DGN_SHOALS_H +#define DGN_SHOALS_H + +void prepare_shoals(int level_number); + +#endif diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index a0100ed3aa..3d1102b31d 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -13,7 +13,6 @@ #include #include #include -#include #include "abyss.h" #include "artefact.h" @@ -24,6 +23,7 @@ #include "coord.h" #include "coordit.h" #include "defines.h" +#include "dgn-shoals.h" #include "effects.h" #include "env.h" #include "enum.h" @@ -113,18 +113,6 @@ static bool _make_box(int room_x1, int room_y1, int room_x2, int room_y2, dungeon_feature_type floor=DNGN_UNSEEN, dungeon_feature_type wall=DNGN_UNSEEN, dungeon_feature_type avoid=DNGN_UNSEEN); -static void _replace_area(const coord_def& p1, const coord_def& p2, - dungeon_feature_type replace, - dungeon_feature_type feature, - unsigned mmask = 0, bool needs_update = false); -static void _replace_area(int sx, int sy, int ex, int ey, - dungeon_feature_type replace, - dungeon_feature_type feature, - unsigned mmask = 0, bool needs_update = false) -{ - _replace_area( coord_def(sx, sy), coord_def(ex, ey), - replace, feature, mmask, needs_update ); -} static builder_rc_type _builder_by_type(int level_number, char level_type); static builder_rc_type _builder_by_branch(int level_number); @@ -146,7 +134,6 @@ static int _place_uniques(int level_number, char level_type); static void _place_traps( int level_number ); static void _place_fog_machines( int level_number ); static void _prepare_swamp(); -static void _prepare_shoals( int level_number ); static void _prepare_water( int level_number ); static void _check_doors(); static void _hide_doors(); @@ -1172,8 +1159,8 @@ static void _fixup_walls() else if (player_in_branch(BRANCH_CRYPT)) vault_wall = DNGN_STONE_WALL; - _replace_area(0, 0, GXM-1, GYM-1, DNGN_ROCK_WALL, vault_wall, - MMT_NO_WALL); + dgn_replace_area(0, 0, GXM-1, GYM-1, DNGN_ROCK_WALL, vault_wall, + MMT_NO_WALL); } } @@ -1808,9 +1795,10 @@ static void _build_dungeon_level(int level_number, int level_type) _hide_doors(); // Change pre-rock to rock, and pre-floor to floor. - _replace_area(0, 0, GXM-1, GYM-1, DNGN_BUILDER_SPECIAL_WALL, - DNGN_ROCK_WALL); - _replace_area(0, 0, GXM-1, GYM-1, DNGN_BUILDER_SPECIAL_FLOOR, DNGN_FLOOR); + dgn_replace_area(0, 0, GXM-1, GYM-1, DNGN_BUILDER_SPECIAL_WALL, + DNGN_ROCK_WALL); + dgn_replace_area(0, 0, GXM-1, GYM-1, DNGN_BUILDER_SPECIAL_FLOOR, + DNGN_FLOOR); const unsigned nvaults = Level_Vaults.size(); @@ -2041,253 +2029,6 @@ static void _connected_flood(int margin, int i, int j, bool taken[GXM][GYM]) _connected_flood(margin, i + idelta, j + jdelta, taken); } -static int _shoals_heights[GYM][GXM]; -static std::vector _shoals_islands; - -const int ISLAND_COLLIDE_DIST2 = 5 * 5; -const int N_PERTURB_ISLAND_CENTER = 50; -const int ISLAND_CENTER_RADIUS_LOW = 3; -const int ISLAND_CENTER_RADIUS_HIGH = 10; - -const int N_PERTURB_OFFSET_LOW = 25; -const int N_PERTURB_OFFSET_HIGH = 45; -const int PERTURB_OFFSET_RADIUS_LOW = 2; -const int PERTURB_OFFSET_RADIUS_HIGH = 7; - -const int _shoals_margin = 6; - -static void _shoals_init_heights() -{ - for (int y = 0; y < GYM; ++y) - for (int x = 0; x < GXM; ++x) - _shoals_heights[y][x] = -17; -} - -static coord_def _random_point_from(const coord_def &c, int radius) -{ - while (true) { - const double angle = random2(360) * M_PI / 180; - coord_def res = c + coord_def(radius * cos(angle), radius * sin(angle)); - if (res.x >= _shoals_margin && res.x < GXM - _shoals_margin - && res.y >= _shoals_margin && res.y < GYM - _shoals_margin) - { - return res; - } - } -} - -static coord_def _random_point(int offset = 0) { - return coord_def(random_range(offset, GXM - offset - 1), - random_range(offset, GYM - offset - 1)); -} - -static void _shoals_island_center(const coord_def &c, int n_perturb, int radius, - int bounce_low, int bounce_high) -{ - for (int i = 0; i < n_perturb; ++i) { - coord_def p = _random_point_from(c, random2(1 + radius)); - _shoals_heights[p.y][p.x] += random_range(bounce_low, bounce_high); - } -} - -static coord_def _shoals_pick_island_spot() -{ - coord_def c; - for (int i = 0; i < 15; ++i) - { - c = _random_point(_shoals_margin * 2); - - bool collides = false; - for (int j = 0, size = _shoals_islands.size(); j < size; ++j) - { - const coord_def island = _shoals_islands[j]; - const coord_def dist = island - c; - if (dist.abs() < ISLAND_COLLIDE_DIST2) - { - collides = true; - break; - } - } - if (!collides) - break; - } - _shoals_islands.push_back(c); - return c; -} - -static void _shoals_build_island() -{ - coord_def c = _shoals_pick_island_spot(); - _shoals_island_center(c, N_PERTURB_ISLAND_CENTER, - random_range(ISLAND_CENTER_RADIUS_LOW, - ISLAND_CENTER_RADIUS_HIGH), - 40, 60); - const int additional_heights = random2(4); - for (int i = 0; i < additional_heights; ++i) { - const int addition_offset = random_range(2, 10); - - coord_def offsetC = _random_point_from(c, addition_offset); - - _shoals_island_center(offsetC, random_range(N_PERTURB_OFFSET_LOW, - N_PERTURB_OFFSET_HIGH), - random_range(PERTURB_OFFSET_RADIUS_LOW, - PERTURB_OFFSET_RADIUS_HIGH), - 25, 35); - } -} - -static void _shoals_init_islands(int depth) -{ - const int nislands = 20 - depth * 2; - for (int i = 0; i < nislands; ++i) - _shoals_build_island(); -} - -static void _shoals_smooth_at(const coord_def &c, int radius) -{ - int max_delta = radius * radius * 2 + 2; - int divisor = 0; - int total = 0; - for (int y = c.y - radius; y <= c.y + radius; ++y) { - for (int x = c.x - radius; x <= c.x + radius; ++x) { - const coord_def p(x, y); - if (!in_bounds(p)) - continue; - const coord_def off = c - p; - int weight = max_delta - off.abs(); - divisor += weight; - total += _shoals_heights[p.y][p.x] * weight; - } - } - _shoals_heights[c.y][c.x] = total / divisor; -} - -static void _shoals_smooth() -{ - for (int y = 0; y < GYM; ++y) - for (int x = 0; x < GXM; ++x) - _shoals_smooth_at(coord_def(x, y), 1); -} - -static dungeon_feature_type _shoals_feature_at(int x, int y) -{ - const int height = _shoals_heights[y][x]; - return height >= 0? DNGN_FLOOR : - height >= -14? DNGN_SHALLOW_WATER : DNGN_DEEP_WATER; -} - -static void _shoals_apply_level() -{ - for (int y = 1; y < GYM - 1; ++y) - for (int x = 1; x < GXM - 1; ++x) - grd[x][y] = _shoals_feature_at(x, y); -} - -static coord_def _pick_shoals_island() -{ - const int lucky_island = random2(_shoals_islands.size()); - const coord_def c = _shoals_islands[lucky_island]; - _shoals_islands.erase(_shoals_islands.begin() + lucky_island); - return c; -} - -struct point_sort_distance_from -{ - coord_def bad_place; - point_sort_distance_from(coord_def c) : bad_place(c) { } - bool operator () (coord_def a, coord_def b) const - { - const int dista = (a - bad_place).abs(), distb = (b - bad_place).abs(); - return dista >= distb; - } -}; - -static coord_def _pick_shoals_island_distant_from(coord_def bad_place) -{ - ASSERT(!_shoals_islands.empty()); - - std::sort(_shoals_islands.begin(), _shoals_islands.end(), - point_sort_distance_from(bad_place)); - const int top_picks = std::min(4, int(_shoals_islands.size())); - const int choice = random2(top_picks); - coord_def chosen = _shoals_islands[choice]; - _shoals_islands.erase(_shoals_islands.begin() + choice); - return chosen; -} - -static void _shoals_furniture(int margin) -{ - if (at_branch_bottom()) - { - const coord_def c = _pick_shoals_island(); - // Put all the stairs on one island. - grd(c) = DNGN_STONE_STAIRS_UP_I; - grd(c + coord_def(1, 0)) = DNGN_STONE_STAIRS_UP_II; - grd(c - coord_def(1, 0)) = DNGN_STONE_STAIRS_UP_III; - - const coord_def p = _pick_shoals_island_distant_from(c); - // Place the rune - const map_def *vault = random_map_for_tag("shoal_rune"); - _build_secondary_vault(you.your_level, vault, -1, false, true, - p); - - const int nhuts = std::min(8, int(_shoals_islands.size())); - for (int i = 2; i < nhuts; ++i) - { - // Place (non-rune) minivaults on the other islands - do - vault = random_map_for_tag("shoal"); - while (!vault); - - _build_secondary_vault(you.your_level, vault, -1, false, true, - _pick_shoals_island()); - } - } - else - { - // Place stairs randomly. No elevators. - for (int i = 0; i < 3; ++i) - { - int x, y; - do - { - x = margin + random2(GXM - 2*margin); - y = margin + random2(GYM - 2*margin); - } - while (grd[x][y] != DNGN_FLOOR); - - grd[x][y] - = static_cast(DNGN_STONE_STAIRS_DOWN_I + i); - - do - { - x = margin + random2(GXM - 2*margin); - y = margin + random2(GYM - 2*margin); - } - while (grd[x][y] != DNGN_FLOOR); - - grd[x][y] - = static_cast(DNGN_STONE_STAIRS_UP_I + i); - } - } - -} - -static void _prepare_shoals(int level_number) -{ - dgn_Build_Method += make_stringf(" shoals+ [%d]", level_number); - dgn_Layout_Type = "shoals"; - - const int shoals_depth = level_id::current().depth - 1; - _replace_area(0, 0, GXM-1, GYM-1, DNGN_ROCK_WALL, DNGN_OPEN_SEA); - _shoals_init_heights(); - _shoals_islands.clear(); - _shoals_init_islands(shoals_depth); - _shoals_smooth(); - _shoals_apply_level(); - _shoals_furniture(6); -} - static void _prepare_swamp() { dgn_Build_Method += " swamp"; @@ -2556,7 +2297,8 @@ static void _portal_vault_level(int level_number) { // XXX: This is pretty hackish, I confess. if (vault->border_fill_type != DNGN_ROCK_WALL) - _replace_area(0, 0, GXM-1, GYM-1, DNGN_ROCK_WALL, vault->border_fill_type); + dgn_replace_area(0, 0, GXM-1, GYM-1, DNGN_ROCK_WALL, + vault->border_fill_type); _ensure_vault_placed( _build_vaults(level_number, vault), true ); } @@ -2681,7 +2423,7 @@ static builder_rc_type _builder_by_branch(int level_number) return BUILD_SKIP; } case BRANCH_SHOALS: - _prepare_shoals(level_number); + prepare_shoals(level_number); return BUILD_SKIP; default: @@ -3984,8 +3726,8 @@ static void _build_rooms(const dgn_region_list &excluded, } const coord_def end = myroom.end(); - _replace_area(myroom.pos.x, myroom.pos.y, end.x, end.y, - DNGN_ROCK_WALL, DNGN_FLOOR); + dgn_replace_area(myroom.pos.x, myroom.pos.y, end.x, end.y, + DNGN_ROCK_WALL, DNGN_FLOOR); if (which_room > 0) { @@ -5302,10 +5044,19 @@ bool seen_replace_feat(dungeon_feature_type old_feat, return (seen); } -static void _replace_area( const coord_def& p1, const coord_def& p2, - dungeon_feature_type replace, - dungeon_feature_type feature, unsigned mapmask, - bool needs_update) +void dgn_replace_area(int sx, int sy, int ex, int ey, + dungeon_feature_type replace, + dungeon_feature_type feature, + unsigned mmask, bool needs_update) +{ + dgn_replace_area( coord_def(sx, sy), coord_def(ex, ey), + replace, feature, mmask, needs_update ); +} + +void dgn_replace_area( const coord_def& p1, const coord_def& p2, + dungeon_feature_type replace, + dungeon_feature_type feature, unsigned mapmask, + bool needs_update) { for (rectangle_iterator ri(p1, p2); ri; ++ri) { @@ -6211,7 +5962,7 @@ static void _plan_main(int level_number, int force_plan) } if (one_chance_in(20)) - _replace_area(0, 0, GXM-1, GYM-1, DNGN_ROCK_WALL, special_grid); + dgn_replace_area(0, 0, GXM-1, GYM-1, DNGN_ROCK_WALL, special_grid); } static bool _plan_1(int level_number) @@ -6292,7 +6043,8 @@ static bool _plan_4(char forbid_x1, char forbid_y1, char forbid_x2, : DNGN_METAL_WALL); // odds: 3 in 18 {dlb} } - _replace_area(10, 10, (GXM - 10), (GYM - 10), DNGN_ROCK_WALL, DNGN_FLOOR); + dgn_replace_area(10, 10, (GXM - 10), (GYM - 10), DNGN_ROCK_WALL, + DNGN_FLOOR); // replace_area can also be used to fill in: for (i = 0; i < number_boxes; i++) @@ -6338,7 +6090,7 @@ static bool _plan_4(char forbid_x1, char forbid_y1, char forbid_x2, temp_rand = random2(210); if (temp_rand > 71) // odds: 138 in 210 {dlb} - _replace_area(b1x, b1y, b2x, b2y, DNGN_FLOOR, drawing); + dgn_replace_area(b1x, b1y, b2x, b2y, DNGN_FLOOR, drawing); else // odds: 72 in 210 {dlb} _box_room(b1x, b2x - 1, b1y, b2y - 1, drawing); } @@ -7151,12 +6903,12 @@ static void _box_room(int bx1, int bx2, int by1, int by2, int temp_rand, new_doors, doors_placed; // Do top & bottom walls. - _replace_area(bx1, by1, bx2, by1, DNGN_FLOOR, wall_type); - _replace_area(bx1, by2, bx2, by2, DNGN_FLOOR, wall_type); + dgn_replace_area(bx1, by1, bx2, by1, DNGN_FLOOR, wall_type); + dgn_replace_area(bx1, by2, bx2, by2, DNGN_FLOOR, wall_type); // Do left & right walls. - _replace_area(bx1, by1+1, bx1, by2-1, DNGN_FLOOR, wall_type); - _replace_area(bx2, by1+1, bx2, by2-1, DNGN_FLOOR, wall_type); + dgn_replace_area(bx1, by1+1, bx1, by2-1, DNGN_FLOOR, wall_type); + dgn_replace_area(bx2, by1+1, bx2, by2-1, DNGN_FLOOR, wall_type); // Sometimes we have to place doors, or else we shut in other // buildings' doors. @@ -7394,8 +7146,8 @@ static void _big_room(int level_number) } // Make the big room. - _replace_area(sr.tl, sr.br, DNGN_ROCK_WALL, type_floor); - _replace_area(sr.tl, sr.br, DNGN_CLOSED_DOOR, type_floor); + dgn_replace_area(sr.tl, sr.br, DNGN_ROCK_WALL, type_floor); + dgn_replace_area(sr.tl, sr.br, DNGN_CLOSED_DOOR, type_floor); if (type_floor == DNGN_FLOOR) { @@ -7493,8 +7245,8 @@ static void _roguey_level(int level_number, spec_room &sr, bool make_stairs) for (i = 0; i < 25; i++) { - _replace_area( rox1[i], roy1[i], rox2[i], roy2[i], - DNGN_ROCK_WALL, DNGN_FLOOR ); + dgn_replace_area( rox1[i], roy1[i], rox2[i], roy2[i], + DNGN_ROCK_WALL, DNGN_FLOOR ); // Inner room? if (rox2[i] - rox1[i] > 5 && roy2[i] - roy1[i] > 5 @@ -7612,36 +7364,36 @@ static void _roguey_level(int level_number, spec_room &sr, bool make_stairs) // by something else (or put monsters in walls, etc...) // top - _replace_area(sr.tl.x-1, sr.tl.y-1, sr.br.x+1,sr.tl.y-1, - DNGN_ROCK_WALL, DNGN_BUILDER_SPECIAL_WALL); - _replace_area(sr.tl.x-1, sr.tl.y-1, sr.br.x+1,sr.tl.y-1, - DNGN_FLOOR, DNGN_BUILDER_SPECIAL_FLOOR); - _replace_area(sr.tl.x-1, sr.tl.y-1, sr.br.x+1,sr.tl.y-1, - DNGN_CLOSED_DOOR, DNGN_BUILDER_SPECIAL_FLOOR); + dgn_replace_area(sr.tl.x-1, sr.tl.y-1, sr.br.x+1,sr.tl.y-1, + DNGN_ROCK_WALL, DNGN_BUILDER_SPECIAL_WALL); + dgn_replace_area(sr.tl.x-1, sr.tl.y-1, sr.br.x+1,sr.tl.y-1, + DNGN_FLOOR, DNGN_BUILDER_SPECIAL_FLOOR); + dgn_replace_area(sr.tl.x-1, sr.tl.y-1, sr.br.x+1,sr.tl.y-1, + DNGN_CLOSED_DOOR, DNGN_BUILDER_SPECIAL_FLOOR); // bottom - _replace_area(sr.tl.x-1, sr.br.y+1, sr.br.x+1,sr.br.y+1, - DNGN_ROCK_WALL, DNGN_BUILDER_SPECIAL_WALL); - _replace_area(sr.tl.x-1, sr.br.y+1, sr.br.x+1,sr.br.y+1, - DNGN_FLOOR, DNGN_BUILDER_SPECIAL_FLOOR); - _replace_area(sr.tl.x-1, sr.br.y+1, sr.br.x+1,sr.br.y+1, - DNGN_CLOSED_DOOR, DNGN_BUILDER_SPECIAL_FLOOR); + dgn_replace_area(sr.tl.x-1, sr.br.y+1, sr.br.x+1,sr.br.y+1, + DNGN_ROCK_WALL, DNGN_BUILDER_SPECIAL_WALL); + dgn_replace_area(sr.tl.x-1, sr.br.y+1, sr.br.x+1,sr.br.y+1, + DNGN_FLOOR, DNGN_BUILDER_SPECIAL_FLOOR); + dgn_replace_area(sr.tl.x-1, sr.br.y+1, sr.br.x+1,sr.br.y+1, + DNGN_CLOSED_DOOR, DNGN_BUILDER_SPECIAL_FLOOR); // left - _replace_area(sr.tl.x-1, sr.tl.y-1, sr.tl.x-1, sr.br.y+1, - DNGN_ROCK_WALL, DNGN_BUILDER_SPECIAL_WALL); - _replace_area(sr.tl.x-1, sr.tl.y-1, sr.tl.x-1, sr.br.y+1, - DNGN_FLOOR, DNGN_BUILDER_SPECIAL_FLOOR); - _replace_area(sr.tl.x-1, sr.tl.y-1, sr.tl.x-1, sr.br.y+1, - DNGN_CLOSED_DOOR, DNGN_BUILDER_SPECIAL_FLOOR); + dgn_replace_area(sr.tl.x-1, sr.tl.y-1, sr.tl.x-1, sr.br.y+1, + DNGN_ROCK_WALL, DNGN_BUILDER_SPECIAL_WALL); + dgn_replace_area(sr.tl.x-1, sr.tl.y-1, sr.tl.x-1, sr.br.y+1, + DNGN_FLOOR, DNGN_BUILDER_SPECIAL_FLOOR); + dgn_replace_area(sr.tl.x-1, sr.tl.y-1, sr.tl.x-1, sr.br.y+1, + DNGN_CLOSED_DOOR, DNGN_BUILDER_SPECIAL_FLOOR); // right - _replace_area(sr.br.x+1, sr.tl.y-1, sr.br.x+1, sr.br.y+1, - DNGN_ROCK_WALL, DNGN_BUILDER_SPECIAL_WALL); - _replace_area(sr.br.x+1, sr.tl.y-1, sr.br.x+1, sr.br.y+1, - DNGN_FLOOR, DNGN_BUILDER_SPECIAL_FLOOR); - _replace_area(sr.br.x+1, sr.tl.y-1, sr.br.x+1, sr.br.y+1, - DNGN_CLOSED_DOOR, DNGN_BUILDER_SPECIAL_FLOOR); + dgn_replace_area(sr.br.x+1, sr.tl.y-1, sr.br.x+1, sr.br.y+1, + DNGN_ROCK_WALL, DNGN_BUILDER_SPECIAL_WALL); + dgn_replace_area(sr.br.x+1, sr.tl.y-1, sr.br.x+1, sr.br.y+1, + DNGN_FLOOR, DNGN_BUILDER_SPECIAL_FLOOR); + dgn_replace_area(sr.br.x+1, sr.tl.y-1, sr.br.x+1, sr.br.y+1, + DNGN_CLOSED_DOOR, DNGN_BUILDER_SPECIAL_FLOOR); } if (!make_stairs) diff --git a/crawl-ref/source/dungeon.h b/crawl-ref/source/dungeon.h index 590a91b897..bc140c3f2e 100644 --- a/crawl-ref/source/dungeon.h +++ b/crawl-ref/source/dungeon.h @@ -163,6 +163,7 @@ public: extern bool Generating_Level; extern std::string dgn_Layout_Type; +extern std::string dgn_Build_Method; extern std::set Level_Unique_Maps; extern std::set Level_Unique_Tags; @@ -187,6 +188,7 @@ void dgn_set_grid_colour_at(const coord_def &c, int colour); bool dgn_place_map(const map_def *map, bool clobber, bool make_no_exits, const coord_def &pos = coord_def(-1, -1)); + void level_clear_vault_memory(); void level_welcome_messages(); @@ -256,6 +258,16 @@ bool octa_room(spec_room &sr, int oblique_max, int count_feature_in_box(int x0, int y0, int x1, int y1, dungeon_feature_type feat); + +void dgn_replace_area(const coord_def& p1, const coord_def& p2, + dungeon_feature_type replace, + dungeon_feature_type feature, + unsigned mmask = 0, bool needs_update = false); +void dgn_replace_area(int sx, int sy, int ex, int ey, + dungeon_feature_type replace, + dungeon_feature_type feature, + unsigned mmask = 0, bool needs_update = false); + inline int count_feature_in_box( const coord_def& p1, const coord_def& p2, dungeon_feature_type feat ) { diff --git a/crawl-ref/source/makefile.obj b/crawl-ref/source/makefile.obj index 8761eb11e7..926b9d5e50 100644 --- a/crawl-ref/source/makefile.obj +++ b/crawl-ref/source/makefile.obj @@ -34,6 +34,7 @@ dgnevent.o \ directn.o \ dlua.o \ dungeon.o \ +dgn-shoals.o \ effects.o \ exclude.o \ feature.o \ -- cgit v1.2.3-54-g00ecf From 0195242aa2ca905ad68c99368a06d8100b2a2fa2 Mon Sep 17 00:00:00 2001 From: Darshan Shaligram Date: Sat, 26 Dec 2009 22:46:16 +0530 Subject: Add rock outcrops at the highest points of the Shoal islands. Also fix Shoal:$ having no rune. --- crawl-ref/source/dgn-shoals.cc | 4 +++- crawl-ref/source/dungeon.cc | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dgn-shoals.cc b/crawl-ref/source/dgn-shoals.cc index 949812d05f..170a004b59 100644 --- a/crawl-ref/source/dgn-shoals.cc +++ b/crawl-ref/source/dgn-shoals.cc @@ -143,7 +143,9 @@ static void _shoals_smooth() static dungeon_feature_type _shoals_feature_at(int x, int y) { const int height = _shoals_heights[y][x]; - return height >= 0? DNGN_FLOOR : + return height >= 230 ? DNGN_STONE_WALL : + height >= 170? DNGN_ROCK_WALL : + height >= 0? DNGN_FLOOR : height >= -14? DNGN_SHALLOW_WATER : DNGN_DEEP_WATER; } diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 3d1102b31d..53658c2a58 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -4091,7 +4091,7 @@ bool dgn_place_map(const map_def *mdef, bool clobber, bool make_no_exits, } } - dungeon_feature_type rune_subst = DNGN_FLOOR; + int rune_subst = -1; if (mdef->has_tag_suffix("_entry")) rune_subst = _dgn_find_rune_subst_tags(mdef->tags); did_map = _build_secondary_vault(you.your_level, mdef, rune_subst, -- cgit v1.2.3-54-g00ecf From 1622664e84adc8657645329ec66ebb738bdfa8d6 Mon Sep 17 00:00:00 2001 From: Darshan Shaligram Date: Sat, 26 Dec 2009 23:45:21 +0530 Subject: Add the occasional cliff in the shoals. --- crawl-ref/source/dgn-shoals.cc | 95 +++++++++++++++++++++++++++++++++--------- 1 file changed, 76 insertions(+), 19 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dgn-shoals.cc b/crawl-ref/source/dgn-shoals.cc index 170a004b59..c4cdf30cca 100644 --- a/crawl-ref/source/dgn-shoals.cc +++ b/crawl-ref/source/dgn-shoals.cc @@ -2,6 +2,7 @@ #include "branch.h" #include "coord.h" +#include "coordit.h" #include "dungeon.h" #include "dgn-shoals.h" #include "env.h" @@ -27,6 +28,29 @@ const int PERTURB_OFFSET_RADIUS_HIGH = 7; const int _shoals_margin = 6; +enum shoals_height_thresholds +{ + SHT_STONE = 230, + SHT_ROCK = 170, + SHT_FLOOR = 0, + SHT_SHALLOW_WATER = -14 +}; + +static double _to_radians(int degrees) +{ + return degrees * M_PI / 180; +} + +static dungeon_feature_type _shoals_feature_at(const coord_def &c) +{ + const int height = _shoals_heights[c.y][c.x]; + return height >= SHT_STONE ? DNGN_STONE_WALL : + height >= SHT_ROCK? DNGN_ROCK_WALL : + height >= SHT_FLOOR? DNGN_FLOOR : + height >= SHT_SHALLOW_WATER? DNGN_SHALLOW_WATER + : DNGN_DEEP_WATER; +} + static void _shoals_init_heights() { for (int y = 0; y < GYM; ++y) @@ -34,11 +58,24 @@ static void _shoals_init_heights() _shoals_heights[y][x] = -17; } -static coord_def _random_point_from(const coord_def &c, int radius) +static double _angle_fuzz() { + double fuzz = _to_radians(random2(15)); + return coinflip()? fuzz : -fuzz; +} + +static coord_def _random_point_from(const coord_def &c, int radius, + int directed_angle = -1) +{ + const double directed_radians( + directed_angle == -1? 0.0 : _to_radians(directed_angle)); while (true) { - const double angle = random2(360) * M_PI / 180; - coord_def res = c + coord_def(radius * cos(angle), radius * sin(angle)); + const double angle = + directed_angle == -1? _to_radians(random2(360)) + : ((coinflip()? directed_radians : -directed_radians) + + _angle_fuzz()); + coord_def res = c + coord_def(radius * cos(angle), + radius * sin(angle)); if (res.x >= _shoals_margin && res.x < GXM - _shoals_margin && res.y >= _shoals_margin && res.y < GYM - _shoals_margin) { @@ -114,6 +151,36 @@ static void _shoals_init_islands(int depth) _shoals_build_island(); } +// Cliffs are usually constructed in shallow water adjacent to deep +// water (for effect). +static void _shoals_build_cliff() +{ + coord_def cliffc = _random_point(_shoals_margin * 2); + if (in_bounds(cliffc)) + { + const int length = random_range(6, 15); + double angle = _to_radians(random2(360)); + for (int i = 0; i < length; i += 3) + { + int distance = i - length / 2; + coord_def place = cliffc + coord_def(distance * cos(angle), + distance * sin(angle)); + coord_def fuzz = coord_def(random_range(-2, 2), + random_range(-2, 2)); + place += fuzz; + _shoals_island_center(place, random_range(40, 60), 3, + 100, 130); + } + } +} + +static void _shoals_cliffs() +{ + const int ncliffs = random_range(0, 6, 2); + for (int i = 0; i < ncliffs; ++i) + _shoals_build_cliff(); +} + static void _shoals_smooth_at(const coord_def &c, int radius) { int max_delta = radius * radius * 2 + 2; @@ -135,25 +202,14 @@ static void _shoals_smooth_at(const coord_def &c, int radius) static void _shoals_smooth() { - for (int y = 0; y < GYM; ++y) - for (int x = 0; x < GXM; ++x) - _shoals_smooth_at(coord_def(x, y), 1); -} - -static dungeon_feature_type _shoals_feature_at(int x, int y) -{ - const int height = _shoals_heights[y][x]; - return height >= 230 ? DNGN_STONE_WALL : - height >= 170? DNGN_ROCK_WALL : - height >= 0? DNGN_FLOOR : - height >= -14? DNGN_SHALLOW_WATER : DNGN_DEEP_WATER; + for (rectangle_iterator ri(0); ri; ++ri) + _shoals_smooth_at(*ri, 1); } static void _shoals_apply_level() { - for (int y = 1; y < GYM - 1; ++y) - for (int x = 1; x < GXM - 1; ++x) - grd[x][y] = _shoals_feature_at(x, y); + for (rectangle_iterator ri(1); ri; ++ri) + grd(*ri) = _shoals_feature_at(*ri); } static coord_def _pick_shoals_island() @@ -253,7 +309,8 @@ void prepare_shoals(int level_number) _shoals_init_heights(); _shoals_islands.clear(); _shoals_init_islands(shoals_depth); + _shoals_cliffs(); _shoals_smooth(); _shoals_apply_level(); - _shoals_furniture(6); + _shoals_furniture(_shoals_margin); } -- cgit v1.2.3-54-g00ecf From ec717839b67f5acc52044fca7820df71680f5ff6 Mon Sep 17 00:00:00 2001 From: Darshan Shaligram Date: Sun, 27 Dec 2009 02:46:16 +0530 Subject: Remove floor at corners of shoal huts. --- crawl-ref/source/dat/shoals.des | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dat/shoals.des b/crawl-ref/source/dat/shoals.des index 4983347ecd..2b52eb6ade 100644 --- a/crawl-ref/source/dat/shoals.des +++ b/crawl-ref/source/dat/shoals.des @@ -243,13 +243,13 @@ SHUFFLE: ABCD SUBST: A:x, B:x, C:x=, D=+ LROCKTILE: wall_vines MAP -.xxCxx. + xxCxx xx...xx x.....x B..O..D x.....x xx...xx -.xxAxx + xxAxx ENDMAP ################################################################################ @@ -262,11 +262,11 @@ TAGS: allow_dup water_ok shoal no_dump SHUFFLE: ABCD SUBST: A:x, B:x, C:x=, D=+ MAP -.xxCxx. + xxCxx xx...xx x.....x B..|..D x.....x xx...xx -.xxAxx + xxAxx ENDMAP -- cgit v1.2.3-54-g00ecf From e19066eb4995805ccfdfc3c9f2c5ca0890e2c41e Mon Sep 17 00:00:00 2001 From: Jude Brown Date: Sun, 27 Dec 2009 18:44:35 +1000 Subject: Add a tile for human slaves (purge). --- crawl-ref/source/rltiles/dc-mon.txt | 1 + crawl-ref/source/rltiles/dc-mon/slave.png | Bin 0 -> 3395 bytes crawl-ref/source/tilepick.cc | 2 ++ 3 files changed, 3 insertions(+) create mode 100644 crawl-ref/source/rltiles/dc-mon/slave.png (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/rltiles/dc-mon.txt b/crawl-ref/source/rltiles/dc-mon.txt index a01f00d479..3a48f1307d 100644 --- a/crawl-ref/source/rltiles/dc-mon.txt +++ b/crawl-ref/source/rltiles/dc-mon.txt @@ -335,6 +335,7 @@ vault_guard MONS_VAULT_GUARD shapeshifter MONS_SHAPESHIFTER glowing_shapeshifter MONS_GLOWING_SHAPESHIFTER killer_klown MONS_KILLER_KLOWN +slave MONS_SLAVE ## Angels ('A') angel MONS_ANGEL diff --git a/crawl-ref/source/rltiles/dc-mon/slave.png b/crawl-ref/source/rltiles/dc-mon/slave.png new file mode 100644 index 0000000000..0f7e353e5c Binary files /dev/null and b/crawl-ref/source/rltiles/dc-mon/slave.png differ diff --git a/crawl-ref/source/tilepick.cc b/crawl-ref/source/tilepick.cc index 725947c13c..36b3e5014c 100644 --- a/crawl-ref/source/tilepick.cc +++ b/crawl-ref/source/tilepick.cc @@ -764,6 +764,8 @@ int tileidx_monster_base(const monsters *mon, bool detected) return TILEP_MONS_GLOWING_SHAPESHIFTER; case MONS_KILLER_KLOWN: return TILEP_MONS_KILLER_KLOWN; + case MONS_SLAVE: + return TILEP_MONS_SLAVE; // mimics case MONS_GOLD_MIMIC: -- cgit v1.2.3-54-g00ecf From 5684de7409e72c5ded581455409981cc5786a662 Mon Sep 17 00:00:00 2001 From: Darshan Shaligram Date: Sun, 27 Dec 2009 15:22:34 +0530 Subject: Save Shoals heightmap in level tag, increment tag minor version. --- crawl-ref/source/dgn-shoals.cc | 20 ++++++++++++-------- crawl-ref/source/directn.cc | 9 +++++++-- crawl-ref/source/dungeon.cc | 1 + crawl-ref/source/env.h | 3 +++ crawl-ref/source/tags.cc | 24 ++++++++++++++++++++++++ crawl-ref/source/tags.h | 5 +++-- 6 files changed, 50 insertions(+), 12 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dgn-shoals.cc b/crawl-ref/source/dgn-shoals.cc index c4cdf30cca..f3b7e386fd 100644 --- a/crawl-ref/source/dgn-shoals.cc +++ b/crawl-ref/source/dgn-shoals.cc @@ -13,7 +13,11 @@ #include #include -static int _shoals_heights[GYM][GXM]; +inline short &shoals_heights(const coord_def &c) +{ + return (*env.heightmap)(c); +} + static std::vector _shoals_islands; const int ISLAND_COLLIDE_DIST2 = 5 * 5; @@ -43,7 +47,7 @@ static double _to_radians(int degrees) static dungeon_feature_type _shoals_feature_at(const coord_def &c) { - const int height = _shoals_heights[c.y][c.x]; + const int height = shoals_heights(c); return height >= SHT_STONE ? DNGN_STONE_WALL : height >= SHT_ROCK? DNGN_ROCK_WALL : height >= SHT_FLOOR? DNGN_FLOOR : @@ -53,9 +57,9 @@ static dungeon_feature_type _shoals_feature_at(const coord_def &c) static void _shoals_init_heights() { - for (int y = 0; y < GYM; ++y) - for (int x = 0; x < GXM; ++x) - _shoals_heights[y][x] = -17; + env.heightmap.reset(new grid_heightmap); + for (rectangle_iterator ri(0); ri; ++ri) + shoals_heights(*ri) = SHT_SHALLOW_WATER - 3; } static double _angle_fuzz() @@ -94,7 +98,7 @@ static void _shoals_island_center(const coord_def &c, int n_perturb, int radius, { for (int i = 0; i < n_perturb; ++i) { coord_def p = _random_point_from(c, random2(1 + radius)); - _shoals_heights[p.y][p.x] += random_range(bounce_low, bounce_high); + shoals_heights(p) += random_range(bounce_low, bounce_high); } } @@ -194,10 +198,10 @@ static void _shoals_smooth_at(const coord_def &c, int radius) const coord_def off = c - p; int weight = max_delta - off.abs(); divisor += weight; - total += _shoals_heights[p.y][p.x] * weight; + total += shoals_heights(p) * weight; } } - _shoals_heights[c.y][c.x] = total / divisor; + shoals_heights(c) = total / divisor; } static void _shoals_smooth() diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc index 518d21b23c..9807ec54dc 100644 --- a/crawl-ref/source/directn.cc +++ b/crawl-ref/source/directn.cc @@ -3468,14 +3468,19 @@ static void _describe_cell(const coord_def& where, bool in_range) marker = " (" + desc + ")"; } const std::string traveldest = _stair_destination_description(where); + std::string height_desc; + if (env.heightmap.get()) + height_desc = make_stringf(" (height: %d)", (*env.heightmap)(where)); const dungeon_feature_type feat = grd(where); - mprf(MSGCH_DIAGNOSTICS, "(%d,%d): %s - %s (%d/%s)%s%s", where.x, where.y, + mprf(MSGCH_DIAGNOSTICS, "(%d,%d): %s - %s (%d/%s)%s%s%s", + where.x, where.y, stringize_glyph(get_screen_glyph(where)).c_str(), feature_desc.c_str(), feat, dungeon_feature_name(feat), marker.c_str(), - traveldest.c_str()); + traveldest.c_str(), + height_desc.c_str()); #else if (Tutorial.tutorial_left && tutorial_pos_interesting(where.x, where.y)) { diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 53658c2a58..c5f6a788ca 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -975,6 +975,7 @@ void dgn_reset_level() // Forget level properties. env.properties.clear(); + env.heightmap.reset(NULL); // Set up containers for storing some level generation info. env.properties[LEVEL_VAULTS_KEY].new_table(); diff --git a/crawl-ref/source/env.h b/crawl-ref/source/env.h index 1f3c02f142..aa78f2ac0f 100644 --- a/crawl-ref/source/env.h +++ b/crawl-ref/source/env.h @@ -6,6 +6,7 @@ #include "show.h" #include "trap_def.h" +typedef FixedArray grid_heightmap; struct crawl_environment { public: @@ -22,6 +23,8 @@ public: FixedArray< unsigned short, GXM, GYM > cgrid; // cloud grid FixedArray< unsigned short, GXM, GYM > grid_colours; // colour overrides + std::auto_ptr heightmap; + // Player-remembered terrain. TODO: move to class player. FixedArray< map_cell, GXM, GYM > map_knowledge; diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc index ab60932b4f..c092062c23 100644 --- a/crawl-ref/source/tags.cc +++ b/crawl-ref/source/tags.cc @@ -61,6 +61,7 @@ #include "artefact.h" #include "branch.h" +#include "coordit.h" #include "describe.h" #include "dungeon.h" #include "enum.h" @@ -1825,6 +1826,15 @@ static void tag_construct_level(writer &th) env.markers.write(th); env.properties.write(th); + + // Save heightmap, if present. + marshallByte(th, !!env.heightmap.get()); + if (env.heightmap.get()) + { + grid_heightmap &heightmap(*env.heightmap); + for (rectangle_iterator ri(0); ri; ++ri) + marshallShort(th, heightmap(*ri)); + } } void marshallItem(writer &th, const item_def &item) @@ -2217,6 +2227,20 @@ static void tag_read_level( reader &th, char minorVersion ) env.properties.clear(); env.properties.read(th); + + // Restore heightmap + env.heightmap.reset(NULL); + if (_tag_minor_version >= TAG_MINOR_HEIGHTMAP) + { + const bool have_heightmap(unmarshallByte(th)); + if (have_heightmap) + { + env.heightmap.reset(new grid_heightmap); + grid_heightmap &heightmap(*env.heightmap); + for (rectangle_iterator ri(0); ri; ++ri) + heightmap(*ri) = unmarshallShort(th); + } + } } static void tag_read_level_items(reader &th, char minorVersion) diff --git a/crawl-ref/source/tags.h b/crawl-ref/source/tags.h index 26ecf81233..e7877dfd6f 100644 --- a/crawl-ref/source/tags.h +++ b/crawl-ref/source/tags.h @@ -46,8 +46,9 @@ enum tag_major_version // Minor version will be reset to zero when major version changes. enum tag_minor_version { - TAG_MINOR_RESET = 0, // Minor tags were reset - TAG_MINOR_VERSION = 0 // Current version. (Keep equal to max.) + TAG_MINOR_RESET = 0, // Minor tags were reset + TAG_MINOR_HEIGHTMAP = 1, + TAG_MINOR_VERSION = 1 // Current version. (Keep equal to max.) }; struct enum_info -- cgit v1.2.3-54-g00ecf From 382a17cfc82a018bc2c071a6fed85150fe3d2154 Mon Sep 17 00:00:00 2001 From: Darshan Shaligram Date: Sun, 27 Dec 2009 15:49:39 +0530 Subject: Increase depths of deep water by distance from shore. --- crawl-ref/source/dgn-shoals.cc | 66 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dgn-shoals.cc b/crawl-ref/source/dgn-shoals.cc index f3b7e386fd..1f7485dd5b 100644 --- a/crawl-ref/source/dgn-shoals.cc +++ b/crawl-ref/source/dgn-shoals.cc @@ -216,6 +216,71 @@ static void _shoals_apply_level() grd(*ri) = _shoals_feature_at(*ri); } +static bool _has_adjacent_feat(coord_def c, dungeon_feature_type feat) +{ + for (adjacent_iterator ai(c); ai; ++ai) + if (grd(*ai) == feat) + return true; + return false; +} + +// Returns all points in deep water with an adjacent square in shallow water. +static std::vector _shoals_water_depth_change_points() +{ + std::vector points; + for (rectangle_iterator ri(1); ri; ++ri) + { + coord_def c(*ri); + if (grd(c) == DNGN_DEEP_WATER + && _has_adjacent_feat(c, DNGN_SHALLOW_WATER)) + points.push_back(c); + } + return points; +} + +static inline void _shoals_deepen_water_at(coord_def p, int distance) +{ + shoals_heights(p) -= distance * 5; +} + +static void _shoals_deepen_water() +{ + std::vector pages[2]; + int current_page = 0; + pages[current_page] = _shoals_water_depth_change_points(); + FixedArray seen_points(false); + + for (int i = 0, size = pages[current_page].size(); i < size; ++i) + seen_points(pages[current_page][i]) = true; + + int distance = 0; + while (!pages[current_page].empty()) + { + const int next_page = !current_page; + std::vector &cpage(pages[current_page]); + std::vector &npage(pages[next_page]); + for (int i = 0, size = cpage.size(); i < size; ++i) + { + coord_def c(cpage[i]); + if (distance) + _shoals_deepen_water_at(c, distance); + + for (adjacent_iterator ai(c); ai; ++ai) + { + coord_def adj(*ai); + if (!seen_points(adj) && grd(adj) == DNGN_DEEP_WATER) + { + npage.push_back(adj); + seen_points(adj) = true; + } + } + } + cpage.clear(); + current_page = next_page; + distance++; + } +} + static coord_def _pick_shoals_island() { const int lucky_island = random2(_shoals_islands.size()); @@ -316,5 +381,6 @@ void prepare_shoals(int level_number) _shoals_cliffs(); _shoals_smooth(); _shoals_apply_level(); + _shoals_deepen_water(); _shoals_furniture(_shoals_margin); } -- cgit v1.2.3-54-g00ecf From 191aad1fa653d19020b28368bf7423d4b44c38c7 Mon Sep 17 00:00:00 2001 From: Johanna Ploog Date: Sun, 27 Dec 2009 13:27:41 +0100 Subject: Replace the flat Maurice tile with a more 3dimensional one. I'm not entirely convinced this is actually better but the flat one stood out like a sore thumb, so that's a nogo. --- crawl-ref/source/rltiles/dc-mon/unique/maurice.png | Bin 902 -> 1080 bytes 1 file changed, 0 insertions(+), 0 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/rltiles/dc-mon/unique/maurice.png b/crawl-ref/source/rltiles/dc-mon/unique/maurice.png index 284ad4645c..874963221c 100644 Binary files a/crawl-ref/source/rltiles/dc-mon/unique/maurice.png and b/crawl-ref/source/rltiles/dc-mon/unique/maurice.png differ -- cgit v1.2.3-54-g00ecf From bd29fc66d15166b3c34dcad3abaea54e0e3bacbc Mon Sep 17 00:00:00 2001 From: Darshan Shaligram Date: Sun, 27 Dec 2009 18:32:52 +0530 Subject: Add tides to the Shoals. --- crawl-ref/source/actor.h | 8 ++ crawl-ref/source/dgn-shoals.cc | 242 ++++++++++++++++++++++++++++++++++++++++- crawl-ref/source/dgn-shoals.h | 1 + crawl-ref/source/effects.cc | 2 + crawl-ref/source/misc.cc | 2 + crawl-ref/source/player.cc | 14 ++- crawl-ref/source/player.h | 1 + 7 files changed, 264 insertions(+), 6 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/actor.h b/crawl-ref/source/actor.h index f8e920eb14..b29e826307 100644 --- a/crawl-ref/source/actor.h +++ b/crawl-ref/source/actor.h @@ -28,7 +28,15 @@ public: virtual bool is_summoned(int* duration = NULL, int* summon_type = NULL) const = 0; + // [ds] Low-level moveto() - moves the actor without updating relevant + // grids, such as mgrd. virtual void moveto(const coord_def &c) = 0; + + // High-level actor movement. If in doubt, use this. Returns true if the + // actor cannot be moved to the target, possibly because it is already + // occupied. + virtual bool move_to_pos(const coord_def &c) = 0; + virtual void set_position(const coord_def &c); virtual const coord_def& pos() const { return position; } diff --git a/crawl-ref/source/dgn-shoals.cc b/crawl-ref/source/dgn-shoals.cc index 1f7485dd5b..b21315f1a8 100644 --- a/crawl-ref/source/dgn-shoals.cc +++ b/crawl-ref/source/dgn-shoals.cc @@ -6,13 +6,20 @@ #include "dungeon.h" #include "dgn-shoals.h" #include "env.h" +#include "items.h" #include "maps.h" +#include "mon-place.h" +#include "mon-util.h" #include "random.h" +#include "terrain.h" #include #include #include +const char *ENVP_SHOALS_TIDE_KEY = "shoals-tide-height"; +const char *ENVP_SHOALS_TIDE_VEL = "shoals-tide-velocity"; + inline short &shoals_heights(const coord_def &c) { return (*env.heightmap)(c); @@ -45,9 +52,8 @@ static double _to_radians(int degrees) return degrees * M_PI / 180; } -static dungeon_feature_type _shoals_feature_at(const coord_def &c) +static dungeon_feature_type _shoals_feature_by_height(int height) { - const int height = shoals_heights(c); return height >= SHT_STONE ? DNGN_STONE_WALL : height >= SHT_ROCK? DNGN_ROCK_WALL : height >= SHT_FLOOR? DNGN_FLOOR : @@ -55,6 +61,12 @@ static dungeon_feature_type _shoals_feature_at(const coord_def &c) : DNGN_DEEP_WATER; } +static dungeon_feature_type _shoals_feature_at(const coord_def &c) +{ + const int height = shoals_heights(c); + return _shoals_feature_by_height(height); +} + static void _shoals_init_heights() { env.heightmap.reset(new grid_heightmap); @@ -240,7 +252,7 @@ static std::vector _shoals_water_depth_change_points() static inline void _shoals_deepen_water_at(coord_def p, int distance) { - shoals_heights(p) -= distance * 5; + shoals_heights(p) -= distance * 7; } static void _shoals_deepen_water() @@ -365,7 +377,28 @@ static void _shoals_furniture(int margin) = static_cast(DNGN_STONE_STAIRS_UP_I + i); } } +} +static void _shoals_deepen_edges() +{ + const int edge = 2; + // Water of the edge of the screen is too deep to be exposed by tides. + for (int y = 1; y < GYM - 2; ++y) + { + for (int x = 1; x <= edge; ++x) + { + shoals_heights(coord_def(x, y)) -= 800; + shoals_heights(coord_def(GXM - 1 - x, y)) -= 800; + } + } + for (int x = 1; x < GXM - 2; ++x) + { + for (int y = 1; y <= edge; ++y) + { + shoals_heights(coord_def(x, y)) -= 800; + shoals_heights(coord_def(x, GYM - 1 - y)) -= 800; + } + } } void prepare_shoals(int level_number) @@ -382,5 +415,208 @@ void prepare_shoals(int level_number) _shoals_smooth(); _shoals_apply_level(); _shoals_deepen_water(); + _shoals_deepen_edges(); _shoals_furniture(_shoals_margin); } + +// The raw tide height / TIDE_MULTIPLIER is the actual tide height. The higher +// the tide multiplier, the slower the tide advances and recedes. A multiplier +// of X implies that the tide will advance visibly about once in X turns. +const int TIDE_MULTIPLIER = 30; + +const int LOW_TIDE = -25 * TIDE_MULTIPLIER; +const int HIGH_TIDE = 25 * TIDE_MULTIPLIER; +const int TIDE_DECEL_MARGIN = 8; +const int START_TIDE_RISE = 2; + +static void _shoals_run_tide(int &tide, int &acc) +{ + tide += acc; + tide = std::max(std::min(tide, HIGH_TIDE), LOW_TIDE); + if ((tide == HIGH_TIDE && acc > 0) + || (tide == LOW_TIDE && acc < 0)) + acc = -acc; + bool in_decel_margin = + (abs(tide - HIGH_TIDE) < TIDE_DECEL_MARGIN) + || (abs(tide - LOW_TIDE) < TIDE_DECEL_MARGIN); + if ((abs(acc) == 2) == in_decel_margin) + acc = in_decel_margin? acc / 2 : acc * 2; +} + +static coord_def _shoals_escape_place_from(coord_def bad_place, + bool monster_free) +{ + int best_height = -1000; + coord_def chosen; + for (adjacent_iterator ai(bad_place); ai; ++ai) + { + coord_def p(*ai); + const dungeon_feature_type feat(grd(p)); + if (!feat_is_solid(feat) && !feat_destroys_items(feat) + && (!monster_free || !actor_at(p))) + { + if (best_height == -1000 || shoals_heights(p) > best_height) + { + best_height = shoals_heights(p); + chosen = p; + } + } + } + return chosen; +} + +static bool _shoals_tide_sweep_items_clear(coord_def c) +{ + int link = igrd(c); + if (link == NON_ITEM) + return true; + + const coord_def target(_shoals_escape_place_from(c, false)); + if (target.origin()) + return false; + + move_item_stack_to_grid(c, target); + return true; +} + +static bool _shoals_tide_sweep_actors_clear(coord_def c) +{ + actor *victim = actor_at(c); + if (!victim) + return true; + + if (victim->atype() == ACT_MONSTER) + { + monsters *mvictim = dynamic_cast(victim); + // Plants and statues cannot be moved away; the tide cannot + // drown them. + if (mons_class_is_stationary(mvictim->type)) + return false; + + // If the monster doesn't need help, move along. + if (monster_habitable_grid(mvictim, DNGN_DEEP_WATER)) + return true; + } + coord_def evacuation_point(_shoals_escape_place_from(c, true)); + // The tide moves on even if we cannot evacuate the tile! + if (!evacuation_point.origin()) + victim->move_to_pos(evacuation_point); + return true; +} + +// The tide will attempt to push items and non-water-capable monsters to +// adjacent squares. +static bool _shoals_tide_sweep_clear(coord_def c) +{ + return _shoals_tide_sweep_items_clear(c) + && _shoals_tide_sweep_actors_clear(c); +} + +static void _shoals_apply_tide_feature_at(coord_def c, + dungeon_feature_type feat) +{ + if (feat == DNGN_DEEP_WATER && !_shoals_tide_sweep_clear(c)) + feat = DNGN_SHALLOW_WATER; + + const dungeon_feature_type current_feat = grd(c); + if (feat == current_feat) + return; + + dungeon_terrain_changed(c, feat, true, false, true); +} + +static void _shoals_apply_tide_at(coord_def c, int tide) +{ + const int effective_height = shoals_heights(c) - tide; + dungeon_feature_type newfeat = + _shoals_feature_by_height(effective_height); + // Make sure we're not sprouting new walls. + if (feat_is_wall(newfeat)) + newfeat = DNGN_FLOOR; + + _shoals_apply_tide_feature_at(c, newfeat); +} + +static void _shoals_apply_tide(int tide) +{ + std::vector pages[2]; + int current_page = 0; + + // Start from corners of the map. + pages[current_page].push_back(coord_def(1,1)); + pages[current_page].push_back(coord_def(GXM - 2, 1)); + pages[current_page].push_back(coord_def(1, GYM - 2)); + pages[current_page].push_back(coord_def(GXM - 2, GYM - 2)); + + FixedArray seen_points(false); + + while (!pages[current_page].empty()) + { + int next_page = !current_page; + std::vector &cpage(pages[current_page]); + std::vector &npage(pages[next_page]); + + for (int i = 0, size = cpage.size(); i < size; ++i) + { + coord_def c(cpage[i]); + const bool was_wet(feat_is_water(grd(c))); + seen_points(c) = true; + _shoals_apply_tide_at(c, tide); + + // Only wet squares can propagate the tide onwards. + if (was_wet) + { + for (adjacent_iterator ai(c); ai; ++ai) + { + coord_def adj(*ai); + if (!in_bounds(adj)) + continue; + if (!seen_points(adj)) + { + const dungeon_feature_type feat = grd(adj); + if (feat_is_water(feat) || feat == DNGN_FLOOR) + { + npage.push_back(adj); + seen_points(adj) = true; + } + } + } + } + } + + cpage.clear(); + current_page = next_page; + } +} + +static void _shoals_init_tide() +{ + if (!env.properties.exists(ENVP_SHOALS_TIDE_KEY)) + { + env.properties[ENVP_SHOALS_TIDE_KEY] = short(0); + env.properties[ENVP_SHOALS_TIDE_VEL] = short(2); + } +} + +void shoals_apply_tides(int turns_elapsed) +{ + if (!player_in_branch(BRANCH_SHOALS) || !turns_elapsed + || !env.heightmap.get()) + { + return; + } + + const int TIDE_UNIT = HIGH_TIDE - LOW_TIDE; + // If we've been gone a long time, eliminate some unnecessary math. + if (turns_elapsed > TIDE_UNIT * 2) + turns_elapsed = turns_elapsed % TIDE_UNIT + TIDE_UNIT; + + _shoals_init_tide(); + int tide = env.properties[ENVP_SHOALS_TIDE_KEY].get_short(); + int acc = env.properties[ENVP_SHOALS_TIDE_VEL].get_short(); + while (turns_elapsed-- > 0) + _shoals_run_tide(tide, acc); + env.properties[ENVP_SHOALS_TIDE_KEY] = short(tide); + env.properties[ENVP_SHOALS_TIDE_VEL] = short(acc); + _shoals_apply_tide(tide / TIDE_MULTIPLIER); +} diff --git a/crawl-ref/source/dgn-shoals.h b/crawl-ref/source/dgn-shoals.h index 023f321fe6..aae09ff653 100644 --- a/crawl-ref/source/dgn-shoals.h +++ b/crawl-ref/source/dgn-shoals.h @@ -2,5 +2,6 @@ #define DGN_SHOALS_H void prepare_shoals(int level_number); +void shoals_apply_tides(int turns_elapsed); #endif diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc index 30687dd58d..bede6d46c2 100644 --- a/crawl-ref/source/effects.cc +++ b/crawl-ref/source/effects.cc @@ -27,6 +27,7 @@ #include "coordit.h" #include "decks.h" #include "delay.h" +#include "dgn-shoals.h" #include "dungeon.h" #include "directn.h" #include "dgnevent.h" @@ -4263,6 +4264,7 @@ void update_level(double elapsedTime) #endif update_corpses(elapsedTime); + shoals_apply_tides(turns); if (env.sanctuary_time) { diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index 5697133c4a..3312bfcf94 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -36,6 +36,7 @@ #include "coordit.h" #include "database.h" #include "delay.h" +#include "dgn-shoals.h" #include "directn.h" #include "dgnevent.h" #include "directn.h" @@ -3092,6 +3093,7 @@ void run_environment_effects() } run_corruption_effects(you.time_taken); + shoals_apply_tides(div_rand_round(you.time_taken, 10)); } coord_def pick_adjacent_free_square(const coord_def& p) diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index 4e5cf2dc77..e7e54c63d6 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -7031,6 +7031,17 @@ void player::moveto(const coord_def &c) set_position(c); } +bool player::move_to_pos(const coord_def &c) +{ + actor *target = actor_at(c); + if (!target || target->submerged()) + { + moveto(c); + return true; + } + return false; +} + void player::shiftto(const coord_def &c) { crawl_view.shift_player_to(c); @@ -7423,6 +7434,3 @@ void player::set_duration(duration_type dur, int turns, you.duration[dur] = 0; increase_duration(dur, turns, cap, msg); } - - - diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h index d7f5306c08..a02e5f5c4c 100644 --- a/crawl-ref/source/player.h +++ b/crawl-ref/source/player.h @@ -314,6 +314,7 @@ public: void set_position(const coord_def &c); // Low-level move the player. Use this instead of changing pos directly. void moveto(const coord_def &c); + bool move_to_pos(const coord_def &c); // Move the player during an abyss shift. void shiftto(const coord_def &c); bool blink_to(const coord_def& c, bool quiet = false); -- cgit v1.2.3-54-g00ecf From 0fe55b6adbe990a2321dfc9b50e862da27186759 Mon Sep 17 00:00:00 2001 From: Vsevolod Kozlov Date: Sun, 27 Dec 2009 16:40:20 +0300 Subject: Use strip_tag for cursed/randart/damaged in parse_single_spec. --- crawl-ref/source/mapdef.cc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc index 060ec78677..5eda9e7792 100644 --- a/crawl-ref/source/mapdef.cc +++ b/crawl-ref/source/mapdef.cc @@ -3898,20 +3898,17 @@ item_spec item_list::parse_single_spec(std::string s) } } - if (s.find("damaged ") == 0) + if (strip_tag(s, "damaged")) { result.level = ISPEC_DAMAGED; - s = s.substr(8); } - if (s.find("cursed ") == 0) + if (strip_tag(s, "cursed")) { result.level = ISPEC_BAD; // damaged + cursed, actually - s = s.substr(7); } - if (s.find("randart ") == 0) + if (strip_tag(s, "randart")) { result.level = ISPEC_RANDART; - s = s.substr(8); } if (strip_tag(s, "no_uniq")) -- cgit v1.2.3-54-g00ecf From c0788ba0603604a5d998c0c30afd8e33b4c1c6ce Mon Sep 17 00:00:00 2001 From: Vsevolod Kozlov Date: Sun, 27 Dec 2009 16:50:24 +0300 Subject: Reduce code duplication in trap_def::shot_damage. --- crawl-ref/source/traps.cc | 42 ++++++++++++++++-------------------------- 1 file changed, 16 insertions(+), 26 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/traps.cc b/crawl-ref/source/traps.cc index e8b8d92bce..e2dcd625ea 100644 --- a/crawl-ref/source/traps.cc +++ b/crawl-ref/source/traps.cc @@ -679,36 +679,26 @@ void trap_def::trigger(actor& triggerer, bool flat_footed) int trap_def::shot_damage(actor& act) { - if (act.atype() == ACT_PLAYER) - { - switch (this->type) - { - case TRAP_NEEDLE: return 0; - case TRAP_DART: return random2( 4 + you.your_level/2) + 1; - case TRAP_ARROW: return random2( 7 + you.your_level) + 1; - case TRAP_SPEAR: return random2(10 + you.your_level) + 1; - case TRAP_BOLT: return random2(13 + you.your_level) + 1; - case TRAP_AXE: return random2(15 + you.your_level) + 1; - default: return 0; - } - } - else if (act.atype() == ACT_MONSTER) + int level = you.your_level; + + // Trap damage to monsters is not a function of level, because + // they are fairly stupid and tend to have fewer hp than + // players -- this choice prevents traps from easily killing + // large monsters fairly deep within the dungeon. + if (act.atype() == ACT_MONSTER) + level = 0; + + switch (this->type) { - // Trap damage to monsters is not a function of level, because - // they are fairly stupid and tend to have fewer hp than - // players -- this choice prevents traps from easily killing - // large monsters fairly deep within the dungeon. - switch (this->type) - { case TRAP_NEEDLE: return 0; - case TRAP_DART: return random2( 4) + 1; - case TRAP_ARROW: return random2( 7) + 1; - case TRAP_SPEAR: return random2(10) + 1; - case TRAP_BOLT: return random2(13) + 1; - case TRAP_AXE: return random2(15) + 1; + case TRAP_DART: return random2( 4 + level/2) + 1; + case TRAP_ARROW: return random2( 7 + level) + 1; + case TRAP_SPEAR: return random2(10 + level) + 1; + case TRAP_BOLT: return random2(13 + level) + 1; + case TRAP_AXE: return random2(15 + level) + 1; default: return 0; - } } + return (0); } -- cgit v1.2.3-54-g00ecf From 34c10bc02d11249b2f24faa34a157db3911046e7 Mon Sep 17 00:00:00 2001 From: Darshan Shaligram Date: Sun, 27 Dec 2009 19:25:19 +0530 Subject: Reduce low tide effects in the Shoals. --- crawl-ref/source/dgn-shoals.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dgn-shoals.cc b/crawl-ref/source/dgn-shoals.cc index b21315f1a8..f7a44a0c5c 100644 --- a/crawl-ref/source/dgn-shoals.cc +++ b/crawl-ref/source/dgn-shoals.cc @@ -424,7 +424,7 @@ void prepare_shoals(int level_number) // of X implies that the tide will advance visibly about once in X turns. const int TIDE_MULTIPLIER = 30; -const int LOW_TIDE = -25 * TIDE_MULTIPLIER; +const int LOW_TIDE = -18 * TIDE_MULTIPLIER; const int HIGH_TIDE = 25 * TIDE_MULTIPLIER; const int TIDE_DECEL_MARGIN = 8; const int START_TIDE_RISE = 2; -- cgit v1.2.3-54-g00ecf From 22d52312ea69d1ad0e291920defa83e84d273992 Mon Sep 17 00:00:00 2001 From: Darshan Shaligram Date: Sun, 27 Dec 2009 19:33:10 +0530 Subject: Shoals tides should not try to move flying/swimming monsters out of the way, fixed. --- crawl-ref/source/dgn-shoals.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dgn-shoals.cc b/crawl-ref/source/dgn-shoals.cc index f7a44a0c5c..5de4294d8d 100644 --- a/crawl-ref/source/dgn-shoals.cc +++ b/crawl-ref/source/dgn-shoals.cc @@ -482,7 +482,7 @@ static bool _shoals_tide_sweep_items_clear(coord_def c) static bool _shoals_tide_sweep_actors_clear(coord_def c) { actor *victim = actor_at(c); - if (!victim) + if (!victim || victim->airborne() || victim->swimming()) return true; if (victim->atype() == ACT_MONSTER) -- cgit v1.2.3-54-g00ecf From 1b9f02892b65f3e7b0c1c02ca8de71a45f041787 Mon Sep 17 00:00:00 2001 From: Darshan Shaligram Date: Sun, 27 Dec 2009 19:48:39 +0530 Subject: Apply second smoothing pass to Shoals deep water to reduce ugly rectangular deep water outlines at low tide. --- crawl-ref/source/dgn-shoals.cc | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dgn-shoals.cc b/crawl-ref/source/dgn-shoals.cc index 5de4294d8d..201f3f4690 100644 --- a/crawl-ref/source/dgn-shoals.cc +++ b/crawl-ref/source/dgn-shoals.cc @@ -41,6 +41,7 @@ const int _shoals_margin = 6; enum shoals_height_thresholds { + SHT_UNDEFINED = -10000, SHT_STONE = 230, SHT_ROCK = 170, SHT_FLOOR = 0, @@ -197,8 +198,13 @@ static void _shoals_cliffs() _shoals_build_cliff(); } -static void _shoals_smooth_at(const coord_def &c, int radius) +static void _shoals_smooth_at(const coord_def &c, int radius, + int max_height = SHT_UNDEFINED) { + const int height = shoals_heights(c); + if (max_height != SHT_UNDEFINED && height > max_height) + return; + int max_delta = radius * radius * 2 + 2; int divisor = 0; int total = 0; @@ -207,10 +213,13 @@ static void _shoals_smooth_at(const coord_def &c, int radius) const coord_def p(x, y); if (!in_bounds(p)) continue; + const int nheight = shoals_heights(p); + if (max_height != SHT_UNDEFINED && nheight > max_height) + continue; const coord_def off = c - p; int weight = max_delta - off.abs(); divisor += weight; - total += shoals_heights(p) * weight; + total += nheight * weight; } } shoals_heights(c) = total / divisor; @@ -222,6 +231,12 @@ static void _shoals_smooth() _shoals_smooth_at(*ri, 1); } +static void _shoals_smooth_water() +{ + for (rectangle_iterator ri(0); ri; ++ri) + _shoals_smooth_at(*ri, 1, SHT_SHALLOW_WATER - 1); +} + static void _shoals_apply_level() { for (rectangle_iterator ri(1); ri; ++ri) @@ -416,6 +431,7 @@ void prepare_shoals(int level_number) _shoals_apply_level(); _shoals_deepen_water(); _shoals_deepen_edges(); + _shoals_smooth_water(); _shoals_furniture(_shoals_margin); } -- cgit v1.2.3-54-g00ecf From 21d39fbc5baa0d247abb40f66dfee07a3abd7a99 Mon Sep 17 00:00:00 2001 From: Adam Borowski Date: Sun, 27 Dec 2009 03:33:57 +0100 Subject: Don't say that "Kiku likes sacrifices of corpses", as that costs piety. --- crawl-ref/source/religion.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index 395db6af89..2524fbfcd5 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -609,7 +609,7 @@ std::string get_god_likes(god_type which_god, bool verbose) break; } - if (god_likes_fresh_corpses(which_god)) + if (god_likes_fresh_corpses(which_god) && which_god != GOD_KIKUBAAQUDGHA) { snprintf(info, INFO_SIZE, "you sacrifice fresh corpses%s", verbose ? " (by standing over them and praying)" : ""); -- cgit v1.2.3-54-g00ecf From f10addfc13d3b174e4de2529978db2cfce4e5bb1 Mon Sep 17 00:00:00 2001 From: Adam Borowski Date: Sun, 27 Dec 2009 15:13:02 +0100 Subject: Replace '+' by '∞' for books in CSET_UNICODE and CSET_IBM. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crawl-ref/source/viewchar.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/viewchar.cc b/crawl-ref/source/viewchar.cc index 78818642bd..bf0460591c 100644 --- a/crawl-ref/source/viewchar.cc +++ b/crawl-ref/source/viewchar.cc @@ -24,27 +24,35 @@ static const unsigned dchar_table[ NUM_CSET ][ NUM_DCHAR_TYPES ] = 177, 176, 249, 250, '\'', 254, '^', '>', '<', // wall .. stairs up 220, 239, 244, 247, '8', '~', '~', // altar .. item detect '0', ')', '[', '/', '%', '?', '=', '!', '(', // orb .. missile - '+', '\\', '}', '%', '$', '"', '#', 234, // book .. trees + 236, '\\', '}', '%', '$', '"', '#', 234, // book .. trees ' ', '!', '#', '%', '+', ')', '*', '+', // space .. fired_burst '/', '=', '?', 'X', '[', '`', '#' // fi_stick .. explosion }, // CSET_DEC - remember: 224-255 are mapped to shifted 96-127 + // It's better known as "vt100 line drawing characters". { 225, 224, 254, ':', '\'', 238, '^', '>', '<', // wall .. stairs up 251, 182, 167, 187, '8', 171, 168, // altar .. item detect '0', ')', '[', '/', '%', '?', '=', '!', '(', // orb .. missile - '+', '\\', '}', '%', '$', '"', '#', '7', // book .. trees + ':', '\\', '}', '%', '$', '"', '#', '7', // book .. trees ' ', '!', '#', '%', '+', ')', '*', '+', // space .. fired_burst '/', '=', '?', 'X', '[', '`', '#' // fi_stick .. explosion }, // CSET_UNICODE + /* Beware, some popular terminals (PuTTY, xterm) are incapable of coping with + the lack of a character in the chosen font, and most popular fonts have a + quite limited repertoire. A subset that is reasonably likely to be present + is http://en.wikipedia.org/wiki/WGL4; we could provide a richer alternate + set for those on more capable terminals (including for example Thai 0xEB0 + for clouds), but that would require decoupling encoding from charset. + */ { 0x2592, 0x2591, 0xB7, 0x25E6, '\'', 0x25FC, '^', '>', '<', '_', 0x2229, 0x2320, 0x2248, '8', '~', '~', '0', ')', '[', '/', '%', '?', '=', '!', '(', - '+', '|', '}', '%', '$', '"', '#', 0x2663, + 0x221E, '|', '}', '%', '$', '"', '#', 0x2663, ' ', '!', '#', '%', '+', ')', '*', '+', // space .. fired_burst '/', '=', '?', 'X', '[', '`', '#' // fi_stick .. explosion }, -- cgit v1.2.3-54-g00ecf From e42132c99bf63b213388404676a54c6610bd613c Mon Sep 17 00:00:00 2001 From: Adam Borowski Date: Sun, 27 Dec 2009 15:19:32 +0100 Subject: Before a better solution is decided on, slash TSO holy revenge by a factor of 4. This is roughly half of maxhp for vampires and mummies -- still harsh after a hard battle, especially when there's more holies around. --- crawl-ref/source/godwrath.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/godwrath.cc b/crawl-ref/source/godwrath.cc index a94b0ec2c8..e3e87198ca 100644 --- a/crawl-ref/source/godwrath.cc +++ b/crawl-ref/source/godwrath.cc @@ -1249,7 +1249,8 @@ static void _tso_blasts_cleansing_flame(const char *message) simple_god_message(" blasts you with cleansing flame!", GOD_SHINING_ONE); - cleansing_flame(20 + (you.experience_level * 7) / 3, + // damage is 2d(pow), *3/2 for undead and demonspawn + cleansing_flame(5 + (you.experience_level * 7) / 12, CLEANSING_FLAME_TSO, you.pos()); } } -- cgit v1.2.3-54-g00ecf From 23929ee3b2452b1c3a133061eff44b31dc70fb09 Mon Sep 17 00:00:00 2001 From: Jude Brown Date: Mon, 28 Dec 2009 00:17:23 +1000 Subject: Customisable clouds! cloud_struct now has members for colour, name, and tile; colour will be used instead of the default colour of the cloud type, and will be used to recolour the tile of the cloud (if it exists). Name will be used to rebrand the cloud's description, and also alter the message generate while standing in a cloud. Finally, tile can be used to completely customise the tile used for the cloud. The value is stored as a string in order to maintain save compatibility across ASCII and tiles. A random tile (found using tile_main_count) from that set will also be used, however, no duration effects will be applied. Recoloured cloud tiles using just the colour code should be possible, though aren't yet fully tested. This commit bumps TAG_MAJOR_VERSION: changing marshalling of the FogMachine Lua code causes nasty crashes on reloading saved games. Otherwise, I don't think I broke anything else. :-) --- crawl-ref/source/beam.cc | 5 +- crawl-ref/source/cloud.cc | 110 ++++++++++++++++++++++++++--------- crawl-ref/source/cloud.h | 24 ++++++-- crawl-ref/source/dat/clua/lm_fog.lua | 21 ++++++- crawl-ref/source/directn.cc | 3 +- crawl-ref/source/externs.h | 6 +- crawl-ref/source/l_dgn.cc | 18 ++++-- crawl-ref/source/misc.cc | 5 +- crawl-ref/source/player.cc | 2 +- crawl-ref/source/show.cc | 3 +- crawl-ref/source/spells1.cc | 17 +++--- crawl-ref/source/spells1.h | 9 ++- crawl-ref/source/spells4.cc | 5 +- crawl-ref/source/spells4.h | 3 +- crawl-ref/source/spl-util.cc | 19 +++--- crawl-ref/source/spl-util.h | 6 +- crawl-ref/source/tags.cc | 6 ++ crawl-ref/source/tags.h | 2 +- crawl-ref/source/tilepick.cc | 109 +++++++++++++++++++++------------- crawl-ref/source/tilereg.cc | 8 +-- crawl-ref/source/tiles.h | 2 +- crawl-ref/source/tutorial.cc | 2 +- 22 files changed, 261 insertions(+), 124 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index cdeefc8204..8b05a833d9 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -3243,17 +3243,18 @@ void bolt::affect_place_clouds() if (p == you.pos()) { mprf("The %s you are in turns into %s!", - cloud_name(ctype).c_str(), cloud_name(new_type).c_str()); + cloud_name(cloudidx).c_str(), cloud_name(new_type).c_str()); obvious_effect = true; } else if (you.see_cell(p)) { mprf("A cloud of %s turns into %s.", - cloud_name(ctype).c_str(), cloud_name(new_type).c_str()); + cloud_name(cloudidx).c_str(), cloud_name(new_type).c_str()); obvious_effect = true; } ctype = new_type; + env.cloud[cloudidx].name = ""; return; } diff --git a/crawl-ref/source/cloud.cc b/crawl-ref/source/cloud.cc index 638432f504..bd5670b846 100644 --- a/crawl-ref/source/cloud.cc +++ b/crawl-ref/source/cloud.cc @@ -27,6 +27,11 @@ #include "stuff.h" #include "env.h" #include "terrain.h" +#ifdef USE_TILE +#include "tiles.h" +#include "tiledef-gui.h" +#include "tiledef-main.h" +#endif #include "mutation.h" static int _actual_spread_rate(cloud_type type, int spread_rate) @@ -70,7 +75,8 @@ static bool _killer_whose_match(kill_category whose, killer_type killer) static void _new_cloud( int cloud, cloud_type type, const coord_def& p, int decay, kill_category whose, killer_type killer, - unsigned char spread_rate ) + unsigned char spread_rate, int colour, std::string name, + std::string tile) { ASSERT( env.cloud[cloud].type == CLOUD_NONE ); ASSERT(_killer_whose_match(whose, killer)); @@ -83,13 +89,28 @@ static void _new_cloud( int cloud, cloud_type type, const coord_def& p, c.whose = whose; c.killer = killer; c.spread_rate = spread_rate; + c.colour = colour; + c.name = name; +#ifdef USE_TILE + if (!tile.empty()) + { + unsigned int index; + if (!tile_main_index(tile.c_str(), index)) + { + mprf(MSGCH_ERROR, "Invalid tile requested for cloud: '%s'.", tile.c_str()); + tile = ""; + } + } +#endif + c.tile = tile; env.cgrid(p) = cloud; env.cloud_no++; } static void _place_new_cloud(cloud_type cltype, const coord_def& p, int decay, kill_category whose, killer_type killer, - int spread_rate) + int spread_rate, int colour, std::string name, + std::string tile) { if (env.cloud_no >= MAX_CLOUDS) return; @@ -99,7 +120,8 @@ static void _place_new_cloud(cloud_type cltype, const coord_def& p, int decay, { if (env.cloud[ci].type == CLOUD_NONE) // i.e., is empty { - _new_cloud( ci, cltype, p, decay, whose, killer, spread_rate ); + _new_cloud( ci, cltype, p, decay, whose, killer, spread_rate, colour, + name, tile ); break; } } @@ -129,7 +151,7 @@ static int _spread_cloud(const cloud_struct &cloud) newdecay = cloud.decay - 1; _place_new_cloud( cloud.type, *ai, newdecay, cloud.whose, cloud.killer, - cloud.spread_rate ); + cloud.spread_rate, cloud.colour, cloud.name, cloud.tile ); extra_decay += 8; } @@ -151,7 +173,8 @@ static void _spread_fire(const cloud_struct &cloud) // burning trees produce flames all around if (!cell_is_solid(*ai) && make_flames) _place_new_cloud( CLOUD_FIRE, *ai, cloud.decay/2+1, cloud.whose, - cloud.killer, cloud.spread_rate ); + cloud.killer, cloud.spread_rate, cloud.colour, + cloud.name, cloud.tile ); // forest fire doesn't spread in all directions at once, // every neighbouring square gets a separate roll @@ -161,7 +184,8 @@ static void _spread_fire(const cloud_struct &cloud) mpr("The forest fire spreads!"); grd(*ai) = DNGN_FLOOR; _place_new_cloud( cloud.type, *ai, random2(30)+25, cloud.whose, - cloud.killer, cloud.spread_rate ); + cloud.killer, cloud.spread_rate, cloud.colour, + cloud.name, cloud.tile ); } } @@ -248,6 +272,9 @@ void delete_cloud( int cloud ) c.whose = KC_OTHER; c.killer = KILL_NONE; c.spread_rate = 0; + c.colour = -1; + c.name = ""; + c.tile = ""; env.cgrid(c.pos) = EMPTY_CLOUD; c.pos.reset(); @@ -271,32 +298,37 @@ void move_cloud( int cloud, const coord_def& newpos ) // Places a cloud with the given stats assuming one doesn't already // exist at that point. void check_place_cloud( cloud_type cl_type, const coord_def& p, int lifetime, - kill_category whose, int spread_rate ) + kill_category whose, int spread_rate, int colour, + std::string name, std::string tile) { check_place_cloud(cl_type, p, lifetime, whose, - cloud_struct::whose_to_killer(whose), spread_rate); + cloud_struct::whose_to_killer(whose), spread_rate, colour, + name, tile); } // Places a cloud with the given stats assuming one doesn't already // exist at that point. void check_place_cloud( cloud_type cl_type, const coord_def& p, int lifetime, - killer_type killer, int spread_rate ) + killer_type killer, int spread_rate, int colour, + std::string name, std::string tile) { check_place_cloud(cl_type, p, lifetime, cloud_struct::killer_to_whose(killer), killer, - spread_rate); + spread_rate, colour, name, tile); } // Places a cloud with the given stats assuming one doesn't already // exist at that point. void check_place_cloud( cloud_type cl_type, const coord_def& p, int lifetime, kill_category whose, killer_type killer, - int spread_rate ) + int spread_rate, int colour, std::string name, + std::string tile) { if (!in_bounds(p) || env.cgrid(p) != EMPTY_CLOUD) return; - place_cloud( cl_type, p, lifetime, whose, killer, spread_rate ); + place_cloud( cl_type, p, lifetime, whose, killer, spread_rate, colour, + name, tile ); } int steam_cloud_damage(const cloud_struct &cloud) @@ -317,27 +349,32 @@ int steam_cloud_damage(int decay) // make way if there are too many on level. Will overwrite an old // cloud under some circumstances. void place_cloud(cloud_type cl_type, const coord_def& ctarget, int cl_range, - kill_category whose, int _spread_rate) + kill_category whose, int _spread_rate, int colour, + std::string name, std::string tile) { place_cloud(cl_type, ctarget, cl_range, whose, - cloud_struct::whose_to_killer(whose), _spread_rate); + cloud_struct::whose_to_killer(whose), _spread_rate, + colour, name, tile); } // Places a cloud with the given stats. May delete old clouds to // make way if there are too many on level. Will overwrite an old // cloud under some circumstances. void place_cloud(cloud_type cl_type, const coord_def& ctarget, int cl_range, - killer_type killer, int _spread_rate) + killer_type killer, int _spread_rate, int colour, + std::string name, std::string tile) { place_cloud(cl_type, ctarget, cl_range, - cloud_struct::killer_to_whose(killer), killer, _spread_rate); + cloud_struct::killer_to_whose(killer), killer, _spread_rate, + colour, name, tile); } // Places a cloud with the given stats. May delete old clouds to // make way if there are too many on level. Will overwrite an old // cloud under some circumstances. void place_cloud(cloud_type cl_type, const coord_def& ctarget, int cl_range, - kill_category whose, killer_type killer, int _spread_rate) + kill_category whose, killer_type killer, int _spread_rate, + int colour, std::string name, std::string tile) { if (is_sanctuary(ctarget) && !is_harmless_cloud(cl_type)) return; @@ -393,7 +430,7 @@ void place_cloud(cloud_type cl_type, const coord_def& ctarget, int cl_range, if (cl_new != -1) { _new_cloud( cl_new, cl_type, ctarget, cl_range * 10, - whose, killer, spread_rate ); + whose, killer, spread_rate, colour, name, tile ); } else { @@ -403,7 +440,7 @@ void place_cloud(cloud_type cl_type, const coord_def& ctarget, int cl_range, if (env.cloud[ci].type == CLOUD_NONE) // ie is empty { _new_cloud( ci, cl_type, ctarget, cl_range * 10, - whose, killer, spread_rate ); + whose, killer, spread_rate, colour, name, tile ); break; } } @@ -609,6 +646,7 @@ void in_a_cloud() int cl = env.cgrid(you.pos()); int hurted = 0; int resist; + std::string name = env.cloud[cl].name; if (you.duration[DUR_CONDENSATION_SHIELD] > 0) remove_condensation_shield(); @@ -620,7 +658,7 @@ void in_a_cloud() if (you.duration[DUR_FIRE_SHIELD]) return; - mpr("You are engulfed in roaring flames!"); + mprf("You are engulfed in %s!", !name.empty() ? name.c_str() : "roaring flames"); resist = player_res_fire(); @@ -650,7 +688,8 @@ void in_a_cloud() case CLOUD_STINK: // If you don't have to breathe, unaffected - mpr("You are engulfed in noxious fumes!"); + mprf("You are engulfed in %s!", !name.empty() ? name.c_str() : "noxious fumes"); + if (player_res_poison()) break; @@ -674,7 +713,7 @@ void in_a_cloud() if (you.mutation[MUT_PASSIVE_FREEZE]) break; - mpr("You are engulfed in freezing vapours!"); + mprf("You are engulfed in %s!", !name.empty() ? name.c_str() : "freezing vapours"); resist = player_res_cold(); @@ -703,7 +742,8 @@ void in_a_cloud() case CLOUD_POISON: // If you don't have to breathe, unaffected - mpr("You are engulfed in poison gas!"); + mprf("You are engulfed in %s!", !name.empty() ? name.c_str() : "poison gas"); + if (!player_res_poison()) { ouch((random2(10) * you.time_taken) / 10, cl, KILLED_BY_CLOUD, @@ -717,12 +757,14 @@ void in_a_cloud() case CLOUD_TLOC_ENERGY: case CLOUD_PURPLE_SMOKE: case CLOUD_BLACK_SMOKE: - mpr("You are engulfed in a cloud of smoke!"); + mprf("You are engulfed in %s!", !name.empty() ? name.c_str() : "a cloud of smoke"); + break; case CLOUD_STEAM: { - mpr("You are engulfed in a cloud of scalding steam!"); + mprf("You are engulfed in %s!", !name.empty() ? name.c_str() : "a cloud of scalding steam"); + if (player_res_steam() > 0) { mpr("It doesn't seem to affect you."); @@ -746,7 +788,7 @@ void in_a_cloud() } case CLOUD_MIASMA: - mpr("You are engulfed in a dark miasma."); + mprf("You are engulfed in %s!", !name.empty() ? name.c_str() : "a dark miasma"); if (you.res_rotting()) return; @@ -771,11 +813,12 @@ void in_a_cloud() you.duration[DUR_MISLED] = 0; } - mpr("You are standing in the rain."); + mprf("You are engulfed in %s.", !name.empty() ? name.c_str() : "the rain"); + break; case CLOUD_MUTAGENIC: - mpr("You are engulfed in a mutagenic fog!"); + mprf("You are engulfed in %s!", !name.empty() ? name.c_str() : "a mutagenic fog"); if (coinflip()) { @@ -870,6 +913,14 @@ cloud_type in_what_cloud() return (env.cloud[cl].type); } +std::string cloud_name(int cloudno) +{ + if (!env.cloud[cloudno].name.empty()) + return (env.cloud[cloudno].name); + else + return cloud_name(env.cloud[cloudno].type); +} + std::string cloud_name(cloud_type type) { switch (type) @@ -975,6 +1026,9 @@ void cloud_struct::set_killer(killer_type _killer) int get_cloud_colour(int cloudno) { int which_colour = LIGHTGREY; + if (env.cloud[cloudno].colour != -1) + return (env.cloud[cloudno].colour); + switch (env.cloud[cloudno].type) { case CLOUD_FIRE: diff --git a/crawl-ref/source/cloud.h b/crawl-ref/source/cloud.h index 9cd1ef249c..9bb5ba7f00 100644 --- a/crawl-ref/source/cloud.h +++ b/crawl-ref/source/cloud.h @@ -34,19 +34,30 @@ void delete_cloud( int cloud ); void move_cloud( int cloud, const coord_def& newpos ); void check_place_cloud( cloud_type cl_type, const coord_def& p, int lifetime, - kill_category whose, int spread_rate = -1 ); + kill_category whose, int spread_rate = -1, + int colour = -1, std::string name = "", + std::string tile = ""); void check_place_cloud( cloud_type cl_type, const coord_def& p, int lifetime, - killer_type killer, int spread_rate = -1 ); + killer_type killer, int spread_rate = -1, + int colour = -1, std::string name = "", + std::string tile = ""); void check_place_cloud( cloud_type cl_type, const coord_def& p, int lifetime, kill_category whose, killer_type killer, - int spread_rate = -1 ); + int spread_rate = -1, + int colour = -1, std::string name = "", + std::string tile = ""); void place_cloud( cloud_type cl_type, const coord_def& ctarget, - int cl_range, kill_category whose, int spread_rate = -1 ); + int cl_range, kill_category whose, int spread_rate = -1, + int colour = -1, std::string name = "", + std::string tile = ""); void place_cloud( cloud_type cl_type, const coord_def& ctarget, - int cl_range, killer_type killer, int spread_rate = -1 ); + int cl_range, killer_type killer, int spread_rate = -1, + int colour = -1, std::string name = "", + std::string tile = ""); void place_cloud( cloud_type cl_type, const coord_def& ctarget, int cl_range, kill_category whose, killer_type killer, - int spread_rate = -1 ); + int spread_rate = -1, int colour = -1, std::string name = "", + std::string tile = ""); void manage_clouds(void); @@ -61,6 +72,7 @@ int resist_fraction(int resist, int bonus_res = 0); int max_cloud_damage(cloud_type cl_type, int power = -1); void in_a_cloud(void); +std::string cloud_name(int cloudno); std::string cloud_name(cloud_type type); int get_cloud_colour(int cloudno); diff --git a/crawl-ref/source/dat/clua/lm_fog.lua b/crawl-ref/source/dat/clua/lm_fog.lua index 17b80e652e..ace95fec53 100644 --- a/crawl-ref/source/dat/clua/lm_fog.lua +++ b/crawl-ref/source/dat/clua/lm_fog.lua @@ -52,6 +52,10 @@ -- start_clouds: The number of clouds to lay when the level containing -- the cloud machine is entered. This is necessary since clouds -- are cleared when the player leaves a level. +-- colour: A string value with which to recolour the cloud. +-- name: A string value with which to rebrand (specifically, rename) the +-- cloud in question. +-- tile: A string value with which to retile the cloud. -- listener: A table with a function field called 'func'. Will be called -- whenever the countdown is activated, and whenever the fog -- machine is reset. It will be called with a reference to the table, @@ -100,6 +104,9 @@ function FogMachine:new(pars) m.size_max = pars.size_max or pars.size m.spread_rate = pars.spread_rate or -1 m.start_clouds = pars.start_clouds or 1 + m.colour = pars.colour or "" + m.name = pars.name or "" + m.tile = pars.tile or "" m.size_buildup_amnt = pars.size_buildup_amnt or 0 m.size_buildup_time = pars.size_buildup_time or 1 @@ -125,9 +132,10 @@ function FogMachine:new(pars) end function FogMachine:apply_cloud(point, pow_min, pow_max, pow_rolls, - size, cloud_type, kill_cat, spread) + size, cloud_type, kill_cat, spread, colour, + name, tile) dgn.apply_area_cloud(point.x, point.y, pow_min, pow_max, pow_rolls, size, - cloud_type, kill_cat, spread) + cloud_type, kill_cat, spread, colour, name, tile) end function FogMachine:do_fog(point) @@ -165,7 +173,8 @@ function FogMachine:do_fog(point) self:apply_cloud(p, self.pow_min, self.pow_max, self.pow_rolls, crawl.random_range(size_min, size_max, 1), - self.cloud_type, self.kill_cat, spread) + self.cloud_type, self.kill_cat, spread, self.colour, + self.name, self.tile) end function FogMachine:do_trigger(triggerer, marker, ev) @@ -225,6 +234,9 @@ function FogMachine:write(marker, th) file.marshall(th, self.spread_buildup_amnt) file.marshall(th, self.spread_buildup_time) file.marshall(th, self.buildup_turns) + file.marshall(th, self.colour) + file.marshall(th, self.name) + file.marshall(th, self.tile) end function FogMachine:read(marker, th) @@ -245,6 +257,9 @@ function FogMachine:read(marker, th) self.spread_buildup_amnt = file.unmarshall_number(th) self.spread_buildup_time = file.unmarshall_number(th) self.buildup_turns = file.unmarshall_number(th) + self.colour = file.unmarshall_string(th) + self.name = file.unmarshall_string(th) + self.tile = file.unmarshall_string(th) setmetatable(self, FogMachine) diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc index 9807ec54dc..3b0a1262b3 100644 --- a/crawl-ref/source/directn.cc +++ b/crawl-ref/source/directn.cc @@ -3418,10 +3418,9 @@ static void _describe_cell(const coord_def& where, bool in_range) if (env.cgrid(where) != EMPTY_CLOUD) { const int cloud_inspected = env.cgrid(where); - const cloud_type ctype = (cloud_type) env.cloud[cloud_inspected].type; mprf(MSGCH_EXAMINE, "There is a cloud of %s here.", - cloud_name(ctype).c_str()); + cloud_name(cloud_inspected).c_str()); cloud_described = true; } diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index e1a8083ef3..c3eb240a16 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -257,9 +257,13 @@ struct cloud_struct unsigned char spread_rate; kill_category whose; killer_type killer; + int colour; + std::string name; + std::string tile; cloud_struct() : pos(), type(CLOUD_NONE), decay(0), spread_rate(0), - whose(KC_OTHER), killer(KILL_NONE) + whose(KC_OTHER), killer(KILL_NONE), colour(-1), + name(""), tile("") { } diff --git a/crawl-ref/source/l_dgn.cc b/crawl-ref/source/l_dgn.cc index 99035d37f0..dddb216da4 100644 --- a/crawl-ref/source/l_dgn.cc +++ b/crawl-ref/source/l_dgn.cc @@ -1173,14 +1173,16 @@ static int lua_cloud_pow_rolls; static int make_a_lua_cloud(coord_def where, int garbage, int spread_rate, cloud_type ctype, kill_category whose, - killer_type killer) + killer_type killer, int colour, std::string name, + std::string tile) { UNUSED( garbage ); const int pow = random_range(lua_cloud_pow_min, lua_cloud_pow_max, lua_cloud_pow_rolls); - place_cloud( ctype, where, pow, whose, killer, spread_rate ); + place_cloud( ctype, where, pow, whose, killer, spread_rate, colour, name, + tile ); return 1; } @@ -1200,6 +1202,10 @@ static int dgn_apply_area_cloud(lua_State *ls) const int spread_rate = lua_isnumber(ls, 9) ? luaL_checkint(ls, 9) : -1; + const int colour = lua_isstring(ls, 10) ? str_to_colour(luaL_checkstring(ls, 10)) : -1; + std::string name = lua_isstring(ls, 11) ? luaL_checkstring(ls, 11) : ""; + std::string tile = lua_isstring(ls, 12) ? luaL_checkstring(ls, 12) : ""; + if (!in_bounds(x, y)) { char buf[80]; @@ -1265,7 +1271,7 @@ static int dgn_apply_area_cloud(lua_State *ls) apply_area_cloud(make_a_lua_cloud, coord_def(x, y), 0, size, ctype, kc, cloud_struct::whose_to_killer(kc), - spread_rate); + spread_rate, colour, name, tile); return (0); } @@ -1282,6 +1288,10 @@ static int dgn_place_cloud(lua_State *ls) const int spread_rate = lua_isnumber(ls, 6) ? luaL_checkint(ls, 6) : -1; + const int colour = lua_isstring(ls, 7) ? str_to_colour(luaL_checkstring(ls, 7)) : -1; + std::string name = lua_isstring(ls, 8) ? luaL_checkstring(ls, 8) : ""; + std::string tile = lua_isstring(ls, 9) ? luaL_checkstring(ls, 9) : ""; + if (!in_bounds(x, y)) { char buf[80]; @@ -1315,7 +1325,7 @@ static int dgn_place_cloud(lua_State *ls) return (0); } - place_cloud(ctype, coord_def(x, y), cl_range, kc, spread_rate); + place_cloud(ctype, coord_def(x, y), cl_range, kc, spread_rate, colour, name, tile); return (0); } diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index 3312bfcf94..b5c9e6bb40 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -2889,14 +2889,15 @@ bool i_feel_safe(bool announce, bool want_move, bool just_monsters, int range) // check clouds if (in_bounds(you.pos()) && env.cgrid(you.pos()) != EMPTY_CLOUD) { - const cloud_type type = env.cloud[env.cgrid(you.pos())].type; + const int cloudidx = env.cgrid(you.pos()); + const cloud_type type = env.cloud[cloudidx].type; if (is_damaging_cloud(type, want_move)) { if (announce) { mprf(MSGCH_WARN, "You're standing in a cloud of %s!", - cloud_name(type).c_str()); + cloud_name(cloudidx).c_str()); } return (false); } diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index e7e54c63d6..f16b6742c6 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -165,7 +165,7 @@ bool move_player_to_grid( const coord_def& p, bool stepped, bool allow_shift, { std::string prompt = make_stringf( "Really step into that cloud of %s?", - cloud_name(ctype).c_str()); + cloud_name(cloud).c_str()); if (!yesno(prompt.c_str(), false, 'n')) { diff --git a/crawl-ref/source/show.cc b/crawl-ref/source/show.cc index d6c3ff577a..c37901d7e0 100644 --- a/crawl-ref/source/show.cc +++ b/crawl-ref/source/show.cc @@ -273,8 +273,7 @@ void show_def::_update_cloud(int cloudno) grid(e).colour = which_colour; #ifdef USE_TILE - tile_place_cloud(e.x, e.y, env.cloud[cloudno].type, - env.cloud[cloudno].decay); + tile_place_cloud(e.x, e.y, env.cloud[cloudno]); #endif } diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc index 647077f2f4..f6dd4009a3 100644 --- a/crawl-ref/source/spells1.cc +++ b/crawl-ref/source/spells1.cc @@ -661,29 +661,32 @@ bool stinking_cloud( int pow, bolt &beem ) int cast_big_c(int pow, cloud_type cty, kill_category whose, bolt &beam) { - big_cloud( cty, whose, beam.target, pow, 8 + random2(3) ); + big_cloud( cty, whose, beam.target, pow, 8 + random2(3), -1 ); return (1); } void big_cloud(cloud_type cl_type, kill_category whose, - const coord_def& where, int pow, int size, int spread_rate) + const coord_def& where, int pow, int size, int spread_rate, + int colour, std::string name, std::string tile) { big_cloud(cl_type, whose, cloud_struct::whose_to_killer(whose), - where, pow, size, spread_rate); + where, pow, size, spread_rate, colour, name, tile); } void big_cloud(cloud_type cl_type, killer_type killer, - const coord_def& where, int pow, int size, int spread_rate) + const coord_def& where, int pow, int size, int spread_rate, + int colour, std::string name, std::string tile) { big_cloud(cl_type, cloud_struct::killer_to_whose(killer), killer, - where, pow, size, spread_rate); + where, pow, size, spread_rate, colour, name, tile); } void big_cloud(cloud_type cl_type, kill_category whose, killer_type killer, - const coord_def& where, int pow, int size, int spread_rate) + const coord_def& where, int pow, int size, int spread_rate, + int colour, std::string name, std::string tile) { apply_area_cloud(make_a_normal_cloud, where, pow, size, - cl_type, whose, killer, spread_rate); + cl_type, whose, killer, spread_rate, colour, name, tile); } static bool _mons_hostile(const monsters *mon) diff --git a/crawl-ref/source/spells1.h b/crawl-ref/source/spells1.h index 8368947f03..b342b71684 100644 --- a/crawl-ref/source/spells1.h +++ b/crawl-ref/source/spells1.h @@ -21,11 +21,14 @@ void remove_divine_stamina(); bool cast_vitalisation(); void big_cloud(cloud_type cl_type, kill_category whose, const coord_def& where, - int pow, int size, int spread_rate = -1); + int pow, int size, int spread_rate = -1, int colour = -1, + std::string name = "", std::string tile = ""); void big_cloud(cloud_type cl_type, killer_type killer, const coord_def& where, - int pow, int size, int spread_rate = -1); + int pow, int size, int spread_rate = -1, int colour = -1, + std::string name = "", std::string tile = ""); void big_cloud(cloud_type cl_type, kill_category whose, killer_type killer, - const coord_def& where, int pow, int size, int spread_rate = -1); + const coord_def& where, int pow, int size, int spread_rate = -1, + int colour = -1, std::string name = "", std::string tile = ""); int blink(int pow, bool high_level_controlled_blink, bool wizard_blink = false); diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc index 6819599ee5..6fbb55f399 100644 --- a/crawl-ref/source/spells4.cc +++ b/crawl-ref/source/spells4.cc @@ -879,14 +879,15 @@ void cast_dispersal(int pow) int make_a_normal_cloud(coord_def where, int pow, int spread_rate, cloud_type ctype, kill_category whose, - killer_type killer) + killer_type killer, int colour, std::string name, + std::string tile) { if (killer == KILL_NONE) killer = cloud_struct::whose_to_killer(whose); place_cloud( ctype, where, (3 + random2(pow / 4) + random2(pow / 4) + random2(pow / 4)), - whose, killer, spread_rate ); + whose, killer, spread_rate, colour, name, tile ); return 1; } diff --git a/crawl-ref/source/spells4.h b/crawl-ref/source/spells4.h index fbadac0203..cd977e3d01 100644 --- a/crawl-ref/source/spells4.h +++ b/crawl-ref/source/spells4.h @@ -16,7 +16,8 @@ struct bolt; bool backlight_monsters(coord_def where, int pow, int garbage); int make_a_normal_cloud(coord_def where, int pow, int spread_rate, cloud_type ctype, kill_category, - killer_type killer = KILL_NONE); + killer_type killer = KILL_NONE, int colour = -1, + std::string name = "", std::string tile = ""); int disperse_monsters(coord_def where, int pow); void remove_condensation_shield(); diff --git a/crawl-ref/source/spl-util.cc b/crawl-ref/source/spl-util.cc index 2f32ea67e1..75d7264e07 100644 --- a/crawl-ref/source/spl-util.cc +++ b/crawl-ref/source/spl-util.cc @@ -73,7 +73,8 @@ static struct spell_desc *_seekspell(spell_type spellid); static bool _cloud_helper(cloud_func func, const coord_def& where, int pow, int spread_rate, cloud_type ctype, kill_category whose, - killer_type killer); + killer_type killer, int colour, + std::string name, std::string tile); // // BEGIN PUBLIC FUNCTIONS @@ -677,13 +678,14 @@ int apply_area_within_radius(cell_func cf, const coord_def& where, void apply_area_cloud( cloud_func func, const coord_def& where, int pow, int number, cloud_type ctype, kill_category whose, killer_type killer, - int spread_rate ) + int spread_rate, int colour, std::string name, + std::string tile) { int good_squares = 0; int neighbours[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; if (number && _cloud_helper(func, where, pow, spread_rate, ctype, whose, - killer)) + killer, colour, name, tile)) number--; if (number == 0) @@ -703,7 +705,8 @@ void apply_area_cloud( cloud_func func, const coord_def& where, { const int aux = arrs[m][i]; if ( _cloud_helper(func, where + Compass[aux], - pow, spread_rate, ctype, whose, killer)) + pow, spread_rate, ctype, whose, killer, colour, + name, tile)) { number--; good_squares++; @@ -729,7 +732,7 @@ void apply_area_cloud( cloud_func func, const coord_def& where, number -= spread; good_squares--; apply_area_cloud(func, where + Compass[j], pow, spread, ctype, whose, - killer, spread_rate); + killer, spread_rate, colour, name, tile); } } @@ -893,11 +896,13 @@ bool is_valid_spell(spell_type spell) static bool _cloud_helper(cloud_func func, const coord_def& where, int pow, int spread_rate, cloud_type ctype, kill_category whose, - killer_type killer) + killer_type killer, int colour, std::string name, + std::string tile) { if (!feat_is_solid(grd(where)) && env.cgrid(where) == EMPTY_CLOUD) { - func(where, pow, spread_rate, ctype, whose, killer); + func(where, pow, spread_rate, ctype, whose, killer, colour, name, + tile); return (true); } diff --git a/crawl-ref/source/spl-util.h b/crawl-ref/source/spl-util.h index 8ff8e4ceeb..eb44f4db07 100644 --- a/crawl-ref/source/spl-util.h +++ b/crawl-ref/source/spl-util.h @@ -80,7 +80,8 @@ const char* spelltype_long_name( int which_spelltype ); typedef int cell_func(coord_def where, int pow, int aux, actor *agent); typedef int cloud_func(coord_def where, int pow, int spreadrate, cloud_type type, kill_category whose, - killer_type killer); + killer_type killer, int colour, std::string name, + std::string tile); int apply_area_visible(cell_func cf, int power, bool pass_through_trans = false, actor *agent = NULL); @@ -104,7 +105,8 @@ int apply_area_within_radius(cell_func cf, const coord_def& where, void apply_area_cloud(cloud_func func, const coord_def& where, int pow, int number, cloud_type ctype, kill_category kc, killer_type killer, - int spread_rate = -1); + int spread_rate = -1, int colour = -1, + std::string name = "", std::string tile = ""); bool spell_direction( dist &spelld, bolt &pbolt, targetting_type restrict = DIR_NONE, diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc index c092062c23..8a90a4ee00 100644 --- a/crawl-ref/source/tags.cc +++ b/crawl-ref/source/tags.cc @@ -1803,6 +1803,9 @@ static void tag_construct_level(writer &th) marshallByte(th, (char) env.cloud[i].spread_rate); marshallByte(th, env.cloud[i].whose); marshallByte(th, env.cloud[i].killer); + marshallShort(th, env.cloud[i].colour); + marshallString(th, env.cloud[i].name); + marshallString(th, env.cloud[i].tile); } // how many shops? @@ -2201,6 +2204,9 @@ static void tag_read_level( reader &th, char minorVersion ) env.cloud[i].spread_rate = (unsigned char) unmarshallByte(th); env.cloud[i].whose = static_cast(unmarshallByte(th)); env.cloud[i].killer = static_cast(unmarshallByte(th)); + env.cloud[i].colour = unmarshallShort(th); + env.cloud[i].name = unmarshallString(th); + env.cloud[i].tile = unmarshallString(th); } // how many shops? diff --git a/crawl-ref/source/tags.h b/crawl-ref/source/tags.h index e7877dfd6f..3ecacbbcd1 100644 --- a/crawl-ref/source/tags.h +++ b/crawl-ref/source/tags.h @@ -40,7 +40,7 @@ enum tag_file_type // file types supported by tag system enum tag_major_version { TAG_MAJOR_START = 5, - TAG_MAJOR_VERSION = 11 + TAG_MAJOR_VERSION = 12 }; // Minor version will be reset to zero when major version changes. diff --git a/crawl-ref/source/tilepick.cc b/crawl-ref/source/tilepick.cc index 36b3e5014c..34cbf7eb7f 100644 --- a/crawl-ref/source/tilepick.cc +++ b/crawl-ref/source/tilepick.cc @@ -2649,64 +2649,89 @@ int tileidx_feature(dungeon_feature_type feat, int gx, int gy) } } -static int _tileidx_cloud(int type, int decay) +static int _tileidx_cloud(cloud_struct cl) { + int type = cl.type; + int decay = cl.decay; + std::string override = cl.tile; + int colour = cl.colour; + int ch = TILE_ERROR; int dur = decay/20; if (dur > 2) dur = 2; - switch (type) + if (!override.empty()) { - case CLOUD_FIRE: - ch = TILE_CLOUD_FIRE_0 + dur; - break; + unsigned int index; + if (!tile_main_index(override.c_str(), index)) + { + mprf(MSGCH_ERROR, "Invalid tile requested for cloud: '%s'.", override.c_str()); + } + else + { + int offset = tile_main_count(index); + ch = index + offset; + } + } + else + { + switch (type) + { + case CLOUD_FIRE: + ch = TILE_CLOUD_FIRE_0 + dur; + break; - case CLOUD_COLD: - ch = TILE_CLOUD_COLD_0 + dur; - break; + case CLOUD_COLD: + ch = TILE_CLOUD_COLD_0 + dur; + break; - case CLOUD_STINK: - case CLOUD_POISON: - ch = TILE_CLOUD_POISON_0 + dur; - break; + case CLOUD_STINK: + case CLOUD_POISON: + ch = TILE_CLOUD_POISON_0 + dur; + break; - case CLOUD_BLUE_SMOKE: - ch = TILE_CLOUD_BLUE_SMOKE; - break; + case CLOUD_BLUE_SMOKE: + ch = TILE_CLOUD_BLUE_SMOKE; + break; - case CLOUD_PURPLE_SMOKE: - case CLOUD_TLOC_ENERGY: - ch = TILE_CLOUD_TLOC_ENERGY; - break; + case CLOUD_PURPLE_SMOKE: + case CLOUD_TLOC_ENERGY: + ch = TILE_CLOUD_TLOC_ENERGY; + break; - case CLOUD_MIASMA: - ch = TILE_CLOUD_MIASMA; - break; + case CLOUD_MIASMA: + ch = TILE_CLOUD_MIASMA; + break; - case CLOUD_BLACK_SMOKE: - ch = TILE_CLOUD_BLACK_SMOKE; - break; + case CLOUD_BLACK_SMOKE: + ch = TILE_CLOUD_BLACK_SMOKE; + break; - case CLOUD_MUTAGENIC: - ch = (dur == 0 ? TILE_CLOUD_MUTAGENIC_0 : - dur == 1 ? TILE_CLOUD_MUTAGENIC_1 - : TILE_CLOUD_MUTAGENIC_2); - ch += random2(tile_main_count(ch)); - break; + case CLOUD_MUTAGENIC: + ch = (dur == 0 ? TILE_CLOUD_MUTAGENIC_0 : + dur == 1 ? TILE_CLOUD_MUTAGENIC_1 + : TILE_CLOUD_MUTAGENIC_2); + ch += random2(tile_main_count(ch)); + break; - case CLOUD_MIST: - ch = TILE_CLOUD_MIST; - break; + case CLOUD_MIST: + ch = TILE_CLOUD_MIST; + break; - case CLOUD_RAIN: - ch = TILE_CLOUD_RAIN + random2(tile_main_count(TILE_CLOUD_RAIN)); - break; + case CLOUD_RAIN: + ch = TILE_CLOUD_RAIN + random2(tile_main_count(TILE_CLOUD_RAIN)); + break; - default: - ch = TILE_CLOUD_GREY_SMOKE; - break; + default: + ch = TILE_CLOUD_GREY_SMOKE; + break; + } } + + if (colour != -1) + ch = tile_main_coloured(ch, colour); + return (ch | TILE_FLAG_FLYING); } @@ -4852,9 +4877,9 @@ void tile_place_monster(int gx, int gy, int idx, bool foreground, bool detected) } } -void tile_place_cloud(int x, int y, int type, int decay) +void tile_place_cloud(int x, int y, cloud_struct cl) { - env.tile_fg[x][y] = _tileidx_cloud(type, decay); + env.tile_fg[x][y] = _tileidx_cloud(cl); } unsigned int num_tile_rays = 0; diff --git a/crawl-ref/source/tilereg.cc b/crawl-ref/source/tilereg.cc index 753ea5be30..82ed562c56 100644 --- a/crawl-ref/source/tilereg.cc +++ b/crawl-ref/source/tilereg.cc @@ -1541,10 +1541,8 @@ int DungeonRegion::handle_mouse(MouseEvent &event) const int cloudidx = env.cgrid(gc); if (cloudidx != EMPTY_CLOUD) { - cloud_type ctype = env.cloud[cloudidx].type; - std::string terrain_desc = desc; - desc = cloud_name(ctype); + desc = cloud_name(cloudidx); if (!terrain_desc.empty()) desc += "\n" + terrain_desc; @@ -1937,9 +1935,7 @@ bool DungeonRegion::update_alt_text(std::string &alt) const int cloudidx = env.cgrid(gc); if (cloudidx != EMPTY_CLOUD) { - cloud_type ctype = env.cloud[cloudidx].type; - - inf.prefix = "There is a cloud of " + cloud_name(ctype) + inf.prefix = "There is a cloud of " + cloud_name(cloudidx) + " here.$$"; } } diff --git a/crawl-ref/source/tiles.h b/crawl-ref/source/tiles.h index d938715e55..2f1028b72d 100644 --- a/crawl-ref/source/tiles.h +++ b/crawl-ref/source/tiles.h @@ -74,7 +74,7 @@ void tile_place_monster(int gx, int gy, int idx, bool foreground = true, bool detected = false); void tile_place_item(int x, int y, int idx); void tile_place_item_marker(int x, int y, int idx); -void tile_place_cloud(int x, int y, int type, int decay); +void tile_place_cloud(int x, int y, cloud_struct cl); void tile_place_ray(const coord_def& gc, bool in_range); void tile_draw_rays(bool resetCount); void tile_clear_buf(); diff --git a/crawl-ref/source/tutorial.cc b/crawl-ref/source/tutorial.cc index 6893f64262..7f6bc68bc8 100644 --- a/crawl-ref/source/tutorial.cc +++ b/crawl-ref/source/tutorial.cc @@ -4440,7 +4440,7 @@ static void _tutorial_describe_cloud(int x, int y) if (ctype == CLOUD_NONE) return; - std::string cname = cloud_name(ctype); + std::string cname = cloud_name(env.cgrid(coord_def(x, y))); std::ostringstream ostr; -- cgit v1.2.3-54-g00ecf From 8b00e0051117ac616b658fddddfc61451aaf5e74 Mon Sep 17 00:00:00 2001 From: Darshan Shaligram Date: Sun, 27 Dec 2009 20:02:40 +0530 Subject: Reset tag minor version, since major version has been incremented (due). --- crawl-ref/source/tags.cc | 15 ++++++--------- crawl-ref/source/tags.h | 3 +-- 2 files changed, 7 insertions(+), 11 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc index 8a90a4ee00..6d12c323ab 100644 --- a/crawl-ref/source/tags.cc +++ b/crawl-ref/source/tags.cc @@ -2236,16 +2236,13 @@ static void tag_read_level( reader &th, char minorVersion ) // Restore heightmap env.heightmap.reset(NULL); - if (_tag_minor_version >= TAG_MINOR_HEIGHTMAP) + const bool have_heightmap(unmarshallByte(th)); + if (have_heightmap) { - const bool have_heightmap(unmarshallByte(th)); - if (have_heightmap) - { - env.heightmap.reset(new grid_heightmap); - grid_heightmap &heightmap(*env.heightmap); - for (rectangle_iterator ri(0); ri; ++ri) - heightmap(*ri) = unmarshallShort(th); - } + env.heightmap.reset(new grid_heightmap); + grid_heightmap &heightmap(*env.heightmap); + for (rectangle_iterator ri(0); ri; ++ri) + heightmap(*ri) = unmarshallShort(th); } } diff --git a/crawl-ref/source/tags.h b/crawl-ref/source/tags.h index 3ecacbbcd1..f9c3959299 100644 --- a/crawl-ref/source/tags.h +++ b/crawl-ref/source/tags.h @@ -47,8 +47,7 @@ enum tag_major_version enum tag_minor_version { TAG_MINOR_RESET = 0, // Minor tags were reset - TAG_MINOR_HEIGHTMAP = 1, - TAG_MINOR_VERSION = 1 // Current version. (Keep equal to max.) + TAG_MINOR_VERSION = 0 // Current version. (Keep equal to max.) }; struct enum_info -- cgit v1.2.3-54-g00ecf From 21c3ed598c240e9ab0bcb856c6dc84d2cee11f99 Mon Sep 17 00:00:00 2001 From: Adam Borowski Date: Sun, 27 Dec 2009 15:35:16 +0100 Subject: Use the old message for rain, "You are engulfed in the rain." is bad. --- crawl-ref/source/cloud.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/cloud.cc b/crawl-ref/source/cloud.cc index bd5670b846..58eb185c97 100644 --- a/crawl-ref/source/cloud.cc +++ b/crawl-ref/source/cloud.cc @@ -813,7 +813,10 @@ void in_a_cloud() you.duration[DUR_MISLED] = 0; } - mprf("You are engulfed in %s.", !name.empty() ? name.c_str() : "the rain"); + if (name.empty() || name == "the rain") + mpr("You are standing in the rain."); + else + mprf("You are engulfed in %s.", name.c_str()); break; -- cgit v1.2.3-54-g00ecf From caad029e611bb2eeedcab049d624a9e2be4e0dd5 Mon Sep 17 00:00:00 2001 From: Vsevolod Kozlov Date: Sun, 27 Dec 2009 18:21:20 +0300 Subject: Unify wizard_create_feature_{name,number}. It works fine, but it does not show the verbose message about placing the feature, as wizard_create_feature_name used to. (This doesn't seem very necessary since debug-mode 'x' tends to give enough information.) --- crawl-ref/source/main.cc | 4 +- crawl-ref/source/wiz-dgn.cc | 91 ++++++++++++++++++--------------------------- crawl-ref/source/wiz-dgn.h | 3 +- 3 files changed, 39 insertions(+), 59 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/main.cc b/crawl-ref/source/main.cc index c1b4c6d615..9dcd774a00 100644 --- a/crawl-ref/source/main.cc +++ b/crawl-ref/source/main.cc @@ -533,8 +533,8 @@ static void _do_wizard_command(int wiz_command, bool silent_fail) case 'I': wizard_unidentify_pack(); break; case 'Z': case 'z': wizard_cast_spec_spell(); break; - case '(': wizard_create_feature_number(); break; - case ')': wizard_create_feature_name(); break; + case '(': + case ')': wizard_create_feature(); break; case ':': wizard_list_branches(); break; case '{': wizard_map_level(); break; case '}': wizard_reveal_traps(); break; diff --git a/crawl-ref/source/wiz-dgn.cc b/crawl-ref/source/wiz-dgn.cc index ea55dc9e56..8251e6c76e 100644 --- a/crawl-ref/source/wiz-dgn.cc +++ b/crawl-ref/source/wiz-dgn.cc @@ -269,70 +269,53 @@ void wizard_create_portal() } } -void wizard_create_feature_number() +void wizard_create_feature() { char specs[256]; int feat_num; - mpr("Create which feature (by number)? ", MSGCH_PROMPT); + dungeon_feature_type feat; + mpr("Create which feature? ", MSGCH_PROMPT); - if (!cancelable_get_line(specs, sizeof(specs)) - && (feat_num = atoi(specs))) + if (!cancelable_get_line(specs, sizeof(specs)) && specs[0] != 0) { - dungeon_feature_type feat = static_cast(feat_num); - if (feat == DNGN_ENTER_SHOP) + if ((feat_num = atoi(specs))) { - debug_make_shop(); - return; + feat = static_cast(feat_num); } - - dungeon_terrain_changed(you.pos(), feat, false); -#ifdef USE_TILE - env.tile_flv(you.pos()).special = 0; -#endif - } - else - canned_msg(MSG_OK); -} - -void wizard_create_feature_name() -{ - char specs[256]; - mpr("Create which feature (by name)? ", MSGCH_PROMPT); - if (!cancelable_get_line(specs, sizeof(specs)) && specs[0] != 0) - { - // Accept both "shallow_water" and "Shallow water" - std::string name = lowercase_string(specs); - name = replace_all(name, " ", "_"); - - dungeon_feature_type feat = dungeon_feature_by_name(name); - if (feat == DNGN_UNSEEN) // no exact match + else { - std::vector matches = dungeon_feature_matches(name); - - if (matches.empty()) + std::string name = lowercase_string(specs); + name = replace_all(name, " ", "_"); + feat = dungeon_feature_by_name(name); + if (feat == DNGN_UNSEEN) // no exact match { - mprf(MSGCH_DIAGNOSTICS, "No features matching '%s'", - name.c_str()); - return; - } + std::vector matches = dungeon_feature_matches(name); - // Only one possible match, use that. - if (matches.size() == 1) - { - name = matches[0]; - feat = dungeon_feature_by_name(name); - } - // Multiple matches, list them to wizard - else - { - std::string prefix = "No exact match for feature '" + - name + "', possible matches are: "; + if (matches.empty()) + { + mprf(MSGCH_DIAGNOSTICS, "No features matching '%s'", + name.c_str()); + return; + } - // Use mpr_comma_separated_list() because the list - // might be *LONG*. - mpr_comma_separated_list(prefix, matches, " and ", ", ", - MSGCH_DIAGNOSTICS); - return; + // Only one possible match, use that. + if (matches.size() == 1) + { + name = matches[0]; + feat = dungeon_feature_by_name(name); + } + // Multiple matches, list them to wizard + else + { + std::string prefix = "No exact match for feature '" + + name + "', possible matches are: "; + + // Use mpr_comma_separated_list() because the list + // might be *LONG*. + mpr_comma_separated_list(prefix, matches, " and ", ", ", + MSGCH_DIAGNOSTICS); + return; + } } } @@ -342,8 +325,6 @@ void wizard_create_feature_name() return; } - mprf(MSGCH_DIAGNOSTICS, "Setting (%d,%d) to %s (%d)", - you.pos().x, you.pos().y, name.c_str(), feat); dungeon_terrain_changed(you.pos(), feat, false); #ifdef USE_TILE env.tile_flv(you.pos()).special = 0; diff --git a/crawl-ref/source/wiz-dgn.h b/crawl-ref/source/wiz-dgn.h index c8561dcb1f..3db62ceb1b 100644 --- a/crawl-ref/source/wiz-dgn.h +++ b/crawl-ref/source/wiz-dgn.h @@ -10,8 +10,7 @@ #include void wizard_create_portal(); -void wizard_create_feature_number(); -void wizard_create_feature_name(); +void wizard_create_feature(); void wizard_list_branches(); void wizard_reveal_traps(); void wizard_map_level(); -- cgit v1.2.3-54-g00ecf From fa0307d3451bef981c807759f956b0de01d5485f Mon Sep 17 00:00:00 2001 From: Vsevolod Kozlov Date: Sun, 27 Dec 2009 18:23:31 +0300 Subject: dungeon.cc: Kill a small piece of code duplication in special room handling. Hopefully I've got the logic inversion right... --- crawl-ref/source/dungeon.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index c5f6a788ca..61b09b2717 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -7346,12 +7346,11 @@ static void _roguey_level(int level_number, spec_room &sr, bool make_stairs) // Is one of them a special room? const map_def *sroom = NULL; -#ifdef DEBUG_SPECIAL_ROOMS - if ((sroom = random_map_for_tag("special_room", true)) != NULL) -#else - if (one_chance_in(10) - && (sroom = random_map_for_tag("special_room", true)) != NULL) + if ( +#ifndef DEBUG_SPECIAL_ROOMS + one_chance_in(10) && #endif + (sroom = random_map_for_tag("special_room", true)) != NULL) { int spec_room_done = random2(25); -- cgit v1.2.3-54-g00ecf From 2be5d5f08528b99817be0cf6fe8c04bab40842ec Mon Sep 17 00:00:00 2001 From: Adam Borowski Date: Sun, 27 Dec 2009 16:37:34 +0100 Subject: Untie disarm confirmations from autotravel settings (Mantis 254). Since it is done only on an explicit request, copious safety margins are not needed. I didn't provide an alternate way to disable the confirmation, but since the danger is now always real, I don't think that's needed. --- crawl-ref/source/trap_def.h | 1 + crawl-ref/source/traps.cc | 37 ++++++++++++++++++++++++++----------- 2 files changed, 27 insertions(+), 11 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/trap_def.h b/crawl-ref/source/trap_def.h index 90c2cc4372..2ec924d3b4 100644 --- a/crawl-ref/source/trap_def.h +++ b/crawl-ref/source/trap_def.h @@ -18,6 +18,7 @@ struct trap_def void prepare_ammo(); bool type_has_ammo() const; bool active() const; + int max_damage(const actor& act); private: void message_trap_entry(); diff --git a/crawl-ref/source/traps.cc b/crawl-ref/source/traps.cc index e2dcd625ea..9083576b6e 100644 --- a/crawl-ref/source/traps.cc +++ b/crawl-ref/source/traps.cc @@ -677,7 +677,7 @@ void trap_def::trigger(actor& triggerer, bool flat_footed) this->destroy(); } -int trap_def::shot_damage(actor& act) +int trap_def::max_damage(const actor& act) { int level = you.your_level; @@ -691,17 +691,27 @@ int trap_def::shot_damage(actor& act) switch (this->type) { case TRAP_NEEDLE: return 0; - case TRAP_DART: return random2( 4 + level/2) + 1; - case TRAP_ARROW: return random2( 7 + level) + 1; - case TRAP_SPEAR: return random2(10 + level) + 1; - case TRAP_BOLT: return random2(13 + level) + 1; - case TRAP_AXE: return random2(15 + level) + 1; + case TRAP_DART: return 4 + level/2; + case TRAP_ARROW: return 7 + level; + case TRAP_SPEAR: return 10 + level; + case TRAP_BOLT: return 13 + level; + case TRAP_AXE: return 15 + level; default: return 0; + case TRAP_BLADE: return (level ? level*2 : 10) + 28; } return (0); } +int trap_def::shot_damage(actor& act) +{ + const int dam = max_damage(act); + + if (!dam) + return 0; + return random2(dam) + 1; +} + int reveal_traps(const int range) { int traps_found = 0; @@ -746,6 +756,15 @@ trap_type get_trap_type(const coord_def& pos) return (TRAP_UNASSIGNED); } +static bool _disarm_is_deadly(trap_def& trap) +{ + int dam = trap.max_damage(you); + if (trap.type == TRAP_NEEDLE && you.res_poison() <= 0) + dam += 15; // arbitrary + + return you.hp <= dam; +} + // where *must* point to a valid, discovered trap. void disarm_trap(const coord_def& where) { @@ -770,11 +789,8 @@ void disarm_trap(const coord_def& where) break; } -#ifdef CLUA_BINDINGS // Prompt for any trap for which you might not survive setting it off. - // (See trapwalk.lua) - if (Options.trap_prompt - && !clua.callbooleanfn(false, "ch_cross_trap", "s", trap_name(where))) + if (_disarm_is_deadly(trap)) { std::string prompt = make_stringf( "Really try disarming that %s?", @@ -789,7 +805,6 @@ void disarm_trap(const coord_def& where) return; } } -#endif // Make the actual attempt you.turn_is_over = true; -- cgit v1.2.3-54-g00ecf From 76b76949fb3f6fe4c1e735f0b1d9ef72ae4a6a68 Mon Sep 17 00:00:00 2001 From: Vsevolod Kozlov Date: Sun, 27 Dec 2009 18:43:04 +0300 Subject: Don't show normal teleport messages on wizard teleports. The "You may choose your destination..." and "Expect minor deviation" messages are lost due to the absence of the more prompt on wizard teleports, and arrive after the teleport, which is more annoying than not at all. --- crawl-ref/source/spells3.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc index 26747c1f07..3a7f8130e1 100644 --- a/crawl-ref/source/spells3.cc +++ b/crawl-ref/source/spells3.cc @@ -1528,13 +1528,15 @@ static bool _teleport_player(bool allow_control, bool new_abyss_area, bool wizar if (is_controlled) { - mpr("You may choose your destination (press '.' or delete to select)."); - mpr("Expect minor deviation."); check_ring_TC = true; - // Only have the more prompt for non-wizard. + // Only have the messages and the more prompt for non-wizard. if (!wizard_tele) + { + mpr("You may choose your destination (press '.' or delete to select)."); + mpr("Expect minor deviation."); more(); + } while (true) { -- cgit v1.2.3-54-g00ecf From 507c3523d54cd2c15185f06f8be1f1ea353497d8 Mon Sep 17 00:00:00 2001 From: Vsevolod Kozlov Date: Sun, 27 Dec 2009 19:00:10 +0300 Subject: Make item_is_critical a method of item_def. --- crawl-ref/source/externs.h | 3 +++ crawl-ref/source/itemprop.cc | 15 --------------- crawl-ref/source/itemprop.h | 3 --- crawl-ref/source/items.cc | 15 +++++++++++++++ crawl-ref/source/terrain.cc | 2 +- crawl-ref/source/xom.cc | 2 +- 6 files changed, 20 insertions(+), 20 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index c3eb240a16..cf2b98d8d0 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -533,6 +533,9 @@ public: bool is_valid() const; + // Returns true if this item should be preserved as far as possible. + bool is_critical() const; + private: std::string name_aux(description_level_type desc, bool terse, bool ident, diff --git a/crawl-ref/source/itemprop.cc b/crawl-ref/source/itemprop.cc index 720dfff844..ee8e022c63 100644 --- a/crawl-ref/source/itemprop.cc +++ b/crawl-ref/source/itemprop.cc @@ -567,21 +567,6 @@ bool item_ident( const item_def &item, unsigned long flags ) return ((item.flags & flags) == flags); } -// The Orb of Zot and unique runes are considered critical. -bool item_is_critical(const item_def &item) -{ - if (!item.is_valid()) - return (false); - - if (item.base_type == OBJ_ORBS) - return (true); - - return (item.base_type == OBJ_MISCELLANY - && item.sub_type == MISC_RUNE_OF_ZOT - && item.plus != RUNE_DEMONIC - && item.plus != RUNE_ABYSSAL); -} - // Is item something that no one would usually bother enchanting? bool item_is_mundane(const item_def &item) { diff --git a/crawl-ref/source/itemprop.h b/crawl-ref/source/itemprop.h index a8f1eceabd..3a38fdb35b 100644 --- a/crawl-ref/source/itemprop.h +++ b/crawl-ref/source/itemprop.h @@ -14,9 +14,6 @@ struct bolt; void init_properties(void); -// Returns true if this item should be preserved as far as possible. -bool item_is_critical(const item_def &item); - // Returns true if this item should not normally be enchanted. bool item_is_mundane(const item_def &item); diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index a3418761d4..fa2b57fdea 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -2919,6 +2919,21 @@ bool item_def::is_valid() const return (base_type != OBJ_UNASSIGNED && quantity > 0); } +// The Orb of Zot and unique runes are considered critical. +bool item_def::is_critical() const +{ + if (!is_valid()) + return (false); + + if (base_type == OBJ_ORBS) + return (true); + + return (base_type == OBJ_MISCELLANY + && sub_type == MISC_RUNE_OF_ZOT + && plus != RUNE_DEMONIC + && plus != RUNE_ABYSSAL); +} + static void _rune_from_specs(const char* _specs, item_def &item) { char specs[80]; diff --git a/crawl-ref/source/terrain.cc b/crawl-ref/source/terrain.cc index 05b3033e8e..9b2fe96deb 100644 --- a/crawl-ref/source/terrain.cc +++ b/crawl-ref/source/terrain.cc @@ -664,7 +664,7 @@ static void _dgn_check_terrain_items(const coord_def &pos, bool preserve_items) item = mitm[item].link; // Game-critical item. - if (preserve_items || item_is_critical(mitm[curr])) + if (preserve_items || mitm[curr].is_critical()) _dgn_shift_item(pos, mitm[curr]); else { diff --git a/crawl-ref/source/xom.cc b/crawl-ref/source/xom.cc index a2c7a4d227..4f01f1145a 100644 --- a/crawl-ref/source/xom.cc +++ b/crawl-ref/source/xom.cc @@ -2308,7 +2308,7 @@ static void _xom_zero_miscast() { const item_def &item(you.inv[i]); if (item.is_valid() && !item_is_equipped(item) - && !item_is_critical(item)) + && !item.is_critical()) { inv_items.push_back(i); } -- cgit v1.2.3-54-g00ecf From dc3e12a4da48363a7cadb77f30b8e784d5f82acf Mon Sep 17 00:00:00 2001 From: Vsevolod Kozlov Date: Sun, 27 Dec 2009 19:25:32 +0300 Subject: Replace uses of item_cursed with item_def::cursed. --- crawl-ref/source/delay.cc | 2 +- crawl-ref/source/fight.cc | 4 ++-- crawl-ref/source/food.cc | 4 ++-- crawl-ref/source/invent.cc | 2 +- crawl-ref/source/item_use.cc | 42 +++++++++++++++++++++--------------------- crawl-ref/source/itemname.cc | 10 +++++----- crawl-ref/source/itemprop.cc | 9 ++------- crawl-ref/source/itemprop.h | 1 - crawl-ref/source/items.cc | 4 ++-- crawl-ref/source/l_item.cc | 2 +- crawl-ref/source/makeitem.cc | 2 +- crawl-ref/source/mon-stuff.cc | 2 +- crawl-ref/source/monster.cc | 6 +++--- crawl-ref/source/player.cc | 2 +- crawl-ref/source/religion.cc | 2 +- crawl-ref/source/spells2.cc | 4 ++-- crawl-ref/source/spells3.cc | 4 ++-- crawl-ref/source/tilereg.cc | 4 ++-- crawl-ref/source/tilesdl.cc | 2 +- crawl-ref/source/transfor.cc | 2 +- crawl-ref/source/tutorial.cc | 4 ++-- crawl-ref/source/wiz-item.cc | 2 +- 22 files changed, 55 insertions(+), 61 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc index a3a6ca6d5d..56c166fdec 100644 --- a/crawl-ref/source/delay.cc +++ b/crawl-ref/source/delay.cc @@ -1564,7 +1564,7 @@ void armour_wear_effects(const int item_slot) use_artefact(arm, &show_msgs, melded); } - if (item_cursed(arm) && !melded) + if (arm.cursed() && !melded) { mpr("Oops, that feels deathly cold."); learned_something_new(TUT_YOU_CURSED); diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc index 1543ddabb1..b2237a92cb 100644 --- a/crawl-ref/source/fight.cc +++ b/crawl-ref/source/fight.cc @@ -374,7 +374,7 @@ void melee_attack::check_hand_half_bonus_eligible() && !can_do_unarmed && !shield && weapon - && !item_cursed(*weapon) + && !weapon->cursed() && hands == HANDS_HALF); } @@ -3832,7 +3832,7 @@ int melee_attack::player_to_hit(bool random_factor) && !can_do_unarmed && !shield && weapon - && !item_cursed( *weapon ) + && !weapon ->cursed() && hands == HANDS_HALF; int your_to_hit = 15 + (calc_stat_to_hit_base() / 2); diff --git a/crawl-ref/source/food.cc b/crawl-ref/source/food.cc index 112f9e1739..bd2db8d728 100644 --- a/crawl-ref/source/food.cc +++ b/crawl-ref/source/food.cc @@ -377,7 +377,7 @@ static void _terminate_butchery(bool wpn_switch, bool removed_gloves, { // Switch weapon back. if (wpn_switch && you.equip[EQ_WEAPON] != old_weapon - && (!you.weapon() || !item_cursed(*you.weapon()))) + && (!you.weapon() || !you.weapon()->cursed())) { start_delay(DELAY_WEAPON_SWAP, 1, old_weapon); } @@ -479,7 +479,7 @@ bool butchery(int which_corpse) && !player_wearing_slot(EQ_GLOVES); bool gloved_butcher = (you.has_claws() && player_wearing_slot(EQ_GLOVES) - && !item_cursed(you.inv[you.equip[EQ_GLOVES]])); + && !you.inv[you.equip[EQ_GLOVES]].cursed()); bool can_butcher = (teeth_butcher || barehand_butcher || you.weapon() && can_cut_meat(*you.weapon())); diff --git a/crawl-ref/source/invent.cc b/crawl-ref/source/invent.cc index 047a502467..887fbd436c 100644 --- a/crawl-ref/source/invent.cc +++ b/crawl-ref/source/invent.cc @@ -109,7 +109,7 @@ const std::string &InvEntry::get_fullname() const bool InvEntry::is_item_cursed() const { - return (item_ident(*item, ISFLAG_KNOW_CURSE) && item_cursed(*item)); + return (item_ident(*item, ISFLAG_KNOW_CURSE) && item->cursed()); } bool InvEntry::is_item_glowing() const diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index 38bf295a7a..fd01008e25 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -112,7 +112,7 @@ bool can_wield(item_def *weapon, bool say_reason, if (!ignore_temporary_disability && you.weapon() && you.weapon()->base_type == OBJ_WEAPONS - && item_cursed(*you.weapon())) + && you.weapon()->cursed()) { SAY(mpr("You can't unwield your weapon to draw a new one!")); return (false); @@ -721,7 +721,7 @@ void wield_effects(int item_wield_2, bool showMsgs) } } - if (item_cursed(item)) + if (item.cursed()) { mpr("It sticks to your hand!"); int amusement = 16; @@ -1059,7 +1059,7 @@ bool do_wear_armour(int item, bool quiet) && you.equip[EQ_CLOAK] != -1 && !cloak_is_being_removed()) { if (you.equip[EQ_BODY_ARMOUR] != -1 - && item_cursed(you.inv[you.equip[EQ_BODY_ARMOUR]])) + && you.inv[you.equip[EQ_BODY_ARMOUR]].cursed()) { if (!quiet) { @@ -1069,7 +1069,7 @@ bool do_wear_armour(int item, bool quiet) } return (false); } - if (!item_cursed(you.inv[you.equip[EQ_CLOAK]])) + if (!you.inv[you.equip[EQ_CLOAK]].cursed()) { cloak = you.equip[EQ_CLOAK]; if (!takeoff_armour(you.equip[EQ_CLOAK])) @@ -1149,7 +1149,7 @@ bool takeoff_armour(int item) } // If we get here, we're wearing the item. - if (item_cursed(invitem)) + if (invitem.cursed()) { mprf("%s is stuck to your body!", invitem.name(DESC_CAP_YOUR).c_str()); return (false); @@ -1165,7 +1165,7 @@ bool takeoff_armour(int item) { if (you.equip[EQ_CLOAK] != -1 && !cloak_is_being_removed()) { - if (!item_cursed(you.inv[you.equip[EQ_CLOAK]])) + if (!you.inv[you.equip[EQ_CLOAK]].cursed()) { cloak = you.equip[ EQ_CLOAK ]; if (!takeoff_armour(you.equip[EQ_CLOAK])) @@ -1453,7 +1453,7 @@ static bool _fire_validate_item(int slot, std::string &err) { if (slot == you.equip[EQ_WEAPON] && you.inv[slot].base_type == OBJ_WEAPONS - && item_cursed(you.inv[slot])) + && you.inv[slot].cursed()) { err = "That weapon is stuck to your hand!"; return (false); @@ -3481,7 +3481,7 @@ void jewellery_wear_effects(item_def &item) set_ident_flags(item, ISFLAG_EQ_JEWELLERY_MASK); } - if (item_cursed(item)) + if (item.cursed()) { mprf("Oops, that %s feels deathly cold.", jewellery_is_amulet(item)? "amulet" : "ring"); @@ -3510,7 +3510,7 @@ static int _prompt_ring_to_remove(int new_ring) const item_def *left = you.slot_item(EQ_LEFT_RING); const item_def *right = you.slot_item(EQ_RIGHT_RING); - if (item_cursed(*left) && item_cursed(*right)) + if (left->cursed() && right->cursed()) { mprf("You're already wearing two cursed rings!"); return (-1); @@ -3730,7 +3730,7 @@ static bool _swap_rings(int ring_slot) const item_def* lring = you.slot_item(EQ_LEFT_RING); const item_def* rring = you.slot_item(EQ_RIGHT_RING); - if (item_cursed(*lring) && item_cursed(*rring)) + if (lring->cursed() && rring->cursed()) { mprf("You're already wearing two cursed rings!"); return (false); @@ -3744,7 +3744,7 @@ static bool _swap_rings(int ring_slot) && lring->plus2 == rring->plus2 && !is_artefact(*lring) && !is_artefact(*rring)) { - if (item_cursed(*lring)) + if (lring->cursed()) unwanted = you.equip[EQ_RIGHT_RING]; else unwanted = you.equip[EQ_LEFT_RING]; @@ -3811,7 +3811,7 @@ bool puton_item(int item_slot) if (!is_amulet) // i.e. it's a ring { const item_def* gloves = you.slot_item(EQ_GLOVES); - if (gloves && item_cursed(*gloves)) + if (gloves && gloves->cursed()) { mpr("You can't take your gloves off to put on a ring!"); return (false); @@ -4025,7 +4025,7 @@ bool remove_ring(int slot, bool announce) } if (you.equip[EQ_GLOVES] != -1 - && item_cursed( you.inv[you.equip[EQ_GLOVES]] ) + && you.inv[you.equip[EQ_GLOVES]] .cursed() && you.equip[EQ_AMULET] == -1) { mpr("You can't take your gloves off to remove any rings!"); @@ -4089,7 +4089,7 @@ bool remove_ring(int slot, bool announce) } if (you.equip[EQ_GLOVES] != -1 - && item_cursed( you.inv[you.equip[EQ_GLOVES]] ) + && you.inv[you.equip[EQ_GLOVES]] .cursed() && (hand_used == EQ_LEFT_RING || hand_used == EQ_RIGHT_RING)) { mpr("You can't take your gloves off to remove any rings!"); @@ -4102,7 +4102,7 @@ bool remove_ring(int slot, bool announce) return (false); } - if (item_cursed( you.inv[you.equip[hand_used]] )) + if (you.inv[you.equip[hand_used]] .cursed()) { if (announce) { @@ -4771,7 +4771,7 @@ bool enchant_weapon(enchant_stat_type which_stat, bool quiet, item_def &wpn) return (false); } - const bool is_cursed = item_cursed(wpn); + const bool is_cursed = wpn.cursed(); // Missiles only have one stat. if (wpn.base_type == OBJ_MISSILES) @@ -4882,7 +4882,7 @@ bool enchant_armour(int &ac_change, bool quiet, item_def &arm) return (false); } - const bool is_cursed = item_cursed(arm); + const bool is_cursed = arm.cursed(); // Turn hides into mails where applicable. // NOTE: It is assumed that armour which changes in this way does @@ -5355,7 +5355,7 @@ void read_scroll(int slot) case SCR_CURSE_WEAPON: if (!you.weapon() || you.weapon()->base_type != OBJ_WEAPONS - || item_cursed(*you.weapon())) + || you.weapon()->cursed()) { canned_msg(MSG_NOTHING_HAPPENS); id_the_scroll = false; @@ -5383,7 +5383,7 @@ void read_scroll(int slot) { item_def& wpn = *you.weapon(); - const bool is_cursed = item_cursed(wpn); + const bool is_cursed = wpn.cursed(); if (wpn.base_type != OBJ_WEAPONS && wpn.base_type != OBJ_MISSILES || !is_cursed @@ -5491,7 +5491,7 @@ void read_scroll(int slot) int affected = EQ_WEAPON; for (int i = EQ_CLOAK; i <= EQ_BODY_ARMOUR; i++) { - if (you.equip[i] != -1 && !item_cursed(you.inv[you.equip[i]])) + if (you.equip[i] != -1 && !you.inv[you.equip[i]].cursed()) { count++; if (one_chance_in(count)) @@ -5695,7 +5695,7 @@ void use_artefact(item_def &item, bool *show_msgs, bool unmeld) artefact_wpn_learn_prop(item, ARTP_BERSERK); } - if (!unmeld && !item_cursed(item) && proprt[ARTP_CURSED] > 0 + if (!unmeld && !item.cursed() && proprt[ARTP_CURSED] > 0 && one_chance_in(proprt[ARTP_CURSED])) { do_curse_item( item, false ); diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc index 8d487d2682..c8ce048107 100644 --- a/crawl-ref/source/itemname.cc +++ b/crawl-ref/source/itemname.cc @@ -1037,7 +1037,7 @@ std::string item_def::name_aux(description_level_type desc, // this behaviour, *please* make it so that there is an option // that maintains this behaviour. -- bwr // Nor for artefacts. Again, the state should be obvious. --jpeg - if (item_cursed(*this)) + if (cursed()) buff << "cursed "; else if (Options.show_uncursed && !know_pluses && (!know_type || !is_artefact(*this))) @@ -1108,7 +1108,7 @@ std::string item_def::name_aux(description_level_type desc, if (know_brand) buff << weapon_brand_name(*this, terse); - if (know_curse && item_cursed(*this) && terse) + if (know_curse && cursed() && terse) buff << " (curse)"; break; @@ -1197,7 +1197,7 @@ std::string item_def::name_aux(description_level_type desc, case OBJ_ARMOUR: if (know_curse && !terse) { - if (item_cursed(*this)) + if (cursed()) buff << "cursed "; else if (Options.show_uncursed && !know_pluses) buff << "uncursed "; @@ -1310,7 +1310,7 @@ std::string item_def::name_aux(description_level_type desc, } } - if (know_curse && item_cursed(*this) && terse) + if (know_curse && cursed() && terse) buff << " (curse)"; break; @@ -1462,7 +1462,7 @@ std::string item_def::name_aux(description_level_type desc, if (know_curse) { - if (item_cursed(*this)) + if (cursed()) buff << "cursed "; else if (Options.show_uncursed && !terse && (!is_randart || !know_type) diff --git a/crawl-ref/source/itemprop.cc b/crawl-ref/source/itemprop.cc index ee8e022c63..ea2f8bd7b3 100644 --- a/crawl-ref/source/itemprop.cc +++ b/crawl-ref/source/itemprop.cc @@ -457,11 +457,6 @@ void init_properties() // // Item cursed status functions: // -bool item_cursed( const item_def &item ) -{ - return (item.flags & ISFLAG_CURSED); -} - bool item_known_cursed( const item_def &item ) { return ((item.flags & ISFLAG_KNOW_CURSE) && (item.flags & ISFLAG_CURSED)); @@ -1195,7 +1190,7 @@ bool is_enchantable_weapon(const item_def &wpn, bool uncurse, bool first) || first && wpn.plus >= MAX_WPN_ENCHANT || !first && wpn.plus2 >= MAX_WPN_ENCHANT) { - return (uncurse && item_cursed(wpn)); + return (uncurse && wpn.cursed()); } } // Highly enchanted missiles, which have only one stat, cannot be @@ -1228,7 +1223,7 @@ bool is_enchantable_armour(const item_def &arm, bool uncurse, bool unknown) // Artefacts or highly enchanted armour cannot be enchanted, only // uncursed. if (is_artefact(arm) || arm.plus >= armour_max_enchant(arm)) - return (uncurse && item_cursed(arm)); + return (uncurse && arm.cursed()); return (true); } diff --git a/crawl-ref/source/itemprop.h b/crawl-ref/source/itemprop.h index 3a38fdb35b..99c861da67 100644 --- a/crawl-ref/source/itemprop.h +++ b/crawl-ref/source/itemprop.h @@ -18,7 +18,6 @@ void init_properties(void); bool item_is_mundane(const item_def &item); // cursed: -bool item_cursed( const item_def &item ); bool item_known_cursed( const item_def &item ); bool item_known_uncursed( const item_def &item ); void do_curse_item( item_def &item, bool quiet = true ); diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index fa2b57fdea..7543da8ea5 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -1921,7 +1921,7 @@ bool drop_item( int item_dropped, int quant_drop, bool try_offer ) if (item_dropped == you.equip[EQ_WEAPON] && you.inv[item_dropped].base_type == OBJ_WEAPONS - && item_cursed( you.inv[item_dropped] )) + && you.inv[item_dropped] .cursed()) { mpr("That object is stuck to you!"); return (false); @@ -2821,7 +2821,7 @@ int item_def::book_number() const bool item_def::cursed() const { - return (item_cursed(*this)); + return (flags & ISFLAG_CURSED); } bool item_def::launched_by(const item_def &launcher) const diff --git a/crawl-ref/source/l_item.cc b/crawl-ref/source/l_item.cc index c2248e1682..80bbc88df9 100644 --- a/crawl-ref/source/l_item.cc +++ b/crawl-ref/source/l_item.cc @@ -463,7 +463,7 @@ static int l_item_cursed(lua_State *ls) { LUA_ITEM(item, 1); bool cursed = item && item_ident(*item, ISFLAG_KNOW_CURSE) - && item_cursed(*item); + && item->cursed(); lua_pushboolean(ls, cursed); return (1); } diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc index ee473f1a04..977198929d 100644 --- a/crawl-ref/source/makeitem.cc +++ b/crawl-ref/source/makeitem.cc @@ -2924,7 +2924,7 @@ static void _generate_jewellery_item(item_def& item, bool allow_uniques, if (item.sub_type == RING_SLAYING ) // requires plus2 too { - if (item_cursed(item) && !one_chance_in(20)) + if (item.cursed() && !one_chance_in(20)) item.plus2 = -1 - random2avg(6, 2); else { diff --git a/crawl-ref/source/mon-stuff.cc b/crawl-ref/source/mon-stuff.cc index d8f0a8e7a2..730fb54ef2 100644 --- a/crawl-ref/source/mon-stuff.cc +++ b/crawl-ref/source/mon-stuff.cc @@ -198,7 +198,7 @@ bool curse_an_item( bool decay_potions, bool quiet ) || you.inv[i].base_type == OBJ_JEWELLERY || you.inv[i].base_type == OBJ_POTIONS) { - if (item_cursed( you.inv[i] )) + if (you.inv[i] .cursed()) continue; if (you.inv[i].base_type != OBJ_POTIONS diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc index 4cefe30857..5285da7795 100644 --- a/crawl-ref/source/monster.cc +++ b/crawl-ref/source/monster.cc @@ -577,11 +577,11 @@ bool monsters::can_wield(const item_def& item, bool ignore_curse, if (!ignore_curse) { int num_cursed = 0; - if (weap1 && item_cursed(*weap1)) + if (weap1 && weap1->cursed()) num_cursed++; - if (weap2 && item_cursed(*weap2)) + if (weap2 && weap2->cursed()) num_cursed++; - if (_shield && item_cursed(*_shield)) + if (_shield && _shield->cursed()) num_cursed++; if (two_handed && num_cursed > 0 || num_cursed >= avail_slots) diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index f16b6742c6..04c1498297 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -5732,7 +5732,7 @@ bool player::can_wield(const item_def& item, bool ignore_curse, { if (equip[EQ_WEAPON] != -1 && !ignore_curse) { - if (item_cursed(inv[equip[EQ_WEAPON]])) + if (inv[equip[EQ_WEAPON]].cursed()) return (false); } diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index 2524fbfcd5..763f1c0709 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -4230,7 +4230,7 @@ static bool _bless_weapon(god_type god, brand_type brand, int colour) set_item_ego_type(wpn, OBJ_WEAPONS, brand); wpn.colour = colour; - const bool is_cursed = item_cursed(wpn); + const bool is_cursed = wpn.cursed(); enchant_weapon(ENCHANT_TO_HIT, true, wpn); diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc index 4902786aa6..d765d4db5f 100644 --- a/crawl-ref/source/spells2.cc +++ b/crawl-ref/source/spells2.cc @@ -1101,7 +1101,7 @@ bool cast_sticks_to_snakes(int pow, god_type god) const int dur = std::min(3 + random2(pow) / 20, 5); int how_many_max = 1 + random2(1 + you.skills[SK_TRANSMUTATIONS]) / 4; - const bool friendly = (!item_cursed(wpn)); + const bool friendly = (!wpn.cursed()); const beh_type beha = (friendly) ? BEH_FRIENDLY : BEH_HOSTILE; int count = 0; @@ -1712,7 +1712,7 @@ bool cast_tukimas_dance(int pow, god_type god, bool force_hostile) if (success) { // Cursed weapons become hostile. - const bool friendly = (!force_hostile && !item_cursed(you.inv[wpn])); + const bool friendly = (!force_hostile && !you.inv[wpn].cursed()); mgen_data mg(MONS_DANCING_WEAPON, friendly ? BEH_FRIENDLY : BEH_HOSTILE, diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc index 3a7f8130e1..1a30607199 100644 --- a/crawl-ref/source/spells3.cc +++ b/crawl-ref/source/spells3.cc @@ -130,7 +130,7 @@ bool remove_curse(bool suppress_msg) // Only cursed *weapons* in hand count as cursed. - bwr if (you.weapon() && you.weapon()->base_type == OBJ_WEAPONS - && item_cursed(*you.weapon())) + && you.weapon()->cursed()) { // Also sets wield_change. do_uncurse_item(*you.weapon()); @@ -142,7 +142,7 @@ bool remove_curse(bool suppress_msg) for (int i = EQ_WEAPON + 1; i < NUM_EQUIP; i++) { // Melded equipment can also get uncursed this way. - if (you.equip[i] != -1 && item_cursed(you.inv[you.equip[i]])) + if (you.equip[i] != -1 && you.inv[you.equip[i]].cursed()) { do_uncurse_item(you.inv[you.equip[i]]); success = true; diff --git a/crawl-ref/source/tilereg.cc b/crawl-ref/source/tilereg.cc index 82ed562c56..4490e3a59a 100644 --- a/crawl-ref/source/tilereg.cc +++ b/crawl-ref/source/tilereg.cc @@ -2484,7 +2484,7 @@ static bool _can_use_item(const item_def &item, bool equipped) && mons_has_blood(item.plus)); } - if (equipped && item_cursed(item)) + if (equipped && item.cursed()) { // Misc. items/rods can always be evoked, cursed or not. if (item.base_type == OBJ_MISCELLANY || item_is_rod(item)) @@ -2770,7 +2770,7 @@ bool InventoryRegion::update_tip_text(std::string& tip) tip += "\n[R-Click] Info"; // Has to be non-equipped or non-cursed to drop. if (!equipped || !_is_true_equipped_item(you.inv[idx]) - || !item_cursed(you.inv[idx])) + || !you.inv[idx].cursed()) { tip += "\n[Shift-L-Click] Drop (d)"; } diff --git a/crawl-ref/source/tilesdl.cc b/crawl-ref/source/tilesdl.cc index e3c1e978fd..50dbb83f58 100644 --- a/crawl-ref/source/tilesdl.cc +++ b/crawl-ref/source/tilesdl.cc @@ -1433,7 +1433,7 @@ static void _fill_item_info(InventoryTile &desc, const item_def &item) desc.special = tile_known_weapon_brand(item); desc.flag = 0; - if (item_cursed(item) && item_ident(item, ISFLAG_KNOW_CURSE)) + if (item.cursed() && item_ident(item, ISFLAG_KNOW_CURSE)) desc.flag |= TILEI_FLAG_CURSE; if (item_type_tried(item)) desc.flag |= TILEI_FLAG_TRIED; diff --git a/crawl-ref/source/transfor.cc b/crawl-ref/source/transfor.cc index 39f932a5eb..eaa1d12afb 100644 --- a/crawl-ref/source/transfor.cc +++ b/crawl-ref/source/transfor.cc @@ -311,7 +311,7 @@ static bool _check_for_cursed_equipment(const std::set &remove, continue; const item_def& item = you.inv[ you.equip[e] ]; - if (item_cursed(item)) + if (item.cursed()) { if (e != EQ_WEAPON && _tran_may_meld_cursed(trans)) continue; diff --git a/crawl-ref/source/tutorial.cc b/crawl-ref/source/tutorial.cc index 7f6bc68bc8..69aeb760a2 100644 --- a/crawl-ref/source/tutorial.cc +++ b/crawl-ref/source/tutorial.cc @@ -1549,7 +1549,7 @@ static bool _cant_butcher() if (!wpn || wpn->base_type != OBJ_WEAPONS) return false; - return (item_cursed(*wpn) && !can_cut_meat(*wpn)); + return (wpn->cursed() && !can_cut_meat(*wpn)); } static int _num_butchery_tools() @@ -3012,7 +3012,7 @@ void learned_something_new(tutorial_event_type seen_what, coord_def gc) int wpn = you.equip[EQ_WEAPON]; if (wpn != -1 && you.inv[wpn].base_type == OBJ_WEAPONS - && item_cursed(you.inv[wpn])) + && you.inv[wpn].cursed()) { // Don't trigger if the wielded weapon is cursed. Tutorial.tutorial_events[seen_what] = true; diff --git a/crawl-ref/source/wiz-item.cc b/crawl-ref/source/wiz-item.cc index b4b94bb94f..6fa4b411b0 100644 --- a/crawl-ref/source/wiz-item.cc +++ b/crawl-ref/source/wiz-item.cc @@ -697,7 +697,7 @@ void wizard_uncurse_item() { item_def& item(you.inv[i]); - if (item_cursed(item)) + if (item.cursed()) do_uncurse_item(item); else if (_item_type_can_be_cursed(item.base_type)) do_curse_item(item); -- cgit v1.2.3-54-g00ecf From 25249b3649e5684062a8f1bca74b852f3d6fd71c Mon Sep 17 00:00:00 2001 From: Vsevolod Kozlov Date: Sun, 27 Dec 2009 21:23:53 +0300 Subject: Make item_is_mundane a method of item_def. --- crawl-ref/source/artefact.cc | 2 +- crawl-ref/source/externs.h | 3 +++ crawl-ref/source/itemprop.cc | 27 --------------------------- crawl-ref/source/itemprop.h | 3 --- crawl-ref/source/items.cc | 27 +++++++++++++++++++++++++++ crawl-ref/source/makeitem.cc | 8 ++++---- 6 files changed, 35 insertions(+), 35 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/artefact.cc b/crawl-ref/source/artefact.cc index 9b2cc6feed..71ae7b27cd 100644 --- a/crawl-ref/source/artefact.cc +++ b/crawl-ref/source/artefact.cc @@ -1923,7 +1923,7 @@ bool make_item_randart( item_def &item, bool force_mundane ) if (item.flags & ISFLAG_UNRANDART) return (false); - if (item_is_mundane(item) && !one_chance_in(5) && !force_mundane) + if (item.is_mundane() && !one_chance_in(5) && !force_mundane) return (false); ASSERT(!item.props.exists(KNOWN_PROPS_KEY)); diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index cf2b98d8d0..5f4f5e7e40 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -536,6 +536,9 @@ public: // Returns true if this item should be preserved as far as possible. bool is_critical() const; + // Returns true if this item should not normally be enchanted. + bool is_mundane() const; + private: std::string name_aux(description_level_type desc, bool terse, bool ident, diff --git a/crawl-ref/source/itemprop.cc b/crawl-ref/source/itemprop.cc index ea2f8bd7b3..bf47f3ab96 100644 --- a/crawl-ref/source/itemprop.cc +++ b/crawl-ref/source/itemprop.cc @@ -562,33 +562,6 @@ bool item_ident( const item_def &item, unsigned long flags ) return ((item.flags & flags) == flags); } -// Is item something that no one would usually bother enchanting? -bool item_is_mundane(const item_def &item) -{ - switch (item.base_type) - { - case OBJ_WEAPONS: - if (item.sub_type == WPN_CLUB - || item.sub_type == WPN_GIANT_CLUB - || item.sub_type == WPN_GIANT_SPIKED_CLUB - || item.sub_type == WPN_KNIFE) - { - return (true); - } - break; - - case OBJ_ARMOUR: - if (item.sub_type == ARM_ANIMAL_SKIN) - return (true); - break; - - default: - break; - } - - return (false); -} - void set_ident_flags( item_def &item, unsigned long flags ) { preserve_quiver_slots p; diff --git a/crawl-ref/source/itemprop.h b/crawl-ref/source/itemprop.h index 99c861da67..5604d352f5 100644 --- a/crawl-ref/source/itemprop.h +++ b/crawl-ref/source/itemprop.h @@ -14,9 +14,6 @@ struct bolt; void init_properties(void); -// Returns true if this item should not normally be enchanted. -bool item_is_mundane(const item_def &item); - // cursed: bool item_known_cursed( const item_def &item ); bool item_known_uncursed( const item_def &item ); diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index 7543da8ea5..29b25a021b 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -2934,6 +2934,33 @@ bool item_def::is_critical() const && plus != RUNE_ABYSSAL); } +// Is item something that no one would usually bother enchanting? +bool item_def::is_mundane() const +{ + switch (base_type) + { + case OBJ_WEAPONS: + if (sub_type == WPN_CLUB + || sub_type == WPN_GIANT_CLUB + || sub_type == WPN_GIANT_SPIKED_CLUB + || sub_type == WPN_KNIFE) + { + return (true); + } + break; + + case OBJ_ARMOUR: + if (sub_type == ARM_ANIMAL_SKIN) + return (true); + break; + + default: + break; + } + + return (false); +} + static void _rune_from_specs(const char* _specs, item_def &item) { char specs[80]; diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc index 977198929d..442b500112 100644 --- a/crawl-ref/source/makeitem.cc +++ b/crawl-ref/source/makeitem.cc @@ -1699,7 +1699,7 @@ brand_ok: } else if ((force_good || is_demonic(item) || forced_ego || x_chance_in_y(51 + item_level, 200)) - && (!item_is_mundane(item) || force_good)) + && (!item.is_mundane() || force_good)) { // Make a better item (possibly ego). if (!no_brand) @@ -2399,7 +2399,7 @@ static void _generate_armour_item(item_def& item, bool allow_uniques, } else if ((force_good || forced_ego || item.sub_type == ARM_WIZARD_HAT || x_chance_in_y(51 + item_level, 250)) - && (!item_is_mundane(item) || force_good)) + && (!item.is_mundane() || force_good)) { // Make a good item... item.plus += random2(3); @@ -3233,7 +3233,7 @@ static bool _weapon_is_visibly_special(const item_def &item) if (visibly_branded || is_artefact(item)) return (true); - if (item_is_mundane(item)) + if (item.is_mundane()) return (false); if ((item.plus || item.plus2) @@ -3256,7 +3256,7 @@ static bool _armour_is_visibly_special(const item_def &item) if (visibly_branded || is_artefact(item)) return (true); - if (item_is_mundane(item)) + if (item.is_mundane()) return (false); if (item.plus && !one_chance_in(3)) -- cgit v1.2.3-54-g00ecf From 56c839b54f62141c2ae92dc0a8a92c58323bdbd7 Mon Sep 17 00:00:00 2001 From: Darshan Shaligram Date: Mon, 28 Dec 2009 03:56:44 +0530 Subject: Shoals tides do not fill in features when the tide is receding. Sunlight-dried squares will stay dry until reached by a rising tide. --- crawl-ref/source/dgn-shoals.cc | 51 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dgn-shoals.cc b/crawl-ref/source/dgn-shoals.cc index 201f3f4690..c4f51753da 100644 --- a/crawl-ref/source/dgn-shoals.cc +++ b/crawl-ref/source/dgn-shoals.cc @@ -48,6 +48,14 @@ enum shoals_height_thresholds SHT_SHALLOW_WATER = -14 }; +enum tide_direction +{ + TIDE_RISING, + TIDE_FALLING +}; + +static tide_direction _shoals_tide_direction; + static double _to_radians(int degrees) { return degrees * M_PI / 180; @@ -541,6 +549,33 @@ static void _shoals_apply_tide_feature_at(coord_def c, dungeon_terrain_changed(c, feat, true, false, true); } +static int _shoals_feature_height(dungeon_feature_type feat) +{ + switch (feat) + { + case DNGN_FLOOR: + return SHT_FLOOR; + case DNGN_SHALLOW_WATER: + return SHT_SHALLOW_WATER; + case DNGN_DEEP_WATER: + return SHT_SHALLOW_WATER - 1; + default: + return 0; + } +} + +// Determines if the +static tide_direction _shoals_feature_tide_height_change( + dungeon_feature_type oldfeat, + dungeon_feature_type newfeat) +{ + const int height_delta = + _shoals_feature_height(newfeat) - _shoals_feature_height(oldfeat); + // If the apparent height of the new feature is greater (floor vs water), + // the tide is receding. + return height_delta < 0? TIDE_RISING : TIDE_FALLING; +} + static void _shoals_apply_tide_at(coord_def c, int tide) { const int effective_height = shoals_heights(c) - tide; @@ -549,6 +584,14 @@ static void _shoals_apply_tide_at(coord_def c, int tide) // Make sure we're not sprouting new walls. if (feat_is_wall(newfeat)) newfeat = DNGN_FLOOR; + const dungeon_feature_type oldfeat = grd(c); + + if (oldfeat == newfeat + || (_shoals_feature_tide_height_change(oldfeat, newfeat) != + _shoals_tide_direction)) + { + return; + } _shoals_apply_tide_feature_at(c, newfeat); } @@ -630,9 +673,15 @@ void shoals_apply_tides(int turns_elapsed) _shoals_init_tide(); int tide = env.properties[ENVP_SHOALS_TIDE_KEY].get_short(); int acc = env.properties[ENVP_SHOALS_TIDE_VEL].get_short(); + const int old_tide = tide; while (turns_elapsed-- > 0) _shoals_run_tide(tide, acc); env.properties[ENVP_SHOALS_TIDE_KEY] = short(tide); env.properties[ENVP_SHOALS_TIDE_VEL] = short(acc); - _shoals_apply_tide(tide / TIDE_MULTIPLIER); + if (old_tide / TIDE_MULTIPLIER != tide / TIDE_MULTIPLIER) + { + _shoals_tide_direction = + tide > old_tide ? TIDE_RISING : TIDE_FALLING; + _shoals_apply_tide(tide / TIDE_MULTIPLIER); + } } -- cgit v1.2.3-54-g00ecf From d333f654e907b79612b62581f8131d6edaff8191 Mon Sep 17 00:00:00 2001 From: David Ploog Date: Sun, 27 Dec 2009 23:30:40 +0100 Subject: Minor modifications of cavernous ossuary (Lordsloth). --- crawl-ref/source/dat/ossuary.des | 44 ++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 17 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dat/ossuary.des b/crawl-ref/source/dat/ossuary.des index f0e5e18580..89d9465766 100644 --- a/crawl-ref/source/dat/ossuary.des +++ b/crawl-ref/source/dat/ossuary.des @@ -476,11 +476,21 @@ TAGS: ossuary no_item_gen no_monster_gen ITEM: any scroll / any potion MONS: kobold skeleton / goblin skeleton / gnoll skeleton / \ orc skeleton +MONS: mummy # Loot: 10-19 +# Some random content. +SHUFFLE: Bb/Zz, Dd/Ww, Ee/Vv +SUBST: Z=c, z=c, W=c, w=c, V=c, v=c +SUBST: B=X, D=X, E=X +NSUBST: b = 1:= / c +NSUBST: d = 1:= / c +NSUBST: e = 1:= / c +SUBST: X = x2 # Guaranteed 10 items and 10 mummies, two in hidden rooms. # 50/50 chance of loot for each of the eleven rats in the rat room. KITEM: x = any scroll / any potion KMONS: x = mummy +NSUBST: ' = 10:^ / *:. KFEAT: ^ = dart trap / arrow trap KITEM: y = any scroll w:5 / any potion w:5 / nothing w:10 KMONS: y = rat skeleton @@ -489,23 +499,23 @@ KMONS: y = rat skeleton MAP ccc cccxccccc - ccc....+.^c cccccc - cc.1.ccccc.c cc.+^.cc - cc..ccc cc+cc cc..cc..cc - cc.^cc cc...ccccc..cccc.1ccc -ccc cc+cc c+.x.+...1.cc cc...cc -cAccc...cc cc...cccxccc ccc.cc -c..+.^1.+c cc+cc ccc ccc cc+cc -c Date: Sun, 27 Dec 2009 22:01:19 +0100 Subject: A few spacing changes. --- crawl-ref/source/traps.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/traps.cc b/crawl-ref/source/traps.cc index 9083576b6e..b7ca9f2dec 100644 --- a/crawl-ref/source/traps.cc +++ b/crawl-ref/source/traps.cc @@ -686,18 +686,18 @@ int trap_def::max_damage(const actor& act) // players -- this choice prevents traps from easily killing // large monsters fairly deep within the dungeon. if (act.atype() == ACT_MONSTER) - level = 0; + level = 0; switch (this->type) { - case TRAP_NEEDLE: return 0; + case TRAP_NEEDLE: return 0; case TRAP_DART: return 4 + level/2; case TRAP_ARROW: return 7 + level; case TRAP_SPEAR: return 10 + level; case TRAP_BOLT: return 13 + level; case TRAP_AXE: return 15 + level; - default: return 0; - case TRAP_BLADE: return (level ? level*2 : 10) + 28; + case TRAP_BLADE: return (level ? 2*level : 10) + 28; + default: return 0; } return (0); @@ -762,7 +762,7 @@ static bool _disarm_is_deadly(trap_def& trap) if (trap.type == TRAP_NEEDLE && you.res_poison() <= 0) dam += 15; // arbitrary - return you.hp <= dam; + return (you.hp <= dam); } // where *must* point to a valid, discovered trap. -- cgit v1.2.3-54-g00ecf From 4e6820b10db6edf0d821e785df046bcbcfa165e1 Mon Sep 17 00:00:00 2001 From: Darshan Shaligram Date: Mon, 28 Dec 2009 06:05:48 +0530 Subject: Make _build_vaults check for collisions by default, should fix minivaults appearing in encompass vaults. --- crawl-ref/source/dbg-util.cc | 15 ++++++++------- crawl-ref/source/dungeon.cc | 14 ++++++++++++-- 2 files changed, 20 insertions(+), 9 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dbg-util.cc b/crawl-ref/source/dbg-util.cc index 57bf3b1b37..84e0f87a0e 100644 --- a/crawl-ref/source/dbg-util.cc +++ b/crawl-ref/source/dbg-util.cc @@ -129,12 +129,15 @@ void debug_dump_levgen() else { const CrawlHashTable &vaults = props[TEMP_VAULTS_KEY].get_table(); - CrawlHashTable::const_iterator i = vaults.begin(); - - for (; i != vaults.end(); ++i) + if (!vaults.empty()) { - mprf(" %s: %s", i->first.c_str(), - i->second.get_string().c_str()); + CrawlHashTable::const_iterator i = vaults.begin(); + + for (; i != vaults.end(); ++i) + { + mprf(" %s: %s", i->first.c_str(), + i->second.get_string().c_str()); + } } } mpr(""); @@ -413,5 +416,3 @@ int debug_cap_stat(int stat) stat > 127 ? 127 : stat); } - - diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 61b09b2717..37ecb28ef6 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -202,7 +202,7 @@ static bool _build_secondary_vault(int level_number, const map_def *vault, static bool _build_vaults(int level_number, const map_def *vault, int rune_subst = -1, bool build_only = false, - bool check_collisions = false, + bool check_collisions = true, bool make_no_exits = false, const coord_def &where = coord_def(-1, -1)); static void _vault_grid(vault_placement &, @@ -823,7 +823,17 @@ void dgn_register_place(const vault_placement &place, bool register_vault) dgn_register_vault(place.map); if (!place.map.has_tag("layout")) - _mask_vault(place, MMT_VAULT | MMT_NO_DOOR); + { + if (place.map.orient == MAP_ENCOMPASS) + { + for (rectangle_iterator ri(0); ri; ++ri) + dgn_Map_Mask(*ri) |= MMT_VAULT | MMT_NO_DOOR; + } + else + { + _mask_vault(place, MMT_VAULT | MMT_NO_DOOR); + } + } if (place.map.has_tag("no_monster_gen")) _mask_vault(place, MMT_NO_MONS); -- cgit v1.2.3-54-g00ecf From 892714e8a99eb74424a3a06ad69f45f84ac9e4ca Mon Sep 17 00:00:00 2001 From: Darshan Shaligram Date: Mon, 28 Dec 2009 06:10:16 +0530 Subject: Fix shoals builder dying if an island is placed too close to map edge. --- crawl-ref/source/dgn-shoals.cc | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dgn-shoals.cc b/crawl-ref/source/dgn-shoals.cc index c4f51753da..da0070239e 100644 --- a/crawl-ref/source/dgn-shoals.cc +++ b/crawl-ref/source/dgn-shoals.cc @@ -94,7 +94,9 @@ static coord_def _random_point_from(const coord_def &c, int radius, { const double directed_radians( directed_angle == -1? 0.0 : _to_radians(directed_angle)); - while (true) { + int attempts = 70; + while (attempts-- > 0) + { const double angle = directed_angle == -1? _to_radians(random2(360)) : ((coinflip()? directed_radians : -directed_radians) @@ -107,9 +109,11 @@ static coord_def _random_point_from(const coord_def &c, int radius, return res; } } + return coord_def(); } -static coord_def _random_point(int offset = 0) { +static coord_def _random_point(int offset = 0) +{ return coord_def(random_range(offset, GXM - offset - 1), random_range(offset, GYM - offset - 1)); } @@ -119,7 +123,8 @@ static void _shoals_island_center(const coord_def &c, int n_perturb, int radius, { for (int i = 0; i < n_perturb; ++i) { coord_def p = _random_point_from(c, random2(1 + radius)); - shoals_heights(p) += random_range(bounce_low, bounce_high); + if (!p.origin()) + shoals_heights(p) += random_range(bounce_low, bounce_high); } } @@ -160,12 +165,12 @@ static void _shoals_build_island() const int addition_offset = random_range(2, 10); coord_def offsetC = _random_point_from(c, addition_offset); - - _shoals_island_center(offsetC, random_range(N_PERTURB_OFFSET_LOW, - N_PERTURB_OFFSET_HIGH), - random_range(PERTURB_OFFSET_RADIUS_LOW, - PERTURB_OFFSET_RADIUS_HIGH), - 25, 35); + if (!offsetC.origin()) + _shoals_island_center(offsetC, random_range(N_PERTURB_OFFSET_LOW, + N_PERTURB_OFFSET_HIGH), + random_range(PERTURB_OFFSET_RADIUS_LOW, + PERTURB_OFFSET_RADIUS_HIGH), + 25, 35); } } -- cgit v1.2.3-54-g00ecf From 585dab9ccd0db72c6b76bddc3003f6f504fe9c3a Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sun, 27 Dec 2009 18:45:11 -0600 Subject: remove mpr message length limitation --- crawl-ref/source/message.cc | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/message.cc b/crawl-ref/source/message.cc index 6a3d36c487..a6adba6847 100644 --- a/crawl-ref/source/message.cc +++ b/crawl-ref/source/message.cc @@ -413,12 +413,17 @@ int channel_to_colour( msg_channel_type channel, int param ) static void do_message_print( msg_channel_type channel, int param, const char *format, va_list argp ) { - // Is this limit intentional? char buff[200]; - vsnprintf( buff, sizeof( buff ), format, argp ); - buff[199] = 0; - - mpr(buff, channel, param); + size_t len = vsnprintf( buff, sizeof( buff ), format, argp ); + if (len < sizeof( buff )) { + mpr( buff, channel, param ); + } + else { + char *heapbuf = (char*)malloc( len + 1 ); + vsnprintf( heapbuf, len + 1, format, argp ); + mpr( heapbuf, channel, param ); + free( heapbuf ); + } } void mprf( msg_channel_type channel, int param, const char *format, ... ) -- cgit v1.2.3-54-g00ecf From 608eec96965d630ced67178319351c2a6b40be05 Mon Sep 17 00:00:00 2001 From: Darshan Shaligram Date: Mon, 28 Dec 2009 06:25:39 +0530 Subject: Fix map masks not being checked correctly for collisions. --- crawl-ref/source/dungeon.cc | 2 +- crawl-ref/source/maps.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 37ecb28ef6..18ae2d498b 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -202,7 +202,7 @@ static bool _build_secondary_vault(int level_number, const map_def *vault, static bool _build_vaults(int level_number, const map_def *vault, int rune_subst = -1, bool build_only = false, - bool check_collisions = true, + bool check_collisions = false, bool make_no_exits = false, const coord_def &where = coord_def(-1, -1)); static void _vault_grid(vault_placement &, diff --git a/crawl-ref/source/maps.cc b/crawl-ref/source/maps.cc index 07da121e02..072b7c8557 100644 --- a/crawl-ref/source/maps.cc +++ b/crawl-ref/source/maps.cc @@ -337,7 +337,7 @@ static bool _safe_vault_place(const map_def &map, if (lines[dp.y][dp.x] == ' ') continue; - if (dgn_Map_Mask[cp.x][cp.y] == MMT_VAULT) + if (dgn_Map_Mask[cp.x][cp.y] & MMT_VAULT) return (false); const dungeon_feature_type dfeat = grd(cp); -- cgit v1.2.3-54-g00ecf From 5f928a55ffa589e57045eb99c7427621e63f2a50 Mon Sep 17 00:00:00 2001 From: Jude Brown Date: Mon, 28 Dec 2009 10:39:13 +1000 Subject: Mark spec'd items for summoned monsters as summoned. --- crawl-ref/source/dungeon.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 18ae2d498b..89e643a68b 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -4533,6 +4533,11 @@ static void _dgn_give_mon_spec_items(mons_spec &mspec, if (item_made != NON_ITEM && item_made != -1) { item_def &item(mitm[item_made]); + + // Mark items on summoned monsters as such. + if (mspec.abjuration_duration != 0) + item.flags |= ISFLAG_SUMMONED; + if (!mon.pickup_item(item, 0, true)) destroy_item(item_made, true); } -- cgit v1.2.3-54-g00ecf From b29345dd9d85fb18ec21ad19db53636a7bbf68e2 Mon Sep 17 00:00:00 2001 From: Jude Brown Date: Mon, 28 Dec 2009 11:01:51 +1000 Subject: Move and tweak Mislead code. Newly placed monsters during the mislead status are also given a mislead_as monster type. --- crawl-ref/source/makefile.obj | 1 + crawl-ref/source/mislead.cc | 127 ++++++++++++++++++++++++++++++++++++++++++ crawl-ref/source/mislead.h | 8 +++ crawl-ref/source/mon-cast.cc | 103 +--------------------------------- crawl-ref/source/mon-place.cc | 4 ++ 5 files changed, 141 insertions(+), 102 deletions(-) create mode 100644 crawl-ref/source/mislead.cc create mode 100644 crawl-ref/source/mislead.h (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/makefile.obj b/crawl-ref/source/makefile.obj index 926b9d5e50..1b1d038f31 100644 --- a/crawl-ref/source/makefile.obj +++ b/crawl-ref/source/makefile.obj @@ -102,6 +102,7 @@ menu.o \ message.o \ mgen_data.o \ misc.o \ +mislead.o \ mon-abil.o \ mon-act.o \ mon-behv.o \ diff --git a/crawl-ref/source/mislead.cc b/crawl-ref/source/mislead.cc new file mode 100644 index 0000000000..64c574d97a --- /dev/null +++ b/crawl-ref/source/mislead.cc @@ -0,0 +1,127 @@ +/* File: mislead.cc + * Summary: Handling of the Mislead spell and stats + */ + +#include "AppHdr.h" +#include "mislead.h" + +#include "enum.h" +#include "env.h" +#include "message.h" +#include "monster.h" +#include "mon-iter.h" +#include "mon-util.h" +#include "view.h" +#include "random.h" +#include "tutorial.h" +#include "xom.h" + +bool unsuitable_misled_monster(monster_type mons) +{ + return (mons_is_unique(mons) || mons_is_mimic(mons) + || mons_class_is_stationary(mons) || mons_genus(mons) == MONS_DRACONIAN + || mons == MONS_DANCING_WEAPON || mons == MONS_UGLY_THING + || mons == MONS_VERY_UGLY_THING || mons == MONS_ZOMBIE_SMALL + || mons == MONS_ZOMBIE_LARGE || mons == MONS_SKELETON_SMALL + || mons == MONS_SKELETON_LARGE || mons == MONS_SIMULACRUM_SMALL + || mons == MONS_SIMULACRUM_LARGE || mons == MONS_SPECTRAL_THING + || mons == MONS_SLIME_CREATURE || mons == MONS_BALLISTOMYCETE + || mons == MONS_HYDRA || mons == MONS_PLAYER_GHOST + || mons == MONS_SHAPESHIFTER || mons == MONS_PANDEMONIUM_DEMON + || mons == MONS_KILLER_KLOWN || mons == MONS_KRAKEN + || mons == MONS_KRAKEN_TENTACLE + || mons == MONS_GLOWING_SHAPESHIFTER + || mons == MONS_GIANT_BAT); +} + +monster_type get_misled_monster (monsters *monster) +{ + monster_type mons = random_monster_at_grid(monster->pos()); + if (unsuitable_misled_monster(mons)) + mons = random_monster_at_grid(monster->pos()); + + if (unsuitable_misled_monster(mons)) + return (MONS_GIANT_BAT); + + return mons; +} + +bool update_mislead_monster(monsters* monster) +{ + // Don't affect uniques, named monsters, and monsters with special tiles. + if (mons_is_unique(monster->type) || !monster->mname.empty() + || monster->props.exists("monster_tile") + || monster->props.exists("mislead_as")) + { + return (false); + } + + short misled_as = get_misled_monster(monster); + monster->props["mislead_as"] = misled_as; + + if (misled_as == MONS_GIANT_BAT) + return (false); + + return (true); +} + +int update_mislead_monsters(monsters* caster) +{ + int count = 0; + + for (monster_iterator mi; mi; ++mi) + if (*mi != caster && update_mislead_monster(*mi)) + count++; + + return count; +} + +void mons_cast_mislead(monsters *monster) +{ + // This really only affects the player; it causes confusion when cast on + // non-player foes, but that is dealt with inside ye-great-Switch-of-Doom. + if (monster->foe != MHITYOU) + return; + + // Prevents Mislead spam by Mara and co. {due} + if (you.duration[DUR_MISLED] > 10 && one_chance_in(3)) + return; + + if (wearing_amulet(AMU_CLARITY)) + { + mpr("Your vision blurs momentarily."); + return; + } + + update_mislead_monsters(monster); + + const int old_value = you.duration[DUR_MISLED]; + you.increase_duration(DUR_MISLED, monster->hit_dice * 12 / 3, 50); + if (you.duration[DUR_MISLED] > old_value) + { + you.check_awaken(500); + + if (old_value <= 0) + { + mpr("But for a moment, strange images dance in front of your eyes.", MSGCH_WARN); +#ifdef USE_TILE + tiles.add_overlay(you.pos(), tileidx_zap(MAGENTA)); + update_screen(); +#else + flash_view(MAGENTA); +#endif + more(); + } + else + mpr("You are even more misled!", MSGCH_WARN); + + learned_something_new(TUT_YOU_ENCHANTED); + + xom_is_stimulated((you.duration[DUR_MISLED] - old_value) + / BASELINE_DELAY); + } + + return; +} + + diff --git a/crawl-ref/source/mislead.h b/crawl-ref/source/mislead.h new file mode 100644 index 0000000000..540ffea9b1 --- /dev/null +++ b/crawl-ref/source/mislead.h @@ -0,0 +1,8 @@ +/* File: mislead.h + * Summary: Handling of the Mislead spell and stats + */ + +bool unsuitable_misled_monster(monster_type mons); +monster_type get_misled_monster (monsters *monster); +int update_mislead_monsters(monsters* caster); +bool update_mislead_monster(monsters* monster); diff --git a/crawl-ref/source/mon-cast.cc b/crawl-ref/source/mon-cast.cc index 761521f7ab..7bbbd77862 100644 --- a/crawl-ref/source/mon-cast.cc +++ b/crawl-ref/source/mon-cast.cc @@ -24,6 +24,7 @@ #include "mon-place.h" #include "terrain.h" #include "tutorial.h" +#include "mislead.h" #include "mgen_data.h" #include "coord.h" #include "mon-speak.h" @@ -1564,108 +1565,6 @@ int _count_mara_fakes() return count; } -bool _unsuitable_misled_monster(monster_type mons) -{ - return (mons_is_unique(mons) || mons_is_mimic(mons) - || mons_class_is_stationary(mons) || mons_genus(mons) == MONS_DRACONIAN - || mons == MONS_DANCING_WEAPON || mons == MONS_UGLY_THING - || mons == MONS_VERY_UGLY_THING || mons == MONS_ZOMBIE_SMALL - || mons == MONS_ZOMBIE_LARGE || mons == MONS_SKELETON_SMALL - || mons == MONS_SKELETON_LARGE || mons == MONS_SIMULACRUM_SMALL - || mons == MONS_SIMULACRUM_LARGE || mons == MONS_SPECTRAL_THING - || mons == MONS_SLIME_CREATURE || mons == MONS_BALLISTOMYCETE - || mons == MONS_HYDRA || mons == MONS_PLAYER_GHOST - || mons == MONS_SHAPESHIFTER || mons == MONS_PANDEMONIUM_DEMON - || mons == MONS_KILLER_KLOWN || mons == MONS_KRAKEN - || mons == MONS_KRAKEN_TENTACLE - || mons == MONS_GLOWING_SHAPESHIFTER); -} - -monster_type _get_misled_monster (monsters *monster) -{ - monster_type mons = random_monster_at_grid(monster->pos()); - if (_unsuitable_misled_monster(mons)) - mons = random_monster_at_grid(monster->pos()); - - if (_unsuitable_misled_monster(mons)) - return (MONS_GIANT_BAT); - - return mons; -} - -int _update_mislead_monsters(monsters* monster) -{ - int count = 0; - - for (monster_iterator mi; mi; ++mi) - { - if (*mi == monster) - continue; - - // Don't affect uniques, named monsters, and monsters with special tiles. - if (mons_is_unique(mi->type) || !mi->mname.empty() - || mi->props.exists("monster_tile") || mi->props.exists("mislead_as")) - { - continue; - } - else - { - mi->props["mislead_as"] = short(_get_misled_monster(*mi)); - count++; - } - } - - return count; -} - -void mons_cast_mislead(monsters *monster) -{ - // This really only affects the player; it causes confusion when cast on - // non-player foes, but that is dealt with inside ye-great-Switch-of-Doom. - if (monster->foe != MHITYOU) - return; - - // Prevents Mislead spam by Mara and co. {due} - if (you.duration[DUR_MISLED] > 10 && one_chance_in(3)) - return; - - if (wearing_amulet(AMU_CLARITY)) - { - mpr("Your vision blurs momentarily."); - return; - } - - _update_mislead_monsters(monster); - - const int old_value = you.duration[DUR_MISLED]; - you.increase_duration(DUR_MISLED, monster->hit_dice * 12 / 3, 50); - if (you.duration[DUR_MISLED] > old_value) - { - you.check_awaken(500); - - if (old_value <= 0) - { - mpr("But for a moment, strange images dance in front of your eyes.", MSGCH_WARN); -#ifdef USE_TILE - tiles.add_overlay(you.pos(), tileidx_zap(MAGENTA)); - update_screen(); -#else - flash_view(MAGENTA); -#endif - more(); - } - else - mpr("You are even more misled!", MSGCH_WARN); - - learned_something_new(TUT_YOU_ENCHANTED); - - xom_is_stimulated((you.duration[DUR_MISLED] - old_value) - / BASELINE_DELAY); - } - - return; -} - bool _find_players_ghost () { bool found = false; diff --git a/crawl-ref/source/mon-place.cc b/crawl-ref/source/mon-place.cc index 9faa371cb8..3a88d27774 100644 --- a/crawl-ref/source/mon-place.cc +++ b/crawl-ref/source/mon-place.cc @@ -24,6 +24,7 @@ #include "lev-pand.h" #include "makeitem.h" #include "message.h" +#include "mislead.h" #include "mon-behv.h" #include "mon-gear.h" #include "mon-iter.h" @@ -1242,6 +1243,9 @@ static int _place_monster_aux(const mgen_data &mg, mon->add_ench(ENCH_SLOWLY_DYING); } + if (!crawl_state.arena && you.misled()) + update_mislead_monster(mon); + if (monster_can_submerge(mon, grd(fpos)) && !one_chance_in(5)) mon->add_ench(ENCH_SUBMERGED); -- cgit v1.2.3-54-g00ecf