1 #include "object-enchant/object-boost.h"
2 #include "art-definition/random-art-effects.h"
3 #include "object-enchant/tr-types.h"
4 #include "system/floor-type-definition.h"
5 #include "system/object-type-definition.h"
6 #include "util/bit-flags-calculator.h"
9 * @brief 上質以上のオブジェクトに与えるための各種ボーナスを正規乱数も加えて算出する。
10 * Help determine an "enchantment bonus" for an object.
12 * @param level ボーナス値に加味する基準生成階
15 * To avoid floating point but still provide a smooth distribution of bonuses,\n
16 * we simply round the results of division in such a way as to "average" the\n
17 * correct floating point value.\n
19 * This function has been changed. It uses "randnor()" to choose values from\n
20 * a normal distribution, whose mean moves from zero towards the max as the\n
21 * level increases, and whose standard deviation is equal to 1/4 of the max,\n
22 * and whose values are forced to lie between zero and the max, inclusive.\n
24 * Since the "level" rarely passes 100 before Morgoth is dead, it is very\n
25 * rare to get the "full" enchantment on an object, even a deep levels.\n
27 * It is always possible (albeit unlikely) to get the "full" enchantment.\n
29 * A sample distribution of values from "m_bonus(10, N)" is shown below:\n
31 * N 0 1 2 3 4 5 6 7 8 9 10\n
32 * --- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----\n
33 * 0 66.37 13.01 9.73 5.47 2.89 1.31 0.72 0.26 0.12 0.09 0.03\n
34 * 8 46.85 24.66 12.13 8.13 4.20 2.30 1.05 0.36 0.19 0.08 0.05\n
35 * 16 30.12 27.62 18.52 10.52 6.34 3.52 1.95 0.90 0.31 0.15 0.05\n
36 * 24 22.44 15.62 30.14 12.92 8.55 5.30 2.39 1.63 0.62 0.28 0.11\n
37 * 32 16.23 11.43 23.01 22.31 11.19 7.18 4.46 2.13 1.20 0.45 0.41\n
38 * 40 10.76 8.91 12.80 29.51 16.00 9.69 5.90 3.43 1.47 0.88 0.65\n
39 * 48 7.28 6.81 10.51 18.27 27.57 11.76 7.85 4.99 2.80 1.22 0.94\n
40 * 56 4.41 4.73 8.52 11.96 24.94 19.78 11.06 7.18 3.68 1.96 1.78\n
41 * 64 2.81 3.07 5.65 9.17 13.01 31.57 13.70 9.30 6.04 3.04 2.64\n
42 * 72 1.87 1.99 3.68 7.15 10.56 20.24 25.78 12.17 7.52 4.42 4.62\n
43 * 80 1.02 1.23 2.78 4.75 8.37 12.04 27.61 18.07 10.28 6.52 7.33\n
44 * 88 0.70 0.57 1.56 3.12 6.34 10.06 15.76 30.46 12.58 8.47 10.38\n
45 * 96 0.27 0.60 1.25 2.28 4.30 7.60 10.77 22.52 22.51 11.37 16.53\n
46 * 104 0.22 0.42 0.77 1.36 2.62 5.33 8.93 13.05 29.54 15.23 22.53\n
47 * 112 0.15 0.20 0.56 0.87 2.00 3.83 6.86 10.06 17.89 27.31 30.27\n
48 * 120 0.03 0.11 0.31 0.46 1.31 2.48 4.60 7.78 11.67 25.53 45.72\n
49 * 128 0.02 0.01 0.13 0.33 0.83 1.41 3.24 6.17 9.57 14.22 64.07\n
51 int m_bonus(int max, DEPTH level)
53 int bonus, stand, extra, value;
56 /* Paranoia -- enforce maximal "level" */
57 if (level > MAX_DEPTH - 1) level = MAX_DEPTH - 1;
60 /* The "bonus" moves towards the max */
61 bonus = ((max * level) / MAX_DEPTH);
63 /* Hack -- determine fraction of error */
64 extra = ((max * level) % MAX_DEPTH);
66 /* Hack -- simulate floating point computations */
67 if (randint0(MAX_DEPTH) < extra) bonus++;
70 /* The "stand" is equal to one quarter of the max */
73 /* Hack -- determine fraction of error */
76 /* Hack -- simulate floating point computations */
77 if (randint0(4) < extra) stand++;
80 /* Choose an "interesting" value */
81 value = randnor(bonus, stand);
83 /* Enforce the minimum value */
84 if (value < 0) return 0;
86 /* Enforce the maximum value */
87 if (value > max) return (max);
92 * @brief 対象のオブジェクトにランダムな能力維持を一つ付加する。/ Choose one random sustain
94 * @param o_ptr 対象のオブジェクト構造体ポインタ
97 void one_sustain(object_type *o_ptr)
99 switch (randint0(A_MAX))
101 case 0: add_flag(o_ptr->art_flags, TR_SUST_STR); break;
102 case 1: add_flag(o_ptr->art_flags, TR_SUST_INT); break;
103 case 2: add_flag(o_ptr->art_flags, TR_SUST_WIS); break;
104 case 3: add_flag(o_ptr->art_flags, TR_SUST_DEX); break;
105 case 4: add_flag(o_ptr->art_flags, TR_SUST_CON); break;
106 case 5: add_flag(o_ptr->art_flags, TR_SUST_CHR); break;
111 * @brief オブジェクトにランダムな強いESPを与える
112 * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
113 * @return TR_ESP_NONLIVINGがついたならばTRUE
115 bool add_esp_strong(object_type *o_ptr)
121 case 1: add_flag(o_ptr->art_flags, TR_ESP_EVIL); break;
122 case 2: add_flag(o_ptr->art_flags, TR_TELEPATHY); break;
123 case 3: add_flag(o_ptr->art_flags, TR_ESP_NONLIVING); nonliv = TRUE; break;
130 * @brief オブジェクトにランダムな弱いESPを与える
131 * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
132 * @param extra TRUEならばESPの最大付与数が増える(TRUE -> 3+1d6 / FALSE -> 1d3)
135 void add_esp_weak(object_type *o_ptr, bool extra)
138 u32b weak_esp_list[] = {
150 const int MAX_ESP_WEAK = sizeof(weak_esp_list) / sizeof(weak_esp_list[0]);
151 const int add_count = MIN(MAX_ESP_WEAK, (extra) ? (3 + randint1(randint1(6))) : randint1(3));
153 /* Add unduplicated weak esp flags randomly */
154 for (i = 0; i < add_count; ++i)
156 int choice = rand_range(i, MAX_ESP_WEAK - 1);
158 add_flag(o_ptr->art_flags, weak_esp_list[choice]);
159 weak_esp_list[choice] = weak_esp_list[i];
164 * @brief 対象のオブジェクトに元素耐性を一つ付加する。/ Choose one random element resistance
165 * @details 候補は火炎、冷気、電撃、酸のいずれかであり、重複の抑止はない。
166 * @param o_ptr 対象のオブジェクト構造体ポインタ
169 void one_ele_resistance(object_type *o_ptr)
173 case 0: add_flag(o_ptr->art_flags, TR_RES_ACID); break;
174 case 1: add_flag(o_ptr->art_flags, TR_RES_ELEC); break;
175 case 2: add_flag(o_ptr->art_flags, TR_RES_COLD); break;
176 case 3: add_flag(o_ptr->art_flags, TR_RES_FIRE); break;
181 * @brief 対象のオブジェクトにドラゴン装備向け元素耐性を一つ付加する。/ Choose one random element or poison resistance
182 * @details 候補は1/7の確率で毒、6/7の確率で火炎、冷気、電撃、酸のいずれか(one_ele_resistance()のコール)であり、重複の抑止はない。
183 * @param o_ptr 対象のオブジェクト構造体ポインタ
186 void one_dragon_ele_resistance(object_type *o_ptr)
190 add_flag(o_ptr->art_flags, TR_RES_POIS);
194 one_ele_resistance(o_ptr);
199 * @brief 対象のオブジェクトにランダムな上位耐性を一つ付加する。/ Choose one random high resistance
200 * @details 重複の抑止はない。候補は毒、閃光、暗黒、破片、盲目、混乱、地獄、因果混乱、カオス、劣化、恐怖のいずれか。
201 * @param o_ptr 対象のオブジェクト構造体ポインタ
204 void one_high_resistance(object_type *o_ptr)
206 switch (randint0(12))
208 case 0: add_flag(o_ptr->art_flags, TR_RES_POIS); break;
209 case 1: add_flag(o_ptr->art_flags, TR_RES_LITE); break;
210 case 2: add_flag(o_ptr->art_flags, TR_RES_DARK); break;
211 case 3: add_flag(o_ptr->art_flags, TR_RES_SHARDS); break;
212 case 4: add_flag(o_ptr->art_flags, TR_RES_BLIND); break;
213 case 5: add_flag(o_ptr->art_flags, TR_RES_CONF); break;
214 case 6: add_flag(o_ptr->art_flags, TR_RES_SOUND); break;
215 case 7: add_flag(o_ptr->art_flags, TR_RES_NETHER); break;
216 case 8: add_flag(o_ptr->art_flags, TR_RES_NEXUS); break;
217 case 9: add_flag(o_ptr->art_flags, TR_RES_CHAOS); break;
218 case 10: add_flag(o_ptr->art_flags, TR_RES_DISEN); break;
219 case 11: add_flag(o_ptr->art_flags, TR_RES_FEAR); break;
225 * @brief ドラゴン装備にランダムな耐性を与える
226 * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
229 void dragon_resist(object_type *o_ptr)
234 one_dragon_ele_resistance(o_ptr);
236 one_high_resistance(o_ptr);
237 } while (one_in_(2));
242 * @brief 対象のオブジェクトに耐性を一つ付加する。/ Choose one random resistance
243 * @details 1/3で元素耐性(one_ele_resistance())、2/3で上位耐性(one_high_resistance)
245 * @param o_ptr 対象のオブジェクト構造体ポインタ
248 void one_resistance(object_type *o_ptr)
252 one_ele_resistance(o_ptr);
256 one_high_resistance(o_ptr);
262 * @brief 対象のオブジェクトに能力を一つ付加する。/ Choose one random ability
263 * @details 候補は浮遊、永久光源+1、透明視、警告、遅消化、急回復、麻痺知らず、経験値維持のいずれか。
265 * @param o_ptr 対象のオブジェクト構造体ポインタ
268 void one_ability(object_type *o_ptr)
270 switch (randint0(10))
272 case 0: add_flag(o_ptr->art_flags, TR_LEVITATION); break;
273 case 1: add_flag(o_ptr->art_flags, TR_LITE_1); break;
274 case 2: add_flag(o_ptr->art_flags, TR_SEE_INVIS); break;
275 case 3: add_flag(o_ptr->art_flags, TR_WARNING); break;
276 case 4: add_flag(o_ptr->art_flags, TR_SLOW_DIGEST); break;
277 case 5: add_flag(o_ptr->art_flags, TR_REGEN); break;
278 case 6: add_flag(o_ptr->art_flags, TR_FREE_ACT); break;
279 case 7: add_flag(o_ptr->art_flags, TR_HOLD_EXP); break;
289 * @brief 対象のオブジェクトに弱いESPを一つ付加する。/ Choose one lower rank esp
290 * @details 候補は動物、アンデッド、悪魔、オーク、トロル、巨人、
291 * ドラゴン、人間、善良、ユニークESPのいずれかであり、重複の抑止はない。
292 * @param o_ptr 対象のオブジェクト構造体ポインタ
295 void one_low_esp(object_type *o_ptr)
297 switch (randint1(10))
299 case 1: add_flag(o_ptr->art_flags, TR_ESP_ANIMAL); break;
300 case 2: add_flag(o_ptr->art_flags, TR_ESP_UNDEAD); break;
301 case 3: add_flag(o_ptr->art_flags, TR_ESP_DEMON); break;
302 case 4: add_flag(o_ptr->art_flags, TR_ESP_ORC); break;
303 case 5: add_flag(o_ptr->art_flags, TR_ESP_TROLL); break;
304 case 6: add_flag(o_ptr->art_flags, TR_ESP_GIANT); break;
305 case 7: add_flag(o_ptr->art_flags, TR_ESP_DRAGON); break;
306 case 8: add_flag(o_ptr->art_flags, TR_ESP_HUMAN); break;
307 case 9: add_flag(o_ptr->art_flags, TR_ESP_GOOD); break;
308 case 10: add_flag(o_ptr->art_flags, TR_ESP_UNIQUE); break;
314 * @brief 対象のオブジェクトに発動を一つ付加する。/ Choose one random activation
315 * @details 候補多数。ランダムアーティファクトのバイアスには一切依存せず、
316 * whileループによる構造で能力的に強力なものほど確率を落としている。
317 * @param o_ptr 対象のオブジェクト構造体ポインタ
320 void one_activation(object_type *o_ptr)
323 PERCENTAGE chance = 0;
325 while (randint1(100) >= chance)
327 type = randint1(255);
342 case ACT_CURE_POISON:
353 case ACT_HYPODYNAMIA_1:
368 case ACT_HYPODYNAMIA_2:
380 case ACT_CHARM_ANIMAL:
383 case ACT_SUMMON_ANIMAL:
389 case ACT_BANISH_EVIL:
392 case ACT_CHARM_UNDEAD:
393 case ACT_CHARM_OTHER:
394 case ACT_SUMMON_PHANTOM:
401 case ACT_CHARM_ANIMALS:
402 case ACT_CHARM_OTHERS:
403 case ACT_SUMMON_ELEMENTAL:
412 case ACT_DETECT_XTRA:
416 case ACT_SUMMON_UNDEAD:
417 case ACT_SUMMON_DEMON:
428 /* A type was chosen... */
429 o_ptr->xtra2 = (byte)type;
430 add_flag(o_ptr->art_flags, TR_ACTIVATE);
436 * @brief 対象のオブジェクトに王者の指輪向けの上位耐性を一つ付加する。/ Choose one random high resistance
437 * @details 候補は閃光、暗黒、破片、盲目、混乱、地獄、因果混乱、カオス、恐怖であり
438 * 王者の指輪にあらかじめついている耐性をone_high_resistance()から除外したものである。
439 * ランダム付加そのものに重複の抑止はない。
440 * @param o_ptr 対象のオブジェクト構造体ポインタ
443 void one_lordly_high_resistance(object_type *o_ptr)
445 switch (randint0(10))
447 case 0: add_flag(o_ptr->art_flags, TR_RES_LITE); break;
448 case 1: add_flag(o_ptr->art_flags, TR_RES_DARK); break;
449 case 2: add_flag(o_ptr->art_flags, TR_RES_SHARDS); break;
450 case 3: add_flag(o_ptr->art_flags, TR_RES_BLIND); break;
451 case 4: add_flag(o_ptr->art_flags, TR_RES_CONF); break;
452 case 5: add_flag(o_ptr->art_flags, TR_RES_SOUND); break;
453 case 6: add_flag(o_ptr->art_flags, TR_RES_NETHER); break;
454 case 7: add_flag(o_ptr->art_flags, TR_RES_NEXUS); break;
455 case 8: add_flag(o_ptr->art_flags, TR_RES_CHAOS); break;
456 case 9: add_flag(o_ptr->art_flags, TR_RES_FEAR); break;