diff options
-rw-r--r-- | crawl-ref/source/acr.cc | 30 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 7 | ||||
-rw-r--r-- | crawl-ref/source/player.cc | 57 | ||||
-rw-r--r-- | crawl-ref/source/player.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/spells3.cc | 22 |
5 files changed, 113 insertions, 4 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index c52b723e25..fa477bac6d 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -1231,6 +1231,7 @@ bool apply_berserk_penalty = false; static void input() { crawl_state.clear_god_acting(); + check_beholders(); if (crawl_state.is_replaying_keys() && crawl_state.is_repeating_cmd() && kbhit()) @@ -1454,11 +1455,26 @@ static bool toggle_flag( bool* flag, const char* flagname ) return *flag; } +static bool stairs_check_beheld() +{ + if (you.duration[DUR_BEHELD] && !you.duration[DUR_CONF]) + { + mprf("You cannot move away from %s!", + menv[you.beheld_by[0]].name(DESC_NOCAP_THE, true).c_str()); + return true; + } + + return false; +} + static void go_downstairs(); static void go_upstairs() { const dungeon_feature_type ygrd = grd(you.pos()); + if (stairs_check_beheld()) + return; + // Allow both < and > to work for Abyss exits. if (ygrd == DNGN_EXIT_ABYSS) { @@ -1500,6 +1516,10 @@ static void go_downstairs() bool shaft = (trap_type_at_xy(you.x_pos, you.y_pos) == TRAP_SHAFT && grd[you.x_pos][you.y_pos] != DNGN_UNDISCOVERED_TRAP); + + if (stairs_check_beheld()) + return; + if (shaft && you.flies() == FL_LEVITATE) { mpr("You can't fall through a shaft while levitating."); @@ -3663,14 +3683,16 @@ static void move_player(int move_x, int move_y) { for (unsigned int i = 0; i < you.beheld_by.size(); i++) { - coord_def pos = menv[you.beheld_by[i]].pos(); + monsters* mon = &menv[you.beheld_by[i]]; + coord_def pos = mon->pos(); int olddist = distance(you.x_pos, you.y_pos, pos.x, pos.y); - int newdist = distance(you.x_pos + move_x, you.y_pos + move_y, pos.x, pos.y); - + int newdist = distance(you.x_pos + move_x, you.y_pos + move_y, + pos.x, pos.y); + if (olddist < newdist) { mprf("You cannot move away from %s!", - (menv[you.beheld_by[i]]).name(DESC_NOCAP_THE, true).c_str()); + mon->name(DESC_NOCAP_THE, true).c_str()); move_x = 0; move_y = 0; diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 98ccfbf0f0..f46c35fed0 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -1166,6 +1166,13 @@ bool monster_polymorph( monsters *monster, monster_type targetc, bool player_messaged = simple_monster_message(monster, str_polymon.c_str() ); + // Even if the monster transforms from one type that can behold the + // player into a different type which can also behold the player, + // the polymoprh disrupts the beholding process. Do this before + // changing monster->type, since unbeholding can only happen while + // monster is still a mermaid. + update_beholders(monster, true); + // the actual polymorphing: const int old_hp = monster->hit_points; const int old_hp_max = monster->max_hit_points; diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index 77a94ded67..d137d8f1b6 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -2399,6 +2399,63 @@ void update_beholders(const monsters *mon, bool force) } } +void check_beholders() +{ + for (int i = you.beheld_by.size() - 1; i >= 0; i--) + { + const monsters* mon = &menv[you.beheld_by[i]]; + if (!mon->alive() || mon->type != MONS_MERMAID) + { +#if DEBUG + if (!mon->alive()) + mpr("Dead mermaid still beholding?", MSGCH_DIAGNOSTICS); + else if (mon->type != MONS_MERMAID) + mprf(MSGCH_DIAGNOSTICS, "Non-mermaid '%s' beholding?", + mon->name(DESC_PLAIN, true).c_str()); +#endif + + you.beheld_by.erase(you.beheld_by.begin() + i); + if (you.beheld_by.empty()) + { + mpr("You are no longer entranced.", MSGCH_RECOVERY); + you.duration[DUR_BEHELD] = 0; + break; + } + continue; + } + const coord_def pos = mon->pos(); + int walls = num_feats_between(you.x_pos, you.y_pos, + pos.x, pos.y, DNGN_UNSEEN, + DNGN_MAXWALL); + + if (walls > 0) + { +#if DEBUG + mprf(MSGCH_DIAGNOSTICS, "%d walls between beholding '%s' " + "and player", walls, mon->name(DESC_PLAIN, true).c_str()); +#endif + you.beheld_by.erase(you.beheld_by.begin() + i); + if (you.beheld_by.empty()) + { + mpr("You are no longer entranced.", MSGCH_RECOVERY); + you.duration[DUR_BEHELD] = 0; + break; + } + continue; + } + } + + if (you.duration[DUR_BEHELD] > 0 && you.beheld_by.empty()) + { +#if DEBUG + mpr("Beheld with no mermaids left?", MSGCH_DIAGNOSTICS); +#endif + + mpr("You are no longer entranced.", MSGCH_RECOVERY); + you.duration[DUR_BEHELD] = 0; + } +} + int player_sust_abil(bool calc_unid) { int sa = 0; diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h index 95e35193f9..fcfcb6a0c1 100644 --- a/crawl-ref/source/player.h +++ b/crawl-ref/source/player.h @@ -265,6 +265,7 @@ bool player_monster_visible( const monsters *mon ); bool player_beheld_by( const monsters *mon ); void update_beholders( const monsters *mon, bool force = false); +void check_beholders(); /* *********************************************************************** * called from: acr - decks - it_use2 - ouch diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc index f35ae60e35..9bbb8789e5 100644 --- a/crawl-ref/source/spells3.cc +++ b/crawl-ref/source/spells3.cc @@ -766,7 +766,29 @@ bool entomb(int powc) } if (number_built > 0) + { mpr("Walls emerge from the floor!"); + + for (int i = you.beheld_by.size() - 1; i >= 0; i--) + { + const monsters* mon = &menv[you.beheld_by[i]]; + const coord_def pos = mon->pos(); + int walls = num_feats_between(you.x_pos, you.y_pos, + pos.x, pos.y, DNGN_UNSEEN, + DNGN_MAXWALL); + + if (walls > 0) + { + update_beholders(mon, true); + if (you.beheld_by.empty()) + { + you.duration[DUR_BEHELD] = 0; + break; + } + continue; + } + } + } else canned_msg(MSG_NOTHING_HAPPENS); |