2 * @brief ベースアイテムを強化する処理
7 #include "object-enchant/item-magic-applier.h"
8 #include "artifact/fixed-art-generator.h"
9 #include "dungeon/dungeon.h"
10 #include "object-enchant/enchanter-base.h"
11 #include "object-enchant/enchanter-factory.h"
12 #include "object-enchant/item-apply-magic.h"
13 #include "object-enchant/object-curse.h"
14 #include "object-enchant/special-object-flags.h"
15 #include "object/object-kind.h"
16 #include "player/player-status-flags.h"
17 #include "system/artifact-type-definition.h"
18 #include "system/floor-type-definition.h"
19 #include "system/player-type-definition.h"
20 #include "util/bit-flags-calculator.h"
21 #include "world/world.h"
25 * @param player_ptr プレイヤーへの参照ポインタ
26 * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
30 ItemMagicApplier::ItemMagicApplier(PlayerType *player_ptr, ObjectType *o_ptr, DEPTH lev, BIT_FLAGS mode)
31 : player_ptr(player_ptr)
36 if (player_ptr->ppersonality == PERSONALITY_MUNCHKIN) {
37 this->lev += randint0(player_ptr->lev / 2 + 10);
40 if (this->lev > MAX_DEPTH - 1) {
41 this->lev = MAX_DEPTH - 1;
46 * @brief 生成されたベースアイテムに魔法的な強化を与えるメインルーチン
47 * @details エゴ&アーティファクトの生成、呪い、pval強化
49 void ItemMagicApplier::execute()
51 auto [chance_good, chance_great] = this->calculate_chances();
52 auto power = this->calculate_power(chance_good, chance_great);
53 auto rolls = this->calculate_rolls(power);
54 this->try_make_artifact(rolls);
55 if (this->set_fixed_artifact_generation_info()) {
59 auto enchanter = EnchanterFactory::create_enchanter(this->player_ptr, this->o_ptr, this->lev, power);
60 enchanter->apply_magic();
61 if (this->o_ptr->is_ego()) {
62 apply_ego(this->o_ptr, this->lev);
70 * @brief 上質及び高級品の生成確率 [%]を算出する
71 * @return 上質と高級品の生成確率組み合わせ
73 std::tuple<int, int> ItemMagicApplier::calculate_chances()
75 auto chance_good = this->lev + 10;
76 if (chance_good > d_info[this->player_ptr->dungeon_idx].obj_good) {
77 chance_good = d_info[this->player_ptr->dungeon_idx].obj_good;
80 auto chance_great = chance_good * 2 / 3;
81 if ((this->player_ptr->ppersonality != PERSONALITY_MUNCHKIN) && (chance_great > d_info[this->player_ptr->dungeon_idx].obj_great)) {
82 chance_great = d_info[this->player_ptr->dungeon_idx].obj_great;
85 if (has_good_luck(this->player_ptr)) {
88 } else if (this->player_ptr->muta.has(PlayerMutationType::BAD_LUCK)) {
93 return std::make_tuple(chance_good, chance_great);
97 * @brief 上質/高級品/アーティファクト生成パワー計算
98 * @param chance_good 上質品が生成される確率 [%]
99 * @param chance_great 高級品が生成される確率 [%]
101 * @details アーティファクト生成はデバッグ専用
103 int ItemMagicApplier::calculate_power(const int chance_good, const int chance_great)
106 if (any_bits(this->mode, AM_GOOD) || magik(chance_good)) {
108 if (any_bits(this->mode, AM_GREAT) || magik(chance_great)) {
110 if (any_bits(this->mode, AM_SPECIAL)) {
114 } else if (magik(chance_good)) {
116 if (magik(chance_great)) {
121 if (any_bits(this->mode, AM_CURSED)) {
133 * @brief 生成パワーを元にアーティファクト生成の試行回数を算出する
136 int ItemMagicApplier::calculate_rolls(const int power)
143 if (any_bits(this->mode, AM_GREAT | AM_SPECIAL)) {
147 if (any_bits(this->mode, AM_NO_FIXED_ART) || this->o_ptr->is_fixed_artifact()) {
155 * @brief アーティファクト生成を試みる
158 void ItemMagicApplier::try_make_artifact(const int rolls)
160 for (auto i = 0; i < rolls; i++) {
161 if (make_artifact(this->player_ptr, this->o_ptr)) {
165 if (!has_good_luck(this->player_ptr) || !one_in_(77)) {
169 if (make_artifact(this->player_ptr, this->o_ptr)) {
176 * @brief 固定アーティファクトの生成情報を記憶する
178 bool ItemMagicApplier::set_fixed_artifact_generation_info()
180 if (!this->o_ptr->is_fixed_artifact()) {
184 apply_artifact(this->player_ptr, this->o_ptr);
185 auto &a_ref = a_info.at(this->o_ptr->fixed_artifact_idx);
186 a_ref.is_generated = true;
187 if (w_ptr->character_dungeon) {
188 a_ref.floor_id = this->player_ptr->floor_id;
195 * @brief アイテムに呪いフラグを付与する
197 void ItemMagicApplier::apply_cursed()
199 if (this->o_ptr->k_idx == 0) {
203 const auto *k_ptr = &k_info[this->o_ptr->k_idx];
204 if (!k_info[this->o_ptr->k_idx].cost) {
205 set_bits(this->o_ptr->ident, IDENT_BROKEN);
208 if (k_ptr->gen_flags.has(ItemGenerationTraitType::CURSED)) {
209 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
212 if (k_ptr->gen_flags.has(ItemGenerationTraitType::HEAVY_CURSE)) {
213 this->o_ptr->curse_flags.set(CurseTraitType::HEAVY_CURSE);
216 if (k_ptr->gen_flags.has(ItemGenerationTraitType::PERMA_CURSE)) {
217 this->o_ptr->curse_flags.set(CurseTraitType::PERMA_CURSE);
220 if (k_ptr->gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE0)) {
221 this->o_ptr->curse_flags.set(get_curse(0, this->o_ptr));
224 if (k_ptr->gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE1)) {
225 this->o_ptr->curse_flags.set(get_curse(1, this->o_ptr));
228 if (k_ptr->gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE2)) {
229 this->o_ptr->curse_flags.set(get_curse(2, this->o_ptr));