OSDN Git Service

7617d2e73e1fb2f2364e5b9ef7f967233117a106
[hengbandforosx/hengbandosx.git] / src / spell-kind / spells-detection.c
1 #include "spell-kind/spells-detection.h"
2 #include "core/window-redrawer.h"
3 #include "dungeon/dungeon-flag-types.h"
4 #include "dungeon/dungeon.h"
5 #include "floor/cave.h"
6 #include "floor/floor-save-util.h"
7 #include "grid/grid.h"
8 #include "grid/trap.h"
9 #include "monster-race/monster-race.h"
10 #include "monster-race/race-flags2.h"
11 #include "monster-race/race-flags3.h"
12 #include "monster-race/monster-race-hook.h"
13 #include "monster/monster-flag-types.h"
14 #include "monster/monster-info.h"
15 #include "monster/monster-status.h"
16 #include "monster/monster-update.h"
17 #include "object-hook/hook-checker.h"
18 #include "object-hook/hook-enchant.h"
19 #include "object/object-mark-types.h"
20 #include "object/tval-types.h"
21 #include "realm/realm-song-numbers.h"
22 #include "realm/realm-song.h"
23 #include "system/floor-type-definition.h"
24 #include "system/object-type-definition.h"
25 #include "util/string-processor.h"
26 #include "view/display-messages.h"
27
28 /*!
29  * @brief プレイヤー周辺の地形を感知する
30  * @param caster_ptr プレーヤーへの参照ポインタ
31  * @param range 効果範囲
32  * @param flag 特定地形ID
33  * @param known 地形から危険フラグを外すならTRUE
34  * @return 効力があった場合TRUEを返す
35  */
36 static bool detect_feat_flag(player_type *caster_ptr, POSITION range, int flag, bool known)
37 {
38     if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
39         range /= 3;
40
41     grid_type *g_ptr;
42     bool detect = FALSE;
43     for (POSITION y = 1; y < caster_ptr->current_floor_ptr->height - 1; y++) {
44         for (POSITION x = 1; x <= caster_ptr->current_floor_ptr->width - 1; x++) {
45             int dist = distance(caster_ptr->y, caster_ptr->x, y, x);
46             if (dist > range)
47                 continue;
48             g_ptr = &caster_ptr->current_floor_ptr->grid_array[y][x];
49             if (flag == FF_TRAP) {
50                 /* Mark as detected */
51                 if (dist <= range && known) {
52                     if (dist <= range - 1)
53                         g_ptr->info |= (CAVE_IN_DETECT);
54
55                     g_ptr->info &= ~(CAVE_UNSAFE);
56
57                     lite_spot(caster_ptr, y, x);
58                 }
59             }
60
61             if (cave_has_flag_grid(g_ptr, flag)) {
62                 disclose_grid(caster_ptr, y, x);
63                 g_ptr->info |= (CAVE_MARK);
64                 lite_spot(caster_ptr, y, x);
65                 detect = TRUE;
66             }
67         }
68     }
69
70     return detect;
71 }
72
73 /*!
74  * @brief プレイヤー周辺のトラップを感知する / Detect all traps on current panel
75  * @param caster_ptr プレーヤーへの参照ポインタ
76  * @param range 効果範囲
77  * @param known 感知外範囲を超える警告フラグを立てる場合TRUEを返す
78  * @return 効力があった場合TRUEを返す
79  */
80 bool detect_traps(player_type *caster_ptr, POSITION range, bool known)
81 {
82     bool detect = detect_feat_flag(caster_ptr, range, FF_TRAP, known);
83
84     if (known)
85         caster_ptr->dtrap = TRUE;
86
87     if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 0)
88         detect = FALSE;
89     if (detect) {
90         msg_print(_("トラップの存在を感じとった!", "You sense the presence of traps!"));
91     }
92
93     return detect;
94 }
95
96 /*!
97  * @brief プレイヤー周辺のドアを感知する / Detect all doors on current panel
98  * @param caster_ptr プレーヤーへの参照ポインタ
99  * @param range 効果範囲
100  * @return 効力があった場合TRUEを返す
101  */
102 bool detect_doors(player_type *caster_ptr, POSITION range)
103 {
104     bool detect = detect_feat_flag(caster_ptr, range, FF_DOOR, TRUE);
105
106     if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 0)
107         detect = FALSE;
108     if (detect) {
109         msg_print(_("ドアの存在を感じとった!", "You sense the presence of doors!"));
110     }
111
112     return detect;
113 }
114
115 /*!
116  * @brief プレイヤー周辺の階段を感知する / Detect all stairs on current panel
117  * @param caster_ptr プレーヤーへの参照ポインタ
118  * @param range 効果範囲
119  * @return 効力があった場合TRUEを返す
120  */
121 bool detect_stairs(player_type *caster_ptr, POSITION range)
122 {
123     bool detect = detect_feat_flag(caster_ptr, range, FF_STAIRS, TRUE);
124
125     if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 0)
126         detect = FALSE;
127     if (detect) {
128         msg_print(_("階段の存在を感じとった!", "You sense the presence of stairs!"));
129     }
130
131     return detect;
132 }
133
134 /*!
135  * @brief プレイヤー周辺の地形財宝を感知する / Detect any treasure on the current panel
136  * @param caster_ptr プレーヤーへの参照ポインタ
137  * @param range 効果範囲
138  * @return 効力があった場合TRUEを返す
139  */
140 bool detect_treasure(player_type *caster_ptr, POSITION range)
141 {
142     bool detect = detect_feat_flag(caster_ptr, range, FF_HAS_GOLD, TRUE);
143
144     if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 6)
145         detect = FALSE;
146     if (detect) {
147         msg_print(_("埋蔵された財宝の存在を感じとった!", "You sense the presence of buried treasure!"));
148     }
149
150     return detect;
151 }
152 /*!
153  * @brief プレイヤー周辺のアイテム財宝を感知する / Detect all "gold" objects on the current panel
154  * @param caster_ptr プレーヤーへの参照ポインタ
155  * @param range 効果範囲
156  * @return 効力があった場合TRUEを返す
157  */
158 bool detect_objects_gold(player_type *caster_ptr, POSITION range)
159 {
160     POSITION range2 = range;
161     if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
162         range2 /= 3;
163
164     /* Scan objects */
165     bool detect = FALSE;
166     POSITION y, x;
167     for (OBJECT_IDX i = 1; i < caster_ptr->current_floor_ptr->o_max; i++) {
168         object_type *o_ptr = &caster_ptr->current_floor_ptr->o_list[i];
169
170         if (!object_is_valid(o_ptr))
171             continue;
172         if (object_is_held_monster(o_ptr))
173             continue;
174
175         y = o_ptr->iy;
176         x = o_ptr->ix;
177         if (distance(caster_ptr->y, caster_ptr->x, y, x) > range2)
178             continue;
179
180         if (o_ptr->tval == TV_GOLD) {
181             o_ptr->marked |= OM_FOUND;
182             lite_spot(caster_ptr, y, x);
183             detect = TRUE;
184         }
185     }
186
187     if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 6)
188         detect = FALSE;
189     if (detect) {
190         msg_print(_("財宝の存在を感じとった!", "You sense the presence of treasure!"));
191     }
192
193     if (detect_monsters_string(caster_ptr, range, "$")) {
194         detect = TRUE;
195     }
196
197     return detect;
198 }
199
200 /*!
201  * @brief 通常のアイテムオブジェクトを感知する / Detect all "normal" objects on the current panel
202  * @param caster_ptr プレーヤーへの参照ポインタ
203  * @param range 効果範囲
204  * @return 効力があった場合TRUEを返す
205  */
206 bool detect_objects_normal(player_type *caster_ptr, POSITION range)
207 {
208     POSITION range2 = range;
209     if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
210         range2 /= 3;
211
212     bool detect = FALSE;
213     for (OBJECT_IDX i = 1; i < caster_ptr->current_floor_ptr->o_max; i++) {
214         object_type *o_ptr = &caster_ptr->current_floor_ptr->o_list[i];
215
216         if (!object_is_valid(o_ptr))
217             continue;
218         if (object_is_held_monster(o_ptr))
219             continue;
220
221         POSITION y = o_ptr->iy;
222         POSITION x = o_ptr->ix;
223
224         if (distance(caster_ptr->y, caster_ptr->x, y, x) > range2)
225             continue;
226
227         if (o_ptr->tval != TV_GOLD) {
228             o_ptr->marked |= OM_FOUND;
229             lite_spot(caster_ptr, y, x);
230             detect = TRUE;
231         }
232     }
233
234     if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 6)
235         detect = FALSE;
236     if (detect) {
237         msg_print(_("アイテムの存在を感じとった!", "You sense the presence of objects!"));
238     }
239
240     if (detect_monsters_string(caster_ptr, range, "!=?|/`")) {
241         detect = TRUE;
242     }
243
244     return detect;
245 }
246
247 /*!
248  * @brief 魔法効果のあるのアイテムオブジェクトを感知する / Detect all "magic" objects on the current panel.
249  * @param caster_ptr プレーヤーへの参照ポインタ
250  * @param range 効果範囲
251  * @return 効力があった場合TRUEを返す
252  * @details
253  * <pre>
254  * This will light up all spaces with "magic" items, including artifacts,
255  * ego-items, potions, scrolls, books, rods, wands, staffs, amulets, rings,
256  * and "enchanted" items of the "good" variety.
257  *
258  * It can probably be argued that this function is now too powerful.
259  * </pre>
260  */
261 bool detect_objects_magic(player_type *caster_ptr, POSITION range)
262 {
263     if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
264         range /= 3;
265
266     tval_type tv;
267     bool detect = FALSE;
268     for (OBJECT_IDX i = 1; i < caster_ptr->current_floor_ptr->o_max; i++) {
269         object_type *o_ptr = &caster_ptr->current_floor_ptr->o_list[i];
270
271         if (!object_is_valid(o_ptr))
272             continue;
273         if (object_is_held_monster(o_ptr))
274             continue;
275
276         POSITION y = o_ptr->iy;
277         POSITION x = o_ptr->ix;
278
279         if (distance(caster_ptr->y, caster_ptr->x, y, x) > range)
280             continue;
281
282         tv = o_ptr->tval;
283         if (object_is_artifact(o_ptr) || object_is_ego(o_ptr) || (tv == TV_WHISTLE) || (tv == TV_AMULET) || (tv == TV_RING) || (tv == TV_STAFF)
284             || (tv == TV_WAND) || (tv == TV_ROD) || (tv == TV_SCROLL) || (tv == TV_POTION) || (tv == TV_LIFE_BOOK) || (tv == TV_SORCERY_BOOK)
285             || (tv == TV_NATURE_BOOK) || (tv == TV_CHAOS_BOOK) || (tv == TV_DEATH_BOOK) || (tv == TV_TRUMP_BOOK) || (tv == TV_ARCANE_BOOK)
286             || (tv == TV_CRAFT_BOOK) || (tv == TV_DEMON_BOOK) || (tv == TV_CRUSADE_BOOK) || (tv == TV_MUSIC_BOOK) || (tv == TV_HISSATSU_BOOK)
287             || (tv == TV_HEX_BOOK) || ((o_ptr->to_a > 0) || (o_ptr->to_h + o_ptr->to_d > 0))) {
288             o_ptr->marked |= OM_FOUND;
289             lite_spot(caster_ptr, y, x);
290             detect = TRUE;
291         }
292     }
293
294     if (detect) {
295         msg_print(_("魔法のアイテムの存在を感じとった!", "You sense the presence of magic objects!"));
296     }
297
298     return detect;
299 }
300
301 /*!
302  * @brief 一般のモンスターを感知する / Detect all "normal" monsters on the current panel
303  * @param caster_ptr プレーヤーへの参照ポインタ
304  * @param range 効果範囲
305  * @return 効力があった場合TRUEを返す
306  */
307 bool detect_monsters_normal(player_type *caster_ptr, POSITION range)
308 {
309     if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
310         range /= 3;
311
312     bool flag = FALSE;
313     for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++) {
314         monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
315         monster_race *r_ptr = &r_info[m_ptr->r_idx];
316         if (!monster_is_valid(m_ptr))
317             continue;
318
319         POSITION y = m_ptr->fy;
320         POSITION x = m_ptr->fx;
321         if (distance(caster_ptr->y, caster_ptr->x, y, x) > range)
322             continue;
323
324         if (!(r_ptr->flags2 & RF2_INVISIBLE) || caster_ptr->see_inv) {
325             repair_monsters = TRUE;
326             m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
327             update_monster(caster_ptr, i, FALSE);
328             flag = TRUE;
329         }
330     }
331
332     if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 3)
333         flag = FALSE;
334     if (flag) {
335         msg_print(_("モンスターの存在を感じとった!", "You sense the presence of monsters!"));
336     }
337
338     return flag;
339 }
340
341 /*!
342  * @brief 不可視のモンスターを感知する / Detect all "invisible" monsters around the player
343  * @param caster_ptr プレーヤーへの参照ポインタ
344  * @param range 効果範囲
345  * @return 効力があった場合TRUEを返す
346  */
347 bool detect_monsters_invis(player_type *caster_ptr, POSITION range)
348 {
349     if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
350         range /= 3;
351
352     bool flag = FALSE;
353     for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++) {
354         monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
355         monster_race *r_ptr = &r_info[m_ptr->r_idx];
356
357         if (!monster_is_valid(m_ptr))
358             continue;
359
360         POSITION y = m_ptr->fy;
361         POSITION x = m_ptr->fx;
362
363         if (distance(caster_ptr->y, caster_ptr->x, y, x) > range)
364             continue;
365
366         if (r_ptr->flags2 & RF2_INVISIBLE) {
367             if (caster_ptr->monster_race_idx == m_ptr->r_idx) {
368                 caster_ptr->window_flags |= (PW_MONSTER);
369             }
370
371             repair_monsters = TRUE;
372             m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
373             update_monster(caster_ptr, i, FALSE);
374             flag = TRUE;
375         }
376     }
377
378     if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 3)
379         flag = FALSE;
380     if (flag) {
381         msg_print(_("透明な生物の存在を感じとった!", "You sense the presence of invisible creatures!"));
382     }
383
384     return flag;
385 }
386
387 /*!
388  * @brief 邪悪なモンスターを感知する / Detect all "evil" monsters on current panel
389  * @param caster_ptr プレーヤーへの参照ポインタ
390  * @param range 効果範囲
391  * @return 効力があった場合TRUEを返す
392  */
393 bool detect_monsters_evil(player_type *caster_ptr, POSITION range)
394 {
395     if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
396         range /= 3;
397
398     bool flag = FALSE;
399     for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++) {
400         monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
401         monster_race *r_ptr = &r_info[m_ptr->r_idx];
402         if (!monster_is_valid(m_ptr))
403             continue;
404
405         POSITION y = m_ptr->fy;
406         POSITION x = m_ptr->fx;
407
408         if (distance(caster_ptr->y, caster_ptr->x, y, x) > range)
409             continue;
410
411         if (r_ptr->flags3 & RF3_EVIL) {
412             if (is_original_ap(m_ptr)) {
413                 r_ptr->r_flags3 |= (RF3_EVIL);
414                 if (caster_ptr->monster_race_idx == m_ptr->r_idx) {
415                     caster_ptr->window_flags |= (PW_MONSTER);
416                 }
417             }
418
419             repair_monsters = TRUE;
420             m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
421             update_monster(caster_ptr, i, FALSE);
422             flag = TRUE;
423         }
424     }
425
426     if (flag) {
427         msg_print(_("邪悪なる生物の存在を感じとった!", "You sense the presence of evil creatures!"));
428     }
429
430     return flag;
431 }
432
433 /*!
434  * @brief 無生命のモンスターを感知する(アンデッド、悪魔系を含む) / Detect all "nonliving", "undead" or "demonic" monsters on current panel
435  * @param caster_ptr プレーヤーへの参照ポインタ
436  * @param range 効果範囲
437  * @return 効力があった場合TRUEを返す
438  */
439 bool detect_monsters_nonliving(player_type *caster_ptr, POSITION range)
440 {
441     if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
442         range /= 3;
443
444     bool flag = FALSE;
445     for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++) {
446         monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
447         if (!monster_is_valid(m_ptr))
448             continue;
449
450         POSITION y = m_ptr->fy;
451         POSITION x = m_ptr->fx;
452         if (distance(caster_ptr->y, caster_ptr->x, y, x) > range)
453             continue;
454
455         if (!monster_living(m_ptr->r_idx)) {
456             if (caster_ptr->monster_race_idx == m_ptr->r_idx) {
457                 caster_ptr->window_flags |= (PW_MONSTER);
458             }
459
460             repair_monsters = TRUE;
461             m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
462             update_monster(caster_ptr, i, FALSE);
463             flag = TRUE;
464         }
465     }
466
467     if (flag) {
468         msg_print(_("自然でないモンスターの存在を感じた!", "You sense the presence of unnatural beings!"));
469     }
470
471     return flag;
472 }
473
474 /*!
475  * @brief 精神のあるモンスターを感知する / Detect all monsters it has mind on current panel
476  * @param caster_ptr プレーヤーへの参照ポインタ
477  * @param range 効果範囲
478  * @return 効力があった場合TRUEを返す
479  */
480 bool detect_monsters_mind(player_type *caster_ptr, POSITION range)
481 {
482     if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
483         range /= 3;
484
485     bool flag = FALSE;
486     for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++) {
487         monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
488         monster_race *r_ptr = &r_info[m_ptr->r_idx];
489         if (!monster_is_valid(m_ptr))
490             continue;
491
492         POSITION y = m_ptr->fy;
493         POSITION x = m_ptr->fx;
494
495         if (distance(caster_ptr->y, caster_ptr->x, y, x) > range)
496             continue;
497
498         if (!(r_ptr->flags2 & RF2_EMPTY_MIND)) {
499             if (caster_ptr->monster_race_idx == m_ptr->r_idx) {
500                 caster_ptr->window_flags |= (PW_MONSTER);
501             }
502
503             repair_monsters = TRUE;
504             m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
505             update_monster(caster_ptr, i, FALSE);
506             flag = TRUE;
507         }
508     }
509
510     if (flag) {
511         msg_print(_("殺気を感じとった!", "You sense the presence of someone's mind!"));
512     }
513
514     return flag;
515 }
516
517 /*!
518  * @brief 該当シンボルのモンスターを感知する / Detect all (string) monsters on current panel
519  * @param caster_ptr プレーヤーへの参照ポインタ
520  * @param range 効果範囲
521  * @param Match 対応シンボルの混じったモンスター文字列(複数指定化)
522  * @return 効力があった場合TRUEを返す
523  */
524 bool detect_monsters_string(player_type *caster_ptr, POSITION range, concptr Match)
525 {
526     if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
527         range /= 3;
528
529     bool flag = FALSE;
530     for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++) {
531         monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
532         monster_race *r_ptr = &r_info[m_ptr->r_idx];
533         if (!monster_is_valid(m_ptr))
534             continue;
535
536         POSITION y = m_ptr->fy;
537         POSITION x = m_ptr->fx;
538
539         if (distance(caster_ptr->y, caster_ptr->x, y, x) > range)
540             continue;
541
542         if (angband_strchr(Match, r_ptr->d_char)) {
543             if (caster_ptr->monster_race_idx == m_ptr->r_idx) {
544                 caster_ptr->window_flags |= (PW_MONSTER);
545             }
546
547             repair_monsters = TRUE;
548             m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
549             update_monster(caster_ptr, i, FALSE);
550             flag = TRUE;
551         }
552     }
553
554     if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 3)
555         flag = FALSE;
556     if (flag) {
557         msg_print(_("モンスターの存在を感じとった!", "You sense the presence of monsters!"));
558     }
559
560     return flag;
561 }
562
563 /*!
564  * @brief flags3に対応するモンスターを感知する / A "generic" detect monsters routine, tagged to flags3
565  * @param caster_ptr プレーヤーへの参照ポインタ
566  * @param range 効果範囲
567  * @param match_flag 感知フラグ
568  * @return 効力があった場合TRUEを返す
569  */
570 bool detect_monsters_xxx(player_type *caster_ptr, POSITION range, u32b match_flag)
571 {
572     if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
573         range /= 3;
574
575     bool flag = FALSE;
576     for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++) {
577         monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
578         monster_race *r_ptr = &r_info[m_ptr->r_idx];
579         if (!monster_is_valid(m_ptr))
580             continue;
581
582         POSITION y = m_ptr->fy;
583         POSITION x = m_ptr->fx;
584
585         if (distance(caster_ptr->y, caster_ptr->x, y, x) > range)
586             continue;
587
588         if (r_ptr->flags3 & (match_flag)) {
589             if (is_original_ap(m_ptr)) {
590                 r_ptr->r_flags3 |= (match_flag);
591                 if (caster_ptr->monster_race_idx == m_ptr->r_idx) {
592                     caster_ptr->window_flags |= (PW_MONSTER);
593                 }
594             }
595
596             repair_monsters = TRUE;
597             m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
598             update_monster(caster_ptr, i, FALSE);
599             flag = TRUE;
600         }
601     }
602
603     concptr desc_monsters = _("変なモンスター", "weird monsters");
604     if (flag) {
605         switch (match_flag) {
606         case RF3_DEMON:
607             desc_monsters = _("デーモン", "demons");
608             break;
609         case RF3_UNDEAD:
610             desc_monsters = _("アンデッド", "the undead");
611             break;
612         }
613
614         msg_format(_("%sの存在を感じとった!", "You sense the presence of %s!"), desc_monsters);
615         msg_print(NULL);
616     }
617
618     return flag;
619 }
620
621 /*!
622  * @brief 全感知処理 / Detect everything
623  * @param caster_ptr プレーヤーへの参照ポインタ
624  * @param range 効果範囲
625  * @return 効力があった場合TRUEを返す
626  */
627 bool detect_all(player_type *caster_ptr, POSITION range)
628 {
629     bool detect = FALSE;
630     if (detect_traps(caster_ptr, range, TRUE))
631         detect = TRUE;
632     if (detect_doors(caster_ptr, range))
633         detect = TRUE;
634     if (detect_stairs(caster_ptr, range))
635         detect = TRUE;
636     if (detect_objects_gold(caster_ptr, range))
637         detect = TRUE;
638     if (detect_objects_normal(caster_ptr, range))
639         detect = TRUE;
640     if (detect_monsters_invis(caster_ptr, range))
641         detect = TRUE;
642     if (detect_monsters_normal(caster_ptr, range))
643         detect = TRUE;
644     return (detect);
645 }