summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authorRobert Vollmert <rvollmert@gmx.net>2009-11-05 20:50:54 +0100
committerRobert Vollmert <rvollmert@gmx.net>2009-11-05 22:30:03 +0100
commitdc3f573c6ef467ddcc4a837ce90ca9df3b502c2e (patch)
treef7915736d0a9bad11d83c3ff8a0263577a27e979 /crawl-ref/source
parent31124ec682c2b826f169c23e808fa741a3033a04 (diff)
downloadcrawl-ref-dc3f573c6ef467ddcc4a837ce90ca9df3b502c2e.tar.gz
crawl-ref-dc3f573c6ef467ddcc4a837ce90ca9df3b502c2e.zip
Unify mesmerisation code.
There were several places that had copies of the same code, checking whether mesmerisation blocked movement to a given target. The various mesmerisation functions have become methods of player and were moved into behold.cc.
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/acr.cc26
-rw-r--r--crawl-ref/source/behold.cc173
-rw-r--r--crawl-ref/source/debug.cc7
-rw-r--r--crawl-ref/source/directn.cc4
-rw-r--r--crawl-ref/source/makefile.obj1
-rw-r--r--crawl-ref/source/misc.cc6
-rw-r--r--crawl-ref/source/mon-abil.cc23
-rw-r--r--crawl-ref/source/mon-act.cc8
-rw-r--r--crawl-ref/source/mon-behv.cc2
-rw-r--r--crawl-ref/source/monstuff.cc5
-rw-r--r--crawl-ref/source/output.cc4
-rw-r--r--crawl-ref/source/player.cc125
-rw-r--r--crawl-ref/source/player.h27
-rw-r--r--crawl-ref/source/spells1.cc25
-rw-r--r--crawl-ref/source/spells3.cc50
-rw-r--r--crawl-ref/source/spells4.cc5
-rw-r--r--crawl-ref/source/tags.cc8
-rw-r--r--crawl-ref/source/view.cc35
-rw-r--r--crawl-ref/source/viewmap.cc22
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