OSDN Git Service

[Refactor] 鍛冶対象アイテムの絞り込み方法を改善
authorHabu <habu1010+github@gmail.com>
Sun, 12 Sep 2021 11:49:55 +0000 (20:49 +0900)
committerHabu <habu1010+github@gmail.com>
Sun, 12 Sep 2021 11:49:55 +0000 (20:49 +0900)
アイテムを鍛冶の対象にできるかを調べる仮想関数
ISmithInfo::can_give_smith_effect() を追加し、
Smith::get_item_tester() ではこれを使用して ItemTester
オブジェクトを生成して返すようにする。
また、従来の鍛冶コマンドではすでに強化できない★☆や
鍛冶済みのアイテムも候補に選ばれていたが、選ばれない
ようにすることでインターフェースを改善する。

src/object-enchant/object-smith.cpp
src/object-enchant/smith-info.cpp
src/object-enchant/smith-info.h

index a6922eb..25f2921 100644 (file)
@@ -182,25 +182,15 @@ int Smith::get_essence_consumption(SmithEffect effect, const object_type *o_ptr)
  */
 std::unique_ptr<ItemTester> Smith::get_item_tester(SmithEffect effect)
 {
-    auto category = SmithCategory::NONE;
-    if (auto info = find_smith_info(effect); info.has_value()) {
-        category = info.value()->category;
-    }
-
-    if (effect == SmithEffect::SLAY_GLOVE) {
-        return std::make_unique<TvalItemTester>(TV_GLOVES);
-    }
-    if (category == SmithCategory::WEAPON_ATTR || category == SmithCategory::SLAYING) {
-        return std::make_unique<FuncItemTester>(&object_type::is_melee_ammo);
-    }
-    if (effect == SmithEffect::ATTACK) {
-        return std::make_unique<FuncItemTester>(&object_type::allow_enchant_weapon);
-    }
-    if (effect == SmithEffect::AC) {
-        return std::make_unique<FuncItemTester>(&object_type::is_armour);
+    auto info = find_smith_info(effect);
+    if (!info.has_value()) {
+        return std::make_unique<TvalItemTester>(TV_NONE);
     }
 
-    return std::make_unique<FuncItemTester>(&object_type::is_weapon_armour_ammo);
+    auto tester_func = [i = info.value()](const object_type *o_ptr) {
+        return i->can_give_smith_effect(o_ptr);
+    };
+    return std::make_unique<FuncItemTester>(tester_func);
 }
 
 /*!
index 7486031..a2175d7 100644 (file)
@@ -1,4 +1,6 @@
 #include "object-enchant/smith-info.h"
+#include "object-enchant/smith-types.h"
+#include "object-enchant/tr-types.h"
 #include "object/object-flags.h"
 #include "system/object-type-definition.h"
 #include "system/player-type-definition.h"
@@ -48,6 +50,29 @@ TrFlags BasicSmithInfo::tr_flags() const
     return this->add_flags;
 }
 
+bool BasicSmithInfo::can_give_smith_effect(const object_type *o_ptr) const
+{
+    /*!
+     * @note 固定orランダムアーティファクトもしくはすでに鍛冶済みでないかを最初にチェックし、
+     * 残る具体的な絞り込みは BasicSmithInfo::can_give_smith_effect_impl およびその派生クラスで
+     * オーバーライドした関数にて行う
+     */
+    if (o_ptr->is_artifact() || o_ptr->is_smith()) {
+        return false;
+    }
+
+    return this->can_give_smith_effect_impl(o_ptr);
+}
+
+bool BasicSmithInfo::can_give_smith_effect_impl(const object_type *o_ptr) const
+{
+    if (this->category == SmithCategory::WEAPON_ATTR || this->category == SmithCategory::SLAYING) {
+        return o_ptr->is_melee_ammo();
+    }
+
+    return o_ptr->is_weapon_armour_ammo();
+}
+
 ActivationSmithInfo::ActivationSmithInfo(SmithEffect effect, concptr name, SmithCategory category, std::vector<SmithEssence> need_essences, int consumption, TrFlags add_flags, random_art_activation_type act_idx)
     : BasicSmithInfo(effect, name, category, std::move(need_essences), consumption, std::move(add_flags))
     , act_idx(act_idx)
@@ -82,6 +107,11 @@ bool EnchantWeaponSmithInfo::add_essence(player_type *player_ptr, object_type *o
     return true;
 }
 
+bool EnchantWeaponSmithInfo::can_give_smith_effect(const object_type *o_ptr) const
+{
+    return o_ptr->allow_enchant_melee_weapon();
+}
+
 EnchantArmourSmithInfo::EnchantArmourSmithInfo(SmithEffect effect, concptr name, SmithCategory category, std::vector<SmithEssence> need_essences, int consumption)
     : ISmithInfo(effect, name, category, std::move(need_essences), consumption)
 {
@@ -99,6 +129,11 @@ bool EnchantArmourSmithInfo::add_essence(player_type *player_ptr, object_type *o
     return true;
 }
 
+bool EnchantArmourSmithInfo::can_give_smith_effect(const object_type *o_ptr) const
+{
+    return o_ptr->is_armour();
+}
+
 SustainSmithInfo::SustainSmithInfo(SmithEffect effect, concptr name, SmithCategory category, std::vector<SmithEssence> need_essences, int consumption)
     : ISmithInfo(effect, name, category, std::move(need_essences), consumption)
 {
@@ -114,6 +149,11 @@ bool SustainSmithInfo::add_essence(player_type *, object_type *o_ptr, int) const
     return true;
 }
 
+bool SustainSmithInfo::can_give_smith_effect(const object_type *o_ptr) const
+{
+    return o_ptr->is_weapon_armour_ammo();
+}
+
 SlayingGlovesSmithInfo::SlayingGlovesSmithInfo(SmithEffect effect, concptr name, SmithCategory category, std::vector<SmithEssence> need_essences, int consumption)
     : BasicSmithInfo(effect, name, category, std::move(need_essences), consumption, {})
 {
@@ -144,3 +184,8 @@ void SlayingGlovesSmithInfo::erase_essence(object_type *o_ptr) const
     if (o_ptr->to_d < 0)
         o_ptr->to_d = 0;
 }
+
+bool SlayingGlovesSmithInfo::can_give_smith_effect_impl(const object_type *o_ptr) const
+{
+    return o_ptr->tval == TV_GLOVES;
+}
index 5cf8b38..a1be18e 100644 (file)
@@ -55,6 +55,14 @@ public:
      */
     virtual std::optional<random_art_activation_type> activation_index() const;
 
+    /*!
+     * @brief 鍛冶を行えるアイテムかどうかを調べる
+     *
+     * @param o_ptr 鍛冶を行うアイテム構造体へのポインタ
+     * @return 鍛冶を行えるなら true、そうでなければ false
+     */
+    virtual bool can_give_smith_effect(const object_type *o_ptr) const = 0;
+
     SmithEffect effect; //!< 鍛冶で与える効果の種類
     concptr name; //!< 鍛冶で与える能力の名称
     SmithCategory category; //!< 鍛冶で与える能力が所属するグループ
@@ -75,8 +83,10 @@ public:
     virtual bool add_essence(player_type *player_ptr, object_type *o_ptr, int number) const override;
     virtual void erase_essence(object_type *o_ptr) const override;
     virtual TrFlags tr_flags() const override;
+    virtual bool can_give_smith_effect(const object_type *o_ptr) const final override;
 
 private:
+    virtual bool can_give_smith_effect_impl(const object_type *o_ptr) const;
     TrFlags add_flags; //!< 鍛冶で能力を与えることにより付与されるアイテム特性フラグ
 };
 
@@ -103,6 +113,7 @@ public:
     EnchantWeaponSmithInfo(SmithEffect effect, concptr name, SmithCategory category, std::vector<SmithEssence> need_essences, int consumption);
     virtual bool add_essence(player_type *player_ptr, object_type *o_ptr, int number) const override;
     virtual void erase_essence(object_type *) const override {}
+    virtual bool can_give_smith_effect(const object_type *o_ptr) const override;
 };
 
 /*!
@@ -114,6 +125,7 @@ public:
     EnchantArmourSmithInfo(SmithEffect effect, concptr name, SmithCategory category, std::vector<SmithEssence> need_essences, int consumption);
     virtual bool add_essence(player_type *player_ptr, object_type *o_ptr, int number) const override;
     virtual void erase_essence(object_type *) const override {}
+    virtual bool can_give_smith_effect(const object_type *o_ptr) const override;
 };
 
 /*!
@@ -125,6 +137,7 @@ public:
     SustainSmithInfo(SmithEffect effect, concptr name, SmithCategory category, std::vector<SmithEssence> need_essences, int consumption);
     virtual bool add_essence(player_type *player_ptr, object_type *o_ptr, int number) const override;
     virtual void erase_essence(object_type *) const override {}
+    virtual bool can_give_smith_effect(const object_type *o_ptr) const override;
 };
 
 /*!
@@ -136,4 +149,7 @@ public:
     SlayingGlovesSmithInfo(SmithEffect effect, concptr name, SmithCategory category, std::vector<SmithEssence> need_essences, int consumption);
     virtual bool add_essence(player_type *player_ptr, object_type *o_ptr, int number) const override;
     virtual void erase_essence(object_type *) const override;
+
+private:
+    virtual bool can_give_smith_effect_impl(const object_type *o_ptr) const override;
 };