diff options
-rw-r--r-- | crawl-ref/source/acr.cc | 26 | ||||
-rw-r--r-- | crawl-ref/source/behold.cc | 173 | ||||
-rw-r--r-- | crawl-ref/source/debug.cc | 7 | ||||
-rw-r--r-- | crawl-ref/source/directn.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/makefile.obj | 1 | ||||
-rw-r--r-- | crawl-ref/source/misc.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/mon-abil.cc | 23 | ||||
-rw-r--r-- | crawl-ref/source/mon-act.cc | 8 | ||||
-rw-r--r-- | crawl-ref/source/mon-behv.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 5 | ||||
-rw-r--r-- | crawl-ref/source/output.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/player.cc | 125 | ||||
-rw-r--r-- | crawl-ref/source/player.h | 27 | ||||
-rw-r--r-- | crawl-ref/source/spells1.cc | 25 | ||||
-rw-r--r-- | crawl-ref/source/spells3.cc | 50 | ||||
-rw-r--r-- | crawl-ref/source/spells4.cc | 5 | ||||
-rw-r--r-- | crawl-ref/source/tags.cc | 8 | ||||
-rw-r--r-- | crawl-ref/source/view.cc | 35 | ||||
-rw-r--r-- | crawl-ref/source/viewmap.cc | 22 |
19 files changed, 248 insertions, 308 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index 02ee5a3772..1976e1405b 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -920,7 +920,7 @@ static void _input() crawl_state.clear_mon_acting(); religion_turn_start(); - check_beholders(); + you.update_beholders(); // Currently only set if Xom accidentally kills the player. you.reset_escaped_death(); @@ -1188,10 +1188,11 @@ static void _input() static bool _stairs_check_mesmerised() { - if (you.duration[DUR_MESMERISED] && !you.confused()) + if (you.beheld() && !you.confused()) { + const monsters* beholder = you.get_any_beholder(); mprf("You cannot move away from %s!", - menv[you.mesmerised_by[0]].name(DESC_NOCAP_THE, true).c_str()); + beholder->name(DESC_NOCAP_THE, true).c_str()); return (true); } @@ -2370,7 +2371,7 @@ static void _decrement_durations() if (_decrement_a_duration(DUR_MESMERISED, "You break out of your daze.", 0, NULL, MSGCH_RECOVERY)) { - you.mesmerised_by.clear(); + you.clear_beholders(); } dec_slow_player(); @@ -3913,21 +3914,8 @@ static void _move_player(coord_def move) // You cannot move away from a mermaid but you CAN fight monsters on // neighbouring squares. monsters *beholder = NULL; - if (you.duration[DUR_MESMERISED] && !you.confused()) - { - for (unsigned int i = 0; i < you.mesmerised_by.size(); ++i) - { - monsters& mon = menv[you.mesmerised_by[i]]; - int olddist = grid_distance(you.pos(), mon.pos()); - int newdist = grid_distance(targ, mon.pos()); - - if (olddist < newdist) - { - beholder = &mon; - break; - } - } - } + if (!you.confused()) + beholder = you.get_beholder(targ); if (you.running.check_stop_running()) { diff --git a/crawl-ref/source/behold.cc b/crawl-ref/source/behold.cc new file mode 100644 index 0000000000..37571e1b0a --- /dev/null +++ b/crawl-ref/source/behold.cc @@ -0,0 +1,173 @@ +#include "AppHdr.h" + +#include "player.h" + +#include "coord.h" +#include "debug.h" +#include "env.h" +#include "los.h" +#include "mon-util.h" +#include "monster.h" +#include "random.h" +#include "stuff.h" +#include "view.h" + +// Add a monster to the list of beholders. +void player::add_beholder(const monsters* mon) +{ + if (!duration[DUR_MESMERISED]) + { + duration[DUR_MESMERISED] = 7; + beholders.push_back(mon->mindex()); + mprf(MSGCH_WARN, "You are mesmerised by %s!", + mon->name(DESC_NOCAP_THE).c_str()); + } + else + { + duration[DUR_MESMERISED] += 5; + if (!beheld_by(mon)) + beholders.push_back(mon->mindex()); + } + + if (duration[DUR_MESMERISED] > 12) + duration[DUR_MESMERISED] = 12; +} + +// Whether player is mesmerised. +bool player::beheld() const +{ + ASSERT(duration[DUR_MESMERISED] > 0 == !beholders.empty()); + return (duration[DUR_MESMERISED] > 0); +} + +// Whether player is mesmerised by the given monster. +bool player::beheld_by(const monsters* mon) const +{ + for (unsigned int i = 0; i < beholders.size(); i++) + if (beholders[i] == mon->mindex()) + return (true); + return (false); +} + +// Checks whether a beholder keeps you from moving to +// target, and returns one if it exists. +monsters* player::get_beholder(const coord_def &target) const +{ + for (unsigned int i = 0; i < beholders.size(); i++) + { + monsters *mon = &menv[beholders[i]]; + const int olddist = grid_distance(you.pos(), mon->pos()); + const int newdist = grid_distance(target, mon->pos()); + + if (olddist < newdist) + return (mon); + } + return (NULL); +} + +monsters* player::get_any_beholder() const +{ + if (beholders.size() > 0) + return (&menv[beholders[0]]); + else + return (NULL); +} + +// Removes a monster from the list of beholders if present. +void player::remove_beholder(const monsters *mon) +{ + for (unsigned int i = 0; i < beholders.size(); i++) + if (beholders[i] == mon->mindex()) + { + beholders.erase(beholders.begin() + i); + _removed_beholder(); + return; + } +} + +// Clear the list of beholders. Doesn't message. +void player::clear_beholders() +{ + beholders.clear(); + duration[DUR_MESMERISED] = 0; +} + +// Possibly end mesmerisation if a loud noise happened. +void player::beholders_check_noise(int loudness) +{ + if (loudness >= 20 && you.beheld()) + { + mprf("For a moment, you cannot hear the mermaid%s!", + beholders.size() > 1 ? "s" : ""); + clear_beholders(); + _removed_beholder(); + } +} + +// Update all beholders' status after changes. +void player::update_beholders() +{ + if (!beheld()) + return; + bool removed = false; + for (int i = beholders.size() - 1; i >= 0; i--) + { + const monsters* mon = &menv[beholders[i]]; + if (!_possible_beholder(mon)) + { + beholders.erase(beholders.begin() + i); + removed = true; + } + } + if (removed) + _removed_beholder(); +} + +// Update a single beholder. +void player::update_beholder(const monsters *mon) +{ + if (_possible_beholder(mon)) + return; + for (unsigned int i = 0; i < beholders.size(); i++) + if (beholders[i] = mon->mindex()) + { + beholders.erase(beholders.begin() + i); + _removed_beholder(); + return; + } +} + +// Helper function that resets the duration and messages if the player +// is no longer mesmerised. +void player::_removed_beholder() +{ + if (beholders.empty()) + { + duration[DUR_MESMERISED] = 0; + mpr(coinflip() ? "You break out of your daze!" + : "You are no longer entranced.", + MSGCH_DURATION); + } +} + +// Helper function that checks whether the given monster is a possible +// beholder. +bool player::_possible_beholder(const monsters *mon) const +{ + if (silenced(you.pos())) + return (false); + if (!mon->alive() || !mons_near(mon) || mons_friendly(mon) + || mon->submerged() || mon->confused() || mons_cannot_move(mon) + || mon->asleep() || silenced(mon->pos())) + { + return (false); + } + + // TODO: replace this by see/see_no_trans. + int walls = num_feats_between(you.pos(), mon->pos(), + DNGN_UNSEEN, DNGN_MAXOPAQUE); + if (walls > 0) + return (false); + + return (true); +} diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc index fee098066b..90ae37f211 100644 --- a/crawl-ref/source/debug.cc +++ b/crawl-ref/source/debug.cc @@ -2140,11 +2140,8 @@ void wizard_heal(bool super_heal) // Clear more stuff and give a HP boost. you.magic_contamination = 0; you.duration[DUR_LIQUID_FLAMES] = 0; - if (you.duration[DUR_MESMERISED]) - { - you.duration[DUR_MESMERISED] = 0; - you.mesmerised_by.clear(); - } + you.clear_beholders(); + // If we're repeating then do the HP increase all at once. int amount = 10; if (crawl_state.cmd_repeat_goal > 0) diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc index 4ea97767f0..cd75cf221d 100644 --- a/crawl-ref/source/directn.cc +++ b/crawl-ref/source/directn.cc @@ -627,7 +627,7 @@ void full_describe_view() std::string str = get_monster_equipment_desc(list_mons[i], true, DESC_CAP_A, true); - if (player_mesmerised_by(list_mons[i])) + if (you.beheld_by(list_mons[i])) str += ", keeping you mesmerised"; if (damage_level != MDAM_OKAY) @@ -3123,7 +3123,7 @@ static std::string _get_monster_desc(const monsters *mon) std::string text = ""; std::string pronoun = mon->pronoun(PRONOUN_CAP); - if (player_mesmerised_by(mon)) + if (you.beheld_by(mon)) text += "You are mesmerised by her song.\n"; if (!mons_is_mimic(mon->type) && mons_behaviour_perceptible(mon)) diff --git a/crawl-ref/source/makefile.obj b/crawl-ref/source/makefile.obj index 9ebecb6531..30815c01f6 100644 --- a/crawl-ref/source/makefile.obj +++ b/crawl-ref/source/makefile.obj @@ -6,6 +6,7 @@ actor.o \ arena.o \ artefact.o \ beam.o \ +behold.o \ bitary.o \ branch.o \ chardump.o \ diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index 9f10f2ad3c..bdfd78fbe0 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -2580,11 +2580,7 @@ void down_stairs( int old_level, dungeon_feature_type force_stair, } // Clear list of beholding monsters. - if (you.duration[DUR_MESMERISED]) - { - you.mesmerised_by.clear(); - you.duration[DUR_MESMERISED] = 0; - } + you.clear_beholders(); if (you.skills[SK_TRANSLOCATIONS] > 0 && !allow_control_teleport( true )) mpr( "You sense a powerful magical force warping space.", MSGCH_WARN ); diff --git a/crawl-ref/source/mon-abil.cc b/crawl-ref/source/mon-abil.cc index 680c86f02d..cd5d2909ad 100644 --- a/crawl-ref/source/mon-abil.cc +++ b/crawl-ref/source/mon-abil.cc @@ -1202,7 +1202,7 @@ bool mon_special_ability(monsters *monster, bolt & beem) break; } - bool already_mesmerised = player_mesmerised_by(monster); + bool already_mesmerised = you.beheld_by(monster); if (one_chance_in(5) || monster->foe == MHITYOU && !already_mesmerised && coinflip()) @@ -1257,23 +1257,9 @@ bool mon_special_ability(monsters *monster, bolt & beem) break; } - if (!you.duration[DUR_MESMERISED]) - { - you.duration[DUR_MESMERISED] = 7; - you.mesmerised_by.push_back(monster_index(monster)); - mprf(MSGCH_WARN, "You are mesmerised by %s!", - monster->name(DESC_NOCAP_THE).c_str()); - } - else - { - you.duration[DUR_MESMERISED] += 5; - if (!already_mesmerised) - you.mesmerised_by.push_back(monster_index(monster)); - } - used = true; + you.add_beholder(monster); - if (you.duration[DUR_MESMERISED] > 12) - you.duration[DUR_MESMERISED] = 12; + used = true; } break; } @@ -1361,7 +1347,7 @@ void mon_nearby_ability(monsters *monster) if (monster_can_submerge(monster, grd(monster->pos())) && !monster->caught() // No submerging while caught. - && !player_mesmerised_by(monster) // No submerging if player entranced. + && !you.beheld_by(monster) // No submerging if player entranced. && !mons_is_lurking(monster) // Handled elsewhere. && monster->wants_submerge()) { @@ -1369,7 +1355,6 @@ void mon_nearby_ability(monsters *monster) monster->add_ench(ENCH_SUBMERGED); monster->speed_increment -= ENERGY_SUBMERGE(entry); - update_beholders(monster); return; } diff --git a/crawl-ref/source/mon-act.cc b/crawl-ref/source/mon-act.cc index 09f3a93c80..ebd07d6fcf 100644 --- a/crawl-ref/source/mon-act.cc +++ b/crawl-ref/source/mon-act.cc @@ -2040,7 +2040,7 @@ static void _handle_monster_move(monsters *monster) if (mons_cannot_move(monster) || !_monster_move(monster)) monster->speed_increment -= non_move_energy; } - update_beholders(monster); + you.update_beholder(monster); // Reevaluate behaviour, since the monster's surroundings have // changed (it may have moved, or died for that matter). Don't @@ -2087,11 +2087,7 @@ void handle_monsters() if (you.banished) { // Clear list of mesmerising monsters. - if (you.duration[DUR_MESMERISED]) - { - you.mesmerised_by.clear(); - you.duration[DUR_MESMERISED] = 0; - } + you.clear_beholders(); break; } } diff --git a/crawl-ref/source/mon-behv.cc b/crawl-ref/source/mon-behv.cc index d3eff47330..ae406d0e49 100644 --- a/crawl-ref/source/mon-behv.cc +++ b/crawl-ref/source/mon-behv.cc @@ -1391,7 +1391,7 @@ void handle_behaviour(monsters *mon) { // The foe is the player. if (mon->type == MONS_SIREN - && player_mesmerised_by(mon) + && you.beheld_by(mon) && _find_siren_water_target(mon)) { break; diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 1f9cb7b05d..6c65a4a923 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -1323,8 +1323,7 @@ int monster_die(monsters *monster, killer_type killer, mons_clear_trapping_net(monster); - // Update list of monsters beholding player. - update_beholders(monster, true); + you.remove_beholder(monster); // Clear auto exclusion now the monster is killed -- if we know about it. if (mons_near(monster) || wizard) @@ -2257,7 +2256,7 @@ bool monster_polymorph(monsters *monster, monster_type targetc, // the polymorph disrupts the beholding process. Do this before // changing monster->type, since unbeholding can only happen while // the monster is still a mermaid/siren. - update_beholders(monster, true); + you.remove_beholder(monster); // Inform listeners that the original monster is gone. _fire_monster_death_event(monster, KILL_MISC, NON_MONSTER, true); diff --git a/crawl-ref/source/output.cc b/crawl-ref/source/output.cc index d5505d48ac..fcc94f0cd7 100644 --- a/crawl-ref/source/output.cc +++ b/crawl-ref/source/output.cc @@ -737,7 +737,7 @@ static void _get_status_lights(std::vector<status_light>& out) out.push_back(status_light(RED, "-MR")); // TODO: Differentiate between mermaids and sirens! - if (you.duration[DUR_MESMERISED]) + if (you.beheld()) out.push_back(status_light(RED, "Mesm")); if (you.duration[DUR_LIQUID_FLAMES]) @@ -2056,7 +2056,7 @@ std::string _status_mut_abilities() status.push_back("short of breath"); // TODO: Differentiate between mermaids and sirens! - if (you.duration[DUR_MESMERISED]) + if (you.beheld()) status.push_back("mesmerised"); if (you.duration[DUR_LIQUID_FLAMES]) diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index 6bb655a253..5d00539bc9 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -2554,127 +2554,6 @@ int player_shield_class(void) //jmf: changes for new spell return (base_shield); } -// Returns true if player is mesmerised by a given monster. -bool player_mesmerised_by(const monsters *mon) -{ - if (!you.duration[DUR_MESMERISED]) - return (false); - - // Can this monster even behold you? - if (mons_genus(mon->type) != MONS_MERMAID) - return (false); - -#ifdef DEBUG_DIAGNOSTICS - mprf(MSGCH_DIAGNOSTICS, "mesmerised_by.size: %d, DUR_MESMERISED: %d, " - "current mon: %d", you.mesmerised_by.size(), - you.duration[DUR_MESMERISED], mon->mindex()); -#endif - - if (you.mesmerised_by.empty()) // shouldn't happen - { - you.duration[DUR_MESMERISED] = 0; - return (false); - } - - for (unsigned int i = 0; i < you.mesmerised_by.size(); i++) - { - unsigned int which_mon = you.mesmerised_by[i]; - if (monster_index(mon) == which_mon) - return (true); - } - - return (false); -} - -// Removes a monster from the list of beholders if force == true -// (e.g. monster dead) or one of several cases is met. -void update_beholders(const monsters *mon, bool force) -{ - if (!player_mesmerised_by(mon)) // Not in list? - return; - - // Is an update even necessary? - if (force || !mons_near(mon) || mons_friendly(mon) || mon->submerged() - || mon->has_ench(ENCH_CONFUSION) || mons_cannot_move(mon) - || mon->asleep() || silenced(you.pos()) || silenced(mon->pos())) - { - const std::vector<int> help = you.mesmerised_by; - you.mesmerised_by.clear(); - - for (unsigned int i = 0; i < help.size(); i++) - { - unsigned int which_mon = help[i]; - if (monster_index(mon) != which_mon) - you.mesmerised_by.push_back(which_mon); - } - - if (you.mesmerised_by.empty()) - { - mpr("You are no longer entranced.", MSGCH_RECOVERY); - you.duration[DUR_MESMERISED] = 0; - } - } -} - -void check_beholders() -{ - for (int i = you.mesmerised_by.size() - 1; i >= 0; i--) - { - const monsters* mon = &menv[you.mesmerised_by[i]]; - if (!mon->alive() || mons_genus(mon->type) != MONS_MERMAID - || mon->submerged()) - { -#ifdef DEBUG - if (!mon->alive()) - mpr("Dead mermaid/siren still mesmerising?", MSGCH_DIAGNOSTICS); - else if (mons_genus(mon->type) != MONS_MERMAID) - { - mprf(MSGCH_DIAGNOSTICS, "Non-mermaid/siren '%s' mesmerising?", - mon->name(DESC_PLAIN, true).c_str()); - } -#endif - - you.mesmerised_by.erase(you.mesmerised_by.begin() + i); - if (you.mesmerised_by.empty()) - { - mpr("You are no longer entranced.", MSGCH_RECOVERY); - you.duration[DUR_MESMERISED] = 0; - break; - } - continue; - } - const coord_def pos = mon->pos(); - int walls = num_feats_between(you.pos(), pos, - DNGN_UNSEEN, DNGN_MAXOPAQUE); - - if (walls > 0) - { -#ifdef DEBUG - mprf(MSGCH_DIAGNOSTICS, "%d walls between mesmerising '%s' " - "and player", walls, mon->name(DESC_PLAIN, true).c_str()); -#endif - you.mesmerised_by.erase(you.mesmerised_by.begin() + i); - if (you.mesmerised_by.empty()) - { - mpr("You are no longer entranced.", MSGCH_RECOVERY); - you.duration[DUR_MESMERISED] = 0; - break; - } - continue; - } - } - - if (you.duration[DUR_MESMERISED] > 0 && you.mesmerised_by.empty()) - { -#ifdef DEBUG - mpr("Mesmerised with no mermaids/sirens left?", MSGCH_DIAGNOSTICS); -#endif - - mpr("You are no longer entranced.", MSGCH_RECOVERY); - you.duration[DUR_MESMERISED] = 0; - } -} - int player_sust_abil(bool calc_unid) { int sa = 0; @@ -3949,7 +3828,7 @@ void display_char_status() mpr("You are confused."); // TODO: Distinguish between mermaids and sirens! - if (you.duration[DUR_MESMERISED]) + if (you.beheld()) mpr("You are mesmerised."); // How exactly did you get to show the status? @@ -6324,7 +6203,7 @@ bool player::can_go_berserk(bool verbose) const return (false); } - if (this->duration[DUR_MESMERISED]) + if (beheld()) { if (verbose) mpr("You are too mesmerised to rage."); diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h index 97fc296692..8ec9756c8d 100644 --- a/crawl-ref/source/player.h +++ b/crawl-ref/source/player.h @@ -35,8 +35,6 @@ public: bool banished; std::string banished_by; - std::vector<int> mesmerised_by; // monsters mesmerising player - int friendly_pickup; // pickup setting for allies unsigned short prev_targ; @@ -283,10 +281,15 @@ public: // When other levels are loaded (e.g. viewing), is the player on this level? bool on_current_level; + // monsters mesmerising player; should be proteced, but needs to be saved + // and restored. + std::vector<int> beholders; + protected: FixedVector<PlaceInfo, NUM_BRANCHES> branch_info; FixedVector<PlaceInfo, NUM_LEVEL_AREA_TYPES - 1> non_branch_info; + public: player(); player(const player &other); @@ -319,6 +322,18 @@ public: bool light_flight() const; bool travelling_light() const; + // Dealing with beholders. Implemented in behold.cc. + void add_beholder(const monsters *mon); + bool beheld() const; + bool beheld_by(const monsters *mon) const; + monsters* get_beholder(const coord_def &pos) const; + monsters* get_any_beholder() const; + void remove_beholder(const monsters *mon); + void clear_beholders(); + void beholders_check_noise(int loudness); + void update_beholders(); + void update_beholder(const monsters *mon); + kill_category kill_alignment() const; bool has_spell(spell_type spell) const; @@ -489,6 +504,9 @@ public: protected: void base_moveto(const coord_def &c); + + void _removed_beholder(); + bool _possible_beholder(const monsters *mon) const; }; extern player you; @@ -633,11 +651,6 @@ int scan_artefacts(artefact_prop_type which_property, bool calc_unid = true); int slaying_bonus(char which_affected, bool ranged = false); - -bool player_mesmerised_by(const monsters *mon); -void update_beholders(const monsters *mon, bool force = false); -void check_beholders(); - unsigned long exp_needed(int lev); int get_expiration_threshold(duration_type dur); diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc index 0267230e41..e94fc43957 100644 --- a/crawl-ref/source/spells1.cc +++ b/crawl-ref/source/spells1.cc @@ -117,27 +117,12 @@ int blink(int pow, bool high_level_controlled_blink, bool wizard_blink) return (-1); // early return {dlb} } - if (!wizard_blink && you.duration[DUR_MESMERISED]) + monsters* beholder = you.get_beholder(beam.target); + if (!wizard_blink && beholder) { - bool blocked_movement = false; - for (unsigned int i = 0; i < you.mesmerised_by.size(); i++) - { - monsters& mon = menv[you.mesmerised_by[i]]; - const int olddist = grid_distance(you.pos(), mon.pos()); - const int newdist = grid_distance(beam.target, mon.pos()); - - if (olddist < newdist) - { - mprf("You cannot blink away from %s!", - mon.name(DESC_NOCAP_THE, true).c_str()); - - blocked_movement = true; - break; - } - } - - if (blocked_movement) - continue; + mprf("You cannot blink away from %s!", + beholder->name(DESC_NOCAP_THE, true).c_str()); + continue; } if (grd(beam.target) == DNGN_OPEN_SEA) diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc index d6293b7063..9ccd1ec3e7 100644 --- a/crawl-ref/source/spells3.cc +++ b/crawl-ref/source/spells3.cc @@ -1478,30 +1478,16 @@ static bool _teleport_player(bool allow_control, bool new_abyss_area) return (false); } - if (you.duration[DUR_MESMERISED]) + monsters *beholder = you.get_beholder(pos); + if (beholder) { - bool blocked_movement = false; - for (unsigned int i = 0; i < you.mesmerised_by.size(); i++) - { - monsters& mon = menv[you.mesmerised_by[i]]; - const int olddist = grid_distance(you.pos(), mon.pos()); - const int newdist = grid_distance(pos, mon.pos()); - - if (olddist < newdist) - { - mprf("You cannot teleport away from %s!", - mon.name(DESC_NOCAP_THE, true).c_str()); - mpr("Choose another destination (press '.' or delete to select)."); - more(); - - blocked_movement = true; - break; - } - } - - if (blocked_movement) - continue; + mprf("You cannot teleport away from %s!", + beholder->name(DESC_NOCAP_THE, true).c_str()); + mpr("Choose another destination (press '.' or delete to select)."); + more(); + continue; } + break; } @@ -1717,25 +1703,7 @@ bool entomb(int powc) if (number_built > 0) { mpr("Walls emerge from the floor!"); - - for (int i = you.mesmerised_by.size() - 1; i >= 0; i--) - { - const monsters* mon = &menv[you.mesmerised_by[i]]; - int walls = num_feats_between(you.pos(), mon->pos(), - DNGN_UNSEEN, DNGN_MAXWALL, - true, true); - - if (walls > 0) - { - update_beholders(mon, true); - if (you.mesmerised_by.empty()) - { - you.duration[DUR_MESMERISED] = 0; - break; - } - continue; - } - } + you.update_beholders(); } else canned_msg(MSG_NOTHING_HAPPENS); diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc index 15566f5cf5..bf965913da 100644 --- a/crawl-ref/source/spells4.cc +++ b/crawl-ref/source/spells4.cc @@ -767,11 +767,10 @@ void cast_silence(int pow) if (you.duration[DUR_SILENCE] > 100) you.duration[DUR_SILENCE] = 100; - if (you.duration[DUR_MESMERISED]) + if (you.beheld()) { + you.clear_beholders(); mpr("You break out of your daze!", MSGCH_RECOVERY); - you.duration[DUR_MESMERISED] = 0; - you.mesmerised_by.clear(); } } diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc index 45471455d9..f65421e5a1 100644 --- a/crawl-ref/source/tags.cc +++ b/crawl-ref/source/tags.cc @@ -1007,9 +1007,9 @@ static void tag_construct_you(writer &th) // be recalculated on game start. // List of currently beholding monsters (usually empty). - marshallByte(th, you.mesmerised_by.size()); - for (unsigned int k = 0; k < you.mesmerised_by.size(); k++) - marshallByte(th, you.mesmerised_by[k]); + marshallByte(th, you.beholders.size()); + for (unsigned int k = 0; k < you.beholders.size(); k++) + marshallByte(th, you.beholders[k]); marshallByte(th, you.piety_hysteresis); @@ -1449,7 +1449,7 @@ static void tag_read_you(reader &th, char minorVersion) // List of currently beholding monsters (usually empty). count_c = unmarshallByte(th); for (i = 0; i < count_c; i++) - you.mesmerised_by.push_back(unmarshallByte(th)); + you.beholders.push_back(unmarshallByte(th)); you.piety_hysteresis = unmarshallByte(th); diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index e032183849..a17925354d 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -158,31 +158,14 @@ static void _get_symbol( const coord_def& where, && feat <= DNGN_ESCAPE_HATCH_UP && is_exclude_root(where)); - bool blocked_movement = false; - if (!excluded_stairs - && feat >= DNGN_MINMOVE - && you.duration[DUR_MESMERISED]) + if (excluded_stairs) + *colour = Options.tc_excluded | colmask; + else if (feat >= DNGN_MINMOVE && you.get_beholder(where)) { // Colour grids that cannot be reached due to beholders // dark grey. - for (unsigned int i = 0; i < you.mesmerised_by.size(); i++) - { - monsters& mon = menv[you.mesmerised_by[i]]; - const int olddist = grid_distance(you.pos(), mon.pos()); - const int newdist = grid_distance(where, mon.pos()); - - if (olddist < newdist) - { - blocked_movement = true; - break; - } - } - } - - if (excluded_stairs) - *colour = Options.tc_excluded | colmask; - else if (blocked_movement) *colour = DARKGREY | colmask; + } else if (feat >= DNGN_MINMOVE && is_sanctuary(where)) { if (testbits(env.map(where).property, FPROP_SANCTUARY_1)) @@ -953,14 +936,8 @@ bool noisy(int loudness, const coord_def& where, const char *msg, int who, you.check_awaken(dist - player_distance); - if (!mermaid && loudness >= 20 && you.duration[DUR_MESMERISED]) - { - mprf("For a moment, you cannot hear the mermaid%s!", - you.mesmerised_by.size() == 1? "" : "s"); - mpr("You break out of your daze!", MSGCH_DURATION); - you.duration[DUR_MESMERISED] = 0; - you.mesmerised_by.clear(); - } + if (!mermaid) + you.beholders_check_noise(loudness); ret = true; } diff --git a/crawl-ref/source/viewmap.cc b/crawl-ref/source/viewmap.cc index b7d2f066e1..33a2e92a2b 100644 --- a/crawl-ref/source/viewmap.cc +++ b/crawl-ref/source/viewmap.cc @@ -1142,30 +1142,14 @@ screen_buffer_t colour_code_map(const coord_def& p, bool item_colour, if (feature_colour != DARKGREY) tc = feature_colour; - else if (you.duration[DUR_MESMERISED] && on_level) + else if (on_level && you.beheld()) { // If mesmerised, colour the few grids that can be reached anyway // lightgrey. const monsters *blocker = monster_at(p); const bool seen_blocker = blocker && you.can_see(blocker); - if (grd(p) >= DNGN_MINMOVE && !seen_blocker) - { - bool blocked_movement = false; - for (unsigned int i = 0; i < you.mesmerised_by.size(); i++) - { - const monsters& mon = menv[you.mesmerised_by[i]]; - const int olddist = grid_distance(you.pos(), mon.pos()); - const int newdist = grid_distance(p, mon.pos()); - - if (olddist < newdist || !see_cell(env.show_los, p, mon.pos())) - { - blocked_movement = true; - break; - } - } - if (!blocked_movement) - tc = LIGHTGREY; - } + if (grd(p) >= DNGN_MINMOVE && !seen_blocker && !you.get_beholder(p)) + tc = LIGHTGREY; } if (Options.feature_item_brand |