OSDN Git Service

[Fix] 指定護衛のデータ数の制限をなくす
authorHabu <habu1010+github@gmail.com>
Thu, 17 Mar 2022 12:06:00 +0000 (21:06 +0900)
committerHabu <habu1010+github@gmail.com>
Thu, 17 Mar 2022 12:19:22 +0000 (21:19 +0900)
指定護衛のデータを std::vector で持つようにし、1体につき6種までの制限を撤廃する。
ほとんどのモンスターは指定護衛を持たないので無駄なメモリ消費の削減にもなる。

src/info-reader/race-reader.cpp
src/lore/monster-lore.cpp
src/monster-floor/monster-generator.cpp
src/system/monster-race-definition.h
src/view/display-lore.cpp

index f8f5e90..79ce34d 100644 (file)
@@ -196,17 +196,6 @@ errr parse_r_info(std::string_view buf, angband_header *)
         info_set_value(r_ptr->next_r_idx, tokens[6]);
     } else if (tokens[0] == "R") {
         // R:reinforcer_idx:number_dice
-        size_t i = 0;
-        for (; i < A_MAX; i++) {
-            if (!MonsterRace(r_ptr->reinforce_id[i]).is_valid()) {
-                break;
-            }
-        }
-
-        if (i >= 6) {
-            return PARSE_ERROR_GENERIC;
-        }
-
         if (tokens.size() < 3) {
             return PARSE_ERROR_TOO_FEW_ARGUMENTS;
         }
@@ -215,9 +204,13 @@ errr parse_r_info(std::string_view buf, angband_header *)
         }
 
         const auto &dice = str_split(tokens[2], 'd', false, 2);
-        info_set_value(r_ptr->reinforce_id[i], tokens[1]);
-        info_set_value(r_ptr->reinforce_dd[i], dice[0]);
-        info_set_value(r_ptr->reinforce_ds[i], dice[1]);
+        MonsterRaceId r_idx;
+        DICE_NUMBER dd;
+        DICE_SID ds;
+        info_set_value(r_idx, tokens[1]);
+        info_set_value(dd, dice[0]);
+        info_set_value(ds, dice[1]);
+        r_ptr->reinforces.emplace_back(r_idx, dd, ds);
     } else if (tokens[0] == "B") {
         // B:blow_type:blow_effect:dice
         size_t i = 0;
index b796457..63806a0 100644 (file)
@@ -23,6 +23,7 @@
 #include "view/display-lore-magics.h"
 #include "view/display-lore-status.h"
 #include "view/display-lore.h"
+#include <algorithm>
 
 static void set_msex_flags(lore_type *lore_ptr)
 {
@@ -145,11 +146,19 @@ void process_monster_lore(PlayerType *player_ptr, MonsterRaceId r_idx, monster_l
 {
     lore_type tmp_lore;
     lore_type *lore_ptr = initialize_lore_type(&tmp_lore, r_idx, mode);
-    for (int n = 0; n < A_MAX; n++) {
-        if (MonsterRace(lore_ptr->r_ptr->reinforce_id[n]).is_valid()) {
-            lore_ptr->reinforce = true;
-        }
-    }
+
+    auto is_valid_reinforcer = [](const auto &reinforce) {
+        auto [r_idx, dd, ds] = reinforce;
+        auto is_reinforce = MonsterRace(r_idx).is_valid();
+        is_reinforce &= dd > 0;
+        is_reinforce &= ds > 0;
+        return is_reinforce;
+    };
+
+    lore_ptr->reinforce =
+        std::find_if(
+            lore_ptr->r_ptr->reinforces.begin(), lore_ptr->r_ptr->reinforces.end(),
+            is_valid_reinforcer) != lore_ptr->r_ptr->reinforces.end();
 
     if (cheat_know || (mode == MONSTER_LORE_RESEARCH) || (mode == MONSTER_LORE_DEBUG)) {
         lore_ptr->know_everything = true;
index be3f976..4475069 100644 (file)
@@ -306,18 +306,18 @@ bool place_monster_aux(PlayerType *player_ptr, MONSTER_IDX who, POSITION y, POSI
     place_monster_m_idx = hack_m_idx_ii;
 
     /* Reinforcement */
-    for (int i = 0; i < 6; i++) {
-        if (!MonsterRace(r_ptr->reinforce_id[i]).is_valid()) {
-            break;
+    for (auto [reinforce_r_idx, dd, ds] : r_ptr->reinforces) {
+        if (!MonsterRace(reinforce_r_idx).is_valid()) {
+            continue;
         }
-        int n = damroll(r_ptr->reinforce_dd[i], r_ptr->reinforce_ds[i]);
+        auto n = damroll(dd, ds);
         for (int j = 0; j < n; j++) {
             POSITION nx, ny, d;
             const POSITION scatter_min = 7;
             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, r_ptr->reinforce_id[i], mode)) {
+                if (place_monster_one(player_ptr, place_monster_m_idx, ny, nx, reinforce_r_idx, mode)) {
                     break;
                 }
             }
index fb04c37..e398861 100644 (file)
@@ -12,6 +12,8 @@
 #include "system/angband.h"
 #include "util/flag-group.h"
 #include <string>
+#include <tuple>
+#include <vector>
 
 /*! モンスターが1ターンに攻撃する最大回数 (射撃を含む) / The maximum number of times a monster can attack in a turn (including SHOOT) */
 constexpr int MAX_NUM_BLOWS = 4;
@@ -77,9 +79,10 @@ struct monster_race {
     EnumClassFlagGroup<MonsterResistanceType> resistance_flags; //!< 耐性フラグ / Flags R (resistances info)
     EnumClassFlagGroup<MonsterDropType> drop_flags; //!< 能力フラグ(ドロップ) / Drop Flags
     MonsterBlow blow[MAX_NUM_BLOWS]{}; //!< 打撃能力定義 / Up to four blows per round
-    MonsterRaceId reinforce_id[6]{}; //!< 指定護衛モンスター種族ID(6種まで)
-    DICE_NUMBER reinforce_dd[6]{}; //!< 指定護衛数ダイス数
-    DICE_SID reinforce_ds[6]{}; //!< 指定護衛数ダイス面
+
+    //! 指定護衛リスト <モンスター種族ID,護衛数ダイス数,護衛数ダイス面>
+    std::vector<std::tuple<MonsterRaceId, DICE_NUMBER, DICE_SID>> reinforces;
+
     ARTIFACT_IDX artifact_id[4]{}; //!< 特定アーティファクトドロップID
     RARITY artifact_rarity[4]{}; //!< 特定アーティファクトレア度
     PERCENTAGE artifact_percent[4]{}; //!< 特定アーティファクトドロップ率
index 7e97e33..f48a2ea 100644 (file)
@@ -535,30 +535,30 @@ static void display_monster_escort_contents(lore_type *lore_ptr)
     hooked_roff(" contain ");
 #endif
 
-    for (int n = 0; n < A_MAX; n++) {
-        bool is_reinforced = MonsterRace(lore_ptr->r_ptr->reinforce_id[n]).is_valid();
-        is_reinforced &= lore_ptr->r_ptr->reinforce_dd[n] > 0;
-        is_reinforced &= lore_ptr->r_ptr->reinforce_ds[n] > 0;
+    for (auto [r_idx, dd, ds] : lore_ptr->r_ptr->reinforces) {
+        auto is_reinforced = MonsterRace(r_idx).is_valid();
+        is_reinforced &= dd > 0;
+        is_reinforced &= ds > 0;
         if (!is_reinforced) {
             continue;
         }
 
-        monster_race *rf_ptr = &r_info[lore_ptr->r_ptr->reinforce_id[n]];
+        const auto *rf_ptr = &r_info[r_idx];
         if (rf_ptr->kind_flags.has(MonsterKindType::UNIQUE)) {
             hooked_roff(format(_("、%s", ", %s"), rf_ptr->name.c_str()));
             continue;
         }
 
 #ifdef JP
-        hooked_roff(format("、 %dd%d 体の%s", lore_ptr->r_ptr->reinforce_dd[n], lore_ptr->r_ptr->reinforce_ds[n], rf_ptr->name.c_str()));
+        hooked_roff(format("、 %dd%d 体の%s", dd, ds, rf_ptr->name.c_str()));
 #else
-        bool plural = (lore_ptr->r_ptr->reinforce_dd[n] * lore_ptr->r_ptr->reinforce_ds[n] > 1);
+        auto plural = (dd * ds > 1);
         GAME_TEXT name[MAX_NLEN];
         strcpy(name, rf_ptr->name.c_str());
         if (plural) {
             plural_aux(name);
         }
-        hooked_roff(format(",%dd%d %s", lore_ptr->r_ptr->reinforce_dd[n], lore_ptr->r_ptr->reinforce_ds[n], name));
+        hooked_roff(format(",%dd%d %s", dd, ds, name));
 #endif
     }