OSDN Git Service

[Refactor] summon_specificで使用するグローバル変数の除去
authorHabu <habu1010+github@gmail.com>
Sun, 10 Mar 2024 04:59:06 +0000 (13:59 +0900)
committerHabu <habu1010+github@gmail.com>
Mon, 1 Apr 2024 12:09:46 +0000 (21:09 +0900)
summon_specific()で使用する以下のグローバル変数を除去し、引数で渡すように変更する。
- summon_specific_who
- summon_specific_type
- summon_unique_okay

src/monster-floor/monster-generator.cpp
src/monster-floor/monster-generator.h
src/monster-floor/monster-summon.cpp
src/monster-floor/monster-summon.h
src/monster-floor/one-monster-placer.cpp
src/monster-floor/one-monster-placer.h
src/monster/monster-list.cpp
src/monster/monster-list.h
src/monster/monster-util.h
src/mspell/summon-checker.cpp
src/mspell/summon-checker.h

index 4280562..7844f17 100644 (file)
@@ -170,9 +170,10 @@ bool multiply_monster(PlayerType *player_ptr, MONSTER_IDX m_idx, bool clone, BIT
  * @param x 中心生成位置x座標
  * @param r_idx 生成モンスター種族
  * @param mode 生成オプション
+ * @param summoner_m_idx モンスターの召喚による場合、召喚主のモンスターID
  * @return 成功したらtrue
  */
-static bool place_monster_group(PlayerType *player_ptr, MONSTER_IDX src_idx, POSITION y, POSITION x, MonsterRaceId r_idx, BIT_FLAGS mode)
+static bool place_monster_group(PlayerType *player_ptr, MONSTER_IDX src_idx, POSITION y, POSITION x, MonsterRaceId r_idx, BIT_FLAGS mode, std::optional<MONSTER_IDX> summoner_m_idx)
 {
     auto *r_ptr = &monraces_info[r_idx];
     auto total = randint1(10);
@@ -218,7 +219,7 @@ static bool place_monster_group(PlayerType *player_ptr, MONSTER_IDX src_idx, POS
                 continue;
             }
 
-            if (place_monster_one(player_ptr, src_idx, my, mx, r_idx, mode)) {
+            if (place_monster_one(player_ptr, src_idx, my, mx, r_idx, mode, summoner_m_idx)) {
                 hack_y[hack_n] = my;
                 hack_x[hack_n] = mx;
                 hack_n++;
@@ -285,10 +286,11 @@ static bool place_monster_can_escort(PlayerType *player_ptr, MonsterRaceId r_idx
  * @param x 生成地点x座標
  * @param r_idx 生成するモンスターの種族ID
  * @param mode 生成オプション
+ * @param summoner_m_idx モンスターの召喚による場合、召喚主のモンスターID
  * @return 生成に成功したらtrue
  * @details 護衛も一緒に生成する
  */
-bool place_specific_monster(PlayerType *player_ptr, MONSTER_IDX src_idx, POSITION y, POSITION x, MonsterRaceId r_idx, BIT_FLAGS mode)
+bool place_specific_monster(PlayerType *player_ptr, MONSTER_IDX src_idx, POSITION y, POSITION x, MonsterRaceId r_idx, BIT_FLAGS mode, std::optional<MONSTER_IDX> summoner_m_idx)
 {
     auto *r_ptr = &monraces_info[r_idx];
 
@@ -296,7 +298,7 @@ bool place_specific_monster(PlayerType *player_ptr, MONSTER_IDX src_idx, POSITIO
         mode |= PM_KAGE;
     }
 
-    if (!place_monster_one(player_ptr, src_idx, y, x, r_idx, mode)) {
+    if (!place_monster_one(player_ptr, src_idx, y, x, r_idx, mode, summoner_m_idx)) {
         return false;
     }
     if (!(mode & PM_ALLOW_GROUP)) {
@@ -317,7 +319,7 @@ bool place_specific_monster(PlayerType *player_ptr, MONSTER_IDX src_idx, POSITIO
             const POSITION scatter_max = 40;
             for (d = scatter_min; d <= scatter_max; d++) {
                 scatter(player_ptr, &ny, &nx, y, x, d, PROJECT_NONE);
-                if (place_monster_one(player_ptr, place_monster_m_idx, ny, nx, reinforce_r_idx, mode)) {
+                if (place_monster_one(player_ptr, place_monster_m_idx, ny, nx, reinforce_r_idx, mode, summoner_m_idx)) {
                     break;
                 }
             }
@@ -328,7 +330,7 @@ bool place_specific_monster(PlayerType *player_ptr, MONSTER_IDX src_idx, POSITIO
     }
 
     if (r_ptr->misc_flags.has(MonsterMiscType::HAS_FRIENDS)) {
-        (void)place_monster_group(player_ptr, src_idx, y, x, r_idx, mode);
+        (void)place_monster_group(player_ptr, src_idx, y, x, r_idx, mode, summoner_m_idx);
     }
 
     if (r_ptr->misc_flags.has_not(MonsterMiscType::ESCORT)) {
@@ -350,9 +352,9 @@ bool place_specific_monster(PlayerType *player_ptr, MONSTER_IDX src_idx, POSITIO
             break;
         }
 
-        (void)place_monster_one(player_ptr, place_monster_m_idx, ny, nx, z, mode);
+        (void)place_monster_one(player_ptr, place_monster_m_idx, ny, nx, z, mode, summoner_m_idx);
         if (monraces_info[z].misc_flags.has(MonsterMiscType::HAS_FRIENDS) || r_ptr->misc_flags.has(MonsterMiscType::MORE_ESCORT)) {
-            (void)place_monster_group(player_ptr, place_monster_m_idx, ny, nx, z, mode);
+            (void)place_monster_group(player_ptr, place_monster_m_idx, ny, nx, z, mode, summoner_m_idx);
         }
     }
 
index 240adce..d5d751f 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "system/angband.h"
+#include <optional>
 
 enum summon_type : int;
 enum class MonsterRaceId : int16_t;
@@ -9,7 +10,7 @@ typedef bool (*summon_specific_pf)(PlayerType *, MONSTER_IDX, POSITION, POSITION
 
 bool mon_scatter(PlayerType *player_ptr, MonsterRaceId r_idx, POSITION *yp, POSITION *xp, POSITION y, POSITION x, POSITION max_dist);
 bool multiply_monster(PlayerType *player_ptr, MONSTER_IDX m_idx, bool clone, BIT_FLAGS mode);
-bool place_specific_monster(PlayerType *player_ptr, MONSTER_IDX src_idx, POSITION y, POSITION x, MonsterRaceId r_idx, BIT_FLAGS mode);
+bool place_specific_monster(PlayerType *player_ptr, MONSTER_IDX src_idx, POSITION y, POSITION x, MonsterRaceId r_idx, BIT_FLAGS mode, std::optional<MONSTER_IDX> summoner_m_idx = std::nullopt);
 bool place_random_monster(PlayerType *player_ptr, POSITION y, POSITION x, BIT_FLAGS mode);
 bool alloc_horde(PlayerType *player_ptr, POSITION y, POSITION x, summon_specific_pf summon_specific);
 bool alloc_guardian(PlayerType *player_ptr, bool def_val);
index c33bd1c..70237b4 100644 (file)
 #include "system/player-type-definition.h"
 
 /*!
- * @var summon_specific_who
- * @brief 召喚を行ったプレイヤーあるいはモンスターのIDを示すグローバル変数 / Hack -- the index of the summoning monster
- * @todo summon_specific_who グローバル変数の除去と関数引数への代替を行う
- */
-int summon_specific_who = -1;
-
-/*!
- * @var summon_unique_okay
- * @brief 召喚対象にユニークを含めるかを示すグローバル変数 / summoning unique enable
- * @todo summon_unique_okay グローバル変数の除去と関数引数への代替を行う
- */
-bool summon_unique_okay = false;
-
-/*!
  * @brief モンスターが召喚の基本条件に合っているかをチェックする / Hack -- help decide if a monster race is "okay" to summon
  * @param r_idx チェックするモンスター種族ID
+ * @param summon_who 召喚主のモンスター情報ID
+ * @param type 召喚種別
+ * @param is_unique_allowed ユニークモンスターを召喚対象に含めるかどうか
  * @return 召喚対象にできるならばTRUE
  */
-static bool summon_specific_okay(PlayerType *player_ptr, MonsterRaceId r_idx)
+static bool summon_specific_okay(PlayerType *player_ptr, MonsterRaceId r_idx, MONSTER_IDX summon_who, summon_type type, bool is_unique_allowed)
 {
     auto *r_ptr = &monraces_info[r_idx];
     if (!mon_hook_dungeon(player_ptr, r_idx)) {
@@ -47,27 +36,27 @@ static bool summon_specific_okay(PlayerType *player_ptr, MonsterRaceId r_idx)
     }
 
     auto &floor = *player_ptr->current_floor_ptr;
-    if (summon_specific_who > 0) {
-        auto *m_ptr = &floor.m_list[summon_specific_who];
+    if (summon_who > 0) {
+        auto *m_ptr = &floor.m_list[summon_who];
         if (monster_has_hostile_align(player_ptr, m_ptr, 0, 0, r_ptr)) {
             return false;
         }
-    } else if (summon_specific_who < 0) {
+    } else if (summon_who < 0) {
         if (monster_has_hostile_align(player_ptr, nullptr, 10, -10, r_ptr) && !one_in_(std::abs(player_ptr->alignment) / 2 + 1)) {
             return false;
         }
     }
 
-    if (!summon_unique_okay && (r_ptr->kind_flags.has(MonsterKindType::UNIQUE) || (r_ptr->population_flags.has(MonsterPopulationType::NAZGUL)))) {
+    if (!is_unique_allowed && (r_ptr->kind_flags.has(MonsterKindType::UNIQUE) || (r_ptr->population_flags.has(MonsterPopulationType::NAZGUL)))) {
         return false;
     }
 
-    if (!summon_specific_type) {
+    if (type == SUMMON_NONE) {
         return true;
     }
 
     const auto is_like_unique = r_ptr->kind_flags.has(MonsterKindType::UNIQUE) || (r_ptr->population_flags.has(MonsterPopulationType::NAZGUL));
-    if ((summon_specific_who < 0) && is_like_unique && monster_has_hostile_align(player_ptr, nullptr, 10, -10, r_ptr)) {
+    if ((summon_who < 0) && is_like_unique && monster_has_hostile_align(player_ptr, nullptr, 10, -10, r_ptr)) {
         return false;
     }
 
@@ -75,11 +64,11 @@ static bool summon_specific_okay(PlayerType *player_ptr, MonsterRaceId r_idx)
         return true;
     }
 
-    if (summon_specific_who > 0) {
-        auto *m_ptr = &floor.m_list[summon_specific_who];
-        return check_summon_specific(player_ptr, m_ptr->r_idx, r_idx);
+    if (summon_who > 0) {
+        auto *m_ptr = &floor.m_list[summon_who];
+        return check_summon_specific(player_ptr, m_ptr->r_idx, r_idx, type);
     } else {
-        return check_summon_specific(player_ptr, MonsterRaceId::PLAYER, r_idx);
+        return check_summon_specific(player_ptr, MonsterRaceId::PLAYER, r_idx, type);
     }
 }
 
@@ -137,15 +126,14 @@ bool summon_specific(PlayerType *player_ptr, MONSTER_IDX src_idx, POSITION y1, P
         return false;
     }
 
-    summon_specific_who = src_idx;
-    summon_specific_type = type;
-    summon_unique_okay = (mode & PM_ALLOW_UNIQUE) != 0;
-    get_mon_num_prep(player_ptr, summon_specific_okay, get_monster_hook2(player_ptr, y, x));
+    auto summon_specific_hook = [src_idx, type, is_unique_allowed = (mode & PM_ALLOW_UNIQUE) != 0](PlayerType *player_ptr, MonsterRaceId r_idx) {
+        return summon_specific_okay(player_ptr, r_idx, src_idx, type, is_unique_allowed);
+    };
+    get_mon_num_prep(player_ptr, std::move(summon_specific_hook), get_monster_hook2(player_ptr, y, x));
 
     DEPTH dlev = get_dungeon_or_wilderness_level(player_ptr);
     MonsterRaceId r_idx = get_mon_num(player_ptr, 0, (dlev + lev) / 2 + 5, mode);
     if (!MonsterRace(r_idx).is_valid()) {
-        summon_specific_type = SUMMON_NONE;
         return false;
     }
 
@@ -153,13 +141,11 @@ bool summon_specific(PlayerType *player_ptr, MONSTER_IDX src_idx, POSITION y1, P
         mode |= PM_NO_KAGE;
     }
 
-    if (!place_specific_monster(player_ptr, src_idx, y, x, r_idx, mode)) {
-        summon_specific_type = SUMMON_NONE;
+    const auto summon_who = is_monster(src_idx) ? std::make_optional(src_idx) : std::nullopt;
+    if (!place_specific_monster(player_ptr, src_idx, y, x, r_idx, mode, summon_who)) {
         return false;
     }
 
-    summon_specific_type = SUMMON_NONE;
-
     bool notice = false;
     if (!is_monster(src_idx)) {
         notice = true;
index 9039dcb..9882027 100644 (file)
@@ -2,9 +2,6 @@
 
 #include "system/angband.h"
 
-extern int summon_specific_who;
-extern bool summon_unique_okay;
-
 enum summon_type : int;
 enum class MonsterRaceId : int16_t;
 class PlayerType;
index dffaffa..4fe4af3 100644 (file)
@@ -76,7 +76,7 @@ static bool monster_hook_tanuki(PlayerType *player_ptr, MonsterRaceId r_idx)
     }
 
     auto hook_pf = get_monster_hook(player_ptr);
-    return (*hook_pf)(player_ptr, r_idx);
+    return hook_pf(player_ptr, r_idx);
 }
 
 /*!
@@ -257,9 +257,10 @@ static void warn_unique_generation(PlayerType *player_ptr, MonsterRaceId r_idx)
  * @param x 生成位置x座標
  * @param r_idx 生成モンスター種族
  * @param mode 生成オプション
+ * @param summoner_m_idx モンスターの召喚による場合、召喚主のモンスターID
  * @return 成功したらtrue
  */
-bool place_monster_one(PlayerType *player_ptr, MONSTER_IDX src_idx, POSITION y, POSITION x, MonsterRaceId r_idx, BIT_FLAGS mode)
+bool place_monster_one(PlayerType *player_ptr, MONSTER_IDX src_idx, POSITION y, POSITION x, MonsterRaceId r_idx, BIT_FLAGS mode, std::optional<MONSTER_IDX> summoner_m_idx)
 {
     auto &floor = *player_ptr->current_floor_ptr;
     auto *g_ptr = &floor.grid_array[y][x];
@@ -336,7 +337,7 @@ bool place_monster_one(PlayerType *player_ptr, MONSTER_IDX src_idx, POSITION y,
     }
 
     if (r_ptr->misc_flags.has(MonsterMiscType::CHAMELEON)) {
-        choose_new_monster(player_ptr, g_ptr->m_idx, true, MonsterRace::empty_id());
+        choose_new_monster(player_ptr, g_ptr->m_idx, true, MonsterRace::empty_id(), summoner_m_idx);
         r_ptr = &m_ptr->get_monrace();
         m_ptr->mflag2.set(MonsterConstantFlagType::CHAMELEON);
         if (r_ptr->kind_flags.has(MonsterKindType::UNIQUE) && (!is_monster(src_idx))) {
index b7f68d7..1e7ff21 100644 (file)
@@ -1,7 +1,8 @@
 #pragma once
 
 #include "system/angband.h"
+#include <optional>
 
 enum class MonsterRaceId : int16_t;
 class PlayerType;
-bool place_monster_one(PlayerType *player_ptr, MONSTER_IDX src_idx, POSITION y, POSITION x, MonsterRaceId r_idx, BIT_FLAGS mode);
+bool place_monster_one(PlayerType *player_ptr, MONSTER_IDX src_idx, POSITION y, POSITION x, MonsterRaceId r_idx, BIT_FLAGS mode, std::optional<MONSTER_IDX> summoner_m_idx = std::nullopt);
index 052a4da..560dedb 100644 (file)
@@ -203,9 +203,10 @@ MonsterRaceId get_mon_num(PlayerType *player_ptr, DEPTH min_level, DEPTH max_lev
  * @param player_ptr プレイヤーへの参照ポインタ
  * @brief カメレオンの王の変身対象となるモンスターかどうか判定する / Hack -- the index of the summoning monster
  * @param r_idx モンスター種族ID
+ * @param summoner_m_idx モンスターの召喚による場合、召喚者のモンスターID
  * @return 対象にできるならtrueを返す
  */
-static bool monster_hook_chameleon_lord(PlayerType *player_ptr, MonsterRaceId r_idx)
+static bool monster_hook_chameleon_lord(PlayerType *player_ptr, MonsterRaceId r_idx, std::optional<MONSTER_IDX> summoner_m_idx)
 {
     auto *floor_ptr = player_ptr->current_floor_ptr;
     auto *r_ptr = &monraces_info[r_idx];
@@ -235,10 +236,8 @@ static bool monster_hook_chameleon_lord(PlayerType *player_ptr, MonsterRaceId r_
         if (monster_has_hostile_align(player_ptr, m_ptr, 0, 0, r_ptr)) {
             return false;
         }
-    } else if (summon_specific_who > 0) {
-        if (monster_has_hostile_align(player_ptr, &floor_ptr->m_list[summon_specific_who], 0, 0, r_ptr)) {
-            return false;
-        }
+    } else if (summoner_m_idx && monster_has_hostile_align(player_ptr, &floor_ptr->m_list[*summoner_m_idx], 0, 0, r_ptr)) {
+        return false;
     }
 
     return true;
@@ -247,10 +246,11 @@ static bool monster_hook_chameleon_lord(PlayerType *player_ptr, MonsterRaceId r_
 /*!
  * @brief カメレオンの変身対象となるモンスターかどうか判定する / Hack -- the index of the summoning monster
  * @param r_idx モンスター種族ID
+ * @param summoner_m_idx モンスターの召喚による場合、召喚者のモンスターID
  * @return 対象にできるならtrueを返す
  * @todo グローバル変数対策の上 monster_hook.cへ移す。
  */
-static bool monster_hook_chameleon(PlayerType *player_ptr, MonsterRaceId r_idx)
+static bool monster_hook_chameleon(PlayerType *player_ptr, MonsterRaceId r_idx, std::optional<MONSTER_IDX> summoner_m_idx)
 {
     auto *floor_ptr = player_ptr->current_floor_ptr;
     auto *r_ptr = &monraces_info[r_idx];
@@ -285,14 +285,12 @@ static bool monster_hook_chameleon(PlayerType *player_ptr, MonsterRaceId r_idx)
         if (old_r_ptr->kind_flags.has_none_of(alignment_mask)) {
             return false;
         }
-    } else if (summon_specific_who > 0) {
-        if (monster_has_hostile_align(player_ptr, &floor_ptr->m_list[summon_specific_who], 0, 0, r_ptr)) {
-            return false;
-        }
+    } else if (summoner_m_idx && monster_has_hostile_align(player_ptr, &floor_ptr->m_list[*summoner_m_idx], 0, 0, r_ptr)) {
+        return false;
     }
 
     auto hook_pf = get_monster_hook(player_ptr);
-    return (*hook_pf)(player_ptr, r_idx);
+    return hook_pf(player_ptr, r_idx);
 }
 
 /*!
@@ -301,8 +299,9 @@ static bool monster_hook_chameleon(PlayerType *player_ptr, MonsterRaceId r_idx)
  * @param m_idx 変身処理を受けるモンスター情報のID
  * @param born 生成時の初変身先指定ならばtrue
  * @param r_idx 旧モンスター種族のID
+ * @param summoner_m_idx モンスターの召喚による場合、召喚者のモンスターID
  */
-void choose_new_monster(PlayerType *player_ptr, MONSTER_IDX m_idx, bool born, MonsterRaceId r_idx)
+void choose_new_monster(PlayerType *player_ptr, MONSTER_IDX m_idx, bool born, MonsterRaceId r_idx, std::optional<MONSTER_IDX> summoner_m_idx)
 {
     auto *floor_ptr = player_ptr->current_floor_ptr;
     auto *m_ptr = &floor_ptr->m_list[m_idx];
@@ -324,9 +323,11 @@ void choose_new_monster(PlayerType *player_ptr, MONSTER_IDX m_idx, bool born, Mo
 
         chameleon_change_m_idx = m_idx;
         if (old_unique) {
-            get_mon_num_prep(player_ptr, monster_hook_chameleon_lord, nullptr);
+            auto hook = [summoner_m_idx](PlayerType *player_ptr, MonsterRaceId r_idx) { return monster_hook_chameleon_lord(player_ptr, r_idx, summoner_m_idx); };
+            get_mon_num_prep(player_ptr, std::move(hook), nullptr);
         } else {
-            get_mon_num_prep(player_ptr, monster_hook_chameleon, nullptr);
+            auto hook = [summoner_m_idx](PlayerType *player_ptr, MonsterRaceId r_idx) { return monster_hook_chameleon(player_ptr, r_idx, summoner_m_idx); };
+            get_mon_num_prep(player_ptr, std::move(hook), nullptr);
         }
 
         if (old_unique) {
index e8a9082..1b72c74 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "system/angband.h"
+#include <optional>
 
 enum class MonsterRaceId : int16_t;
 class FloorType;
@@ -9,6 +10,6 @@ class PlayerType;
 MONSTER_IDX m_pop(FloorType *floor_ptr);
 
 MonsterRaceId get_mon_num(PlayerType *player_ptr, DEPTH min_level, DEPTH max_level, BIT_FLAGS mode);
-void choose_new_monster(PlayerType *player_ptr, MONSTER_IDX m_idx, bool born, MonsterRaceId r_idx);
+void choose_new_monster(PlayerType *player_ptr, MONSTER_IDX m_idx, bool born, MonsterRaceId r_idx, std::optional<MONSTER_IDX> summoner_m_idx = std::nullopt);
 byte get_mspeed(FloorType *player_ptr, MonsterRaceInfo *r_ptr);
 int get_monster_crowd_number(FloorType *floor_ptr, MONSTER_IDX m_idx);
index ccb7a2e..0e33a7a 100644 (file)
@@ -1,16 +1,16 @@
 #pragma once
 
 #include "system/angband.h"
+#include <functional>
 
 enum class MonsterRaceId : int16_t;
 class PlayerType;
-typedef bool (*monsterrace_hook_type)(PlayerType *, MonsterRaceId);
+using monsterrace_hook_type = std::function<bool(PlayerType *, MonsterRaceId)>;
 
 extern MONSTER_IDX hack_m_idx;
 extern MONSTER_IDX hack_m_idx_ii;
 extern int chameleon_change_m_idx;
 enum summon_type : int;
-extern summon_type summon_specific_type;
 
 monsterrace_hook_type get_monster_hook(PlayerType *player_ptr);
 monsterrace_hook_type get_monster_hook2(PlayerType *player_ptr, POSITION y, POSITION x);
index 53ac271..5a214c0 100644 (file)
  * @return 召喚条件が一致するならtrue
  * @details
  */
-bool check_summon_specific(PlayerType *player_ptr, MonsterRaceId summoner_idx, MonsterRaceId r_idx)
+bool check_summon_specific(PlayerType *player_ptr, MonsterRaceId summoner_idx, MonsterRaceId r_idx, summon_type type)
 {
     const auto &monrace = monraces_info[r_idx];
-    switch (summon_specific_type) {
+    switch (type) {
     case SUMMON_ANT:
         return monrace.d_char == 'a';
     case SUMMON_SPIDER:
index 3981fce..c0e9e6e 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "system/angband.h"
 
+enum summon_type : int;
 enum class MonsterRaceId : int16_t;
 class PlayerType;
-bool check_summon_specific(PlayerType *player_ptr, MonsterRaceId summoner_idx, MonsterRaceId r_idx);
+bool check_summon_specific(PlayerType *player_ptr, MonsterRaceId summoner_idx, MonsterRaceId r_idx, summon_type type);