From c2e225e37b6fd61253cb5804c719462fb29bb136 Mon Sep 17 00:00:00 2001 From: zelgadis Date: Sun, 14 Oct 2007 08:29:33 +0000 Subject: Added to classes actor, monsters and player the method can_pass_through(), which returns true for a grid that the monster or player can pass trhough. Also added new monster type "rock worm" to demonstrate a monster which can pass through solid walls. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2459 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/acr.cc | 8 ++++---- crawl-ref/source/dat/descript/monsters.txt | 4 ++++ crawl-ref/source/dungeon.cc | 8 ++++++-- crawl-ref/source/enum.h | 15 +++++++++++---- crawl-ref/source/externs.h | 10 ++++++++++ crawl-ref/source/luadgn.cc | 4 ++-- crawl-ref/source/mon-data.h | 13 +++++++++++++ crawl-ref/source/mon-util.cc | 30 ++++++++++++++++++++++++++++++ crawl-ref/source/mon-util.h | 2 ++ crawl-ref/source/monplace.cc | 9 ++++++++- crawl-ref/source/monstuff.cc | 21 ++++++++++++++------- crawl-ref/source/player.cc | 17 ++++++++++++++++- crawl-ref/source/spells2.cc | 3 ++- 13 files changed, 122 insertions(+), 22 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index 09f70c8742..322dc850cb 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -3603,7 +3603,7 @@ static void move_player(int move_x, int move_y) const int new_targ_x = you.x_pos + move_x; const int new_targ_y = you.y_pos + move_y; if (!in_bounds(new_targ_x, new_targ_y) - || grid_is_solid(grd[new_targ_x][new_targ_y])) + || !you.can_pass_through(new_targ_x, new_targ_y)) { you.turn_is_over = true; mpr("Ouch!"); @@ -3618,7 +3618,7 @@ static void move_player(int move_x, int move_y) const int targ_y = you.y_pos + move_y; const dungeon_feature_type targ_grid = grd[ targ_x ][ targ_y ]; const unsigned short targ_monst = mgrd[ targ_x ][ targ_y ]; - const bool targ_solid = grid_is_solid(targ_grid); + const bool targ_pass = you.can_pass_through(targ_x, targ_y); // cannot move away from mermaid but you CAN fight neighbouring squares if (you.duration[DUR_BEHELD] && !you.duration[DUR_CONF] @@ -3677,7 +3677,7 @@ static void move_player(int move_x, int move_y) } } - if (!attacking && !targ_solid && moving) + if (!attacking && targ_pass && moving) { you.time_taken *= player_movement_speed(); you.time_taken /= 10; @@ -3694,7 +3694,7 @@ static void move_player(int move_x, int move_y) // BCR - Easy doors single move if (targ_grid == DNGN_CLOSED_DOOR && Options.easy_open) open_door(move_x, move_y, false); - else if (targ_solid) + else if (!targ_pass) { stop_running(); diff --git a/crawl-ref/source/dat/descript/monsters.txt b/crawl-ref/source/dat/descript/monsters.txt index 9900b338a2..21cd5c0d5d 100644 --- a/crawl-ref/source/dat/descript/monsters.txt +++ b/crawl-ref/source/dat/descript/monsters.txt @@ -1201,6 +1201,10 @@ redback A vicious black spider with a splash of red on its swollen abdomen. Its mandibles drip with lethal poison. %%%% +rock worm + +A large worm which moves through rock as if it were air. +%%%% rock troll An enormous and very nasty-looking humanoid creature. Its rocky hide seems to heal almost instantaneously from most wounds. diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index cc9c4f4f46..d2e05fcb30 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -2742,7 +2742,7 @@ static void specr_2(spec_room &sr) if (grd[sx][sy] == DNGN_BUILDER_SPECIAL_WALL) grd[sx][sy] = DNGN_CLOSED_DOOR; - if (j > 0 && grd[sx + dx][sy + dy] > DNGN_ROCK_WALL + if (j > 0 && grd[sx + dx][sy + dy] > DNGN_MINWALL && grd[sx + dx][sy + dy] < DNGN_FLOOR) grd[sx][sy] = DNGN_BUILDER_SPECIAL_FLOOR; @@ -6415,7 +6415,11 @@ static void big_room(int level_number) replace_area(sr.x1, sr.y1, sr.x2, sr.y2, DNGN_CLOSED_DOOR, type_floor); if (type_floor == DNGN_FLOOR) - type_2 = static_cast(DNGN_ROCK_WALL + random2(4)); + { + const int minwall = DNGN_RNDWALL_MIN; + const int range = DNGN_RNDWALL_MAX - DNGN_RNDWALL_MIN + 1; + type_2 = static_cast(minwall + random2(range)); + } // no lava in the Crypt or Tomb, thanks! if (player_in_branch( BRANCH_CRYPT ) || player_in_branch( BRANCH_TOMB )) diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index b2895d7eaa..fad1046349 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -793,11 +793,11 @@ enum dungeon_feature_type DNGN_UNSEEN, // 0 DNGN_CLOSED_DOOR, DNGN_SECRET_DOOR, + DNGN_WAX_WALL, + DNGN_METAL_WALL, + DNGN_GREEN_CRYSTAL_WALL, // 5 DNGN_ROCK_WALL, DNGN_STONE_WALL, - DNGN_METAL_WALL, // 5 - DNGN_GREEN_CRYSTAL_WALL, - DNGN_WAX_WALL, DNGN_PERMAROCK_WALL, // 8 - for undiggable walls DNGN_CLEAR_ROCK_WALL, // 9 - Transparent DNGN_CLEAR_STONE_WALL, // 10 - Transparent @@ -805,9 +805,13 @@ enum dungeon_feature_type DNGN_ORCISH_IDOL, // 12 - Can see past // XXX: lowest/highest grid value which is a wall - DNGN_MINWALL = DNGN_ROCK_WALL, + DNGN_MINWALL = DNGN_WAX_WALL, DNGN_MAXWALL = DNGN_CLEAR_PERMAROCK_WALL, + // Random wall types for big rooms + DNGN_RNDWALL_MIN = DNGN_METAL_WALL, + DNGN_RNDWALL_MAX = DNGN_STONE_WALL, + // XXX: highest grid value which is opaque DNGN_MAXOPAQUE = DNGN_PERMAROCK_WALL, @@ -1750,6 +1754,9 @@ enum monster_type // (int) menv[].type MONS_WATER_ELEMENTAL, MONS_SWAMP_WORM, // 435 + // Monsters which move through rock: + MONS_ROCK_WORM = 440, + // Statuary MONS_ORANGE_STATUE, MONS_SILVER_STATUE, diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index ade001aaee..bcae117be2 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -83,6 +83,10 @@ public: virtual bool swimming() const = 0; virtual bool submerged() const = 0; virtual bool floundering() const = 0; + + virtual bool can_pass_through(const dungeon_feature_type grid) const = 0; + virtual bool can_pass_through(const int x, const int y) const = 0; + virtual bool can_pass_through(const coord_def &c) const = 0; virtual size_type body_size(int psize = PSIZE_TORSO, bool base = false) const = 0; @@ -747,6 +751,9 @@ public: bool swimming() const; bool submerged() const; bool floundering() const; + bool can_pass_through(const dungeon_feature_type grid) const; + bool can_pass_through(const int x, const int y) const; + bool can_pass_through(const coord_def &c) const; size_type body_size(int psize = PSIZE_TORSO, bool base = false) const; int body_weight() const; int total_weight() const; @@ -1011,6 +1018,9 @@ public: bool submerged() const; bool can_drown() const; bool floundering() const; + bool can_pass_through(const dungeon_feature_type grid) const; + bool can_pass_through(const int x, const int y) const; + bool can_pass_through(const coord_def &c) const; size_type body_size(int psize = PSIZE_TORSO, bool base = false) const; int body_weight() const; int total_weight() const; diff --git a/crawl-ref/source/luadgn.cc b/crawl-ref/source/luadgn.cc index 42e07d0ee6..f8001d0708 100644 --- a/crawl-ref/source/luadgn.cc +++ b/crawl-ref/source/luadgn.cc @@ -1060,8 +1060,8 @@ static int dgn_change_rock_colour(lua_State *ls) const char *dngn_feature_names[] = { - "unseen", "closed_door", "secret_door", "rock_wall", "stone_wall", - "metal_wall", "green_crystal_wall", "wax_wall", "permarock_wall", + "unseen", "closed_door", "secret_door", "wax_wall", "metal_wall", + "green_crystal_wall", "rock_wall", "stone_wall", "permarock_wall", "clear_rock_wall", "clear_stone_wall", "clear_permarock_wall", "orcish_idol", "", "", "", "", "", "", "", "", "silver_statue", "granite_statue", "orange_crystal_statue", diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h index 7e77487213..5aace95d2b 100644 --- a/crawl-ref/source/mon-data.h +++ b/crawl-ref/source/mon-data.h @@ -3894,6 +3894,19 @@ // end water monsters {dlb} +// begin "move through rock" monsters {mpc} +{ + MONS_ROCK_WORM, 'w', BROWN, "rock worm", + M_NO_FLAGS, + MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, + 0, 10, MONS_WORM, MONS_ROCK_WORM, MH_NATURAL, -3, + { {AT_BITE, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, + { 5, 5, 5, 0 }, + 3, 12, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_PLANT, + 12, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_LARGE +}, +// end "move through rock" monsters {mpc} + { MONS_WOLF, 'h', LIGHTGREY, "wolf", M_WARM_BLOOD | M_SENSE_INVIS, diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index ed5f52174d..f2396cda5b 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -2391,6 +2391,36 @@ bool monsters::floundering() const && !mons_flies(this)); } +bool mons_class_can_pass(const int mclass, const dungeon_feature_type grid) +{ + // Permanent walls can't be passed through. + if (grid == DNGN_CLEAR_PERMAROCK_WALL || grid == DNGN_PERMAROCK_WALL) + return false; + + switch (mclass) + { + case MONS_ROCK_WORM: + return (grid >= DNGN_ROCK_WALL && grid <= DNGN_CLEAR_PERMAROCK_WALL); + } + + return !grid_is_solid(grid); +} + +bool monsters::can_pass_through(const dungeon_feature_type grid) const +{ + return mons_class_can_pass(type, grid); +} + +bool monsters::can_pass_through(const int _x, const int _y) const +{ + return can_pass_through(grd[_x][_y]); +} + +bool monsters::can_pass_through(const coord_def &c) const +{ + return can_pass_through(grd(c)); +} + bool monsters::can_drown() const { // Mummies can fall apart in water; ghouls and demons can drown in diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h index 12b5807a8e..031f976bbe 100644 --- a/crawl-ref/source/mon-util.h +++ b/crawl-ref/source/mon-util.h @@ -649,4 +649,6 @@ std::string get_mon_shape_str(const monsters *mon); std::string get_mon_shape_str(const int type); std::string get_mon_shape_str(const mon_body_shape shape); +bool mons_class_can_pass(const int mclass, const dungeon_feature_type grid); + #endif diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc index 067b825e38..143bd183b1 100644 --- a/crawl-ref/source/monplace.cc +++ b/crawl-ref/source/monplace.cc @@ -56,6 +56,13 @@ bool grid_compatible(int grid_wanted, int actual_grid, bool generation) || (!generation && actual_grid == DNGN_SHALLOW_WATER); + if (grid_wanted >= DNGN_ROCK_WALL + && grid_wanted <= DNGN_CLEAR_PERMAROCK_WALL) + { + return (actual_grid >= DNGN_ROCK_WALL && + actual_grid <= DNGN_CLEAR_PERMAROCK_WALL); + } + return (grid_wanted == actual_grid || (grid_wanted == DNGN_DEEP_WATER && (actual_grid == DNGN_SHALLOW_WATER @@ -1617,7 +1624,7 @@ int create_monster( int cls, int dur, beh_type beha, int cr_x, int cr_y, { int summd = -1; coord_def pos = find_newmons_square(cls, cr_x, cr_y); - if (force_place && !grid_is_solid(grd[cr_x][cr_y]) + if (force_place && mons_class_can_pass(cls, grd[cr_x][cr_y]) && mgrd[cr_x][cr_y] == NON_MONSTER) { pos.x = cr_x; diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index a6eda2d160..98ccfbf0f0 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -925,7 +925,7 @@ static bool jelly_divide(monsters * parent) { // 10-50 for now - must take clouds into account: if (mgrd[parent->x + jex][parent->y + jey] == NON_MONSTER - && !grid_is_solid(grd[parent->x + jex][parent->y + jey]) + && parent->can_pass_through(parent->x + jex, parent->y + jey) && (parent->x + jex != you.x_pos || parent->y + jey != you.y_pos)) { foundSpot = true; @@ -4113,7 +4113,7 @@ static void handle_monster_move(int i, monsters *monster) for (int xi = -1; xi <= 1; ++xi) { coord_def c = monster->pos() + coord_def(xi, yi); - if (in_bounds(c) && !grid_is_solid(grd(c)) + if (in_bounds(c) && monster->can_pass_through(c) && one_chance_in(++pfound)) { mmov_x = xi; @@ -4139,8 +4139,8 @@ static void handle_monster_move(int i, monsters *monster) mmov_y = 0; } - if (grid_is_solid( - grd[ monster->x + mmov_x ][ monster->y + mmov_y ])) + if (!monster->can_pass_through(monster->x + mmov_x, + monster->y + mmov_y)) { mmov_x = mmov_y = 0; } @@ -4855,8 +4855,10 @@ static bool monster_move(monsters *monster) // effectively slows down monster movement across water. // Fire elementals can't cross at all. + bool no_water = false; if (monster->type == MONS_FIRE_ELEMENTAL || one_chance_in(5)) - okmove = DNGN_WATER_STUCK; + //okmove = DNGN_WATER_STUCK; + no_water = true; if (mons_flies(monster) > 0 || habitat != DNGN_FLOOR @@ -4883,7 +4885,7 @@ static bool monster_move(monsters *monster) continue; } - int target_grid = grd[targ_x][targ_y]; + dungeon_feature_type target_grid = grd[targ_x][targ_y]; const int targ_cloud_num = env.cgrid[ targ_x ][ targ_y ]; const int targ_cloud_type = @@ -4917,7 +4919,9 @@ static bool monster_move(monsters *monster) continue; } } - else if (grd[ targ_x ][ targ_y ] < okmove) + else if (!monster->can_pass_through(target_grid) + || (no_water && target_grid >= DNGN_DEEP_WATER + && target_grid <= DNGN_WATER_STUCK)) { good_move[count_x][count_y] = false; continue; @@ -5589,6 +5593,9 @@ dungeon_feature_type monster_habitat(int which_class) case MONS_SALAMANDER: return (DNGN_LAVA); + case MONS_ROCK_WORM: + return (DNGN_ROCK_WALL); + default: return (DNGN_FLOOR); // closest match to terra firma {dlb} } diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index 02266afb2a..6d7e083a11 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -169,7 +169,7 @@ bool move_player_to_grid( int x, int y, bool stepped, bool allow_shift, const dungeon_feature_type new_grid = grd[x][y]; // really must be clear - ASSERT( !grid_is_solid( new_grid ) ); + ASSERT( you.can_pass_through( new_grid ) ); // if (grid_is_solid( new_grid )) // return (false); @@ -5406,6 +5406,21 @@ bool player::floundering() const return in_water() && !can_swim(); } +bool player::can_pass_through(const dungeon_feature_type grid) const +{ + return !grid_is_solid(grid); +} + +bool player::can_pass_through(const int _x, const int _y) const +{ + return can_pass_through(grd[_x][_y]); +} + +bool player::can_pass_through(const coord_def &c) const +{ + return can_pass_through(grd(c)); +} + size_type player::body_size(int psize, bool base) const { size_type ret = (base) ? SIZE_CHARACTER : transform_size( psize ); diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc index fefdc3b99a..54eea4b000 100644 --- a/crawl-ref/source/spells2.cc +++ b/crawl-ref/source/spells2.cc @@ -155,7 +155,8 @@ static void mark_detected_creature(int gridx, int gridy, const monsters *mon, gx = gridx + random2(fuzz_diam) - fuzz_radius; gy = gridy + random2(fuzz_diam) - fuzz_radius; - if (map_bounds(gx, gy) && !grid_is_solid(grd[gx][gy])) + if (map_bounds(gx, gy) + && mon->can_pass_through(grd[gx][gy])) { found_good = true; break; -- cgit v1.2.3-54-g00ecf