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 "object/object-kind.h"
14 #include "sv-definition/sv-ring-types.h"
15 #include "system/object-type-definition.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, ObjectType *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 switch (this->o_ptr->sval) {
72 this->o_ptr->pval = (PARAMETER_VALUE)m_bonus(2, this->level);
77 if (this->o_ptr->pval < 1) {
78 this->o_ptr->pval = 1;
81 if (this->power < 0) {
82 set_bits(this->o_ptr->ident, IDENT_BROKEN);
83 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
84 this->o_ptr->pval = 0 - (this->o_ptr->pval);
91 this->o_ptr->pval = 1 + (PARAMETER_VALUE)m_bonus(5, this->level);
92 if (this->power < 0) {
93 set_bits(this->o_ptr->ident, IDENT_BROKEN);
94 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
95 this->o_ptr->pval = 0 - (this->o_ptr->pval);
100 this->o_ptr->pval = randint1(5) + (PARAMETER_VALUE)m_bonus(5, this->level);
101 while (randint0(100) < 50) {
105 if (this->power < 0) {
106 set_bits(this->o_ptr->ident, IDENT_BROKEN);
107 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
108 this->o_ptr->pval = 0 - (this->o_ptr->pval);
115 one_lordly_high_resistance(this->o_ptr);
116 } while (one_in_(4));
118 this->o_ptr->to_a = 10 + randint1(5) + (ARMOUR_CLASS)m_bonus(10, this->level);
120 case SV_RING_WARNING:
122 one_low_esp(this->o_ptr);
126 case SV_RING_SEARCHING:
127 this->o_ptr->pval = 1 + (PARAMETER_VALUE)m_bonus(5, this->level);
128 if (this->power < 0) {
129 set_bits(this->o_ptr->ident, IDENT_BROKEN);
130 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
131 this->o_ptr->pval = 0 - (this->o_ptr->pval);
139 this->o_ptr->to_a = 5 + randint1(5) + (ARMOUR_CLASS)m_bonus(10, this->level);
141 case SV_RING_WEAKNESS:
142 case SV_RING_STUPIDITY:
143 set_bits(this->o_ptr->ident, IDENT_BROKEN);
144 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
145 this->o_ptr->pval = 0 - (1 + (PARAMETER_VALUE)m_bonus(5, this->level));
146 if (this->power > 0) {
147 this->power = 0 - this->power;
152 set_bits(this->o_ptr->ident, IDENT_BROKEN);
153 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
154 this->o_ptr->to_a = 0 - (5 + (ARMOUR_CLASS)m_bonus(10, this->level));
155 this->o_ptr->pval = 0 - (1 + (PARAMETER_VALUE)m_bonus(5, this->level));
156 if (this->power > 0) {
157 this->power = 0 - this->power;
162 this->o_ptr->to_d = 1 + randint1(5) + (HIT_POINT)m_bonus(16, this->level);
163 if (this->power < 0) {
164 set_bits(this->o_ptr->ident, IDENT_BROKEN);
165 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
166 this->o_ptr->to_d = 0 - this->o_ptr->to_d;
170 case SV_RING_ACCURACY:
171 this->o_ptr->to_h = 1 + randint1(5) + (HIT_PROB)m_bonus(16, this->level);
172 if (this->power < 0) {
173 set_bits(this->o_ptr->ident, IDENT_BROKEN);
174 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
175 this->o_ptr->to_h = 0 - this->o_ptr->to_h;
179 case SV_RING_PROTECTION:
180 this->o_ptr->to_a = 5 + randint1(8) + (ARMOUR_CLASS)m_bonus(10, this->level);
181 if (this->power < 0) {
182 set_bits(this->o_ptr->ident, IDENT_BROKEN);
183 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
184 this->o_ptr->to_a = 0 - this->o_ptr->to_a;
188 case SV_RING_SLAYING:
189 this->o_ptr->to_d = randint1(5) + (HIT_POINT)m_bonus(12, this->level);
190 this->o_ptr->to_h = randint1(5) + (HIT_PROB)m_bonus(12, this->level);
192 if (this->power < 0) {
193 set_bits(this->o_ptr->ident, IDENT_BROKEN);
194 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
195 this->o_ptr->to_h = 0 - this->o_ptr->to_h;
196 this->o_ptr->to_d = 0 - this->o_ptr->to_d;
202 this->o_ptr->pval = 1 + (PARAMETER_VALUE)m_bonus(3, this->level);
207 if (this->power < 0) {
208 set_bits(this->o_ptr->ident, IDENT_BROKEN);
209 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
210 this->o_ptr->pval = 0 - this->o_ptr->pval;
214 case SV_RING_AGGRAVATION:
215 set_bits(this->o_ptr->ident, IDENT_BROKEN);
216 this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
217 if (this->power > 0) {
218 this->power = 0 - this->power;
227 void RingEnchanter::give_ego_index()
229 while (!this->o_ptr->name2) {
230 int tmp = m_bonus(10, this->level);
231 auto *k_ptr = &k_info[this->o_ptr->k_idx];
232 switch (randint1(28)) {
235 this->o_ptr->name2 = EGO_RING_THROW;
239 if (k_ptr->flags.has(TR_REGEN)) {
243 this->o_ptr->name2 = EGO_RING_REGEN;
247 if (k_ptr->flags.has(TR_LITE_1)) {
251 this->o_ptr->name2 = EGO_RING_LITE;
255 if (k_ptr->flags.has(TR_TELEPORT)) {
259 this->o_ptr->name2 = EGO_RING_TELEPORT;
263 if (this->o_ptr->to_h) {
267 this->o_ptr->name2 = EGO_RING_TO_H;
271 if (this->o_ptr->to_d) {
275 this->o_ptr->name2 = EGO_RING_TO_D;
278 if ((this->o_ptr->to_h) || (this->o_ptr->to_d)) {
282 this->o_ptr->name2 = EGO_RING_SLAY;
285 if ((k_ptr->flags.has(TR_STR)) || this->o_ptr->to_h || this->o_ptr->to_d) {
289 this->o_ptr->name2 = EGO_RING_WIZARD;
292 if (k_ptr->flags.has(TR_ACTIVATE)) {
296 this->o_ptr->name2 = EGO_RING_HERO;
299 if (k_ptr->flags.has(TR_ACTIVATE)) {
304 this->o_ptr->name2 = EGO_RING_MANA_BALL;
309 this->o_ptr->name2 = EGO_RING_MANA_BOLT;
313 this->o_ptr->name2 = EGO_RING_MAGIC_MIS;
316 if (k_ptr->flags.has(TR_ACTIVATE)) {
320 if (k_ptr->flags.has_not(TR_RES_FIRE) && (k_ptr->flags.has(TR_RES_COLD) || k_ptr->flags.has(TR_RES_ELEC) || k_ptr->flags.has(TR_RES_ACID))) {
325 this->o_ptr->name2 = EGO_RING_DRAGON_F;
330 this->o_ptr->name2 = EGO_RING_FIRE_BALL;
334 this->o_ptr->name2 = EGO_RING_FIRE_BOLT;
337 if (k_ptr->flags.has(TR_ACTIVATE)) {
341 if (k_ptr->flags.has_not(TR_RES_COLD) && (k_ptr->flags.has(TR_RES_FIRE) || k_ptr->flags.has(TR_RES_ELEC) || k_ptr->flags.has(TR_RES_ACID))) {
346 this->o_ptr->name2 = EGO_RING_DRAGON_C;
351 this->o_ptr->name2 = EGO_RING_COLD_BALL;
355 this->o_ptr->name2 = EGO_RING_COLD_BOLT;
358 if (k_ptr->flags.has(TR_ACTIVATE)) {
362 if (k_ptr->flags.has_not(TR_RES_ELEC) && (k_ptr->flags.has(TR_RES_COLD) || k_ptr->flags.has(TR_RES_FIRE) || k_ptr->flags.has(TR_RES_ACID))) {
367 this->o_ptr->name2 = EGO_RING_ELEC_BALL;
371 this->o_ptr->name2 = EGO_RING_ELEC_BOLT;
374 if (k_ptr->flags.has(TR_ACTIVATE)) {
378 if (k_ptr->flags.has_not(TR_RES_ACID) && (k_ptr->flags.has(TR_RES_COLD) || k_ptr->flags.has(TR_RES_ELEC) || k_ptr->flags.has(TR_RES_FIRE))) {
383 this->o_ptr->name2 = EGO_RING_ACID_BALL;
387 this->o_ptr->name2 = EGO_RING_ACID_BOLT;
395 give_high_ego_index();
401 void RingEnchanter::give_high_ego_index()
403 switch (this->o_ptr->sval) {
409 this->o_ptr->name2 = EGO_RING_D_SPEED;
412 case SV_RING_ACCURACY:
413 case SV_RING_SLAYING:
419 this->o_ptr->name2 = EGO_RING_HERO;
423 this->o_ptr->name2 = EGO_RING_BERSERKER;
424 this->o_ptr->to_h -= 2 + randint1(4);
425 this->o_ptr->to_d += 2 + randint1(4);
427 case SV_RING_PROTECTION:
428 this->o_ptr->name2 = EGO_RING_SUPER_AC;
429 this->o_ptr->to_a += 7 + m_bonus(5, this->level);
431 case SV_RING_RES_FEAR:
432 this->o_ptr->name2 = EGO_RING_HERO;
439 this->o_ptr->name2 = EGO_RING_HUNTER;
441 case SV_RING_SEARCHING:
442 this->o_ptr->name2 = EGO_RING_STEALTH;
444 case SV_RING_TELEPORTATION:
445 this->o_ptr->name2 = EGO_RING_TELE_AWAY;
447 case SV_RING_RES_BLINDNESS:
448 this->o_ptr->name2 = one_in_(2) ? EGO_RING_RES_LITE : EGO_RING_RES_DARK;
455 one_lordly_high_resistance(this->o_ptr);
456 one_lordly_high_resistance(this->o_ptr);
457 this->o_ptr->name2 = EGO_RING_TRUE;
464 this->o_ptr->name2 = EGO_RING_DRAGON_F;
471 this->o_ptr->name2 = EGO_RING_DRAGON_C;
473 case SV_RING_WARNING:
478 this->o_ptr->name2 = EGO_RING_M_DETECT;
485 void RingEnchanter::give_cursed()
487 if (this->o_ptr->to_h > 0) {
488 this->o_ptr->to_h = 0 - this->o_ptr->to_h;
491 if (this->o_ptr->to_d > 0) {
492 this->o_ptr->to_d = 0 - this->o_ptr->to_d;
495 if (this->o_ptr->to_a > 0) {
496 this->o_ptr->to_a = 0 - this->o_ptr->to_a;
499 if (this->o_ptr->pval > 0) {
500 this->o_ptr->pval = 0 - this->o_ptr->pval;
503 while (!this->o_ptr->name2) {
504 auto *k_ptr = &k_info[this->o_ptr->k_idx];
505 switch (randint1(5)) {
507 if (k_ptr->flags.has(TR_DRAIN_EXP))
509 this->o_ptr->name2 = EGO_RING_DRAIN_EXP;
512 this->o_ptr->name2 = EGO_RING_NO_MELEE;
515 if (k_ptr->flags.has(TR_AGGRAVATE))
517 this->o_ptr->name2 = EGO_RING_AGGRAVATE;
520 if (k_ptr->flags.has(TR_TY_CURSE))
522 this->o_ptr->name2 = EGO_RING_TY_CURSE;
525 this->o_ptr->name2 = EGO_RING_ALBINO;
530 set_bits(this->o_ptr->ident, IDENT_BROKEN);
531 this->o_ptr->curse_flags.set({ CurseTraitType::CURSED, CurseTraitType::HEAVY_CURSE });