7 #include "object-enchant/others/apply-magic-ring.h"
8 #include "artifact/random-art-generator.h"
9 #include "object-enchant/object-boost.h"
10 #include "object-enchant/object-ego.h"
11 #include "object-enchant/special-object-flags.h"
12 #include "object-enchant/trc-types.h"
13 #include "sv-definition/sv-ring-types.h"
14 #include "system/baseitem-info.h"
15 #include "system/item-entity.h"
16 #include "system/player-type-definition.h"
17 #include "util/bit-flags-calculator.h"
21 * @param player_ptr プレイヤーへの参照ポインタ
22 * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
26 RingEnchanter::RingEnchanter(PlayerType *player_ptr, ItemEntity *o_ptr, DEPTH level, int power)
27 : player_ptr(player_ptr)
35 * @brief 指輪に生成ランクごとの強化を与える
36 * Apply magic to an item known to be a "ring" or "amulet"
37 * @param player_ptr プレイヤーへの参照ポインタ
38 * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
42 * @details power > 2はデバッグ専用.
44 void RingEnchanter::apply_magic()
46 if ((this->power == 0) && (randint0(100) < 50)) {
51 if ((this->power > 2) || (one_in_(400) && (this->power > 0) && !this->o_ptr->is_cursed() && (this->level > 79))) {
52 this->o_ptr->pval = std::min<short>(this->o_ptr->pval, 4);
53 become_random_artifact(this->player_ptr, this->o_ptr, false);
57 if ((this->power == 2) && one_in_(2)) {
59 this->o_ptr->curse_flags.clear();
63 if ((this->power == -2) && one_in_(2)) {
68 void RingEnchanter::sval_enchant()
70 const auto sval = this->o_ptr->bi_key.sval();
71 if (!sval.has_value()) {
75 switch (sval.value()) {
77 this->o_ptr->pval = (PARAMETER_VALUE)m_bonus(2, this->level);
82 if (this->o_ptr->pval < 1) {
83 this->o_ptr->pval = 1;
86 if (this->power < 0) {
87 set_bits(this->o_ptr->ident, IDENT_BROKEN);
88 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
89 this->o_ptr->pval = 0 - (this->o_ptr->pval);
96 this->o_ptr->pval = 1 + (PARAMETER_VALUE)m_bonus(5, this->level);
97 if (this->power < 0) {
98 set_bits(this->o_ptr->ident, IDENT_BROKEN);
99 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
100 this->o_ptr->pval = 0 - (this->o_ptr->pval);
105 this->o_ptr->pval = randint1(5) + (PARAMETER_VALUE)m_bonus(5, this->level);
106 while (randint0(100) < 50) {
110 if (this->power < 0) {
111 set_bits(this->o_ptr->ident, IDENT_BROKEN);
112 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
113 this->o_ptr->pval = 0 - (this->o_ptr->pval);
120 one_lordly_high_resistance(this->o_ptr);
121 } while (one_in_(4));
123 this->o_ptr->to_a = 10 + randint1(5) + (ARMOUR_CLASS)m_bonus(10, this->level);
125 case SV_RING_WARNING:
127 one_low_esp(this->o_ptr);
131 case SV_RING_SEARCHING:
132 this->o_ptr->pval = 1 + (PARAMETER_VALUE)m_bonus(5, this->level);
133 if (this->power < 0) {
134 set_bits(this->o_ptr->ident, IDENT_BROKEN);
135 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
136 this->o_ptr->pval = 0 - (this->o_ptr->pval);
144 this->o_ptr->to_a = 5 + randint1(5) + (ARMOUR_CLASS)m_bonus(10, this->level);
146 case SV_RING_WEAKNESS:
147 case SV_RING_STUPIDITY:
148 set_bits(this->o_ptr->ident, IDENT_BROKEN);
149 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
150 this->o_ptr->pval = 0 - (1 + (PARAMETER_VALUE)m_bonus(5, this->level));
151 if (this->power > 0) {
152 this->power = 0 - this->power;
157 set_bits(this->o_ptr->ident, IDENT_BROKEN);
158 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
159 this->o_ptr->to_a = 0 - (5 + (ARMOUR_CLASS)m_bonus(10, this->level));
160 this->o_ptr->pval = 0 - (1 + (PARAMETER_VALUE)m_bonus(5, this->level));
161 if (this->power > 0) {
162 this->power = 0 - this->power;
167 this->o_ptr->to_d = 1 + randint1(5) + (int)m_bonus(16, this->level);
168 if (this->power < 0) {
169 set_bits(this->o_ptr->ident, IDENT_BROKEN);
170 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
171 this->o_ptr->to_d = 0 - this->o_ptr->to_d;
175 case SV_RING_ACCURACY:
176 this->o_ptr->to_h = 1 + randint1(5) + (HIT_PROB)m_bonus(16, this->level);
177 if (this->power < 0) {
178 set_bits(this->o_ptr->ident, IDENT_BROKEN);
179 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
180 this->o_ptr->to_h = 0 - this->o_ptr->to_h;
184 case SV_RING_PROTECTION:
185 this->o_ptr->to_a = 5 + randint1(8) + (ARMOUR_CLASS)m_bonus(10, this->level);
186 if (this->power < 0) {
187 set_bits(this->o_ptr->ident, IDENT_BROKEN);
188 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
189 this->o_ptr->to_a = 0 - this->o_ptr->to_a;
193 case SV_RING_SLAYING:
194 this->o_ptr->to_d = randint1(5) + (int)m_bonus(12, this->level);
195 this->o_ptr->to_h = randint1(5) + (HIT_PROB)m_bonus(12, this->level);
197 if (this->power < 0) {
198 set_bits(this->o_ptr->ident, IDENT_BROKEN);
199 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
200 this->o_ptr->to_h = 0 - this->o_ptr->to_h;
201 this->o_ptr->to_d = 0 - this->o_ptr->to_d;
207 this->o_ptr->pval = 1 + (PARAMETER_VALUE)m_bonus(3, this->level);
212 if (this->power < 0) {
213 set_bits(this->o_ptr->ident, IDENT_BROKEN);
214 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
215 this->o_ptr->pval = 0 - this->o_ptr->pval;
219 case SV_RING_AGGRAVATION:
220 set_bits(this->o_ptr->ident, IDENT_BROKEN);
221 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
222 if (this->power > 0) {
223 this->power = 0 - this->power;
232 void RingEnchanter::give_ego_index()
234 while (!this->o_ptr->is_ego()) {
235 int tmp = m_bonus(10, this->level);
236 const auto &baseitem = this->o_ptr->get_baseitem();
237 switch (randint1(28)) {
240 this->o_ptr->ego_idx = EgoType::RING_THROW;
244 if (baseitem.flags.has(TR_REGEN)) {
248 this->o_ptr->ego_idx = EgoType::RING_REGEN;
252 if (baseitem.flags.has(TR_LITE_1)) {
256 this->o_ptr->ego_idx = EgoType::RING_LITE;
260 if (baseitem.flags.has(TR_TELEPORT)) {
264 this->o_ptr->ego_idx = EgoType::RING_TELEPORT;
268 if (this->o_ptr->to_h) {
272 this->o_ptr->ego_idx = EgoType::RING_TO_H;
276 if (this->o_ptr->to_d) {
280 this->o_ptr->ego_idx = EgoType::RING_TO_D;
283 if ((this->o_ptr->to_h) || (this->o_ptr->to_d)) {
287 this->o_ptr->ego_idx = EgoType::RING_SLAY;
290 if ((baseitem.flags.has(TR_STR)) || this->o_ptr->to_h || this->o_ptr->to_d) {
294 this->o_ptr->ego_idx = EgoType::RING_WIZARD;
297 if (baseitem.flags.has(TR_ACTIVATE)) {
301 this->o_ptr->ego_idx = EgoType::RING_HERO;
304 if (baseitem.flags.has(TR_ACTIVATE)) {
309 this->o_ptr->ego_idx = EgoType::RING_MANA_BALL;
314 this->o_ptr->ego_idx = EgoType::RING_MANA_BOLT;
318 this->o_ptr->ego_idx = EgoType::RING_MAGIC_MIS;
321 if (baseitem.flags.has(TR_ACTIVATE)) {
325 if (baseitem.flags.has_not(TR_RES_FIRE) && (baseitem.flags.has(TR_RES_COLD) || baseitem.flags.has(TR_RES_ELEC) || baseitem.flags.has(TR_RES_ACID))) {
330 this->o_ptr->ego_idx = EgoType::RING_DRAGON_F;
335 this->o_ptr->ego_idx = EgoType::RING_FIRE_BALL;
339 this->o_ptr->ego_idx = EgoType::RING_FIRE_BOLT;
342 if (baseitem.flags.has(TR_ACTIVATE)) {
346 if (baseitem.flags.has_not(TR_RES_COLD) && (baseitem.flags.has(TR_RES_FIRE) || baseitem.flags.has(TR_RES_ELEC) || baseitem.flags.has(TR_RES_ACID))) {
351 this->o_ptr->ego_idx = EgoType::RING_DRAGON_C;
356 this->o_ptr->ego_idx = EgoType::RING_COLD_BALL;
360 this->o_ptr->ego_idx = EgoType::RING_COLD_BOLT;
363 if (baseitem.flags.has(TR_ACTIVATE)) {
367 if (baseitem.flags.has_not(TR_RES_ELEC) && (baseitem.flags.has(TR_RES_COLD) || baseitem.flags.has(TR_RES_FIRE) || baseitem.flags.has(TR_RES_ACID))) {
372 this->o_ptr->ego_idx = EgoType::RING_ELEC_BALL;
376 this->o_ptr->ego_idx = EgoType::RING_ELEC_BOLT;
379 if (baseitem.flags.has(TR_ACTIVATE)) {
383 if (baseitem.flags.has_not(TR_RES_ACID) && (baseitem.flags.has(TR_RES_COLD) || baseitem.flags.has(TR_RES_ELEC) || baseitem.flags.has(TR_RES_FIRE))) {
388 this->o_ptr->ego_idx = EgoType::RING_ACID_BALL;
392 this->o_ptr->ego_idx = EgoType::RING_ACID_BOLT;
400 give_high_ego_index();
406 void RingEnchanter::give_high_ego_index()
408 const auto sval = this->o_ptr->bi_key.sval();
409 if (!sval.has_value()) {
413 switch (sval.value()) {
419 this->o_ptr->ego_idx = EgoType::RING_D_SPEED;
422 case SV_RING_ACCURACY:
423 case SV_RING_SLAYING:
429 this->o_ptr->ego_idx = EgoType::RING_HERO;
433 this->o_ptr->ego_idx = EgoType::RING_BERSERKER;
434 this->o_ptr->to_h -= 2 + randint1(4);
435 this->o_ptr->to_d += 2 + randint1(4);
437 case SV_RING_PROTECTION:
438 this->o_ptr->ego_idx = EgoType::RING_SUPER_AC;
439 this->o_ptr->to_a += 7 + m_bonus(5, this->level);
441 case SV_RING_RES_FEAR:
442 this->o_ptr->ego_idx = EgoType::RING_HERO;
449 this->o_ptr->ego_idx = EgoType::RING_HUNTER;
451 case SV_RING_SEARCHING:
452 this->o_ptr->ego_idx = EgoType::RING_STEALTH;
454 case SV_RING_TELEPORTATION:
455 this->o_ptr->ego_idx = EgoType::RING_TELE_AWAY;
457 case SV_RING_RES_BLINDNESS:
458 this->o_ptr->ego_idx = one_in_(2) ? EgoType::RING_RES_LITE : EgoType::RING_RES_DARK;
465 one_lordly_high_resistance(this->o_ptr);
466 one_lordly_high_resistance(this->o_ptr);
467 this->o_ptr->ego_idx = EgoType::RING_TRUE;
474 this->o_ptr->ego_idx = EgoType::RING_DRAGON_F;
481 this->o_ptr->ego_idx = EgoType::RING_DRAGON_C;
483 case SV_RING_WARNING:
488 this->o_ptr->ego_idx = EgoType::RING_M_DETECT;
495 void RingEnchanter::give_cursed()
497 if (this->o_ptr->to_h > 0) {
498 this->o_ptr->to_h = 0 - this->o_ptr->to_h;
501 if (this->o_ptr->to_d > 0) {
502 this->o_ptr->to_d = 0 - this->o_ptr->to_d;
505 if (this->o_ptr->to_a > 0) {
506 this->o_ptr->to_a = 0 - this->o_ptr->to_a;
509 if (this->o_ptr->pval > 0) {
510 this->o_ptr->pval = 0 - this->o_ptr->pval;
513 while (!this->o_ptr->is_ego()) {
514 const auto &baseitem = this->o_ptr->get_baseitem();
515 switch (randint1(5)) {
517 if (baseitem.flags.has(TR_DRAIN_EXP)) {
520 this->o_ptr->ego_idx = EgoType::RING_DRAIN_EXP;
523 this->o_ptr->ego_idx = EgoType::RING_NO_MELEE;
526 if (baseitem.flags.has(TR_AGGRAVATE)) {
529 this->o_ptr->ego_idx = EgoType::RING_AGGRAVATE;
532 if (baseitem.flags.has(TR_TY_CURSE)) {
535 this->o_ptr->ego_idx = EgoType::RING_TY_CURSE;
538 this->o_ptr->ego_idx = EgoType::RING_ALBINO;
543 set_bits(this->o_ptr->ident, IDENT_BROKEN);
544 this->o_ptr->curse_flags.set({ CurseTraitType::CURSED, CurseTraitType::HEAVY_CURSE });