OSDN Git Service

[Refactor] #1746 monster-loader-savefile10.cpp/h をクラス化し、ファクトリクラスから取ってこれるようにした
authorHourier <66951241+Hourier@users.noreply.github.com>
Sun, 17 Oct 2021 05:39:04 +0000 (14:39 +0900)
committerHourier <66951241+Hourier@users.noreply.github.com>
Sun, 17 Oct 2021 12:11:25 +0000 (21:11 +0900)
12 files changed:
Hengband/Hengband/Hengband.vcxproj
Hengband/Hengband/Hengband.vcxproj.filters
src/Makefile.am
src/load/dummy-loader.cpp
src/load/floor-loader.cpp
src/load/monster/monster-loader-base.h [new file with mode: 0644]
src/load/monster/monster-loader-factory.cpp [new file with mode: 0644]
src/load/monster/monster-loader-factory.h [new file with mode: 0644]
src/load/monster/monster-loader-version-types.h [new file with mode: 0644]
src/load/old/load-v1-5-0.cpp
src/load/old/monster-loader-savefile10.cpp
src/load/old/monster-loader-savefile10.h

index b80ae74..b3a3d6a 100644 (file)
     <ClCompile Include="..\..\src\core\score-util.cpp" />\r
     <ClCompile Include="..\..\src\load\item\item-loader-base.cpp" />\r
     <ClCompile Include="..\..\src\load\item\item-loader-factory.cpp" />\r
+    <ClCompile Include="..\..\src\load\monster\monster-loader-factory.cpp" />\r
     <ClCompile Include="..\..\src\load\player-class-specific-data-loader.cpp" />\r
     <ClCompile Include="..\..\src\object-enchant\object-smith.cpp" />\r
     <ClCompile Include="..\..\src\object-enchant\smith-info.cpp" />\r
     <ClInclude Include="..\..\src\load\item\item-loader-version-types.h" />\r
     <ClInclude Include="..\..\src\load\item\item-loader-base.h" />\r
     <ClInclude Include="..\..\src\load\item\item-loader-factory.h" />\r
+    <ClInclude Include="..\..\src\load\monster\monster-loader-base.h" />\r
+    <ClInclude Include="..\..\src\load\monster\monster-loader-factory.h" />\r
+    <ClInclude Include="..\..\src\load\monster\monster-loader-version-types.h" />\r
     <ClInclude Include="..\..\src\load\old\monster-flag-types-savefile10.h" />\r
     <ClInclude Include="..\..\src\load\player-class-specific-data-loader.h" />\r
     <ClInclude Include="..\..\src\load\savedata-old-flag-types.h" />\r
index 6502d87..630f849 100644 (file)
     <ClCompile Include="..\..\src\load\item\item-loader-factory.cpp">\r
       <Filter>load\item</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\src\load\monster\monster-loader-factory.cpp">\r
+      <Filter>load\monster</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="..\..\src\combat\shoot.h">\r
     <ClInclude Include="..\..\src\load\item\item-loader-version-types.h">\r
       <Filter>load\item</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\src\load\monster\monster-loader-base.h">\r
+      <Filter>load\monster</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\src\load\monster\monster-loader-factory.h">\r
+      <Filter>load\monster</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\src\load\monster\monster-loader-version-types.h">\r
+      <Filter>load\monster</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <None Include="..\..\src\wall.bmp" />\r
     <Filter Include="load\item">\r
       <UniqueIdentifier>{346bc9ba-a477-404f-bc72-2ad9c1ec6daf}</UniqueIdentifier>\r
     </Filter>\r
+    <Filter Include="load\monster">\r
+      <UniqueIdentifier>{ad11aaea-5034-4df2-9a9b-d63457fdad55}</UniqueIdentifier>\r
+    </Filter>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ResourceCompile Include="..\..\src\angband.rc" />\r
index be396ae..4507dae 100644 (file)
@@ -361,6 +361,10 @@ hengband_SOURCES = \
        load/item/item-loader-factory.cpp load/item/item-loader-factory.h \
        load/item/item-loader-version-types.h \
        \
+       load/monster/monster-loader-base.h \
+       load/monster/monster-loader-factory.cpp load/monster/monster-loader-factory.h \
+       load/monster/monster-loader-version-types.h \
+       \
        load/old/item-flag-types-savefile10.h \
        load/old/item-loader-savefile10.cpp load/old/item-loader-savefile10.h \
        load/old/load-v1-5-0.cpp load/old/load-v1-5-0.h \
index 8ca51f9..2be275e 100644 (file)
@@ -1,6 +1,7 @@
 #include "load/dummy-loader.h"
 #include "load/angband-version-comparer.h"
 #include "load/load-util.h"
+#include "load/monster/monster-loader-factory.h"
 #include "load/old/monster-loader-savefile10.h"
 #include "system/floor-type-definition.h"
 #include "system/monster-type-definition.h"
@@ -39,9 +40,10 @@ void rd_dummy_monsters(player_type *player_ptr)
         return;
 
     auto tmp16s = rd_s16b();
+    monster_type dummy_mon;
+    auto monster_loader = MonsterLoaderFactory::create_loader(player_ptr);
     for (int i = 0; i < tmp16s; i++) {
-        monster_type dummy_mon;
-        rd_monster(player_ptr, &dummy_mon);
+        monster_loader->rd_monster(&dummy_mon);
     }
 }
 
index 0c93899..01535d5 100644 (file)
@@ -11,6 +11,7 @@
 #include "load/item/item-loader-factory.h"
 #include "load/load-util.h"
 #include "load/old-feature-types.h"
+#include "load/monster/monster-loader-factory.h"
 #include "load/old/item-loader-savefile10.h"
 #include "load/old/load-v1-5-0.h"
 #include "load/old/monster-loader-savefile10.h"
@@ -173,17 +174,16 @@ errr rd_saved_floor(player_type *player_ptr, saved_floor_type *sf_ptr)
     if (limit > w_ptr->max_m_idx)
         return 161;
 
-    for (int i = 1; i < limit; i++) {
-        grid_type *g_ptr;
-        MONSTER_IDX m_idx;
-        monster_type *m_ptr;
-        m_idx = m_pop(floor_ptr);
-        if (i != m_idx)
+    auto monster_loader = MonsterLoaderFactory::create_loader(player_ptr);
+    for (auto i = 1; i < limit; i++) {
+        auto m_idx = m_pop(floor_ptr);
+        if (i != m_idx) {
             return 162;
+        }
 
-        m_ptr = &floor_ptr->m_list[m_idx];
-        rd_monster(player_ptr, m_ptr);
-        g_ptr = &floor_ptr->grid_array[m_ptr->fy][m_ptr->fx];
+        auto *m_ptr = &floor_ptr->m_list[m_idx];
+        monster_loader->rd_monster(m_ptr);
+        auto *g_ptr = &floor_ptr->grid_array[m_ptr->fy][m_ptr->fx];
         g_ptr->m_idx = m_idx;
         real_r_ptr(m_ptr)->cur_num++;
     }
diff --git a/src/load/monster/monster-loader-base.h b/src/load/monster/monster-loader-base.h
new file mode 100644 (file)
index 0000000..bfb1133
--- /dev/null
@@ -0,0 +1,12 @@
+#pragma once
+
+struct monster_type;
+struct player_type;
+class MonsterLoaderBase {
+public:
+    virtual ~MonsterLoaderBase() = default;
+    virtual void rd_monster(monster_type *m_ptr) = 0;
+
+protected:
+    MonsterLoaderBase() = default;
+};
diff --git a/src/load/monster/monster-loader-factory.cpp b/src/load/monster/monster-loader-factory.cpp
new file mode 100644 (file)
index 0000000..9568715
--- /dev/null
@@ -0,0 +1,52 @@
+/*!
+ * @brief モンスター情報をセーブデータから読み込むクラスを選択するファクトリクラス
+ * @date 2021/10/16
+ * @author Hourier
+ */
+
+#include "load/monster/monster-loader-base.h"
+#include "load/monster/monster-loader-factory.h"
+#include "load/monster/monster-loader-version-types.h"
+#include "load/load-util.h"
+#include "load/old/monster-loader-savefile10.h"
+
+/*!
+ * @brief アイテム読み込みクラスを返却する.
+ * @return アイテム読み込みクラスへの参照ポインタ.
+ * @details MonsterLoaderBaseは純粋仮想関数を含むので参照を返す必要がある.
+ * (値を返す設計はコンパイルエラー)
+ */
+std::shared_ptr<MonsterLoaderBase> MonsterLoaderFactory::create_loader(player_type *player_ptr)
+{
+    auto version = get_version();
+    switch (version) {
+    case MonsterLoaderVersionType::LOAD10:
+        return std::make_shared<MonsterLoader10>(player_ptr);
+    case MonsterLoaderVersionType::LOAD11:
+        // dummy yet.
+    default:
+        throw("Invalid loader version was specified!");
+    }
+}
+
+/*!
+ * @brief MonsterLoaderのバージョン切り替え.
+ * @return セーブファイルバージョン群の中で互換性のある最古のバージョン.
+ * @details (備忘録)例えばバージョン15で更に変更された場合、以下のように書き換えること.
+ * 
+ * if (loading_savefile_version_is_older_than(15)) {
+ *   return MonsterLoaderVersionType::LOAD11;
+ * } else if (loading_savefile_version_is_older_than(11)) {
+ *   return MonsterLoaderVersionType::LOAD10;
+ * } else {
+ *   return MonsterLoaderVersionType::LOAD15;
+ * }
+ */
+MonsterLoaderVersionType MonsterLoaderFactory::get_version()
+{
+    if (loading_savefile_version_is_older_than(11)) {
+        return MonsterLoaderVersionType::LOAD10;
+    } else {
+        return MonsterLoaderVersionType::LOAD11;
+    }
+}
diff --git a/src/load/monster/monster-loader-factory.h b/src/load/monster/monster-loader-factory.h
new file mode 100644 (file)
index 0000000..3f93365
--- /dev/null
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <memory>
+
+enum class MonsterLoaderVersionType;
+struct player_type;
+struct monster_type;
+class MonsterLoaderBase;
+class MonsterLoaderFactory {
+public:
+    static std::shared_ptr<MonsterLoaderBase> create_loader(player_type *player_ptr);
+
+private:
+    MonsterLoaderFactory() = delete;
+    static MonsterLoaderVersionType get_version();
+};
diff --git a/src/load/monster/monster-loader-version-types.h b/src/load/monster/monster-loader-version-types.h
new file mode 100644 (file)
index 0000000..c5097ce
--- /dev/null
@@ -0,0 +1,6 @@
+#pragma once
+
+enum class MonsterLoaderVersionType {
+    LOAD10,
+    LOAD11,
+};
index 9fe1552..86fdeb3 100644 (file)
@@ -16,6 +16,7 @@
 #include "load/item/item-loader-factory.h"
 #include "load/item/item-loader-version-types.h"
 #include "load/load-util.h"
+#include "load/monster/monster-loader-factory.h"
 #include "load/old-feature-types.h"
 #include "load/old/item-loader-savefile10.h"
 #include "load/old/monster-loader-savefile10.h"
@@ -701,19 +702,17 @@ errr rd_dungeon_old(player_type *player_ptr)
         return (161);
     }
 
+    auto monster_loader = MonsterLoaderFactory::create_loader(player_ptr);
     for (int i = 1; i < limit; i++) {
-        MONSTER_IDX m_idx;
-        monster_type *m_ptr;
-        m_idx = m_pop(floor_ptr);
+        auto m_idx = m_pop(floor_ptr);
         if (i != m_idx) {
             load_note(format(_("モンスター配置エラー (%d <> %d)", "Monster allocation error (%d <> %d)"), i, m_idx));
             return (162);
         }
 
-        m_ptr = &floor_ptr->m_list[m_idx];
-        rd_monster(player_ptr, m_ptr);
-        grid_type *g_ptr;
-        g_ptr = &floor_ptr->grid_array[m_ptr->fy][m_ptr->fx];
+        auto m_ptr = &floor_ptr->m_list[m_idx];
+        monster_loader->rd_monster(m_ptr);
+        auto *g_ptr = &floor_ptr->grid_array[m_ptr->fy][m_ptr->fx];
         g_ptr->m_idx = m_idx;
         real_r_ptr(m_ptr)->cur_num++;
     }
index 0578b16..6bc1216 100644 (file)
 #include "util/enum-converter.h"
 #include "util/quarks.h"
 
+MonsterLoader10::MonsterLoader10(player_type *player_ptr)
+    : player_ptr(player_ptr)
+{
+}
+
 /*!
- * @brief モンスターを読み込む(現版) / Read a monster (New method)
- * @param player_ptr プレイヤーへの参照ポインタ
- * @param m_ptr モンスター保存先ポインタ
+ * @brief モンスターを読み込む(v3.0.0 Savefile ver10まで)
  */
-void rd_monster(player_type *player_ptr, monster_type *m_ptr)
+void MonsterLoader10::rd_monster(monster_type *m_ptr_)
 {
+    this->m_ptr = m_ptr_;
     if (h_older_than(1, 5, 0, 0)) {
-        rd_monster_old(player_ptr, m_ptr);
+        rd_monster_old(this->player_ptr, this->m_ptr);
         return;
     }
 
     auto flags = rd_u32b();
-    m_ptr->r_idx = rd_s16b();
-    m_ptr->fy = rd_byte();
-    m_ptr->fx = rd_byte();
+    this->m_ptr->r_idx = rd_s16b();
+    this->m_ptr->fy = rd_byte();
+    this->m_ptr->fx = rd_byte();
 
-    m_ptr->hp = rd_s16b();
-    m_ptr->maxhp = rd_s16b();
-    m_ptr->max_maxhp = rd_s16b();
+    this->m_ptr->hp = rd_s16b();
+    this->m_ptr->maxhp = rd_s16b();
+    this->m_ptr->max_maxhp = rd_s16b();
 
     if (h_older_than(2, 1, 2, 1)) {
-        m_ptr->dealt_damage = 0;
+        this->m_ptr->dealt_damage = 0;
     } else {
-        m_ptr->dealt_damage = rd_s32b();
+        this->m_ptr->dealt_damage = rd_s32b();
     }
 
     if (any_bits(flags, SaveDataMonsterFlagType::AP_R_IDX))
-        m_ptr->ap_r_idx = rd_s16b();
+        this->m_ptr->ap_r_idx = rd_s16b();
     else
-        m_ptr->ap_r_idx = m_ptr->r_idx;
+        this->m_ptr->ap_r_idx = this->m_ptr->r_idx;
 
     if (any_bits(flags, SaveDataMonsterFlagType::SUB_ALIGN))
-        m_ptr->sub_align = rd_byte();
+        this->m_ptr->sub_align = rd_byte();
     else
-        m_ptr->sub_align = 0;
+        this->m_ptr->sub_align = 0;
 
     if (any_bits(flags, SaveDataMonsterFlagType::CSLEEP))
-        m_ptr->mtimed[MTIMED_CSLEEP] = rd_s16b();
+        this->m_ptr->mtimed[MTIMED_CSLEEP] = rd_s16b();
     else
-        m_ptr->mtimed[MTIMED_CSLEEP] = 0;
+        this->m_ptr->mtimed[MTIMED_CSLEEP] = 0;
 
-    m_ptr->mspeed = rd_byte();
+    this->m_ptr->mspeed = rd_byte();
 
-    m_ptr->energy_need = rd_s16b();
+    this->m_ptr->energy_need = rd_s16b();
 
     if (any_bits(flags, SaveDataMonsterFlagType::FAST)) {
-        m_ptr->mtimed[MTIMED_FAST] = rd_byte();
+        this->m_ptr->mtimed[MTIMED_FAST] = rd_byte();
     } else
-        m_ptr->mtimed[MTIMED_FAST] = 0;
+        this->m_ptr->mtimed[MTIMED_FAST] = 0;
 
     if (any_bits(flags, SaveDataMonsterFlagType::SLOW)) {
-        m_ptr->mtimed[MTIMED_SLOW] = rd_byte();
+        this->m_ptr->mtimed[MTIMED_SLOW] = rd_byte();
     } else
-        m_ptr->mtimed[MTIMED_SLOW] = 0;
+        this->m_ptr->mtimed[MTIMED_SLOW] = 0;
 
     if (any_bits(flags, SaveDataMonsterFlagType::STUNNED)) {
-        m_ptr->mtimed[MTIMED_STUNNED] = rd_byte();
+        this->m_ptr->mtimed[MTIMED_STUNNED] = rd_byte();
     } else
-        m_ptr->mtimed[MTIMED_STUNNED] = 0;
+        this->m_ptr->mtimed[MTIMED_STUNNED] = 0;
 
     if (any_bits(flags, SaveDataMonsterFlagType::CONFUSED)) {
-        m_ptr->mtimed[MTIMED_CONFUSED] = rd_byte();
+        this->m_ptr->mtimed[MTIMED_CONFUSED] = rd_byte();
     } else
-        m_ptr->mtimed[MTIMED_CONFUSED] = 0;
+        this->m_ptr->mtimed[MTIMED_CONFUSED] = 0;
 
     if (any_bits(flags, SaveDataMonsterFlagType::MONFEAR)) {
-        m_ptr->mtimed[MTIMED_MONFEAR] = rd_byte();
+        this->m_ptr->mtimed[MTIMED_MONFEAR] = rd_byte();
     } else
-        m_ptr->mtimed[MTIMED_MONFEAR] = 0;
+        this->m_ptr->mtimed[MTIMED_MONFEAR] = 0;
 
     if (any_bits(flags, SaveDataMonsterFlagType::TARGET_Y)) {
-        m_ptr->target_y = rd_s16b();
+        this->m_ptr->target_y = rd_s16b();
     } else
-        m_ptr->target_y = 0;
+        this->m_ptr->target_y = 0;
 
     if (any_bits(flags, SaveDataMonsterFlagType::TARGET_X)) {
-        m_ptr->target_x = rd_s16b();
+        this->m_ptr->target_x = rd_s16b();
     } else
-        m_ptr->target_x = 0;
+        this->m_ptr->target_x = 0;
 
     if (any_bits(flags, SaveDataMonsterFlagType::INVULNER)) {
-        m_ptr->mtimed[MTIMED_INVULNER] = rd_byte();
+        this->m_ptr->mtimed[MTIMED_INVULNER] = rd_byte();
     } else
-        m_ptr->mtimed[MTIMED_INVULNER] = 0;
+        this->m_ptr->mtimed[MTIMED_INVULNER] = 0;
 
-    m_ptr->mflag.clear();
-    m_ptr->mflag2.clear();
+    this->m_ptr->mflag.clear();
+    this->m_ptr->mflag2.clear();
 
     if (any_bits(flags, SaveDataMonsterFlagType::SMART)) {
         if (loading_savefile_version_is_older_than(2)) {
             auto tmp32u = rd_u32b();
-            migrate_bitflag_to_flaggroup(m_ptr->smart, tmp32u);
+            migrate_bitflag_to_flaggroup(this->m_ptr->smart, tmp32u);
 
             // 3.0.0Alpha10以前のSM_CLONED(ビット位置22)、SM_PET(23)、SM_FRIEDLY(28)をMFLAG2に移行する
             // ビット位置の定義はなくなるので、ビット位置の値をハードコードする。
             std::bitset<32> rd_bits(tmp32u);
-            m_ptr->mflag2[MFLAG2::CLONED] = rd_bits[22];
-            m_ptr->mflag2[MFLAG2::PET] = rd_bits[23];
-            m_ptr->mflag2[MFLAG2::FRIENDLY] = rd_bits[28];
-            m_ptr->smart.reset(i2enum<SM>(22)).reset(i2enum<SM>(23)).reset(i2enum<SM>(28));
+            this->m_ptr->mflag2[MFLAG2::CLONED] = rd_bits[22];
+            this->m_ptr->mflag2[MFLAG2::PET] = rd_bits[23];
+            this->m_ptr->mflag2[MFLAG2::FRIENDLY] = rd_bits[28];
+            this->m_ptr->smart.reset(i2enum<SM>(22)).reset(i2enum<SM>(23)).reset(i2enum<SM>(28));
         } else {
-            rd_FlagGroup(m_ptr->smart, rd_byte);
+            rd_FlagGroup(this->m_ptr->smart, rd_byte);
         }
     } else {
-        m_ptr->smart.clear();
+        this->m_ptr->smart.clear();
     }
 
     if (any_bits(flags, SaveDataMonsterFlagType::EXP)) {
-        m_ptr->exp = rd_u32b();
+        this->m_ptr->exp = rd_u32b();
     } else
-        m_ptr->exp = 0;
+        this->m_ptr->exp = 0;
 
     if (any_bits(flags, SaveDataMonsterFlagType::MFLAG2)) {
         if (loading_savefile_version_is_older_than(2)) {
             auto tmp8u = rd_byte();
             constexpr auto base = enum2i(MFLAG2::KAGE);
-            migrate_bitflag_to_flaggroup(m_ptr->mflag2, tmp8u, base, 7);
+            migrate_bitflag_to_flaggroup(this->m_ptr->mflag2, tmp8u, base, 7);
         } else {
-            rd_FlagGroup(m_ptr->mflag2, rd_byte);
+            rd_FlagGroup(this->m_ptr->mflag2, rd_byte);
         }
     }
 
     if (any_bits(flags, SaveDataMonsterFlagType::NICKNAME)) {
         char buf[128];
         rd_string(buf, sizeof(buf));
-        m_ptr->nickname = quark_add(buf);
+        this->m_ptr->nickname = quark_add(buf);
     } else
-        m_ptr->nickname = 0;
+        this->m_ptr->nickname = 0;
 
     if (any_bits(flags, SaveDataMonsterFlagType::PARENT))
-        m_ptr->parent_m_idx = rd_s16b();
+        this->m_ptr->parent_m_idx = rd_s16b();
     else
-        m_ptr->parent_m_idx = 0;
+        this->m_ptr->parent_m_idx = 0;
 }
index e8bbfa3..1fae762 100644 (file)
@@ -1,5 +1,15 @@
 #pragma once
 
+#include "load/monster/monster-loader-base.h"
+
 struct monster_type;
 struct player_type;
-void rd_monster(player_type *player_ptr, monster_type *m_ptr);
+class MonsterLoader10 : public MonsterLoaderBase {
+public:
+    MonsterLoader10(player_type *player_ptr);
+    void rd_monster(monster_type *m_ptr) override;
+
+private:
+    player_type *player_ptr;
+    monster_type *m_ptr = nullptr;
+};