OSDN Git Service

Merge pull request #2122 from sikabane-works/release/3.0.0Alpha52
[hengbandforosx/hengbandosx.git] / src / object-enchant / protector / apply-magic-shield.cpp
1 /*
2  * @brief 盾に耐性等の追加効果を付与する処理
3  * @date 2021/08/01
4  * @author Hourier
5  * @details ドラゴンシールドは必ず付与する. それ以外は確率的に付与する.
6  */
7
8 #include "object-enchant/protector/apply-magic-shield.h"
9 #include "artifact/random-art-generator.h"
10 #include "inventory/inventory-slot-types.h"
11 #include "object-enchant/object-boost.h"
12 #include "object-enchant/object-ego.h"
13 #include "sv-definition/sv-protector-types.h"
14 #include "system/object-type-definition.h"
15
16 /*
17  * @brief コンストラクタ
18  * @param player_ptr プレイヤーへの参照ポインタ
19  * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
20  * @param level 生成基準階
21  * @param power 生成ランク
22  */
23 ShieldEnchanter::ShieldEnchanter(PlayerType *player_ptr, object_type *o_ptr, DEPTH level, int power)
24     : AbstractProtectorEnchanter{ o_ptr, level, power }
25     , player_ptr(player_ptr)
26 {
27 }
28
29 /*
30  * @details power > 2はデバッグ専用.
31  */
32 void ShieldEnchanter::apply_magic()
33 {
34     if (this->o_ptr->sval == SV_DRAGON_SHIELD) {
35         dragon_resist(this->o_ptr);
36         if (!one_in_(3)) {
37             return;
38         }
39     }
40
41     if (this->power <= 1) {
42         return;
43     }
44
45     if (one_in_(20) || (this->power > 2)) {
46         become_random_artifact(this->player_ptr, this->o_ptr, false);
47         return;
48     }
49
50     this->give_ego_index();
51 }
52
53 /*
54  * @details 金属製の盾は魔法を受け付けない.
55  * @todo ミラー・シールドはエゴの付与確率が低い. この仕様で良いか要確認.
56  */
57 void ShieldEnchanter::give_ego_index()
58 {
59     while (true) {
60         this->o_ptr->name2 = get_random_ego(INVEN_SUB_HAND, true);
61         auto is_metal = this->o_ptr->sval == SV_SMALL_METAL_SHIELD;
62         is_metal |= this->o_ptr->sval == SV_LARGE_METAL_SHIELD;
63         if (!is_metal && (this->o_ptr->name2 == EGO_S_DWARVEN)) {
64             continue;
65         }
66
67         break;
68     }
69
70     switch (this->o_ptr->name2) {
71     case EGO_REFLECTION:
72         if (this->o_ptr->sval == SV_MIRROR_SHIELD) {
73             this->o_ptr->name2 = 0;
74         }
75
76         return;
77     default:
78         return;
79     }
80 }