OSDN Git Service

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