OSDN Git Service

[Refactor] #37353 one_high_resistance(), one_ele_resistance(), one_dragon_ele_resista...
[hengband/hengband.git] / src / object-boost.c
1 #include "angband.h"
2 #include "object-boost.h"
3
4 /*!
5  * @brief 上質以上のオブジェクトに与えるための各種ボーナスを正規乱数も加えて算出する。
6  * Help determine an "enchantment bonus" for an object.
7  * @param max ボーナス値の限度
8  * @param level ボーナス値に加味する基準生成階
9  * @return 算出されたボーナス値
10  * @details
11  * To avoid floating point but still provide a smooth distribution of bonuses,\n
12  * we simply round the results of division in such a way as to "average" the\n
13  * correct floating point value.\n
14  *\n
15  * This function has been changed.  It uses "randnor()" to choose values from\n
16  * a normal distribution, whose mean moves from zero towards the max as the\n
17  * level increases, and whose standard deviation is equal to 1/4 of the max,\n
18  * and whose values are forced to lie between zero and the max, inclusive.\n
19  *\n
20  * Since the "level" rarely passes 100 before Morgoth is dead, it is very\n
21  * rare to get the "full" enchantment on an object, even a deep levels.\n
22  *\n
23  * It is always possible (albeit unlikely) to get the "full" enchantment.\n
24  *\n
25  * A sample distribution of values from "m_bonus(10, N)" is shown below:\n
26  *\n
27  *   N       0     1     2     3     4     5     6     7     8     9    10\n
28  * ---    ----  ----  ----  ----  ----  ----  ----  ----  ----  ----  ----\n
29  *   0   66.37 13.01  9.73  5.47  2.89  1.31  0.72  0.26  0.12  0.09  0.03\n
30  *   8   46.85 24.66 12.13  8.13  4.20  2.30  1.05  0.36  0.19  0.08  0.05\n
31  *  16   30.12 27.62 18.52 10.52  6.34  3.52  1.95  0.90  0.31  0.15  0.05\n
32  *  24   22.44 15.62 30.14 12.92  8.55  5.30  2.39  1.63  0.62  0.28  0.11\n
33  *  32   16.23 11.43 23.01 22.31 11.19  7.18  4.46  2.13  1.20  0.45  0.41\n
34  *  40   10.76  8.91 12.80 29.51 16.00  9.69  5.90  3.43  1.47  0.88  0.65\n
35  *  48    7.28  6.81 10.51 18.27 27.57 11.76  7.85  4.99  2.80  1.22  0.94\n
36  *  56    4.41  4.73  8.52 11.96 24.94 19.78 11.06  7.18  3.68  1.96  1.78\n
37  *  64    2.81  3.07  5.65  9.17 13.01 31.57 13.70  9.30  6.04  3.04  2.64\n
38  *  72    1.87  1.99  3.68  7.15 10.56 20.24 25.78 12.17  7.52  4.42  4.62\n
39  *  80    1.02  1.23  2.78  4.75  8.37 12.04 27.61 18.07 10.28  6.52  7.33\n
40  *  88    0.70  0.57  1.56  3.12  6.34 10.06 15.76 30.46 12.58  8.47 10.38\n
41  *  96    0.27  0.60  1.25  2.28  4.30  7.60 10.77 22.52 22.51 11.37 16.53\n
42  * 104    0.22  0.42  0.77  1.36  2.62  5.33  8.93 13.05 29.54 15.23 22.53\n
43  * 112    0.15  0.20  0.56  0.87  2.00  3.83  6.86 10.06 17.89 27.31 30.27\n
44  * 120    0.03  0.11  0.31  0.46  1.31  2.48  4.60  7.78 11.67 25.53 45.72\n
45  * 128    0.02  0.01  0.13  0.33  0.83  1.41  3.24  6.17  9.57 14.22 64.07\n
46  */
47 int m_bonus(int max, DEPTH level)
48 {
49         int bonus, stand, extra, value;
50
51
52         /* Paranoia -- enforce maximal "level" */
53         if (level > MAX_DEPTH - 1) level = MAX_DEPTH - 1;
54
55
56         /* The "bonus" moves towards the max */
57         bonus = ((max * level) / MAX_DEPTH);
58
59         /* Hack -- determine fraction of error */
60         extra = ((max * level) % MAX_DEPTH);
61
62         /* Hack -- simulate floating point computations */
63         if (randint0(MAX_DEPTH) < extra) bonus++;
64
65
66         /* The "stand" is equal to one quarter of the max */
67         stand = (max / 4);
68
69         /* Hack -- determine fraction of error */
70         extra = (max % 4);
71
72         /* Hack -- simulate floating point computations */
73         if (randint0(4) < extra) stand++;
74
75
76         /* Choose an "interesting" value */
77         value = randnor(bonus, stand);
78
79         /* Enforce the minimum value */
80         if (value < 0) return (0);
81
82         /* Enforce the maximum value */
83         if (value > max) return (max);
84         return (value);
85 }
86
87 /*!
88  * @brief 対象のオブジェクトにランダムな能力維持を一つ付加する。/ Choose one random sustain
89  * @details 重複の抑止はない。
90  * @param o_ptr 対象のオブジェクト構造体ポインタ
91  * @return なし
92  */
93 void one_sustain(object_type *o_ptr)
94 {
95         switch (randint0(A_MAX))
96         {
97         case 0: add_flag(o_ptr->art_flags, TR_SUST_STR); break;
98         case 1: add_flag(o_ptr->art_flags, TR_SUST_INT); break;
99         case 2: add_flag(o_ptr->art_flags, TR_SUST_WIS); break;
100         case 3: add_flag(o_ptr->art_flags, TR_SUST_DEX); break;
101         case 4: add_flag(o_ptr->art_flags, TR_SUST_CON); break;
102         case 5: add_flag(o_ptr->art_flags, TR_SUST_CHR); break;
103         }
104 }
105
106 /*!
107  * @brief オブジェクトにランダムな強いESPを与える
108  * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
109  * @return TR_ESP_NONLIVINGがついたならばTRUE
110  */
111 bool add_esp_strong(object_type *o_ptr)
112 {
113         bool nonliv = FALSE;
114
115         switch (randint1(3))
116         {
117         case 1: add_flag(o_ptr->art_flags, TR_ESP_EVIL); break;
118         case 2: add_flag(o_ptr->art_flags, TR_TELEPATHY); break;
119         case 3: add_flag(o_ptr->art_flags, TR_ESP_NONLIVING); nonliv = TRUE; break;
120         }
121
122         return nonliv;
123 }
124
125 /*!
126  * @brief オブジェクトにランダムな弱いESPを与える
127  * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
128  * @param extra TRUEならばESPの最大付与数が増える(TRUE -> 3+1d6 / FALSE -> 1d3)
129  * @return なし
130  */
131 void add_esp_weak(object_type *o_ptr, bool extra)
132 {
133         int i;
134         u32b weak_esp_list[] = {
135                 TR_ESP_ANIMAL,
136                 TR_ESP_UNDEAD,
137                 TR_ESP_DEMON,
138                 TR_ESP_ORC,
139                 TR_ESP_TROLL,
140                 TR_ESP_GIANT,
141                 TR_ESP_DRAGON,
142                 TR_ESP_HUMAN,
143                 TR_ESP_GOOD,
144                 TR_ESP_UNIQUE,
145         };
146         const int MAX_ESP_WEAK = sizeof(weak_esp_list) / sizeof(weak_esp_list[0]);
147         const int add_count = MIN(MAX_ESP_WEAK, (extra) ? (3 + randint1(randint1(6))) : randint1(3));
148
149         /* Add unduplicated weak esp flags randomly */
150         for (i = 0; i < add_count; ++i)
151         {
152                 int choice = rand_range(i, MAX_ESP_WEAK - 1);
153
154                 add_flag(o_ptr->art_flags, weak_esp_list[choice]);
155                 weak_esp_list[choice] = weak_esp_list[i];
156         }
157 }
158
159 /*!
160  * @brief 対象のオブジェクトに元素耐性を一つ付加する。/ Choose one random element resistance
161  * @details 候補は火炎、冷気、電撃、酸のいずれかであり、重複の抑止はない。
162  * @param o_ptr 対象のオブジェクト構造体ポインタ
163  * @return なし
164  */
165 void one_ele_resistance(object_type *o_ptr)
166 {
167         switch (randint0(4))
168         {
169         case  0: add_flag(o_ptr->art_flags, TR_RES_ACID); break;
170         case  1: add_flag(o_ptr->art_flags, TR_RES_ELEC); break;
171         case  2: add_flag(o_ptr->art_flags, TR_RES_COLD); break;
172         case  3: add_flag(o_ptr->art_flags, TR_RES_FIRE); break;
173         }
174 }
175
176 /*!
177  * @brief 対象のオブジェクトにドラゴン装備向け元素耐性を一つ付加する。/ Choose one random element or poison resistance
178  * @details 候補は1/7の確率で毒、6/7の確率で火炎、冷気、電撃、酸のいずれか(one_ele_resistance()のコール)であり、重複の抑止はない。
179  * @param o_ptr 対象のオブジェクト構造体ポインタ
180  * @return なし
181  */
182 void one_dragon_ele_resistance(object_type *o_ptr)
183 {
184         if (one_in_(7))
185         {
186                 add_flag(o_ptr->art_flags, TR_RES_POIS);
187         }
188         else
189         {
190                 one_ele_resistance(o_ptr);
191         }
192 }
193
194 /*!
195  * @brief 対象のオブジェクトにランダムな上位耐性を一つ付加する。/ Choose one random high resistance
196  * @details 重複の抑止はない。候補は毒、閃光、暗黒、破片、盲目、混乱、地獄、因果混乱、カオス、劣化、恐怖のいずれか。
197  * @param o_ptr 対象のオブジェクト構造体ポインタ
198  * @return なし
199  */
200 void one_high_resistance(object_type *o_ptr)
201 {
202         switch (randint0(12))
203         {
204         case  0: add_flag(o_ptr->art_flags, TR_RES_POIS);   break;
205         case  1: add_flag(o_ptr->art_flags, TR_RES_LITE);   break;
206         case  2: add_flag(o_ptr->art_flags, TR_RES_DARK);   break;
207         case  3: add_flag(o_ptr->art_flags, TR_RES_SHARDS); break;
208         case  4: add_flag(o_ptr->art_flags, TR_RES_BLIND);  break;
209         case  5: add_flag(o_ptr->art_flags, TR_RES_CONF);   break;
210         case  6: add_flag(o_ptr->art_flags, TR_RES_SOUND);  break;
211         case  7: add_flag(o_ptr->art_flags, TR_RES_NETHER); break;
212         case  8: add_flag(o_ptr->art_flags, TR_RES_NEXUS);  break;
213         case  9: add_flag(o_ptr->art_flags, TR_RES_CHAOS);  break;
214         case 10: add_flag(o_ptr->art_flags, TR_RES_DISEN);  break;
215         case 11: add_flag(o_ptr->art_flags, TR_RES_FEAR);   break;
216         }
217 }
218
219 /*!
220  * @brief ドラゴン装備にランダムな耐性を与える
221  * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
222  * @return なし
223  */
224 void dragon_resist(object_type * o_ptr)
225 {
226         do
227         {
228                 if (one_in_(4))
229                         one_dragon_ele_resistance(o_ptr);
230                 else
231                         one_high_resistance(o_ptr);
232         } while (one_in_(2));
233 }
234