*/
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);
}
/*!
#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"
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)
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)
{
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)
{
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, {})
{
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;
+}
*/
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; //!< 鍛冶で与える能力が所属するグループ
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; //!< 鍛冶で能力を与えることにより付与されるアイテム特性フラグ
};
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;
};
/*!
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;
};
/*!
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;
};
/*!
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;
};