From 59b053efd22ccd197d042ed5731b117e4846599b Mon Sep 17 00:00:00 2001 From: j-p-e-g Date: Tue, 4 Nov 2008 13:14:08 +0000 Subject: Apply the first part of the labyrinth tweaks: * labyrinths are bordered by (undiggable) metal walls * teleporting inside a labyrinth will always send you away from the centre (as the crow flies: you'll end somewhere in the stone or rock area) Also make sure melded equipment cannot corrode. (I'm still undecided about whether curses should affect melded items.) git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7383 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/dungeon.cc | 49 +++++++++++++++++++++++++++++++++++++++++++++ crawl-ref/source/effects.cc | 2 ++ crawl-ref/source/ouch.cc | 23 +++++++++------------ crawl-ref/source/player.cc | 16 +++++++++++---- crawl-ref/source/player.h | 1 + crawl-ref/source/spells3.cc | 30 ++++++++++++++++++++++++++- 6 files changed, 103 insertions(+), 18 deletions(-) diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index f3c51fedc7..6f4f28af82 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -6589,6 +6589,53 @@ static void _init_minivault_placement(int vault, vault_placement &place) vault_main(vgrid, place, vault); } +// Checks whether a given grid has at least one neighbour surrounded +// entirely by non-floor. +static bool _has_no_floor_neighbours(const coord_def &pos, bool recurse = false) +{ + for (int x = -1; x <= 1; x++) + for (int y = -1; y <= 1; y++) + { + if (x == 0 && y == 0) + continue; + + const coord_def p = pos + coord_def(x, y); + if (!in_bounds(p)) + return (true); + + if (recurse) + { + if (grd(p) == DNGN_FLOOR) + return (false); + } + else if (_has_no_floor_neighbours(p, true)) + return (true); + } + + return (recurse); +} + +// Change the borders of the labyrinth to another (undiggable) wall type. +static void _change_labyrinth_border(const dgn_region ®ion, + const dungeon_feature_type wall) +{ + const coord_def &end = region.pos + region.size; + for (int y = region.pos.y-1; y <= end.y; ++y) + for (int x = region.pos.x-1; x <= end.x; ++x) + { + const coord_def c(x, y); + if (!in_bounds(c)) // paranoia + continue; + + if (grd(c) == wall || !grid_is_wall(grd(c))) + continue; + + // All border grids have neighbours without any access to floor. + if (_has_no_floor_neighbours(c)) + grd[x][y] = wall; + } +} + static void _change_walls_from_centre(const dgn_region ®ion, const coord_def ¢re, bool rectangular, @@ -6783,6 +6830,8 @@ static void _labyrinth_level(int level_number) 34 * 34, DNGN_STONE_WALL, 0); + _change_labyrinth_border(lab, DNGN_METAL_WALL); + _labyrinth_place_entry_point(lab, end); link_items(); diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc index 9a9026ffee..37f96f4646 100644 --- a/crawl-ref/source/effects.cc +++ b/crawl-ref/source/effects.cc @@ -2631,6 +2631,8 @@ void handle_time(long time_delta) exercise(SK_STEALTH, 1); } } +// if (you.level_type == LEVEL_LABYRINTH) +// forget_map(you.species == SP_MINOTAUR ? 12 : 25); spawn_random_monsters(); } diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc index 0dee66ba27..1d3a209196 100644 --- a/crawl-ref/source/ouch.cc +++ b/crawl-ref/source/ouch.cc @@ -64,7 +64,7 @@ static void end_game( scorefile_entry &se ); -static void item_corrode( int itco ); +static void _item_corrode( int itco ); // NOTE: DOES NOT check for hellfire!!! @@ -244,20 +244,19 @@ void splash_with_acid( char acid_strength ) char splc = 0; int dam = 0; - const bool wearing_cloak = (you.equip[EQ_CLOAK] != -1); + const bool wearing_cloak = player_wearing_slot(EQ_CLOAK); for (splc = EQ_CLOAK; splc <= EQ_BODY_ARMOUR; splc++) { - if (you.equip[splc] == -1) + if (!player_wearing_slot(splc)) { if (!wearing_cloak || coinflip()) dam += roll_dice( 1, acid_strength ); - continue; } if (x_chance_in_y(acid_strength + 1, 20)) - item_corrode( you.equip[splc] ); + _item_corrode( you.equip[splc] ); } if (dam > 0) @@ -280,7 +279,7 @@ void weapon_acid( char acid_strength ) { char hand_thing = you.equip[EQ_WEAPON]; - if (hand_thing == -1) + if (hand_thing == -1 && you_tran_can_wear(EQ_GLOVES, true)) hand_thing = you.equip[EQ_GLOVES]; if (hand_thing == -1) @@ -289,10 +288,10 @@ void weapon_acid( char acid_strength ) ouch(roll_dice(1, acid_strength), NON_MONSTER, KILLED_BY_ACID); } else if (x_chance_in_y(acid_strength + 1, 20)) - item_corrode( hand_thing ); + _item_corrode( hand_thing ); } -void item_corrode( int itco ) +void _item_corrode( int itco ) { int chance_corr = 0; // no idea what its full range is {dlb} bool it_resists = false; // code simplifier {dlb} @@ -325,7 +324,7 @@ void item_corrode( int itco ) } else if ((item.sub_type == ARM_CRYSTAL_PLATE_MAIL || get_equip_race(item) == ISFLAG_DWARVEN) - && !one_chance_in(5)) + && !one_chance_in(5)) { it_resists = true; suppress_msg = false; @@ -369,7 +368,7 @@ void item_corrode( int itco ) // ---------------------------- but it needs to stay this way // (as it *was* this way) - // the embedded equation may look funny, but it actually works well + // The embedded equation may look funny, but it actually works well // to generate a pretty probability ramp {6%, 18%, 34%, 58%, 98%} // for values [0,4] which closely matches the original, ugly switch. // {dlb} @@ -409,9 +408,7 @@ void item_corrode( int itco ) if (you.equip[EQ_WEAPON] == itco) you.wield_change = true; } - - return; -} // end item_corrode() +} // Helper function for the expose functions below. // This currently works because elements only target a single type each. diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index 54028f48dd..a75fc6aeb9 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -588,6 +588,14 @@ bool player_has_feet() return (true); } +bool player_wearing_slot(int eq) +{ + if (you.equip[eq] == -1) + return (false); + + return (you_tran_can_wear(you.inv[you.equip[eq]])); +} + bool you_tran_can_wear(const item_def &item) { switch (item.base_type) @@ -1992,7 +2000,7 @@ int player_AC(void) if (i == EQ_SHIELD) continue; - if (you.equip[i] == -1 || !you_tran_can_wear(you.equip[i])) + if (!player_wearing_slot(i)) continue; const item_def& item = you.inv[you.equip[i]]; @@ -4443,11 +4451,11 @@ int scan_randarts(randart_prop_type which_property, bool calc_unid) for (i = EQ_WEAPON; i < NUM_EQUIP; i++) { - const int eq = you.equip[i]; - - if (eq == -1 || !you_tran_can_wear(eq)) + if (!player_wearing_slot(i)) continue; + const int eq = you.equip[i]; + // Only weapons give their effects when in our hands. if (i == EQ_WEAPON && you.inv[ eq ].base_type != OBJ_WEAPONS) continue; diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h index 42eb7f0351..4d6eb1ac9a 100644 --- a/crawl-ref/source/player.h +++ b/crawl-ref/source/player.h @@ -339,6 +339,7 @@ bool is_player_same_species( const int mon, bool = false ); bool you_can_wear( int eq, bool special_armour = false ); bool player_has_feet(void); +bool player_wearing_slot( int eq ); bool you_tran_can_wear(const item_def &item); bool you_tran_can_wear( int eq, bool check_mutation = false ); diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc index a368510a34..af2330a23a 100644 --- a/crawl-ref/source/spells3.cc +++ b/crawl-ref/source/spells3.cc @@ -1350,6 +1350,33 @@ static bool _teleport_player( bool allow_control, bool new_abyss_area ) { coord_def newpos; + // If in a labyrinth, always teleport well away from the centre. + // (Check done for the straight line, no pathfinding involved.) + bool need_distance_check = false; + coord_def centre; + if (you.level_type == LEVEL_LABYRINTH) + { + bool success = false; + for (int xpos = 0; xpos < GXM; xpos++) + { + for (int ypos = 0; ypos < GYM; ypos++) + { + centre = coord_def(xpos, ypos); + if (!in_bounds(centre)) + continue; + + if (grd(centre) == DNGN_ESCAPE_HATCH_UP) + { + success = true; + break; + } + } + if (success) + break; + } + need_distance_check = success; + } + do { newpos.set( random_range(X_BOUND_1 + 1, X_BOUND_2 - 1), @@ -1358,7 +1385,8 @@ static bool _teleport_player( bool allow_control, bool new_abyss_area ) while (grd(newpos) != DNGN_FLOOR && grd(newpos) != DNGN_SHALLOW_WATER || mgrd(newpos) != NON_MONSTER - || env.cgrid(newpos) != EMPTY_CLOUD); + || env.cgrid(newpos) != EMPTY_CLOUD + || need_distance_check && (newpos - centre).abs() < 34*34); // no longer held in net if (newpos != you.pos()) -- cgit v1.2.3-54-g00ecf