From f1eb467e0ebdb0a4113c760170440f182f65c7eb Mon Sep 17 00:00:00 2001 From: Hourier Date: Sat, 16 May 2020 14:07:10 +0900 Subject: [PATCH] [Refactor] #40414 Separated spells-detection.c/h from spells2.c/h --- Hengband/Hengband/Hengband.vcxproj | 2 + Hengband/Hengband/Hengband.vcxproj.filters | 6 + src/Makefile.am | 1 + src/cmd/cmd-activate.c | 1 + src/cmd/cmd-quaff.c | 2 +- src/cmd/cmd-read.c | 1 + src/cmd/cmd-usestaff.c | 2 +- src/cmd/cmd-zaprod.c | 1 + src/mind/mind.c | 1 + src/mind/racial.c | 1 + src/mutation/mutation.c | 1 + src/realm/realm-arcane.c | 1 + src/realm/realm-crusade.c | 1 + src/realm/realm-daemon.c | 1 + src/realm/realm-death.c | 1 + src/realm/realm-hissatsu.c | 1 + src/realm/realm-life.c | 1 + src/realm/realm-nature.c | 1 + src/realm/realm-song.c | 1 + src/realm/realm-sorcery.c | 1 + src/realm/realm-trump.c | 1 + src/spell/spells-detection.c | 631 +++++++++++++++++++++++++++ src/spell/spells-detection.h | 17 + src/spell/spells2.c | 656 ----------------------------- src/spell/spells2.h | 15 - src/wizard/wizard-special-process.c | 1 + 26 files changed, 676 insertions(+), 673 deletions(-) create mode 100644 src/spell/spells-detection.c create mode 100644 src/spell/spells-detection.h diff --git a/Hengband/Hengband/Hengband.vcxproj b/Hengband/Hengband/Hengband.vcxproj index ad77d1a27..9938ec147 100644 --- a/Hengband/Hengband/Hengband.vcxproj +++ b/Hengband/Hengband/Hengband.vcxproj @@ -264,6 +264,7 @@ + @@ -397,6 +398,7 @@ + diff --git a/Hengband/Hengband/Hengband.vcxproj.filters b/Hengband/Hengband/Hengband.vcxproj.filters index 29515d23e..6e9e22ff5 100644 --- a/Hengband/Hengband/Hengband.vcxproj.filters +++ b/Hengband/Hengband/Hengband.vcxproj.filters @@ -839,6 +839,9 @@ core + + spell + @@ -1723,6 +1726,9 @@ core + + spell + diff --git a/src/Makefile.am b/src/Makefile.am index 884614acb..10f7b78dd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -245,6 +245,7 @@ hengband_SOURCES = \ 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 \ \ diff --git a/src/cmd/cmd-activate.c b/src/cmd/cmd-activate.c index ce492f826..fbfab7207 100644 --- a/src/cmd/cmd-activate.c +++ b/src/cmd/cmd-activate.c @@ -36,6 +36,7 @@ #include "effect/effect-characteristics.h" #include "spell/spells2.h" #include "spell/spells3.h" +#include "spell/spells-detection.h" /*! * @brief 装備耐性に準じたブレス効果の選択テーブル / diff --git a/src/cmd/cmd-quaff.c b/src/cmd/cmd-quaff.c index 5cd92403c..e782df9eb 100644 --- a/src/cmd/cmd-quaff.c +++ b/src/cmd/cmd-quaff.c @@ -15,7 +15,6 @@ #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" @@ -31,6 +30,7 @@ #include "object/object-kind.h" #include "view/display-main-window.h" #include "player/player-class.h" +#include "spell/spells-detection.h" /*! * @brief 薬を飲むコマンドのサブルーチン / diff --git a/src/cmd/cmd-read.c b/src/cmd/cmd-read.c index e8a75b68a..110c150fa 100644 --- a/src/cmd/cmd-read.c +++ b/src/cmd/cmd-read.c @@ -36,6 +36,7 @@ #include "spell/spells-type.h" #include "spell/spells2.h" #include "spell/spells3.h" +#include "spell/spells-detection.h" /*! * @brief 巻物を読むコマンドのサブルーチン diff --git a/src/cmd/cmd-usestaff.c b/src/cmd/cmd-usestaff.c index b8a8719cf..18dcfb062 100644 --- a/src/cmd/cmd-usestaff.c +++ b/src/cmd/cmd-usestaff.c @@ -18,7 +18,7 @@ #include "floor/floor.h" #include "object/object-kind.h" #include "view/display-main-window.h" - +#include "spell/spells-detection.h" /*! * @brief 杖の効果を発動する diff --git a/src/cmd/cmd-zaprod.c b/src/cmd/cmd-zaprod.c index 4be5699a8..5b290aa38 100644 --- a/src/cmd/cmd-zaprod.c +++ b/src/cmd/cmd-zaprod.c @@ -18,6 +18,7 @@ #include "view/display-main-window.h" #include "spell/spells2.h" #include "spell/spells3.h" +#include "spell/spells-detection.h" /*! * @brief ロッドの効果を発動する diff --git a/src/mind/mind.c b/src/mind/mind.c index 67368f1e3..7888ea466 100644 --- a/src/mind/mind.c +++ b/src/mind/mind.c @@ -45,6 +45,7 @@ #include "spell/process-effect.h" #include "spell/spells2.h" #include "spell/spells3.h" +#include "spell/spells-detection.h" /*! 特殊技能の一覧テーブル */ mind_power const mind_powers[5] = diff --git a/src/mind/racial.c b/src/mind/racial.c index 9b012f0d6..0e2095148 100644 --- a/src/mind/racial.c +++ b/src/mind/racial.c @@ -40,6 +40,7 @@ #include "spell/spells-type.h" #include "spell/spells2.h" #include "spell/spells3.h" +#include "spell/spells-detection.h" /*! * @brief 修行僧の構え設定処理 diff --git a/src/mutation/mutation.c b/src/mutation/mutation.c index 6363e65e7..e0b347394 100644 --- a/src/mutation/mutation.c +++ b/src/mutation/mutation.c @@ -40,6 +40,7 @@ #include "spell/spells-type.h" #include "spell/spells2.h" #include "spell/spells3.h" +#include "spell/spells-detection.h" /*! * @brief プレイヤーに突然変異を与える diff --git a/src/realm/realm-arcane.c b/src/realm/realm-arcane.c index 8ed9d1f9f..cfeae1b88 100644 --- a/src/realm/realm-arcane.c +++ b/src/realm/realm-arcane.c @@ -16,6 +16,7 @@ #include "io/targeting.h" #include "realm/realm-arcane.h" #include "spell/spells-type.h" +#include "spell/spells-detection.h" /*! * @brief 秘術領域魔法の各処理を行う diff --git a/src/realm/realm-crusade.c b/src/realm/realm-crusade.c index 80be39d12..8158e17c5 100644 --- a/src/realm/realm-crusade.c +++ b/src/realm/realm-crusade.c @@ -17,6 +17,7 @@ #include "spell/process-effect.h" #include "spell/spells2.h" #include "spell/spells3.h" +#include "spell/spells-detection.h" /*! * @brief 破邪領域魔法の各処理を行う diff --git a/src/realm/realm-daemon.c b/src/realm/realm-daemon.c index 6f4d29188..8c0149c14 100644 --- a/src/realm/realm-daemon.c +++ b/src/realm/realm-daemon.c @@ -15,6 +15,7 @@ #include "io/targeting.h" #include "realm/realm-daemon.h" #include "spell/spells2.h" +#include "spell/spells-detection.h" /*! * @brief 悪魔領域魔法の各処理を行う diff --git a/src/realm/realm-death.c b/src/realm/realm-death.c index b39c8ba78..8480ca966 100644 --- a/src/realm/realm-death.c +++ b/src/realm/realm-death.c @@ -17,6 +17,7 @@ #include "effect/effect-characteristics.h" #include "spell/spells2.h" #include "spell/spells3.h" +#include "spell/spells-detection.h" /*! * @brief 暗黒領域魔法の各処理を行う diff --git a/src/realm/realm-hissatsu.c b/src/realm/realm-hissatsu.c index 6dba94d73..c3dc135a3 100644 --- a/src/realm/realm-hissatsu.c +++ b/src/realm/realm-hissatsu.c @@ -27,6 +27,7 @@ #include "spell/process-effect.h" #include "spell/spells2.h" #include "spell/spells3.h" +#include "spell/spells-detection.h" /*! * @brief 剣術の各処理を行う diff --git a/src/realm/realm-life.c b/src/realm/realm-life.c index 8d84362cd..60b3204f7 100644 --- a/src/realm/realm-life.c +++ b/src/realm/realm-life.c @@ -10,6 +10,7 @@ #include "io/targeting.h" #include "realm/realm-life.h" #include "spell/spells-type.h" +#include "spell/spells-detection.h" /*! * @brief 生命領域魔法の各処理を行う diff --git a/src/realm/realm-nature.c b/src/realm/realm-nature.c index 8131fdcd5..efc0788ab 100644 --- a/src/realm/realm-nature.c +++ b/src/realm/realm-nature.c @@ -19,6 +19,7 @@ #include "effect/effect-characteristics.h" #include "spell/spells2.h" #include "spell/spells3.h" +#include "spell/spells-detection.h" /*! * @brief 自然領域魔法の各処理を行う diff --git a/src/realm/realm-song.c b/src/realm/realm-song.c index 28178bbe1..612690720 100644 --- a/src/realm/realm-song.c +++ b/src/realm/realm-song.c @@ -14,6 +14,7 @@ #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 diff --git a/src/realm/realm-sorcery.c b/src/realm/realm-sorcery.c index 306cfcb4a..7067ea585 100644 --- a/src/realm/realm-sorcery.c +++ b/src/realm/realm-sorcery.c @@ -13,6 +13,7 @@ #include "realm/realm-sorcery.h" #include "spell/spells2.h" #include "spell/spells3.h" +#include "spell/spells-detection.h" /*! * @brief 仙術領域魔法の各処理を行う diff --git a/src/realm/realm-trump.c b/src/realm/realm-trump.c index 9e56d4ba6..93a13b443 100644 --- a/src/realm/realm-trump.c +++ b/src/realm/realm-trump.c @@ -14,6 +14,7 @@ #include "spell/spells-type.h" #include "spell/spells2.h" #include "spell/spells3.h" +#include "spell/spells-detection.h" /*! * @brief トランプ領域魔法の各処理を行う diff --git a/src/spell/spells-detection.c b/src/spell/spells-detection.c new file mode 100644 index 000000000..74cf35ad1 --- /dev/null +++ b/src/spell/spells-detection.c @@ -0,0 +1,631 @@ +#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 + *
+ * 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.
+ * 
+ */ +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); +} diff --git a/src/spell/spells-detection.h b/src/spell/spells-detection.h new file mode 100644 index 000000000..ae467bd3c --- /dev/null +++ b/src/spell/spells-detection.h @@ -0,0 +1,17 @@ +#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); diff --git a/src/spell/spells2.c b/src/spell/spells2.c index e35e1c591..fd6cfec46 100644 --- a/src/spell/spells2.c +++ b/src/spell/spells2.c @@ -25,8 +25,6 @@ #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" @@ -59,664 +57,10 @@ #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 - *
- * 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.
- * 
- */ -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 diff --git a/src/spell/spells2.h b/src/spell/spells2.h index 80db45502..bcbc3e7b4 100644 --- a/src/spell/spells2.h +++ b/src/spell/spells2.h @@ -1,20 +1,5 @@ #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); diff --git a/src/wizard/wizard-special-process.c b/src/wizard/wizard-special-process.c index f7c62215c..b1972b99b 100644 --- a/src/wizard/wizard-special-process.c +++ b/src/wizard/wizard-special-process.c @@ -60,6 +60,7 @@ #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 -- 2.11.0