OSDN Git Service

Since struct dirent only holds the last element in the path, build the full path...
[hengband/hengband.git] / src / artifact / random-art-misc.c
1 #include "artifact/random-art-misc.h"
2 #include "artifact/random-art-bias-types.h"
3 #include "object-enchant/tr-types.h"
4 #include "object-hook/hook-armor.h"
5 #include "system/object-type-definition.h"
6 #include "util/bit-flags-calculator.h"
7
8 static bool invest_misc_ranger(object_type *o_ptr)
9 {
10     if (has_flag(o_ptr->art_flags, TR_SUST_CON))
11         return FALSE;
12
13     add_flag(o_ptr->art_flags, TR_SUST_CON);
14     return one_in_(2);
15 }
16
17 static bool invest_misc_strength(object_type *o_ptr)
18 {
19     if (has_flag(o_ptr->art_flags, TR_SUST_STR))
20         return FALSE;
21
22     add_flag(o_ptr->art_flags, TR_SUST_STR);
23     return one_in_(2);
24 }
25
26 static bool invest_misc_wisdom(object_type *o_ptr)
27 {
28     if (has_flag(o_ptr->art_flags, TR_SUST_WIS))
29         return FALSE;
30
31     add_flag(o_ptr->art_flags, TR_SUST_WIS);
32     return one_in_(2);
33 }
34
35 static bool invest_misc_intelligence(object_type *o_ptr)
36 {
37     if (has_flag(o_ptr->art_flags, TR_SUST_INT))
38         return FALSE;
39
40     add_flag(o_ptr->art_flags, TR_SUST_INT);
41     return one_in_(2);
42 }
43
44 static bool invest_misc_dexterity(object_type *o_ptr)
45 {
46     if (has_flag(o_ptr->art_flags, TR_SUST_DEX))
47         return FALSE;
48
49     add_flag(o_ptr->art_flags, TR_SUST_DEX);
50     return one_in_(2);
51 }
52
53 static bool invest_misc_constitution(object_type *o_ptr)
54 {
55     if (has_flag(o_ptr->art_flags, TR_SUST_CON))
56         return FALSE;
57
58     add_flag(o_ptr->art_flags, TR_SUST_CON);
59     return one_in_(2);
60 }
61
62 static bool invest_misc_charisma(object_type *o_ptr)
63 {
64     if (has_flag(o_ptr->art_flags, TR_SUST_CHR))
65         return FALSE;
66
67     add_flag(o_ptr->art_flags, TR_SUST_CHR);
68     return one_in_(2);
69 }
70
71 static bool invest_misc_chaos(object_type *o_ptr)
72 {
73     if (has_flag(o_ptr->art_flags, TR_TELEPORT))
74         return FALSE;
75
76     add_flag(o_ptr->art_flags, TR_TELEPORT);
77     return one_in_(2);
78 }
79
80 /*!
81  * @brief アーティファクトのバイアス値に基づいて特性を付与する
82  * @param o_ptr 対象のオブジェクト構造体への参照ポインタ
83  * @return 処理続行ならFALSE、打ち切るならTRUE
84  */
85 static bool switch_misc_bias(object_type *o_ptr)
86 {
87     switch (o_ptr->artifact_bias) {
88     case BIAS_RANGER:
89         return invest_misc_ranger(o_ptr);
90     case BIAS_STR:
91         return invest_misc_strength(o_ptr);
92     case BIAS_INT:
93         return invest_misc_intelligence(o_ptr);
94     case BIAS_WIS:
95         return invest_misc_wisdom(o_ptr);
96     case BIAS_DEX:
97         return invest_misc_dexterity(o_ptr);
98     case BIAS_CON:
99         return invest_misc_constitution(o_ptr);
100     case BIAS_CHR:
101         return invest_misc_charisma(o_ptr);
102     case BIAS_CHAOS:
103         return invest_misc_chaos(o_ptr);
104     case BIAS_FIRE:
105         if (!(has_flag(o_ptr->art_flags, TR_LITE_1)))
106             add_flag(o_ptr->art_flags, TR_LITE_1);
107
108         return FALSE;
109     default:
110         return FALSE;
111     }
112 }
113
114 static void invest_misc_hit_dice(object_type *o_ptr)
115 {
116     add_flag(o_ptr->art_flags, TR_SHOW_MODS);
117     HIT_PROB bonus_h = 4 + (HIT_PROB)randint1(11);
118     HIT_POINT bonus_d = 4 + (HIT_POINT)randint1(11);
119     if ((o_ptr->tval != TV_SWORD) && (o_ptr->tval != TV_POLEARM) && (o_ptr->tval != TV_HAFTED) && (o_ptr->tval != TV_DIGGING) && (o_ptr->tval != TV_GLOVES)
120         && (o_ptr->tval != TV_RING)) {
121         bonus_h /= 2;
122         bonus_d /= 2;
123     }
124
125     o_ptr->to_h += bonus_h;
126     o_ptr->to_d += bonus_d;
127 }
128
129 static void invest_misc_string_esp(object_type *o_ptr)
130 {
131     switch (randint1(3)) {
132     case 1:
133         add_flag(o_ptr->art_flags, TR_ESP_EVIL);
134         if (!o_ptr->artifact_bias && one_in_(3))
135             o_ptr->artifact_bias = BIAS_LAW;
136
137         return;
138     case 2:
139         add_flag(o_ptr->art_flags, TR_ESP_NONLIVING);
140         if (!o_ptr->artifact_bias && one_in_(3))
141             o_ptr->artifact_bias = BIAS_MAGE;
142
143         return;
144     case 3:
145         add_flag(o_ptr->art_flags, TR_TELEPATHY);
146         if (!o_ptr->artifact_bias && one_in_(9))
147             o_ptr->artifact_bias = BIAS_MAGE;
148
149         return;
150     }
151 }
152
153 static void switch_investment_weak_esps(object_type *o_ptr, const int *idx, const int n)
154 {
155     switch (idx[n]) {
156     case 1:
157         add_flag(o_ptr->art_flags, TR_ESP_ANIMAL);
158         if (!o_ptr->artifact_bias && one_in_(4))
159             o_ptr->artifact_bias = BIAS_RANGER;
160
161         break;
162     case 2:
163         add_flag(o_ptr->art_flags, TR_ESP_UNDEAD);
164         if (!o_ptr->artifact_bias && one_in_(3))
165             o_ptr->artifact_bias = BIAS_PRIESTLY;
166         else if (!o_ptr->artifact_bias && one_in_(6))
167             o_ptr->artifact_bias = BIAS_NECROMANTIC;
168
169         break;
170     case 3:
171         add_flag(o_ptr->art_flags, TR_ESP_DEMON);
172         break;
173     case 4:
174         add_flag(o_ptr->art_flags, TR_ESP_ORC);
175         break;
176     case 5:
177         add_flag(o_ptr->art_flags, TR_ESP_TROLL);
178         break;
179     case 6:
180         add_flag(o_ptr->art_flags, TR_ESP_GIANT);
181         break;
182     case 7:
183         add_flag(o_ptr->art_flags, TR_ESP_DRAGON);
184         break;
185     case 8:
186         add_flag(o_ptr->art_flags, TR_ESP_HUMAN);
187         if (!o_ptr->artifact_bias && one_in_(6))
188             o_ptr->artifact_bias = BIAS_ROGUE;
189
190         break;
191     case 9:
192         add_flag(o_ptr->art_flags, TR_ESP_GOOD);
193         if (!o_ptr->artifact_bias && one_in_(3))
194             o_ptr->artifact_bias = BIAS_LAW;
195
196         break;
197     case 10:
198         add_flag(o_ptr->art_flags, TR_ESP_UNIQUE);
199         if (!o_ptr->artifact_bias && one_in_(3))
200             o_ptr->artifact_bias = BIAS_LAW;
201
202         break;
203     }
204 }
205
206 static void invest_misc_weak_esps(object_type *o_ptr)
207 {
208     int idx[3];
209     idx[0] = randint1(10);
210     idx[1] = randint1(9);
211     if (idx[1] >= idx[0])
212         idx[1]++;
213
214     idx[2] = randint1(8);
215     if (idx[2] >= idx[0])
216         idx[2]++;
217
218     if (idx[2] >= idx[1])
219         idx[2]++;
220
221     int n = randint1(3);
222     while (n--)
223         switch_investment_weak_esps(o_ptr, idx, n);
224 }
225
226 /*!
227  * @brief ランダムアーティファクト生成中、対象のオブジェクトにその他特性を付加する。/ Add one misc flag on generation of randam artifact.
228  * @details 優先的に付加される耐性がランダムアーティファクトバイアスに依存して存在する。
229  * 原則的候補は各種能力維持、永久光源+1、麻痺知らず、経験値維持、浮遊、透明視、急回復、遅消化、
230  * 乱テレポート、反魔法、反テレポート、警告、テレパシー、各種ESP、一部装備に殺戮修正。
231  * @attention オブジェクトのtval、svalに依存したハードコーディング処理がある。
232  * @param o_ptr 対象のオブジェクト構造体ポインタ
233  * @return なし
234  */
235 void random_misc(player_type *player_ptr, object_type *o_ptr)
236 {
237     if (switch_misc_bias(o_ptr))
238         return;
239
240     switch (randint1(33)) {
241     case 1:
242         add_flag(o_ptr->art_flags, TR_SUST_STR);
243         if (!o_ptr->artifact_bias)
244             o_ptr->artifact_bias = BIAS_STR;
245
246         break;
247     case 2:
248         add_flag(o_ptr->art_flags, TR_SUST_INT);
249         if (!o_ptr->artifact_bias)
250             o_ptr->artifact_bias = BIAS_INT;
251
252         break;
253     case 3:
254         add_flag(o_ptr->art_flags, TR_SUST_WIS);
255         if (!o_ptr->artifact_bias)
256             o_ptr->artifact_bias = BIAS_WIS;
257
258         break;
259     case 4:
260         add_flag(o_ptr->art_flags, TR_SUST_DEX);
261         if (!o_ptr->artifact_bias)
262             o_ptr->artifact_bias = BIAS_DEX;
263
264         break;
265     case 5:
266         add_flag(o_ptr->art_flags, TR_SUST_CON);
267         if (!o_ptr->artifact_bias)
268             o_ptr->artifact_bias = BIAS_CON;
269
270         break;
271     case 6:
272         add_flag(o_ptr->art_flags, TR_SUST_CHR);
273         if (!o_ptr->artifact_bias)
274             o_ptr->artifact_bias = BIAS_CHR;
275
276         break;
277     case 7:
278     case 8:
279     case 14:
280         add_flag(o_ptr->art_flags, TR_FREE_ACT);
281         break;
282     case 9:
283         add_flag(o_ptr->art_flags, TR_HOLD_EXP);
284         if (!o_ptr->artifact_bias && one_in_(5))
285             o_ptr->artifact_bias = BIAS_PRIESTLY;
286         else if (!o_ptr->artifact_bias && one_in_(6))
287             o_ptr->artifact_bias = BIAS_NECROMANTIC;
288
289         break;
290     case 10:
291     case 11:
292         add_flag(o_ptr->art_flags, TR_LITE_1);
293         break;
294     case 12:
295     case 13:
296         add_flag(o_ptr->art_flags, TR_LEVITATION);
297         break;
298     case 15:
299     case 16:
300     case 17:
301         add_flag(o_ptr->art_flags, TR_SEE_INVIS);
302         break;
303     case 19:
304     case 20:
305         add_flag(o_ptr->art_flags, TR_SLOW_DIGEST);
306         break;
307     case 21:
308     case 22:
309         add_flag(o_ptr->art_flags, TR_REGEN);
310         break;
311     case 23:
312         add_flag(o_ptr->art_flags, TR_TELEPORT);
313         break;
314     case 24:
315     case 25:
316     case 26:
317         if (object_is_armour(player_ptr, o_ptr))
318             random_misc(player_ptr, o_ptr);
319         else
320             o_ptr->to_a = 4 + randint1(11);
321
322         break;
323     case 27:
324     case 28:
325     case 29:
326         invest_misc_hit_dice(o_ptr);
327         break;
328     case 30:
329         add_flag(o_ptr->art_flags, TR_NO_MAGIC);
330         break;
331     case 31:
332         add_flag(o_ptr->art_flags, TR_NO_TELE);
333         break;
334     case 32:
335         add_flag(o_ptr->art_flags, TR_WARNING);
336         break;
337     case 18:
338         invest_misc_string_esp(o_ptr);
339         break;
340     case 33:
341         invest_misc_weak_esps(o_ptr);
342         break;
343     }
344 }