From: Habu Date: Sun, 12 Sep 2021 11:49:55 +0000 (+0900) Subject: [Refactor] 鍛冶対象アイテムの絞り込み方法を改善 X-Git-Tag: vmacos3.0.0-alpha52~103^2^2~1 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=c815c0568726f5b2e83a2e6af2ae07e58879cfe5;p=hengbandforosx%2Fhengbandosx.git [Refactor] 鍛冶対象アイテムの絞り込み方法を改善 アイテムを鍛冶の対象にできるかを調べる仮想関数 ISmithInfo::can_give_smith_effect() を追加し、 Smith::get_item_tester() ではこれを使用して ItemTester オブジェクトを生成して返すようにする。 また、従来の鍛冶コマンドではすでに強化できない★☆や 鍛冶済みのアイテムも候補に選ばれていたが、選ばれない ようにすることでインターフェースを改善する。 --- diff --git a/src/object-enchant/object-smith.cpp b/src/object-enchant/object-smith.cpp index a6922eb29..25f29213b 100644 --- a/src/object-enchant/object-smith.cpp +++ b/src/object-enchant/object-smith.cpp @@ -182,25 +182,15 @@ int Smith::get_essence_consumption(SmithEffect effect, const object_type *o_ptr) */ std::unique_ptr 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(TV_GLOVES); - } - if (category == SmithCategory::WEAPON_ATTR || category == SmithCategory::SLAYING) { - return std::make_unique(&object_type::is_melee_ammo); - } - if (effect == SmithEffect::ATTACK) { - return std::make_unique(&object_type::allow_enchant_weapon); - } - if (effect == SmithEffect::AC) { - return std::make_unique(&object_type::is_armour); + auto info = find_smith_info(effect); + if (!info.has_value()) { + return std::make_unique(TV_NONE); } - return std::make_unique(&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(tester_func); } /*! diff --git a/src/object-enchant/smith-info.cpp b/src/object-enchant/smith-info.cpp index 74860313c..a2175d79a 100644 --- a/src/object-enchant/smith-info.cpp +++ b/src/object-enchant/smith-info.cpp @@ -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 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 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 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 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; +} diff --git a/src/object-enchant/smith-info.h b/src/object-enchant/smith-info.h index 5cf8b3840..a1be18eea 100644 --- a/src/object-enchant/smith-info.h +++ b/src/object-enchant/smith-info.h @@ -55,6 +55,14 @@ public: */ virtual std::optional 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 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 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 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 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; };