<ClCompile Include="..\..\src\cmd\object-group-table.c" />\r
<ClCompile Include="..\..\src\combat\melee.c" />\r
<ClCompile Include="..\..\src\combat\shoot.c" />\r
+ <ClCompile Include="..\..\src\spell\spells-detection.c" />\r
<ClCompile Include="..\..\src\system\system-variables.c" />\r
<ClCompile Include="..\..\src\core\show-file.c" />\r
<ClCompile Include="..\..\src\monster\creature.c" />\r
<ClInclude Include="..\..\src\core\output-updater.h" />\r
<ClInclude Include="..\..\src\core\special-internal-keys.h" />\r
<ClInclude Include="..\..\src\core\stuff-handler.h" />\r
+ <ClInclude Include="..\..\src\spell\spells-detection.h" />\r
<ClInclude Include="..\..\src\system\angband-version.h" />\r
<ClInclude Include="..\..\src\core\turn-compensator.h" />\r
<ClInclude Include="..\..\src\effect\effect-characteristics.h" />\r
<ClCompile Include="..\..\src\util\util.c">
<Filter>core</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\spell\spells-detection.c">
+ <Filter>spell</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\cmd\cmd-activate.h">
<ClInclude Include="..\..\src\util\util.h">
<Filter>core</Filter>
</ClInclude>
+ <ClInclude Include="..\..\src\spell\spells-detection.h">
+ <Filter>spell</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\src\wall.bmp" />
spell/spells-status.c spell/spells-status.h \
spell/spells-summon.c spell/spells-summon.h \
spell/spells-world.c spell/spells-world.h \
+ spell/spells-detection.c spell/spells-detection.h \
\
view-mainwindow.c view-mainwindow.h targeting.c targeting.h \
\
#include "effect/effect-characteristics.h"
#include "spell/spells2.h"
#include "spell/spells3.h"
+#include "spell/spells-detection.h"
/*!
* @brief 装備耐性に準じたブレス効果の選択テーブル /
#include "object/object-hook.h"
#include "mutation/mutation.h"
#include "player/avatar.h"
-#include "spell/spells2.h"
#include "spell/spells3.h"
#include "spell/spells-status.h"
#include "player/player-effects.h"
#include "object/object-kind.h"
#include "view/display-main-window.h"
#include "player/player-class.h"
+#include "spell/spells-detection.h"
/*!
* @brief 薬を飲むコマンドのサブルーチン /
#include "spell/spells-type.h"
#include "spell/spells2.h"
#include "spell/spells3.h"
+#include "spell/spells-detection.h"
/*!
* @brief 巻物を読むコマンドのサブルーチン
#include "floor/floor.h"
#include "object/object-kind.h"
#include "view/display-main-window.h"
-
+#include "spell/spells-detection.h"
/*!
* @brief 杖の効果を発動する
#include "view/display-main-window.h"
#include "spell/spells2.h"
#include "spell/spells3.h"
+#include "spell/spells-detection.h"
/*!
* @brief ロッドの効果を発動する
#include "spell/process-effect.h"
#include "spell/spells2.h"
#include "spell/spells3.h"
+#include "spell/spells-detection.h"
/*! 特殊技能の一覧テーブル */
mind_power const mind_powers[5] =
#include "spell/spells-type.h"
#include "spell/spells2.h"
#include "spell/spells3.h"
+#include "spell/spells-detection.h"
/*!
* @brief 修行僧の構え設定処理
#include "spell/spells-type.h"
#include "spell/spells2.h"
#include "spell/spells3.h"
+#include "spell/spells-detection.h"
/*!
* @brief プレイヤーに突然変異を与える
#include "io/targeting.h"
#include "realm/realm-arcane.h"
#include "spell/spells-type.h"
+#include "spell/spells-detection.h"
/*!
* @brief 秘術領域魔法の各処理を行う
#include "spell/process-effect.h"
#include "spell/spells2.h"
#include "spell/spells3.h"
+#include "spell/spells-detection.h"
/*!
* @brief 破邪領域魔法の各処理を行う
#include "io/targeting.h"
#include "realm/realm-daemon.h"
#include "spell/spells2.h"
+#include "spell/spells-detection.h"
/*!
* @brief 悪魔領域魔法の各処理を行う
#include "effect/effect-characteristics.h"
#include "spell/spells2.h"
#include "spell/spells3.h"
+#include "spell/spells-detection.h"
/*!
* @brief 暗黒領域魔法の各処理を行う
#include "spell/process-effect.h"
#include "spell/spells2.h"
#include "spell/spells3.h"
+#include "spell/spells-detection.h"
/*!
* @brief 剣術の各処理を行う
#include "io/targeting.h"
#include "realm/realm-life.h"
#include "spell/spells-type.h"
+#include "spell/spells-detection.h"
/*!
* @brief 生命領域魔法の各処理を行う
#include "effect/effect-characteristics.h"
#include "spell/spells2.h"
#include "spell/spells3.h"
+#include "spell/spells-detection.h"
/*!
* @brief 自然領域魔法の各処理を行う
#include "effect/effect-characteristics.h"
#include "spell/spells2.h"
#include "spell/spells3.h"
+#include "spell/spells-detection.h"
/*!
* @brief 歌の開始を処理する / Start singing if the player is a Bard
#include "realm/realm-sorcery.h"
#include "spell/spells2.h"
#include "spell/spells3.h"
+#include "spell/spells-detection.h"
/*!
* @brief 仙術領域魔法の各処理を行う
#include "spell/spells-type.h"
#include "spell/spells2.h"
#include "spell/spells3.h"
+#include "spell/spells-detection.h"
/*!
* @brief トランプ領域魔法の各処理を行う
--- /dev/null
+#include "system/angband.h"
+#include "spell/spells-detection.h"
+#include "dungeon/dungeon.h"
+#include "realm/realm-song.h"
+#include "core/player-processor.h"
+#include "grid/trap.h"
+#include "object/object-hook.h"
+#include "monster/monster-status.h"
+#include "monster/monsterrace-hook.h"
+
+/*!
+ * @brief プレイヤー周辺の地形を感知する
+ * @param caster_ptr プレーヤーへの参照ポインタ
+ * @param range 効果範囲
+ * @param flag 特定地形ID
+ * @param known 地形から危険フラグを外すならTRUE
+ * @return 効力があった場合TRUEを返す
+ */
+static bool detect_feat_flag(player_type* caster_ptr, POSITION range, int flag, bool known)
+{
+ if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
+ range /= 3;
+
+ grid_type* g_ptr;
+ bool detect = FALSE;
+ for (POSITION y = 1; y < caster_ptr->current_floor_ptr->height - 1; y++) {
+ for (POSITION x = 1; x <= caster_ptr->current_floor_ptr->width - 1; x++) {
+ int dist = distance(caster_ptr->y, caster_ptr->x, y, x);
+ if (dist > range)
+ continue;
+ g_ptr = &caster_ptr->current_floor_ptr->grid_array[y][x];
+ if (flag == FF_TRAP) {
+ /* Mark as detected */
+ if (dist <= range && known) {
+ if (dist <= range - 1)
+ g_ptr->info |= (CAVE_IN_DETECT);
+
+ g_ptr->info &= ~(CAVE_UNSAFE);
+
+ lite_spot(caster_ptr, y, x);
+ }
+ }
+
+ if (cave_have_flag_grid(g_ptr, flag)) {
+ disclose_grid(caster_ptr, y, x);
+ g_ptr->info |= (CAVE_MARK);
+ lite_spot(caster_ptr, y, x);
+ detect = TRUE;
+ }
+ }
+ }
+
+ return detect;
+}
+
+/*!
+ * @brief プレイヤー周辺のトラップを感知する / Detect all traps on current panel
+ * @param caster_ptr プレーヤーへの参照ポインタ
+ * @param range 効果範囲
+ * @param known 感知外範囲を超える警告フラグを立てる場合TRUEを返す
+ * @return 効力があった場合TRUEを返す
+ */
+bool detect_traps(player_type* caster_ptr, POSITION range, bool known)
+{
+ bool detect = detect_feat_flag(caster_ptr, range, FF_TRAP, known);
+
+ if (known)
+ caster_ptr->dtrap = TRUE;
+
+ if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 0)
+ detect = FALSE;
+ if (detect) {
+ msg_print(_("トラップの存在を感じとった!", "You sense the presence of traps!"));
+ }
+
+ return detect;
+}
+
+/*!
+ * @brief プレイヤー周辺のドアを感知する / Detect all doors on current panel
+ * @param caster_ptr プレーヤーへの参照ポインタ
+ * @param range 効果範囲
+ * @return 効力があった場合TRUEを返す
+ */
+bool detect_doors(player_type* caster_ptr, POSITION range)
+{
+ bool detect = detect_feat_flag(caster_ptr, range, FF_DOOR, TRUE);
+
+ if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 0)
+ detect = FALSE;
+ if (detect) {
+ msg_print(_("ドアの存在を感じとった!", "You sense the presence of doors!"));
+ }
+
+ return detect;
+}
+
+/*!
+ * @brief プレイヤー周辺の階段を感知する / Detect all stairs on current panel
+ * @param caster_ptr プレーヤーへの参照ポインタ
+ * @param range 効果範囲
+ * @return 効力があった場合TRUEを返す
+ */
+bool detect_stairs(player_type* caster_ptr, POSITION range)
+{
+ bool detect = detect_feat_flag(caster_ptr, range, FF_STAIRS, TRUE);
+
+ if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 0)
+ detect = FALSE;
+ if (detect) {
+ msg_print(_("階段の存在を感じとった!", "You sense the presence of stairs!"));
+ }
+
+ return detect;
+}
+
+/*!
+ * @brief プレイヤー周辺の地形財宝を感知する / Detect any treasure on the current panel
+ * @param caster_ptr プレーヤーへの参照ポインタ
+ * @param range 効果範囲
+ * @return 効力があった場合TRUEを返す
+ */
+bool detect_treasure(player_type* caster_ptr, POSITION range)
+{
+ bool detect = detect_feat_flag(caster_ptr, range, FF_HAS_GOLD, TRUE);
+
+ if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 6)
+ detect = FALSE;
+ if (detect) {
+ msg_print(_("埋蔵された財宝の存在を感じとった!", "You sense the presence of buried treasure!"));
+ }
+
+ return detect;
+}
+/*!
+ * @brief プレイヤー周辺のアイテム財宝を感知する / Detect all "gold" objects on the current panel
+ * @param caster_ptr プレーヤーへの参照ポインタ
+ * @param range 効果範囲
+ * @return 効力があった場合TRUEを返す
+ */
+bool detect_objects_gold(player_type* caster_ptr, POSITION range)
+{
+ POSITION range2 = range;
+ if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
+ range2 /= 3;
+
+ /* Scan objects */
+ bool detect = FALSE;
+ POSITION y, x;
+ for (OBJECT_IDX i = 1; i < caster_ptr->current_floor_ptr->o_max; i++) {
+ object_type* o_ptr = &caster_ptr->current_floor_ptr->o_list[i];
+
+ if (!OBJECT_IS_VALID(o_ptr))
+ continue;
+ if (OBJECT_IS_HELD_MONSTER(o_ptr))
+ continue;
+
+ y = o_ptr->iy;
+ x = o_ptr->ix;
+ if (distance(caster_ptr->y, caster_ptr->x, y, x) > range2)
+ continue;
+
+ if (o_ptr->tval == TV_GOLD) {
+ o_ptr->marked |= OM_FOUND;
+ lite_spot(caster_ptr, y, x);
+ detect = TRUE;
+ }
+ }
+
+ if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 6)
+ detect = FALSE;
+ if (detect) {
+ msg_print(_("財宝の存在を感じとった!", "You sense the presence of treasure!"));
+ }
+
+ if (detect_monsters_string(caster_ptr, range, "$")) {
+ detect = TRUE;
+ }
+
+ return detect;
+}
+
+/*!
+ * @brief 通常のアイテムオブジェクトを感知する / Detect all "normal" objects on the current panel
+ * @param caster_ptr プレーヤーへの参照ポインタ
+ * @param range 効果範囲
+ * @return 効力があった場合TRUEを返す
+ */
+bool detect_objects_normal(player_type* caster_ptr, POSITION range)
+{
+ POSITION range2 = range;
+ if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
+ range2 /= 3;
+
+ bool detect = FALSE;
+ for (OBJECT_IDX i = 1; i < caster_ptr->current_floor_ptr->o_max; i++) {
+ object_type* o_ptr = &caster_ptr->current_floor_ptr->o_list[i];
+
+ if (!OBJECT_IS_VALID(o_ptr))
+ continue;
+ if (OBJECT_IS_HELD_MONSTER(o_ptr))
+ continue;
+
+ POSITION y = o_ptr->iy;
+ POSITION x = o_ptr->ix;
+
+ if (distance(caster_ptr->y, caster_ptr->x, y, x) > range2)
+ continue;
+
+ if (o_ptr->tval != TV_GOLD) {
+ o_ptr->marked |= OM_FOUND;
+ lite_spot(caster_ptr, y, x);
+ detect = TRUE;
+ }
+ }
+
+ if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 6)
+ detect = FALSE;
+ if (detect) {
+ msg_print(_("アイテムの存在を感じとった!", "You sense the presence of objects!"));
+ }
+
+ if (detect_monsters_string(caster_ptr, range, "!=?|/`")) {
+ detect = TRUE;
+ }
+
+ return detect;
+}
+
+/*!
+ * @brief 魔法効果のあるのアイテムオブジェクトを感知する / Detect all "magic" objects on the current panel.
+ * @param caster_ptr プレーヤーへの参照ポインタ
+ * @param range 効果範囲
+ * @return 効力があった場合TRUEを返す
+ * @details
+ * <pre>
+ * This will light up all spaces with "magic" items, including artifacts,
+ * ego-items, potions, scrolls, books, rods, wands, staffs, amulets, rings,
+ * and "enchanted" items of the "good" variety.
+ *
+ * It can probably be argued that this function is now too powerful.
+ * </pre>
+ */
+bool detect_objects_magic(player_type* caster_ptr, POSITION range)
+{
+ if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
+ range /= 3;
+
+ OBJECT_TYPE_VALUE tv;
+ bool detect = FALSE;
+ for (OBJECT_IDX i = 1; i < caster_ptr->current_floor_ptr->o_max; i++) {
+ object_type* o_ptr = &caster_ptr->current_floor_ptr->o_list[i];
+
+ if (!OBJECT_IS_VALID(o_ptr))
+ continue;
+ if (OBJECT_IS_HELD_MONSTER(o_ptr))
+ continue;
+
+ POSITION y = o_ptr->iy;
+ POSITION x = o_ptr->ix;
+
+ if (distance(caster_ptr->y, caster_ptr->x, y, x) > range)
+ continue;
+
+ tv = o_ptr->tval;
+ if (object_is_artifact(o_ptr) || object_is_ego(o_ptr) ||
+ (tv == TV_WHISTLE) || (tv == TV_AMULET) || (tv == TV_RING) || (tv == TV_STAFF) ||
+ (tv == TV_WAND) || (tv == TV_ROD) || (tv == TV_SCROLL) || (tv == TV_POTION) ||
+ (tv == TV_LIFE_BOOK) || (tv == TV_SORCERY_BOOK) || (tv == TV_NATURE_BOOK) ||
+ (tv == TV_CHAOS_BOOK) || (tv == TV_DEATH_BOOK) || (tv == TV_TRUMP_BOOK) ||
+ (tv == TV_ARCANE_BOOK) || (tv == TV_CRAFT_BOOK) || (tv == TV_DAEMON_BOOK) ||
+ (tv == TV_CRUSADE_BOOK) || (tv == TV_MUSIC_BOOK) || (tv == TV_HISSATSU_BOOK) ||
+ (tv == TV_HEX_BOOK) || ((o_ptr->to_a > 0) || (o_ptr->to_h + o_ptr->to_d > 0))) {
+ o_ptr->marked |= OM_FOUND;
+ lite_spot(caster_ptr, y, x);
+ detect = TRUE;
+ }
+ }
+
+ if (detect) {
+ msg_print(_("魔法のアイテムの存在を感じとった!", "You sense the presence of magic objects!"));
+ }
+
+ return detect;
+}
+
+/*!
+ * @brief 一般のモンスターを感知する / Detect all "normal" monsters on the current panel
+ * @param caster_ptr プレーヤーへの参照ポインタ
+ * @param range 効果範囲
+ * @return 効力があった場合TRUEを返す
+ */
+bool detect_monsters_normal(player_type* caster_ptr, POSITION range)
+{
+ if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
+ range /= 3;
+
+ bool flag = FALSE;
+ for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++) {
+ monster_type* m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
+ monster_race* r_ptr = &r_info[m_ptr->r_idx];
+ if (!monster_is_valid(m_ptr))
+ continue;
+
+ POSITION y = m_ptr->fy;
+ POSITION x = m_ptr->fx;
+ if (distance(caster_ptr->y, caster_ptr->x, y, x) > range)
+ continue;
+
+ if (!(r_ptr->flags2 & RF2_INVISIBLE) || caster_ptr->see_inv) {
+ repair_monsters = TRUE;
+ m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
+ update_monster(caster_ptr, i, FALSE);
+ flag = TRUE;
+ }
+ }
+
+ if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 3)
+ flag = FALSE;
+ if (flag) {
+ msg_print(_("モンスターの存在を感じとった!", "You sense the presence of monsters!"));
+ }
+
+ return flag;
+}
+
+/*!
+ * @brief 不可視のモンスターを感知する / Detect all "invisible" monsters around the player
+ * @param caster_ptr プレーヤーへの参照ポインタ
+ * @param range 効果範囲
+ * @return 効力があった場合TRUEを返す
+ */
+bool detect_monsters_invis(player_type* caster_ptr, POSITION range)
+{
+ if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
+ range /= 3;
+
+ bool flag = FALSE;
+ for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++) {
+ monster_type* m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
+ monster_race* r_ptr = &r_info[m_ptr->r_idx];
+
+ if (!monster_is_valid(m_ptr))
+ continue;
+
+ POSITION y = m_ptr->fy;
+ POSITION x = m_ptr->fx;
+
+ if (distance(caster_ptr->y, caster_ptr->x, y, x) > range)
+ continue;
+
+ if (r_ptr->flags2 & RF2_INVISIBLE) {
+ if (caster_ptr->monster_race_idx == m_ptr->r_idx) {
+ caster_ptr->window |= (PW_MONSTER);
+ }
+
+ repair_monsters = TRUE;
+ m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
+ update_monster(caster_ptr, i, FALSE);
+ flag = TRUE;
+ }
+ }
+
+ if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 3)
+ flag = FALSE;
+ if (flag) {
+ msg_print(_("透明な生物の存在を感じとった!", "You sense the presence of invisible creatures!"));
+ }
+
+ return flag;
+}
+
+/*!
+ * @brief 邪悪なモンスターを感知する / Detect all "evil" monsters on current panel
+ * @param caster_ptr プレーヤーへの参照ポインタ
+ * @param range 効果範囲
+ * @return 効力があった場合TRUEを返す
+ */
+bool detect_monsters_evil(player_type* caster_ptr, POSITION range)
+{
+ if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
+ range /= 3;
+
+ bool flag = FALSE;
+ for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++) {
+ monster_type* m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
+ monster_race* r_ptr = &r_info[m_ptr->r_idx];
+ if (!monster_is_valid(m_ptr))
+ continue;
+
+ POSITION y = m_ptr->fy;
+ POSITION x = m_ptr->fx;
+
+ if (distance(caster_ptr->y, caster_ptr->x, y, x) > range)
+ continue;
+
+ if (r_ptr->flags3 & RF3_EVIL) {
+ if (is_original_ap(m_ptr)) {
+ r_ptr->r_flags3 |= (RF3_EVIL);
+ if (caster_ptr->monster_race_idx == m_ptr->r_idx) {
+ caster_ptr->window |= (PW_MONSTER);
+ }
+ }
+
+ repair_monsters = TRUE;
+ m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
+ update_monster(caster_ptr, i, FALSE);
+ flag = TRUE;
+ }
+ }
+
+ if (flag) {
+ msg_print(_("邪悪なる生物の存在を感じとった!", "You sense the presence of evil creatures!"));
+ }
+
+ return flag;
+}
+
+/*!
+ * @brief 無生命のモンスターを感知する(アンデッド、悪魔系を含む) / Detect all "nonliving", "undead" or "demonic" monsters on current panel
+ * @param caster_ptr プレーヤーへの参照ポインタ
+ * @param range 効果範囲
+ * @return 効力があった場合TRUEを返す
+ */
+bool detect_monsters_nonliving(player_type* caster_ptr, POSITION range)
+{
+ if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
+ range /= 3;
+
+ bool flag = FALSE;
+ for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++) {
+ monster_type* m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
+ if (!monster_is_valid(m_ptr))
+ continue;
+
+ POSITION y = m_ptr->fy;
+ POSITION x = m_ptr->fx;
+ if (distance(caster_ptr->y, caster_ptr->x, y, x) > range)
+ continue;
+
+ if (!monster_living(m_ptr->r_idx)) {
+ if (caster_ptr->monster_race_idx == m_ptr->r_idx) {
+ caster_ptr->window |= (PW_MONSTER);
+ }
+
+ repair_monsters = TRUE;
+ m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
+ update_monster(caster_ptr, i, FALSE);
+ flag = TRUE;
+ }
+ }
+
+ if (flag) {
+ msg_print(_("自然でないモンスターの存在を感じた!", "You sense the presence of unnatural beings!"));
+ }
+
+ return flag;
+}
+
+/*!
+ * @brief 精神のあるモンスターを感知する / Detect all monsters it has mind on current panel
+ * @param caster_ptr プレーヤーへの参照ポインタ
+ * @param range 効果範囲
+ * @return 効力があった場合TRUEを返す
+ */
+bool detect_monsters_mind(player_type* caster_ptr, POSITION range)
+{
+ if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
+ range /= 3;
+
+ bool flag = FALSE;
+ for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++) {
+ monster_type* m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
+ monster_race* r_ptr = &r_info[m_ptr->r_idx];
+ if (!monster_is_valid(m_ptr))
+ continue;
+
+ POSITION y = m_ptr->fy;
+ POSITION x = m_ptr->fx;
+
+ if (distance(caster_ptr->y, caster_ptr->x, y, x) > range)
+ continue;
+
+ if (!(r_ptr->flags2 & RF2_EMPTY_MIND)) {
+ if (caster_ptr->monster_race_idx == m_ptr->r_idx) {
+ caster_ptr->window |= (PW_MONSTER);
+ }
+
+ repair_monsters = TRUE;
+ m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
+ update_monster(caster_ptr, i, FALSE);
+ flag = TRUE;
+ }
+ }
+
+ if (flag) {
+ msg_print(_("殺気を感じとった!", "You sense the presence of someone's mind!"));
+ }
+
+ return flag;
+}
+
+/*!
+ * @brief 該当シンボルのモンスターを感知する / Detect all (string) monsters on current panel
+ * @param caster_ptr プレーヤーへの参照ポインタ
+ * @param range 効果範囲
+ * @param Match 対応シンボルの混じったモンスター文字列(複数指定化)
+ * @return 効力があった場合TRUEを返す
+ */
+bool detect_monsters_string(player_type* caster_ptr, POSITION range, concptr Match)
+{
+ if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
+ range /= 3;
+
+ bool flag = FALSE;
+ for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++) {
+ monster_type* m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
+ monster_race* r_ptr = &r_info[m_ptr->r_idx];
+ if (!monster_is_valid(m_ptr))
+ continue;
+
+ POSITION y = m_ptr->fy;
+ POSITION x = m_ptr->fx;
+
+ if (distance(caster_ptr->y, caster_ptr->x, y, x) > range)
+ continue;
+
+ if (my_strchr(Match, r_ptr->d_char)) {
+ if (caster_ptr->monster_race_idx == m_ptr->r_idx) {
+ caster_ptr->window |= (PW_MONSTER);
+ }
+
+ repair_monsters = TRUE;
+ m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
+ update_monster(caster_ptr, i, FALSE);
+ flag = TRUE;
+ }
+ }
+
+ if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 3)
+ flag = FALSE;
+ if (flag) {
+ msg_print(_("モンスターの存在を感じとった!", "You sense the presence of monsters!"));
+ }
+
+ return flag;
+}
+
+/*!
+ * @brief flags3に対応するモンスターを感知する / A "generic" detect monsters routine, tagged to flags3
+ * @param caster_ptr プレーヤーへの参照ポインタ
+ * @param range 効果範囲
+ * @param match_flag 感知フラグ
+ * @return 効力があった場合TRUEを返す
+ */
+bool detect_monsters_xxx(player_type* caster_ptr, POSITION range, u32b match_flag)
+{
+ if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
+ range /= 3;
+
+ bool flag = FALSE;
+ for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++) {
+ monster_type* m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
+ monster_race* r_ptr = &r_info[m_ptr->r_idx];
+ if (!monster_is_valid(m_ptr))
+ continue;
+
+ POSITION y = m_ptr->fy;
+ POSITION x = m_ptr->fx;
+
+ if (distance(caster_ptr->y, caster_ptr->x, y, x) > range)
+ continue;
+
+ if (r_ptr->flags3 & (match_flag)) {
+ if (is_original_ap(m_ptr)) {
+ r_ptr->r_flags3 |= (match_flag);
+ if (caster_ptr->monster_race_idx == m_ptr->r_idx) {
+ caster_ptr->window |= (PW_MONSTER);
+ }
+ }
+
+ repair_monsters = TRUE;
+ m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
+ update_monster(caster_ptr, i, FALSE);
+ flag = TRUE;
+ }
+ }
+
+ concptr desc_monsters = _("変なモンスター", "weird monsters");
+ if (flag) {
+ switch (match_flag) {
+ case RF3_DEMON:
+ desc_monsters = _("デーモン", "demons");
+ break;
+ case RF3_UNDEAD:
+ desc_monsters = _("アンデッド", "the undead");
+ break;
+ }
+
+ msg_format(_("%sの存在を感じとった!", "You sense the presence of %s!"), desc_monsters);
+ msg_print(NULL);
+ }
+
+ return flag;
+}
+
+/*!
+ * @brief 全感知処理 / Detect everything
+ * @param caster_ptr プレーヤーへの参照ポインタ
+ * @param range 効果範囲
+ * @return 効力があった場合TRUEを返す
+ */
+bool detect_all(player_type* caster_ptr, POSITION range)
+{
+ bool detect = FALSE;
+ if (detect_traps(caster_ptr, range, TRUE))
+ detect = TRUE;
+ if (detect_doors(caster_ptr, range))
+ detect = TRUE;
+ if (detect_stairs(caster_ptr, range))
+ detect = TRUE;
+ if (detect_objects_gold(caster_ptr, range))
+ detect = TRUE;
+ if (detect_objects_normal(caster_ptr, range))
+ detect = TRUE;
+ if (detect_monsters_invis(caster_ptr, range))
+ detect = TRUE;
+ if (detect_monsters_normal(caster_ptr, range))
+ detect = TRUE;
+ return (detect);
+}
--- /dev/null
+#pragma once
+
+bool detect_traps(player_type* caster_ptr, POSITION range, bool known);
+bool detect_doors(player_type* caster_ptr, POSITION range);
+bool detect_stairs(player_type* caster_ptr, POSITION range);
+bool detect_treasure(player_type* caster_ptr, POSITION range);
+bool detect_objects_gold(player_type* caster_ptr, POSITION range);
+bool detect_objects_normal(player_type* caster_ptr, POSITION range);
+bool detect_objects_magic(player_type* caster_ptr, POSITION range);
+bool detect_monsters_normal(player_type* caster_ptr, POSITION range);
+bool detect_monsters_invis(player_type* caster_ptr, POSITION range);
+bool detect_monsters_evil(player_type* caster_ptr, POSITION range);
+bool detect_monsters_xxx(player_type* caster_ptr, POSITION range, u32b match_flag);
+bool detect_monsters_string(player_type* caster_ptr, POSITION range, concptr);
+bool detect_monsters_nonliving(player_type* caster_ptr, POSITION range);
+bool detect_monsters_mind(player_type* caster_ptr, POSITION range);
+bool detect_all(player_type* caster_ptr, POSITION range);
#include "cmd/cmd-dump.h"
#include "effect/effect-characteristics.h"
#include "grid/grid.h"
-#include "grid/trap.h"
-#include "monster/monsterrace-hook.h"
#include "melee.h"
#include "world/world.h"
#include "spell/spells2.h"
#include "object/object-kind.h"
#include "monster/monster-race.h"
#include "io/targeting.h"
-#include "realm/realm-song.h"
#include "locale/english.h"
#include "effect/spells-effect-util.h"
#include "spell/spells-type.h"
#include "spell/process-effect.h"
-#include "core/player-processor.h"
-
- /*!
- * @brief プレイヤー周辺の地形を感知する
- * @param caster_ptr プレーヤーへの参照ポインタ
- * @param range 効果範囲
- * @param flag 特定地形ID
- * @param known 地形から危険フラグを外すならTRUE
- * @return 効力があった場合TRUEを返す
- */
-static bool detect_feat_flag(player_type *caster_ptr, POSITION range, int flag, bool known)
-{
- if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range /= 3;
-
- grid_type *g_ptr;
- bool detect = FALSE;
- for (POSITION y = 1; y < caster_ptr->current_floor_ptr->height - 1; y++)
- {
- for (POSITION x = 1; x <= caster_ptr->current_floor_ptr->width - 1; x++)
- {
- int dist = distance(caster_ptr->y, caster_ptr->x, y, x);
- if (dist > range) continue;
- g_ptr = &caster_ptr->current_floor_ptr->grid_array[y][x];
- if (flag == FF_TRAP)
- {
- /* Mark as detected */
- if (dist <= range && known)
- {
- if (dist <= range - 1) g_ptr->info |= (CAVE_IN_DETECT);
-
- g_ptr->info &= ~(CAVE_UNSAFE);
-
- lite_spot(caster_ptr, y, x);
- }
- }
-
- if (cave_have_flag_grid(g_ptr, flag))
- {
- disclose_grid(caster_ptr, y, x);
- g_ptr->info |= (CAVE_MARK);
- lite_spot(caster_ptr, y, x);
- detect = TRUE;
- }
- }
- }
-
- return detect;
-}
-
-
-/*!
- * @brief プレイヤー周辺のトラップを感知する / Detect all traps on current panel
- * @param caster_ptr プレーヤーへの参照ポインタ
- * @param range 効果範囲
- * @param known 感知外範囲を超える警告フラグを立てる場合TRUEを返す
- * @return 効力があった場合TRUEを返す
- */
-bool detect_traps(player_type *caster_ptr, POSITION range, bool known)
-{
- bool detect = detect_feat_flag(caster_ptr, range, FF_TRAP, known);
-
- if (known) caster_ptr->dtrap = TRUE;
-
- if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 0) detect = FALSE;
- if (detect)
- {
- msg_print(_("トラップの存在を感じとった!", "You sense the presence of traps!"));
- }
-
- return detect;
-}
-
-
-/*!
- * @brief プレイヤー周辺のドアを感知する / Detect all doors on current panel
- * @param caster_ptr プレーヤーへの参照ポインタ
- * @param range 効果範囲
- * @return 効力があった場合TRUEを返す
- */
-bool detect_doors(player_type *caster_ptr, POSITION range)
-{
- bool detect = detect_feat_flag(caster_ptr, range, FF_DOOR, TRUE);
-
- if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 0) detect = FALSE;
- if (detect)
- {
- msg_print(_("ドアの存在を感じとった!", "You sense the presence of doors!"));
- }
-
- return detect;
-}
-
-
-/*!
- * @brief プレイヤー周辺の階段を感知する / Detect all stairs on current panel
- * @param caster_ptr プレーヤーへの参照ポインタ
- * @param range 効果範囲
- * @return 効力があった場合TRUEを返す
- */
-bool detect_stairs(player_type *caster_ptr, POSITION range)
-{
- bool detect = detect_feat_flag(caster_ptr, range, FF_STAIRS, TRUE);
-
- if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 0) detect = FALSE;
- if (detect)
- {
- msg_print(_("階段の存在を感じとった!", "You sense the presence of stairs!"));
- }
-
- return detect;
-}
-
-
-/*!
- * @brief プレイヤー周辺の地形財宝を感知する / Detect any treasure on the current panel
- * @param caster_ptr プレーヤーへの参照ポインタ
- * @param range 効果範囲
- * @return 効力があった場合TRUEを返す
- */
-bool detect_treasure(player_type *caster_ptr, POSITION range)
-{
- bool detect = detect_feat_flag(caster_ptr, range, FF_HAS_GOLD, TRUE);
-
- if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 6) detect = FALSE;
- if (detect)
- {
- msg_print(_("埋蔵された財宝の存在を感じとった!", "You sense the presence of buried treasure!"));
- }
-
- return detect;
-}
-
-
-/*!
- * @brief プレイヤー周辺のアイテム財宝を感知する / Detect all "gold" objects on the current panel
- * @param caster_ptr プレーヤーへの参照ポインタ
- * @param range 効果範囲
- * @return 効力があった場合TRUEを返す
- */
-bool detect_objects_gold(player_type *caster_ptr, POSITION range)
-{
- POSITION range2 = range;
- if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range2 /= 3;
-
- /* Scan objects */
- bool detect = FALSE;
- POSITION y, x;
- for (OBJECT_IDX i = 1; i < caster_ptr->current_floor_ptr->o_max; i++)
- {
- object_type *o_ptr = &caster_ptr->current_floor_ptr->o_list[i];
-
- if (!OBJECT_IS_VALID(o_ptr)) continue;
- if (OBJECT_IS_HELD_MONSTER(o_ptr)) continue;
-
- y = o_ptr->iy;
- x = o_ptr->ix;
- if (distance(caster_ptr->y, caster_ptr->x, y, x) > range2) continue;
-
- if (o_ptr->tval == TV_GOLD)
- {
- o_ptr->marked |= OM_FOUND;
- lite_spot(caster_ptr, y, x);
- detect = TRUE;
- }
- }
-
- if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 6) detect = FALSE;
- if (detect)
- {
- msg_print(_("財宝の存在を感じとった!", "You sense the presence of treasure!"));
- }
-
- if (detect_monsters_string(caster_ptr, range, "$"))
- {
- detect = TRUE;
- }
-
- return detect;
-}
-
-
-/*!
- * @brief 通常のアイテムオブジェクトを感知する / Detect all "normal" objects on the current panel
- * @param caster_ptr プレーヤーへの参照ポインタ
- * @param range 効果範囲
- * @return 効力があった場合TRUEを返す
- */
-bool detect_objects_normal(player_type *caster_ptr, POSITION range)
-{
- POSITION range2 = range;
- if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range2 /= 3;
-
- bool detect = FALSE;
- for (OBJECT_IDX i = 1; i < caster_ptr->current_floor_ptr->o_max; i++)
- {
- object_type *o_ptr = &caster_ptr->current_floor_ptr->o_list[i];
-
- if (!OBJECT_IS_VALID(o_ptr)) continue;
- if (OBJECT_IS_HELD_MONSTER(o_ptr)) continue;
-
- POSITION y = o_ptr->iy;
- POSITION x = o_ptr->ix;
-
- if (distance(caster_ptr->y, caster_ptr->x, y, x) > range2) continue;
-
- if (o_ptr->tval != TV_GOLD)
- {
- o_ptr->marked |= OM_FOUND;
- lite_spot(caster_ptr, y, x);
- detect = TRUE;
- }
- }
-
- if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 6) detect = FALSE;
- if (detect)
- {
- msg_print(_("アイテムの存在を感じとった!", "You sense the presence of objects!"));
- }
-
- if (detect_monsters_string(caster_ptr, range, "!=?|/`"))
- {
- detect = TRUE;
- }
-
- return detect;
-}
-
-
-/*!
- * @brief 魔法効果のあるのアイテムオブジェクトを感知する / Detect all "magic" objects on the current panel.
- * @param caster_ptr プレーヤーへの参照ポインタ
- * @param range 効果範囲
- * @return 効力があった場合TRUEを返す
- * @details
- * <pre>
- * This will light up all spaces with "magic" items, including artifacts,
- * ego-items, potions, scrolls, books, rods, wands, staffs, amulets, rings,
- * and "enchanted" items of the "good" variety.
- *
- * It can probably be argued that this function is now too powerful.
- * </pre>
- */
-bool detect_objects_magic(player_type *caster_ptr, POSITION range)
-{
- if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range /= 3;
-
- OBJECT_TYPE_VALUE tv;
- bool detect = FALSE;
- for (OBJECT_IDX i = 1; i < caster_ptr->current_floor_ptr->o_max; i++)
- {
- object_type *o_ptr = &caster_ptr->current_floor_ptr->o_list[i];
-
- if (!OBJECT_IS_VALID(o_ptr)) continue;
- if (OBJECT_IS_HELD_MONSTER(o_ptr)) continue;
-
- POSITION y = o_ptr->iy;
- POSITION x = o_ptr->ix;
-
- if (distance(caster_ptr->y, caster_ptr->x, y, x) > range) continue;
-
- tv = o_ptr->tval;
- if (object_is_artifact(o_ptr) ||
- object_is_ego(o_ptr) ||
- (tv == TV_WHISTLE) ||
- (tv == TV_AMULET) ||
- (tv == TV_RING) ||
- (tv == TV_STAFF) ||
- (tv == TV_WAND) ||
- (tv == TV_ROD) ||
- (tv == TV_SCROLL) ||
- (tv == TV_POTION) ||
- (tv == TV_LIFE_BOOK) ||
- (tv == TV_SORCERY_BOOK) ||
- (tv == TV_NATURE_BOOK) ||
- (tv == TV_CHAOS_BOOK) ||
- (tv == TV_DEATH_BOOK) ||
- (tv == TV_TRUMP_BOOK) ||
- (tv == TV_ARCANE_BOOK) ||
- (tv == TV_CRAFT_BOOK) ||
- (tv == TV_DAEMON_BOOK) ||
- (tv == TV_CRUSADE_BOOK) ||
- (tv == TV_MUSIC_BOOK) ||
- (tv == TV_HISSATSU_BOOK) ||
- (tv == TV_HEX_BOOK) ||
- ((o_ptr->to_a > 0) || (o_ptr->to_h + o_ptr->to_d > 0)))
- {
- o_ptr->marked |= OM_FOUND;
- lite_spot(caster_ptr, y, x);
- detect = TRUE;
- }
- }
-
- if (detect)
- {
- msg_print(_("魔法のアイテムの存在を感じとった!", "You sense the presence of magic objects!"));
- }
-
- return detect;
-}
-
-
-/*!
- * @brief 一般のモンスターを感知する / Detect all "normal" monsters on the current panel
- * @param caster_ptr プレーヤーへの参照ポインタ
- * @param range 効果範囲
- * @return 効力があった場合TRUEを返す
- */
-bool detect_monsters_normal(player_type *caster_ptr, POSITION range)
-{
- if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range /= 3;
-
- bool flag = FALSE;
- for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++)
- {
- monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
- if (!monster_is_valid(m_ptr)) continue;
-
- POSITION y = m_ptr->fy;
- POSITION x = m_ptr->fx;
- if (distance(caster_ptr->y, caster_ptr->x, y, x) > range) continue;
-
- if (!(r_ptr->flags2 & RF2_INVISIBLE) || caster_ptr->see_inv)
- {
- repair_monsters = TRUE;
- m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
- update_monster(caster_ptr, i, FALSE);
- flag = TRUE;
- }
- }
-
- if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 3) flag = FALSE;
- if (flag)
- {
- msg_print(_("モンスターの存在を感じとった!", "You sense the presence of monsters!"));
- }
-
- return flag;
-}
-
-
-/*!
- * @brief 不可視のモンスターを感知する / Detect all "invisible" monsters around the player
- * @param caster_ptr プレーヤーへの参照ポインタ
- * @param range 効果範囲
- * @return 効力があった場合TRUEを返す
- */
-bool detect_monsters_invis(player_type *caster_ptr, POSITION range)
-{
- if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range /= 3;
-
- bool flag = FALSE;
- for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++)
- {
- monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
-
- if (!monster_is_valid(m_ptr)) continue;
-
- POSITION y = m_ptr->fy;
- POSITION x = m_ptr->fx;
-
- if (distance(caster_ptr->y, caster_ptr->x, y, x) > range) continue;
-
- if (r_ptr->flags2 & RF2_INVISIBLE)
- {
- if (caster_ptr->monster_race_idx == m_ptr->r_idx)
- {
- caster_ptr->window |= (PW_MONSTER);
- }
-
- repair_monsters = TRUE;
- m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
- update_monster(caster_ptr, i, FALSE);
- flag = TRUE;
- }
- }
-
- if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 3) flag = FALSE;
- if (flag)
- {
- msg_print(_("透明な生物の存在を感じとった!", "You sense the presence of invisible creatures!"));
- }
-
- return flag;
-}
-
-
-/*!
- * @brief 邪悪なモンスターを感知する / Detect all "evil" monsters on current panel
- * @param caster_ptr プレーヤーへの参照ポインタ
- * @param range 効果範囲
- * @return 効力があった場合TRUEを返す
- */
-bool detect_monsters_evil(player_type *caster_ptr, POSITION range)
-{
- if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range /= 3;
-
- bool flag = FALSE;
- for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++)
- {
- monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
- if (!monster_is_valid(m_ptr)) continue;
-
- POSITION y = m_ptr->fy;
- POSITION x = m_ptr->fx;
-
- if (distance(caster_ptr->y, caster_ptr->x, y, x) > range) continue;
-
- if (r_ptr->flags3 & RF3_EVIL)
- {
- if (is_original_ap(m_ptr))
- {
- r_ptr->r_flags3 |= (RF3_EVIL);
- if (caster_ptr->monster_race_idx == m_ptr->r_idx)
- {
- caster_ptr->window |= (PW_MONSTER);
- }
- }
-
- repair_monsters = TRUE;
- m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
- update_monster(caster_ptr, i, FALSE);
- flag = TRUE;
- }
- }
-
- if (flag)
- {
- msg_print(_("邪悪なる生物の存在を感じとった!", "You sense the presence of evil creatures!"));
- }
-
- return flag;
-}
-
-
-/*!
- * @brief 無生命のモンスターを感知する(アンデッド、悪魔系を含む) / Detect all "nonliving", "undead" or "demonic" monsters on current panel
- * @param caster_ptr プレーヤーへの参照ポインタ
- * @param range 効果範囲
- * @return 効力があった場合TRUEを返す
- */
-bool detect_monsters_nonliving(player_type *caster_ptr, POSITION range)
-{
- if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range /= 3;
-
- bool flag = FALSE;
- for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++)
- {
- monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
- if (!monster_is_valid(m_ptr)) continue;
-
- POSITION y = m_ptr->fy;
- POSITION x = m_ptr->fx;
- if (distance(caster_ptr->y, caster_ptr->x, y, x) > range) continue;
-
- if (!monster_living(m_ptr->r_idx))
- {
- if (caster_ptr->monster_race_idx == m_ptr->r_idx)
- {
- caster_ptr->window |= (PW_MONSTER);
- }
-
- repair_monsters = TRUE;
- m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
- update_monster(caster_ptr, i, FALSE);
- flag = TRUE;
- }
- }
-
- if (flag)
- {
- msg_print(_("自然でないモンスターの存在を感じた!", "You sense the presence of unnatural beings!"));
- }
-
- return flag;
-}
-
-
-/*!
- * @brief 精神のあるモンスターを感知する / Detect all monsters it has mind on current panel
- * @param caster_ptr プレーヤーへの参照ポインタ
- * @param range 効果範囲
- * @return 効力があった場合TRUEを返す
- */
-bool detect_monsters_mind(player_type *caster_ptr, POSITION range)
-{
- if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range /= 3;
-
- bool flag = FALSE;
- for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++)
- {
- monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
- if (!monster_is_valid(m_ptr)) continue;
-
- POSITION y = m_ptr->fy;
- POSITION x = m_ptr->fx;
-
- if (distance(caster_ptr->y, caster_ptr->x, y, x) > range) continue;
-
- if (!(r_ptr->flags2 & RF2_EMPTY_MIND))
- {
- if (caster_ptr->monster_race_idx == m_ptr->r_idx)
- {
- caster_ptr->window |= (PW_MONSTER);
- }
-
- repair_monsters = TRUE;
- m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
- update_monster(caster_ptr, i, FALSE);
- flag = TRUE;
- }
- }
-
- if (flag)
- {
- msg_print(_("殺気を感じとった!", "You sense the presence of someone's mind!"));
- }
-
- return flag;
-}
-
-
-/*!
- * @brief 該当シンボルのモンスターを感知する / Detect all (string) monsters on current panel
- * @param caster_ptr プレーヤーへの参照ポインタ
- * @param range 効果範囲
- * @param Match 対応シンボルの混じったモンスター文字列(複数指定化)
- * @return 効力があった場合TRUEを返す
- */
-bool detect_monsters_string(player_type *caster_ptr, POSITION range, concptr Match)
-{
- if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range /= 3;
-
- bool flag = FALSE;
- for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++)
- {
- monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
- if (!monster_is_valid(m_ptr)) continue;
-
- POSITION y = m_ptr->fy;
- POSITION x = m_ptr->fx;
-
- if (distance(caster_ptr->y, caster_ptr->x, y, x) > range) continue;
-
- if (my_strchr(Match, r_ptr->d_char))
- {
- if (caster_ptr->monster_race_idx == m_ptr->r_idx)
- {
- caster_ptr->window |= (PW_MONSTER);
- }
-
- repair_monsters = TRUE;
- m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
- update_monster(caster_ptr, i, FALSE);
- flag = TRUE;
- }
- }
-
- if (music_singing(caster_ptr, MUSIC_DETECT) && SINGING_COUNT(caster_ptr) > 3) flag = FALSE;
- if (flag)
- {
- msg_print(_("モンスターの存在を感じとった!", "You sense the presence of monsters!"));
- }
-
- return flag;
-}
-
-
-/*!
- * @brief flags3に対応するモンスターを感知する / A "generic" detect monsters routine, tagged to flags3
- * @param caster_ptr プレーヤーへの参照ポインタ
- * @param range 効果範囲
- * @param match_flag 感知フラグ
- * @return 効力があった場合TRUEを返す
- */
-bool detect_monsters_xxx(player_type *caster_ptr, POSITION range, u32b match_flag)
-{
- if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range /= 3;
-
- bool flag = FALSE;
- for (MONSTER_IDX i = 1; i < caster_ptr->current_floor_ptr->m_max; i++)
- {
- monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[i];
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
- if (!monster_is_valid(m_ptr)) continue;
-
- POSITION y = m_ptr->fy;
- POSITION x = m_ptr->fx;
-
- if (distance(caster_ptr->y, caster_ptr->x, y, x) > range) continue;
-
- if (r_ptr->flags3 & (match_flag))
- {
- if (is_original_ap(m_ptr))
- {
- r_ptr->r_flags3 |= (match_flag);
- if (caster_ptr->monster_race_idx == m_ptr->r_idx)
- {
- caster_ptr->window |= (PW_MONSTER);
- }
- }
-
- repair_monsters = TRUE;
- m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
- update_monster(caster_ptr, i, FALSE);
- flag = TRUE;
- }
- }
-
- concptr desc_monsters = _("変なモンスター", "weird monsters");
- if (flag)
- {
- switch (match_flag)
- {
- case RF3_DEMON:
- desc_monsters = _("デーモン", "demons");
- break;
- case RF3_UNDEAD:
- desc_monsters = _("アンデッド", "the undead");
- break;
- }
-
- msg_format(_("%sの存在を感じとった!", "You sense the presence of %s!"), desc_monsters);
- msg_print(NULL);
- }
-
- return flag;
-}
-
-
-/*!
- * @brief 全感知処理 / Detect everything
- * @param caster_ptr プレーヤーへの参照ポインタ
- * @param range 効果範囲
- * @return 効力があった場合TRUEを返す
- */
-bool detect_all(player_type *caster_ptr, POSITION range)
-{
- bool detect = FALSE;
- if (detect_traps(caster_ptr, range, TRUE)) detect = TRUE;
- if (detect_doors(caster_ptr, range)) detect = TRUE;
- if (detect_stairs(caster_ptr, range)) detect = TRUE;
- if (detect_objects_gold(caster_ptr, range)) detect = TRUE;
- if (detect_objects_normal(caster_ptr, range)) detect = TRUE;
- if (detect_monsters_invis(caster_ptr, range)) detect = TRUE;
- if (detect_monsters_normal(caster_ptr, range)) detect = TRUE;
- return (detect);
-}
-
/*!
* @brief 視界内モンスターに魔法効果を与える / Apply a "project()" directly to all viewable monsters
#pragma once
-bool detect_traps(player_type* caster_ptr, POSITION range, bool known);
-bool detect_doors(player_type* caster_ptr, POSITION range);
-bool detect_stairs(player_type* caster_ptr, POSITION range);
-bool detect_treasure(player_type* caster_ptr, POSITION range);
-bool detect_objects_gold(player_type* caster_ptr, POSITION range);
-bool detect_objects_normal(player_type* caster_ptr, POSITION range);
-bool detect_objects_magic(player_type* caster_ptr, POSITION range);
-bool detect_monsters_normal(player_type* caster_ptr, POSITION range);
-bool detect_monsters_invis(player_type* caster_ptr, POSITION range);
-bool detect_monsters_evil(player_type* caster_ptr, POSITION range);
-bool detect_monsters_xxx(player_type* caster_ptr, POSITION range, u32b match_flag);
-bool detect_monsters_string(player_type* caster_ptr, POSITION range, concptr);
-bool detect_monsters_nonliving(player_type* caster_ptr, POSITION range);
-bool detect_monsters_mind(player_type* caster_ptr, POSITION range);
-bool detect_all(player_type* caster_ptr, POSITION range);
bool wall_stone(player_type* caster_ptr);
bool speed_monsters(player_type* caster_ptr);
bool slow_monsters(player_type* caster_ptr, int power);
#include "world/world.h"
#include "spell/spells2.h"
#include "spell/spells3.h"
+#include "spell/spells-detection.h"
#define NUM_O_SET 8
#define NUM_O_BIT 32