1 #include "smith/smith-info.h"
2 #include "object-enchant/tr-types.h"
3 #include "object/object-flags.h"
4 #include "smith/smith-types.h"
5 #include "sv-definition/sv-weapon-types.h"
6 #include "system/object-type-definition.h"
7 #include "system/player-type-definition.h"
9 ISmithInfo::ISmithInfo(SmithEffectType effect, concptr name, SmithCategoryType category, std::vector<SmithEssenceType> need_essences, int consumption)
13 , need_essences(std::move(need_essences))
14 , consumption(consumption)
18 TrFlags ISmithInfo::tr_flags() const
23 BasicSmithInfo::BasicSmithInfo(SmithEffectType effect, concptr name, SmithCategoryType category, std::vector<SmithEssenceType> need_essences, int consumption, TrFlags add_flags)
24 : ISmithInfo(effect, name, category, std::move(need_essences), consumption)
25 , add_flags(add_flags)
29 bool BasicSmithInfo::add_essence(PlayerType *, object_type *o_ptr, int) const
31 o_ptr->smith_effect = effect;
36 void BasicSmithInfo::erase_essence(object_type *o_ptr) const
38 o_ptr->smith_effect = std::nullopt;
39 auto flgs = object_flags(o_ptr);
40 if (flgs.has_none_of(TR_PVAL_FLAG_MASK))
44 TrFlags BasicSmithInfo::tr_flags() const
46 return this->add_flags;
49 bool BasicSmithInfo::can_give_smith_effect(const object_type *o_ptr) const
52 * @note 固定orランダムアーティファクトもしくはすでに鍛冶済みでないかを最初にチェックし、
53 * 残る具体的な絞り込みは BasicSmithInfo::can_give_smith_effect_impl およびその派生クラスで
56 if (o_ptr->is_artifact() || o_ptr->smith_effect.has_value()) {
60 return this->can_give_smith_effect_impl(o_ptr);
63 bool BasicSmithInfo::can_give_smith_effect_impl(const object_type *o_ptr) const
65 if (this->effect == SmithEffectType::XTRA_MIGHT || this->effect == SmithEffectType::XTRA_SHOTS) {
66 return o_ptr->tval == ItemKindType::BOW;
68 if (this->effect == SmithEffectType::VORPAL) {
69 return (o_ptr->tval == ItemKindType::SWORD) && (o_ptr->sval != SV_POISON_NEEDLE);
71 if (this->effect == SmithEffectType::EASY_2WEAPON) {
72 return (o_ptr->tval == ItemKindType::GLOVES);
74 if (this->category == SmithCategoryType::WEAPON_ATTR && o_ptr->is_ammo()) {
75 return this->add_flags.has_any_of({ TR_BRAND_ACID, TR_BRAND_ELEC, TR_BRAND_FIRE, TR_BRAND_COLD, TR_BRAND_POIS });
77 if (this->category == SmithCategoryType::WEAPON_ATTR || this->category == SmithCategoryType::SLAYING) {
78 return o_ptr->is_melee_ammo();
81 return o_ptr->is_weapon_armour_ammo() && o_ptr->is_wearable();
84 ActivationSmithInfo::ActivationSmithInfo(SmithEffectType effect, concptr name, SmithCategoryType category, std::vector<SmithEssenceType> need_essences, int consumption, RandomArtActType act_idx)
85 : ISmithInfo(effect, name, category, std::move(need_essences), consumption)
90 bool ActivationSmithInfo::add_essence(PlayerType *, object_type *o_ptr, int) const
92 o_ptr->smith_act_idx = this->act_idx;
97 void ActivationSmithInfo::erase_essence(object_type *o_ptr) const
99 o_ptr->smith_act_idx = std::nullopt;
102 bool ActivationSmithInfo::can_give_smith_effect(const object_type *o_ptr) const
104 if (o_ptr->is_artifact() || o_ptr->smith_act_idx.has_value()) {
108 return o_ptr->is_weapon_armour_ammo() && o_ptr->is_wearable();
111 EnchantWeaponSmithInfo::EnchantWeaponSmithInfo(SmithEffectType effect, concptr name, SmithCategoryType category, std::vector<SmithEssenceType> need_essences, int consumption)
112 : ISmithInfo(effect, name, category, std::move(need_essences), consumption)
116 bool EnchantWeaponSmithInfo::add_essence(PlayerType *player_ptr, object_type *o_ptr, int) const
118 const auto max_val = player_ptr->lev / 5 + 5;
119 if ((o_ptr->to_h >= max_val) && (o_ptr->to_d >= max_val)) {
123 if (o_ptr->to_h < max_val) {
126 if (o_ptr->to_d < max_val) {
133 bool EnchantWeaponSmithInfo::can_give_smith_effect(const object_type *o_ptr) const
135 return o_ptr->allow_enchant_weapon();
138 EnchantArmourSmithInfo::EnchantArmourSmithInfo(SmithEffectType effect, concptr name, SmithCategoryType category, std::vector<SmithEssenceType> need_essences, int consumption)
139 : ISmithInfo(effect, name, category, std::move(need_essences), consumption)
143 bool EnchantArmourSmithInfo::add_essence(PlayerType *player_ptr, object_type *o_ptr, int) const
145 const auto max_val = player_ptr->lev / 5 + 5;
146 if (o_ptr->to_a >= max_val) {
155 bool EnchantArmourSmithInfo::can_give_smith_effect(const object_type *o_ptr) const
157 return o_ptr->is_armour();
160 SustainSmithInfo::SustainSmithInfo(SmithEffectType effect, concptr name, SmithCategoryType category, std::vector<SmithEssenceType> need_essences, int consumption)
161 : ISmithInfo(effect, name, category, std::move(need_essences), consumption)
165 bool SustainSmithInfo::add_essence(PlayerType *, object_type *o_ptr, int) const
167 o_ptr->art_flags.set(TR_IGNORE_ACID);
168 o_ptr->art_flags.set(TR_IGNORE_ELEC);
169 o_ptr->art_flags.set(TR_IGNORE_FIRE);
170 o_ptr->art_flags.set(TR_IGNORE_COLD);
175 bool SustainSmithInfo::can_give_smith_effect(const object_type *o_ptr) const
177 return o_ptr->is_weapon_armour_ammo();
180 SlayingGlovesSmithInfo::SlayingGlovesSmithInfo(SmithEffectType effect, concptr name, SmithCategoryType category, std::vector<SmithEssenceType> need_essences, int consumption)
181 : BasicSmithInfo(effect, name, category, std::move(need_essences), consumption, {})
185 bool SlayingGlovesSmithInfo::add_essence(PlayerType *player_ptr, object_type *o_ptr, int number) const
187 BasicSmithInfo::add_essence(player_ptr, o_ptr, number);
189 HIT_PROB get_to_h = ((number + 1) / 2 + randint0(number / 2 + 1));
190 HIT_POINT get_to_d = ((number + 1) / 2 + randint0(number / 2 + 1));
191 o_ptr->xtra4 = (get_to_h << 8) + get_to_d;
192 o_ptr->to_h += get_to_h;
193 o_ptr->to_d += get_to_d;
198 void SlayingGlovesSmithInfo::erase_essence(object_type *o_ptr) const
200 BasicSmithInfo::erase_essence(o_ptr);
202 o_ptr->to_h -= (o_ptr->xtra4 >> 8);
203 o_ptr->to_d -= (o_ptr->xtra4 & 0x000f);
211 bool SlayingGlovesSmithInfo::can_give_smith_effect_impl(const object_type *o_ptr) const
213 return o_ptr->tval == ItemKindType::GLOVES;