3 * Summary: player methods dealing with mesmerisation.
21 // Add a monster to the list of beholders.
22 void player::add_beholder(const monster
* mon
)
24 if (is_sanctuary(you
.pos()))
28 mprf("%s's singing sounds muted, and has no effect on you.",
29 mon
->name(DESC_CAP_THE
).c_str());
33 mpr("The melody is strangely muted, and has no effect on you.");
38 if (!duration
[DUR_MESMERISED
])
40 you
.set_duration(DUR_MESMERISED
, 7, 12);
41 beholders
.push_back(mon
->mindex());
42 mprf(MSGCH_WARN
, "You are mesmerised by %s!",
43 mon
->name(DESC_NOCAP_THE
).c_str());
47 you
.increase_duration(DUR_MESMERISED
, 5, 12);
49 beholders
.push_back(mon
->mindex());
53 // Whether player is mesmerised.
54 bool player::beheld() const
56 ASSERT(duration
[DUR_MESMERISED
] > 0 == !beholders
.empty());
57 return (duration
[DUR_MESMERISED
] > 0);
60 // Whether player is mesmerised by the given monster.
61 bool player::beheld_by(const monster
* mon
) const
63 for (unsigned int i
= 0; i
< beholders
.size(); i
++)
64 if (beholders
[i
] == mon
->mindex())
69 // Checks whether a beholder keeps you from moving to
70 // target, and returns one if it exists.
71 monster
* player::get_beholder(const coord_def
&target
) const
73 for (unsigned int i
= 0; i
< beholders
.size(); i
++)
75 monster
* mon
= &menv
[beholders
[i
]];
76 const int olddist
= grid_distance(pos(), mon
->pos());
77 const int newdist
= grid_distance(target
, mon
->pos());
79 if (olddist
< newdist
)
85 monster
* player::get_any_beholder() const
87 if (beholders
.size() > 0)
88 return (&menv
[beholders
[0]]);
93 // Removes a monster from the list of beholders if present.
94 void player::remove_beholder(const monster
* mon
)
96 for (unsigned int i
= 0; i
< beholders
.size(); i
++)
97 if (beholders
[i
] == mon
->mindex())
99 beholders
.erase(beholders
.begin() + i
);
105 // Clear the list of beholders. Doesn't message.
106 void player::clear_beholders()
109 duration
[DUR_MESMERISED
] = 0;
112 // Possibly end mesmerisation if a loud noise happened.
113 void player::beholders_check_noise(int loudness
)
115 if (loudness
>= 20 && beheld())
117 mprf("For a moment, you cannot hear the mermaid%s!",
118 beholders
.size() > 1 ? "s" : "");
124 static void _removed_beholder_msg(const monster
* mon
)
126 if (!mon
->alive() || mons_genus(mon
->type
) != MONS_MERMAID
127 || mon
->submerged() || !you
.see_cell(mon
->pos()))
132 if (is_sanctuary(you
.pos()) && !mons_is_fleeing(mon
))
134 if (you
.can_see(mon
))
136 mprf("%s's singing becomes strangely muted.",
137 mon
->name(DESC_CAP_THE
).c_str());
140 mpr("Something's singing becomes strangely muted.");
145 if (you
.can_see(mon
))
147 if (silenced(you
.pos()) || silenced(mon
->pos()))
149 mprf("You can no longer hear %s's singing!",
150 mon
->name(DESC_NOCAP_THE
).c_str());
153 mprf("%s stops singing.", mon
->name(DESC_CAP_THE
).c_str());
157 mpr("Something stops singing.");
160 // Update all beholders' status after changes.
161 void player::update_beholders()
165 bool removed
= false;
166 for (int i
= beholders
.size() - 1; i
>= 0; i
--)
168 const monster
* mon
= &menv
[beholders
[i
]];
169 if (!_possible_beholder(mon
))
171 beholders
.erase(beholders
.begin() + i
);
173 _removed_beholder_msg(mon
);
180 // Update a single beholder.
181 void player::update_beholder(const monster
* mon
)
183 if (_possible_beholder(mon
))
185 for (unsigned int i
= 0; i
< beholders
.size(); i
++)
186 if (beholders
[i
] == mon
->mindex())
188 beholders
.erase(beholders
.begin() + i
);
189 _removed_beholder_msg(mon
);
195 // Helper function that resets the duration and messages if the player
196 // is no longer mesmerised.
197 void player::_removed_beholder()
199 if (beholders
.empty())
201 duration
[DUR_MESMERISED
] = 0;
202 mpr(coinflip() ? "You break out of your daze!"
203 : "You are no longer entranced.",
208 // Helper function that checks whether the given monster is a possible
210 bool player::_possible_beholder(const monster
* mon
) const
212 if (crawl_state
.game_is_arena())
215 return (mon
->alive() && mons_genus(mon
->type
) == MONS_MERMAID
216 && !silenced(pos()) && !silenced(mon
->pos())
217 && !mon
->has_ench(ENCH_MUTE
)
218 && see_cell(mon
->pos()) && mon
->see_cell(pos())
219 && !mon
->submerged() && !mon
->confused()
220 && !mon
->asleep() && !mon
->cannot_move()
221 && !mon
->wont_attack() && !mon
->pacified()
222 && !mon
->berserk() && !mons_is_fleeing(mon
)
223 && !is_sanctuary(you
.pos()));