Apply the new ground_level method.
[crawl.git] / crawl-ref / source / fearmonger.cc
blobec2be2c50eabbd4f7c41db4a13597c5384d81121
1 /*
2 * File: fearmonger.cc
3 * Summary: player methods dealing with mesmerisation.
4 */
6 #include "AppHdr.h"
8 #include "player.h"
10 #include "coord.h"
11 #include "debug.h"
12 #include "env.h"
13 #include "fprop.h"
14 #include "mon-util.h"
15 #include "monster.h"
16 #include "random.h"
17 #include "state.h"
18 #include "stuff.h"
19 #include "areas.h"
21 // Add a monster to the list of fearmongers.
22 bool player::add_fearmonger(const monster* mon)
24 if (is_sanctuary(you.pos()))
26 if (you.can_see(mon))
28 mprf("%s's aura of fear is muted, and has no effect on you.",
29 mon->name(DESC_CAP_THE).c_str());
31 else
32 mpr("The fearful aura is strangely muted, and has no effect on you.");
34 return (false);
37 if (!duration[DUR_AFRAID])
39 you.set_duration(DUR_AFRAID, 7, 12);
40 fearmongers.push_back(mon->mindex());
41 mprf(MSGCH_WARN, "You are terrified of %s!",
42 mon->name(DESC_NOCAP_THE).c_str());
44 else
46 you.increase_duration(DUR_AFRAID, 5, 12);
47 if (!afraid_of(mon))
48 fearmongers.push_back(mon->mindex());
51 return (true);
54 // Whether player is afraid.
55 bool player::afraid() const
57 ASSERT(duration[DUR_AFRAID] > 0 == !fearmongers.empty());
58 return (duration[DUR_AFRAID] > 0);
61 // Whether player is afraid of the given monster.
62 bool player::afraid_of(const monster* mon) const
64 for (unsigned int i = 0; i < fearmongers.size(); i++)
65 if (fearmongers[i] == mon->mindex())
66 return (true);
67 return (false);
70 // Checks whether a fearmonger keeps you from moving to
71 // target, and returns one if it exists.
72 monster* player::get_fearmonger(const coord_def &target) const
74 for (unsigned int i = 0; i < fearmongers.size(); i++)
76 monster* mon = &menv[fearmongers[i]];
77 const int olddist = grid_distance(pos(), mon->pos());
78 const int newdist = grid_distance(target, mon->pos());
80 if (olddist >= newdist)
81 return (mon);
83 return (NULL);
86 monster* player::get_any_fearmonger() const
88 if (fearmongers.size() > 0)
89 return (&menv[fearmongers[0]]);
90 else
91 return (NULL);
94 // Removes a monster from the list of fearmongers if present.
95 void player::remove_fearmonger(const monster* mon)
97 for (unsigned int i = 0; i < fearmongers.size(); i++)
98 if (fearmongers[i] == mon->mindex())
100 fearmongers.erase(fearmongers.begin() + i);
101 _removed_fearmonger();
102 return;
106 // Clear the list of fearmongers. Doesn't message.
107 void player::clear_fearmongers()
109 fearmongers.clear();
110 duration[DUR_AFRAID] = 0;
113 // Possibly end fear if a loud noise happened.
114 void player::fearmongers_check_noise(int loudness)
116 if (loudness >= 20 && beheld())
118 mprf("For a moment, your terror fades away!");
119 clear_fearmongers();
120 _removed_fearmonger();
124 static void _removed_fearmonger_msg(const monster* mon)
126 return;
129 // Update all fearmongers' status after changes.
130 void player::update_fearmongers()
132 if (!afraid())
133 return;
134 bool removed = false;
135 for (int i = fearmongers.size() - 1; i >= 0; i--)
137 const monster* mon = &menv[fearmongers[i]];
138 if (!_possible_fearmonger(mon))
140 fearmongers.erase(fearmongers.begin() + i);
141 removed = true;
142 _removed_fearmonger_msg(mon);
145 if (removed)
146 _removed_fearmonger();
149 // Update a single fearmonger.
150 void player::update_fearmonger(const monster* mon)
152 if (_possible_fearmonger(mon))
153 return;
154 for (unsigned int i = 0; i < fearmongers.size(); i++)
155 if (fearmongers[i] == mon->mindex())
157 fearmongers.erase(fearmongers.begin() + i);
158 _removed_fearmonger_msg(mon);
159 _removed_fearmonger();
160 return;
164 // Helper function that resets the duration and messages if the player
165 // is no longer afraid.
166 void player::_removed_fearmonger()
168 if (fearmongers.empty())
170 duration[DUR_AFRAID] = 0;
171 mpr("You are no longer terrified.",
172 MSGCH_DURATION);
176 // Helper function that checks whether the given monster is a possible
177 // fearmonger.
178 bool player::_possible_fearmonger(const monster* mon) const
180 if (crawl_state.game_is_arena())
181 return (false);
183 return (mon->alive()
184 && !silenced(pos()) && !silenced(mon->pos())
185 && see_cell(mon->pos()) && mon->see_cell(pos())
186 && !mon->submerged() && !mon->confused()
187 && !mon->asleep() && !mon->cannot_move()
188 && !mon->wont_attack() && !mon->pacified()
189 && !mon->berserk() && !mons_is_fleeing(mon)
190 && !is_sanctuary(you.pos()));