2 * @brief ベースアイテムを強化する処理
7 #include "object-enchant/item-magic-applier.h"
8 #include "artifact/fixed-art-generator.h"
9 #include "object-enchant/enchanter-base.h"
10 #include "object-enchant/enchanter-factory.h"
11 #include "object-enchant/item-apply-magic.h"
12 #include "object-enchant/object-curse.h"
13 #include "object-enchant/special-object-flags.h"
14 #include "player/player-status-flags.h"
15 #include "system/artifact-type-definition.h"
16 #include "system/baseitem-info.h"
17 #include "system/dungeon-info.h"
18 #include "system/floor-type-definition.h"
19 #include "system/item-entity.h"
20 #include "system/player-type-definition.h"
21 #include "util/bit-flags-calculator.h"
22 #include "world/world.h"
26 * @param player_ptr プレイヤーへの参照ポインタ
27 * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
31 ItemMagicApplier::ItemMagicApplier(PlayerType *player_ptr, ItemEntity *o_ptr, DEPTH lev, BIT_FLAGS mode)
32 : player_ptr(player_ptr)
37 if (player_ptr->ppersonality == PERSONALITY_MUNCHKIN) {
38 this->lev += randint0(player_ptr->lev / 2 + 10);
41 if (this->lev > MAX_DEPTH - 1) {
42 this->lev = MAX_DEPTH - 1;
47 * @brief 生成されたベースアイテムに魔法的な強化を与えるメインルーチン
48 * @details エゴ&アーティファクトの生成、呪い、pval強化
50 void ItemMagicApplier::execute()
52 auto [chance_good, chance_great] = this->calculate_chances();
53 auto power = this->calculate_power(chance_good, chance_great);
54 auto rolls = this->calculate_rolls(power);
55 this->try_make_artifact(rolls);
56 if (this->set_fixed_artifact_generation_info()) {
60 auto enchanter = EnchanterFactory::create_enchanter(this->player_ptr, this->o_ptr, this->lev, power);
61 enchanter->apply_magic();
62 if (this->o_ptr->is_ego()) {
63 apply_ego(this->o_ptr, this->lev);
71 * @brief 上質及び高級品の生成確率 [%]を算出する
72 * @return 上質と高級品の生成確率組み合わせ
74 std::tuple<int, int> ItemMagicApplier::calculate_chances()
76 auto chance_good = this->lev + 10;
77 const auto &floor = *this->player_ptr->current_floor_ptr;
78 const auto &dungeon = floor.get_dungeon_definition();
79 if (chance_good > dungeon.obj_good) {
80 chance_good = dungeon.obj_good;
83 auto chance_great = chance_good * 2 / 3;
84 if ((this->player_ptr->ppersonality != PERSONALITY_MUNCHKIN) && (chance_great > dungeon.obj_great)) {
85 chance_great = dungeon.obj_great;
88 if (has_good_luck(this->player_ptr)) {
91 } else if (this->player_ptr->muta.has(PlayerMutationType::BAD_LUCK)) {
96 return std::make_tuple(chance_good, chance_great);
100 * @brief 上質/高級品/アーティファクト生成パワー計算
101 * @param chance_good 上質品が生成される確率 [%]
102 * @param chance_great 高級品が生成される確率 [%]
104 * @details アーティファクト生成はデバッグ専用
106 int ItemMagicApplier::calculate_power(const int chance_good, const int chance_great)
109 if (any_bits(this->mode, AM_GOOD) || magik(chance_good)) {
111 if (any_bits(this->mode, AM_GREAT) || magik(chance_great)) {
113 if (any_bits(this->mode, AM_SPECIAL)) {
117 } else if (magik(chance_good)) {
119 if (magik(chance_great)) {
124 if (any_bits(this->mode, AM_CURSED)) {
136 * @brief 生成パワーを元にアーティファクト生成の試行回数を算出する
139 int ItemMagicApplier::calculate_rolls(const int power)
146 if (any_bits(this->mode, AM_GREAT | AM_SPECIAL)) {
150 if (any_bits(this->mode, AM_NO_FIXED_ART) || this->o_ptr->is_fixed_artifact()) {
158 * @brief アーティファクト生成を試みる
161 void ItemMagicApplier::try_make_artifact(const int rolls)
163 for (auto i = 0; i < rolls; i++) {
164 if (make_artifact(this->player_ptr, this->o_ptr)) {
168 if (!has_good_luck(this->player_ptr) || !one_in_(77)) {
172 if (make_artifact(this->player_ptr, this->o_ptr)) {
179 * @brief 固定アーティファクトの生成情報を記憶する
181 bool ItemMagicApplier::set_fixed_artifact_generation_info()
183 if (!this->o_ptr->is_fixed_artifact()) {
187 apply_artifact(this->player_ptr, this->o_ptr);
188 this->o_ptr->get_fixed_artifact().is_generated = true;
193 * @brief アイテムに呪いフラグを付与する
195 void ItemMagicApplier::apply_cursed()
197 if (!this->o_ptr->is_valid()) {
201 const auto &baseitem = this->o_ptr->get_baseitem();
202 if (!baseitem.cost) {
203 set_bits(this->o_ptr->ident, IDENT_BROKEN);
206 if (baseitem.gen_flags.has(ItemGenerationTraitType::CURSED)) {
207 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
210 if (baseitem.gen_flags.has(ItemGenerationTraitType::HEAVY_CURSE)) {
211 this->o_ptr->curse_flags.set(CurseTraitType::HEAVY_CURSE);
214 if (baseitem.gen_flags.has(ItemGenerationTraitType::PERMA_CURSE)) {
215 this->o_ptr->curse_flags.set(CurseTraitType::PERMA_CURSE);
218 if (baseitem.gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE0)) {
219 this->o_ptr->curse_flags.set(get_curse(0, this->o_ptr));
222 if (baseitem.gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE1)) {
223 this->o_ptr->curse_flags.set(get_curse(1, this->o_ptr));
226 if (baseitem.gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE2)) {
227 this->o_ptr->curse_flags.set(get_curse(2, this->o_ptr));