1 #include "object-enchant/object-boost.h"
2 #include "artifact/random-art-effects.h"
3 #include "object-enchant/tr-types.h"
4 #include "object/object-kind.h"
5 #include "player-ability/player-ability-types.h"
6 #include "system/floor-type-definition.h"
7 #include "system/object-type-definition.h"
8 #include "util/bit-flags-calculator.h"
11 * @brief 上質以上のオブジェクトに与えるための各種ボーナスを正規乱数も加えて算出する。
12 * Help determine an "enchantment bonus" for an object.
14 * @param level ボーナス値に加味する基準生成階
17 * To avoid floating point but still provide a smooth distribution of bonuses,\n
18 * we simply round the results of division in such a way as to "average" the\n
19 * correct floating point value.\n
21 * This function has been changed. It uses "randnor()" to choose values from\n
22 * a normal distribution, whose mean moves from zero towards the max as the\n
23 * level increases, and whose standard deviation is equal to 1/4 of the max,\n
24 * and whose values are forced to lie between zero and the max, inclusive.\n
26 * Since the "level" rarely passes 100 before Morgoth is dead, it is very\n
27 * rare to get the "full" enchantment on an object, even a deep levels.\n
29 * It is always possible (albeit unlikely) to get the "full" enchantment.\n
31 * A sample distribution of values from "m_bonus(10, N)" is shown below:\n
33 * N 0 1 2 3 4 5 6 7 8 9 10\n
34 * --- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----\n
35 * 0 66.37 13.01 9.73 5.47 2.89 1.31 0.72 0.26 0.12 0.09 0.03\n
36 * 8 46.85 24.66 12.13 8.13 4.20 2.30 1.05 0.36 0.19 0.08 0.05\n
37 * 16 30.12 27.62 18.52 10.52 6.34 3.52 1.95 0.90 0.31 0.15 0.05\n
38 * 24 22.44 15.62 30.14 12.92 8.55 5.30 2.39 1.63 0.62 0.28 0.11\n
39 * 32 16.23 11.43 23.01 22.31 11.19 7.18 4.46 2.13 1.20 0.45 0.41\n
40 * 40 10.76 8.91 12.80 29.51 16.00 9.69 5.90 3.43 1.47 0.88 0.65\n
41 * 48 7.28 6.81 10.51 18.27 27.57 11.76 7.85 4.99 2.80 1.22 0.94\n
42 * 56 4.41 4.73 8.52 11.96 24.94 19.78 11.06 7.18 3.68 1.96 1.78\n
43 * 64 2.81 3.07 5.65 9.17 13.01 31.57 13.70 9.30 6.04 3.04 2.64\n
44 * 72 1.87 1.99 3.68 7.15 10.56 20.24 25.78 12.17 7.52 4.42 4.62\n
45 * 80 1.02 1.23 2.78 4.75 8.37 12.04 27.61 18.07 10.28 6.52 7.33\n
46 * 88 0.70 0.57 1.56 3.12 6.34 10.06 15.76 30.46 12.58 8.47 10.38\n
47 * 96 0.27 0.60 1.25 2.28 4.30 7.60 10.77 22.52 22.51 11.37 16.53\n
48 * 104 0.22 0.42 0.77 1.36 2.62 5.33 8.93 13.05 29.54 15.23 22.53\n
49 * 112 0.15 0.20 0.56 0.87 2.00 3.83 6.86 10.06 17.89 27.31 30.27\n
50 * 120 0.03 0.11 0.31 0.46 1.31 2.48 4.60 7.78 11.67 25.53 45.72\n
51 * 128 0.02 0.01 0.13 0.33 0.83 1.41 3.24 6.17 9.57 14.22 64.07\n
53 int m_bonus(int max, DEPTH level)
55 int bonus, stand, extra, value;
57 /* Paranoia -- enforce maximal "level" */
58 if (level > MAX_DEPTH - 1)
59 level = MAX_DEPTH - 1;
61 /* The "bonus" moves towards the max */
62 bonus = ((max * level) / MAX_DEPTH);
64 /* Hack -- determine fraction of error */
65 extra = ((max * level) % MAX_DEPTH);
67 /* Hack -- simulate floating point computations */
68 if (randint0(MAX_DEPTH) < extra)
71 /* The "stand" is equal to one quarter of the max */
74 /* Hack -- determine fraction of error */
77 /* Hack -- simulate floating point computations */
78 if (randint0(4) < extra)
81 /* Choose an "interesting" value */
82 value = randnor(bonus, stand);
84 /* Enforce the minimum value */
88 /* Enforce the maximum value */
95 * @brief 対象のオブジェクトにランダムな能力維持を一つ付加する。/ Choose one random sustain
97 * @param o_ptr 対象のオブジェクト構造体ポインタ
100 void one_sustain(object_type *o_ptr)
102 switch (randint0(A_MAX)) {
104 add_flag(o_ptr->art_flags, TR_SUST_STR);
107 add_flag(o_ptr->art_flags, TR_SUST_INT);
110 add_flag(o_ptr->art_flags, TR_SUST_WIS);
113 add_flag(o_ptr->art_flags, TR_SUST_DEX);
116 add_flag(o_ptr->art_flags, TR_SUST_CON);
119 add_flag(o_ptr->art_flags, TR_SUST_CHR);
125 * @brief オブジェクトにランダムな強いESPを与える
126 * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
127 * @return TR_ESP_NONLIVINGがついたならばTRUE
129 bool add_esp_strong(object_type *o_ptr)
133 switch (randint1(3)) {
135 add_flag(o_ptr->art_flags, TR_ESP_EVIL);
138 add_flag(o_ptr->art_flags, TR_TELEPATHY);
141 add_flag(o_ptr->art_flags, TR_ESP_NONLIVING);
150 * @brief オブジェクトにランダムな弱いESPを与える
151 * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
152 * @param extra TRUEならばESPの最大付与数が増える(TRUE -> 3+1d6 / FALSE -> 1d3)
155 void add_esp_weak(object_type *o_ptr, bool extra)
158 u32b weak_esp_list[] = {
170 const int MAX_ESP_WEAK = sizeof(weak_esp_list) / sizeof(weak_esp_list[0]);
171 const int add_count = MIN(MAX_ESP_WEAK, (extra) ? (3 + randint1(randint1(6))) : randint1(3));
173 /* Add unduplicated weak esp flags randomly */
174 for (i = 0; i < add_count; ++i) {
175 int choice = rand_range(i, MAX_ESP_WEAK - 1);
177 add_flag(o_ptr->art_flags, weak_esp_list[choice]);
178 weak_esp_list[choice] = weak_esp_list[i];
183 * @brief 高級なテレパシー群を付ける
184 * @param o_ptr 対象のオブジェクト構造体ポインタ
188 * ESPまたは邪ESPは1d3の種族ESPを得る。
189 * 無ESPは3+1d6の種族ESPを得る。
191 void add_high_telepathy(object_type* o_ptr)
193 if (add_esp_strong(o_ptr))
194 add_esp_weak(o_ptr, TRUE);
196 add_esp_weak(o_ptr, FALSE);
201 * @param o_ptr 対象のオブジェクト構造体ポインタ
205 * ESP、邪ESP、無ESPまたは1d3の種族ESP。
207 void add_low_telepathy(object_type *o_ptr)
210 add_esp_strong(o_ptr);
212 add_esp_weak(o_ptr, FALSE);
216 * @brief 対象のオブジェクトに元素耐性を一つ付加する。/ Choose one random element resistance
217 * @details 候補は火炎、冷気、電撃、酸のいずれかであり、重複の抑止はない。
218 * @param o_ptr 対象のオブジェクト構造体ポインタ
221 void one_ele_resistance(object_type *o_ptr)
223 switch (randint0(4)) {
225 add_flag(o_ptr->art_flags, TR_RES_ACID);
228 add_flag(o_ptr->art_flags, TR_RES_ELEC);
231 add_flag(o_ptr->art_flags, TR_RES_COLD);
234 add_flag(o_ptr->art_flags, TR_RES_FIRE);
240 * @brief 対象のオブジェクトにドラゴン装備向け元素耐性を一つ付加する。/ Choose one random element or poison resistance
241 * @details 候補は1/7の確率で毒、6/7の確率で火炎、冷気、電撃、酸のいずれか(one_ele_resistance()のコール)であり、重複の抑止はない。
242 * @param o_ptr 対象のオブジェクト構造体ポインタ
245 void one_dragon_ele_resistance(object_type *o_ptr)
248 add_flag(o_ptr->art_flags, TR_RES_POIS);
250 one_ele_resistance(o_ptr);
255 * @brief 対象のオブジェクトにランダムな上位耐性を一つ付加する。/ Choose one random high resistance
256 * @details 重複の抑止はない。候補は毒、閃光、暗黒、破片、盲目、混乱、地獄、因果混乱、カオス、劣化、恐怖のいずれか。
257 * @param o_ptr 対象のオブジェクト構造体ポインタ
260 void one_high_resistance(object_type *o_ptr)
262 switch (randint0(12)) {
264 add_flag(o_ptr->art_flags, TR_RES_POIS);
267 add_flag(o_ptr->art_flags, TR_RES_LITE);
270 add_flag(o_ptr->art_flags, TR_RES_DARK);
273 add_flag(o_ptr->art_flags, TR_RES_SHARDS);
276 add_flag(o_ptr->art_flags, TR_RES_BLIND);
279 add_flag(o_ptr->art_flags, TR_RES_CONF);
282 add_flag(o_ptr->art_flags, TR_RES_SOUND);
285 add_flag(o_ptr->art_flags, TR_RES_NETHER);
288 add_flag(o_ptr->art_flags, TR_RES_NEXUS);
291 add_flag(o_ptr->art_flags, TR_RES_CHAOS);
294 add_flag(o_ptr->art_flags, TR_RES_DISEN);
297 add_flag(o_ptr->art_flags, TR_RES_FEAR);
303 * @brief ドラゴン装備にランダムな耐性を与える
304 * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
307 void dragon_resist(object_type *o_ptr)
311 one_dragon_ele_resistance(o_ptr);
313 one_high_resistance(o_ptr);
314 } while (one_in_(2));
318 * @brief 対象のオブジェクトに耐性を一つ付加する。/ Choose one random resistance
319 * @details 1/3で元素耐性(one_ele_resistance())、2/3で上位耐性(one_high_resistance)
321 * @param o_ptr 対象のオブジェクト構造体ポインタ
324 void one_resistance(object_type *o_ptr)
327 one_ele_resistance(o_ptr);
329 one_high_resistance(o_ptr);
334 * @brief 対象のオブジェクトに能力を一つ付加する。/ Choose one random ability
335 * @details 候補は浮遊、永久光源+1、透明視、警告、遅消化、急回復、麻痺知らず、経験値維持のいずれか。
337 * @param o_ptr 対象のオブジェクト構造体ポインタ
340 void one_ability(object_type *o_ptr)
342 switch (randint0(10)) {
344 add_flag(o_ptr->art_flags, TR_LEVITATION);
347 add_flag(o_ptr->art_flags, TR_LITE_1);
350 add_flag(o_ptr->art_flags, TR_SEE_INVIS);
353 add_flag(o_ptr->art_flags, TR_WARNING);
356 add_flag(o_ptr->art_flags, TR_SLOW_DIGEST);
359 add_flag(o_ptr->art_flags, TR_REGEN);
362 add_flag(o_ptr->art_flags, TR_FREE_ACT);
365 add_flag(o_ptr->art_flags, TR_HOLD_EXP);
375 * @brief 対象のオブジェクトに弱いESPを一つ付加する。/ Choose one lower rank esp
376 * @details 候補は動物、アンデッド、悪魔、オーク、トロル、巨人、
377 * ドラゴン、人間、善良、ユニークESPのいずれかであり、重複の抑止はない。
378 * @param o_ptr 対象のオブジェクト構造体ポインタ
381 void one_low_esp(object_type *o_ptr)
383 switch (randint1(10)) {
385 add_flag(o_ptr->art_flags, TR_ESP_ANIMAL);
388 add_flag(o_ptr->art_flags, TR_ESP_UNDEAD);
391 add_flag(o_ptr->art_flags, TR_ESP_DEMON);
394 add_flag(o_ptr->art_flags, TR_ESP_ORC);
397 add_flag(o_ptr->art_flags, TR_ESP_TROLL);
400 add_flag(o_ptr->art_flags, TR_ESP_GIANT);
403 add_flag(o_ptr->art_flags, TR_ESP_DRAGON);
406 add_flag(o_ptr->art_flags, TR_ESP_HUMAN);
409 add_flag(o_ptr->art_flags, TR_ESP_GOOD);
412 add_flag(o_ptr->art_flags, TR_ESP_UNIQUE);
418 * @brief 対象のオブジェクトに発動を一つ付加する。/ Choose one random activation
419 * @details 候補多数。ランダムアーティファクトのバイアスには一切依存せず、
420 * whileループによる構造で能力的に強力なものほど確率を落としている。
421 * @param o_ptr 対象のオブジェクト構造体ポインタ
424 void one_activation(object_type *o_ptr)
427 PERCENTAGE chance = 0;
428 while (randint1(100) >= chance) {
429 type = randint1(ACT_MAX);
443 case ACT_CURE_POISON:
454 case ACT_HYPODYNAMIA_1:
469 case ACT_HYPODYNAMIA_2:
481 case ACT_CHARM_ANIMAL:
484 case ACT_SUMMON_ANIMAL:
491 case ACT_BANISH_EVIL:
494 case ACT_CHARM_UNDEAD:
495 case ACT_CHARM_OTHER:
496 case ACT_SUMMON_PHANTOM:
503 case ACT_CHARM_ANIMALS:
504 case ACT_CHARM_OTHERS:
505 case ACT_SUMMON_ELEMENTAL:
514 case ACT_DETECT_XTRA:
518 case ACT_TREE_CREATION:
519 case ACT_SUMMON_DEMON:
520 case ACT_SUMMON_UNDEAD:
531 o_ptr->xtra2 = (byte)type;
532 add_flag(o_ptr->art_flags, TR_ACTIVATE);
537 * @brief 対象のオブジェクトに王者の指輪向けの上位耐性を一つ付加する。/ Choose one random high resistance
538 * @details 候補は閃光、暗黒、破片、盲目、混乱、地獄、因果混乱、カオス、恐怖であり
539 * 王者の指輪にあらかじめついている耐性をone_high_resistance()から除外したものである。
540 * ランダム付加そのものに重複の抑止はない。
541 * @param o_ptr 対象のオブジェクト構造体ポインタ
544 void one_lordly_high_resistance(object_type *o_ptr)
546 switch (randint0(12)) {
548 add_flag(o_ptr->art_flags, TR_RES_LITE);
551 add_flag(o_ptr->art_flags, TR_RES_DARK);
554 add_flag(o_ptr->art_flags, TR_RES_SHARDS);
557 add_flag(o_ptr->art_flags, TR_RES_BLIND);
560 add_flag(o_ptr->art_flags, TR_RES_CONF);
563 add_flag(o_ptr->art_flags, TR_RES_SOUND);
566 add_flag(o_ptr->art_flags, TR_RES_NETHER);
569 add_flag(o_ptr->art_flags, TR_RES_NEXUS);
572 add_flag(o_ptr->art_flags, TR_RES_CHAOS);
575 add_flag(o_ptr->art_flags, TR_RES_FEAR);
578 add_flag(o_ptr->art_flags, TR_RES_TIME);
581 add_flag(o_ptr->art_flags, TR_RES_WATER);
587 * @brief オブジェクトの重量を軽くする
588 * @param o_ptr オブジェクト情報への参照ポインタ
591 void make_weight_ligten(object_type* o_ptr)
593 o_ptr->weight = (2 * k_info[o_ptr->k_idx].weight / 3);
597 * @brief オブジェクトの重量を重くする
598 * @param o_ptr オブジェクト情報への参照ポインタ
601 void make_weight_heavy(object_type *o_ptr)
603 o_ptr->weight = (4 * k_info[o_ptr->k_idx].weight / 3);
607 * @brief オブジェクトのベースACを増やす
608 * @param o_ptr オブジェクト情報への参照ポインタ
613 void add_xtra_ac(object_type *o_ptr)
615 o_ptr->ac += MAX(5, o_ptr->ac / 4);