OSDN Git Service

Merge pull request #3569 from sikabane-works/release/3.0.0.88-alpha
[hengbandforosx/hengbandosx.git] / src / artifact / random-art-slay.cpp
1 /*!
2  * @file random-art-slay.cpp
3  * @brief ランダムアーティファクトのスレイ付加処理実装
4  */
5
6 #include "artifact/random-art-slay.h"
7 #include "artifact/random-art-bias-types.h"
8 #include "object-enchant/tr-types.h"
9 #include "object/tval-types.h"
10 #include "sv-definition/sv-weapon-types.h"
11 #include "system/item-entity.h"
12 #include "util/bit-flags-calculator.h"
13
14 static bool random_art_slay_bow(ItemEntity *o_ptr)
15 {
16     if (o_ptr->bi_key.tval() != ItemKindType::BOW) {
17         return false;
18     }
19
20     switch (randint1(6)) {
21     case 1:
22     case 2:
23     case 3:
24         o_ptr->art_flags.set(TR_XTRA_MIGHT);
25         if (!one_in_(7)) {
26             o_ptr->art_flags.reset(TR_XTRA_SHOTS);
27         }
28
29         if ((o_ptr->artifact_bias == BIAS_NONE) && one_in_(9)) {
30             o_ptr->artifact_bias = BIAS_RANGER;
31         }
32
33         return true;
34     default:
35         o_ptr->art_flags.set(TR_XTRA_SHOTS);
36         if (!one_in_(7)) {
37             o_ptr->art_flags.reset(TR_XTRA_MIGHT);
38         }
39
40         if ((o_ptr->artifact_bias == BIAS_NONE) && one_in_(9)) {
41             o_ptr->artifact_bias = BIAS_RANGER;
42         }
43
44         return true;
45     }
46 }
47
48 static bool random_art_slay_chaos(ItemEntity *o_ptr)
49 {
50     if (o_ptr->art_flags.has(TR_CHAOTIC)) {
51         return false;
52     }
53
54     o_ptr->art_flags.set(TR_CHAOTIC);
55     return one_in_(2);
56 }
57
58 static bool random_art_brand_magical(ItemEntity *o_ptr)
59 {
60     if (o_ptr->art_flags.has(TR_BRAND_MAGIC)) {
61         return false;
62     }
63
64     o_ptr->art_flags.set(TR_BRAND_MAGIC);
65     return one_in_(3);
66 }
67
68 static bool random_art_slay_vampiric(ItemEntity *o_ptr)
69 {
70     if (o_ptr->art_flags.has(TR_VAMPIRIC)) {
71         return false;
72     }
73
74     o_ptr->art_flags.set(TR_VAMPIRIC);
75     return one_in_(2);
76 }
77
78 static bool random_art_slay_brand_acid(ItemEntity *o_ptr)
79 {
80     if (o_ptr->art_flags.has(TR_BRAND_ACID)) {
81         return false;
82     }
83
84     o_ptr->art_flags.set(TR_BRAND_ACID);
85     return one_in_(2);
86 }
87
88 static bool random_art_slay_brand_elec(ItemEntity *o_ptr)
89 {
90     if (o_ptr->art_flags.has(TR_BRAND_ELEC)) {
91         return false;
92     }
93
94     o_ptr->art_flags.set(TR_BRAND_ELEC);
95     return one_in_(2);
96 }
97
98 static bool random_art_slay_brand_fire(ItemEntity *o_ptr)
99 {
100     if (o_ptr->art_flags.has(TR_BRAND_FIRE)) {
101         return false;
102     }
103
104     o_ptr->art_flags.set(TR_BRAND_FIRE);
105     return one_in_(2);
106 }
107
108 static bool random_art_slay_brand_cold(ItemEntity *o_ptr)
109 {
110     if (o_ptr->art_flags.has(TR_BRAND_COLD)) {
111         return false;
112     }
113
114     o_ptr->art_flags.set(TR_BRAND_COLD);
115     return one_in_(2);
116 }
117
118 static bool random_art_slay_brand_pois(ItemEntity *o_ptr)
119 {
120     if (o_ptr->art_flags.has(TR_BRAND_POIS) || one_in_(2)) {
121         return false;
122     }
123
124     o_ptr->art_flags.set(TR_BRAND_POIS);
125     return one_in_(2);
126 }
127
128 static bool random_art_slay_animal(ItemEntity *o_ptr)
129 {
130     if (o_ptr->art_flags.has(TR_SLAY_ANIMAL)) {
131         return false;
132     }
133
134     o_ptr->art_flags.set(TR_SLAY_ANIMAL);
135     return one_in_(2);
136 }
137
138 static bool random_art_slay_evil(ItemEntity *o_ptr)
139 {
140     if (o_ptr->art_flags.has(TR_SLAY_EVIL)) {
141         return false;
142     }
143
144     o_ptr->art_flags.set(TR_SLAY_EVIL);
145     return one_in_(2);
146 }
147
148 static bool random_art_slay_undead(ItemEntity *o_ptr)
149 {
150     if (o_ptr->art_flags.has(TR_SLAY_UNDEAD)) {
151         return false;
152     }
153
154     o_ptr->art_flags.set(TR_SLAY_UNDEAD);
155     return one_in_(2);
156 }
157
158 static bool random_art_slay_demon(ItemEntity *o_ptr)
159 {
160     if (o_ptr->art_flags.has(TR_SLAY_DEMON)) {
161         return false;
162     }
163
164     o_ptr->art_flags.set(TR_SLAY_DEMON);
165     return one_in_(2);
166 }
167
168 static bool switch_random_art_slay(ItemEntity *o_ptr)
169 {
170     switch (o_ptr->artifact_bias) {
171     case BIAS_CHAOS:
172         return random_art_slay_chaos(o_ptr);
173     case BIAS_MAGE:
174     case BIAS_INT:
175         return random_art_brand_magical(o_ptr);
176     case BIAS_PRIESTLY: {
177         const auto tval = o_ptr->bi_key.tval();
178         if (((tval == ItemKindType::SWORD) || (tval == ItemKindType::POLEARM)) && o_ptr->art_flags.has_not(TR_BLESSED)) {
179             o_ptr->art_flags.set(TR_BLESSED);
180         }
181
182         return false;
183     }
184     case BIAS_NECROMANTIC:
185         return random_art_slay_vampiric(o_ptr) || random_art_slay_brand_pois(o_ptr);
186     case BIAS_RANGER:
187         return random_art_slay_animal(o_ptr);
188     case BIAS_ROGUE: {
189         auto is_throwable = o_ptr->bi_key == BaseitemKey(ItemKindType::SWORD, SV_DAGGER);
190         is_throwable |= o_ptr->bi_key == BaseitemKey(ItemKindType::POLEARM, SV_SPEAR);
191         if (is_throwable && o_ptr->art_flags.has_not(TR_THROW)) {
192             o_ptr->art_flags.set(TR_THROW);
193         }
194
195         return random_art_slay_brand_pois(o_ptr);
196     }
197     case BIAS_POIS:
198         return random_art_slay_brand_pois(o_ptr);
199     case BIAS_ACID:
200         return random_art_slay_brand_acid(o_ptr);
201     case BIAS_ELEC:
202         return random_art_slay_brand_elec(o_ptr);
203     case BIAS_FIRE:
204         return random_art_slay_brand_fire(o_ptr);
205     case BIAS_COLD:
206         return random_art_slay_brand_cold(o_ptr);
207     case BIAS_LAW:
208         return random_art_slay_evil(o_ptr) || random_art_slay_undead(o_ptr) || random_art_slay_demon(o_ptr);
209     default:
210         return false;
211     }
212 }
213
214 /*!
215  * @brief ランダムアーティファクト生成中、対象のオブジェクトにスレイ効果を付加する。/ Add one slaying on generation of randam artifact.
216  * @details 優先的に付加される耐性がランダムアーティファクトバイアスに依存して存在する。
217  * 原則的候補は強力射、高速射、混沌効果、吸血効果、祝福、投擲しやすい、焼棄、凍結、電撃、溶解、毒殺、
218  * 動物スレイ、邪悪スレイ、悪魔スレイ、不死スレイ、オークスレイ、トロルスレイ、巨人スレイ、ドラゴンスレイ、
219  * *ドラゴンスレイ*、人間スレイ、切れ味、地震、理力。
220  * @attention オブジェクトのtval、svalに依存したハードコーディング処理がある。
221  * @param o_ptr 対象のオブジェクト構造体ポインタ
222  */
223 void random_slay(ItemEntity *o_ptr)
224 {
225     if (random_art_slay_bow(o_ptr) || switch_random_art_slay(o_ptr)) {
226         return;
227     }
228
229     switch (randint1(39)) {
230     case 1:
231     case 2:
232         if (one_in_(4)) {
233             o_ptr->art_flags.set(TR_KILL_ANIMAL);
234         } else {
235             o_ptr->art_flags.set(TR_SLAY_ANIMAL);
236         }
237
238         break;
239     case 3:
240     case 4:
241         if (one_in_(8)) {
242             o_ptr->art_flags.set(TR_KILL_EVIL);
243         } else {
244             o_ptr->art_flags.set(TR_SLAY_EVIL);
245         }
246
247         if ((o_ptr->artifact_bias == BIAS_NONE) && one_in_(2)) {
248             o_ptr->artifact_bias = BIAS_LAW;
249             break;
250         }
251
252         if ((o_ptr->artifact_bias == BIAS_NONE) && one_in_(9)) {
253             o_ptr->artifact_bias = BIAS_PRIESTLY;
254         }
255
256         break;
257     case 5:
258     case 6:
259         if (one_in_(4)) {
260             o_ptr->art_flags.set(TR_KILL_UNDEAD);
261         } else {
262             o_ptr->art_flags.set(TR_SLAY_UNDEAD);
263         }
264
265         if ((o_ptr->artifact_bias == BIAS_NONE) && one_in_(9)) {
266             o_ptr->artifact_bias = BIAS_PRIESTLY;
267         }
268
269         break;
270     case 7:
271     case 8:
272         if (one_in_(4)) {
273             o_ptr->art_flags.set(TR_KILL_DEMON);
274         } else {
275             o_ptr->art_flags.set(TR_SLAY_DEMON);
276         }
277
278         if ((o_ptr->artifact_bias == BIAS_NONE) && one_in_(9)) {
279             o_ptr->artifact_bias = BIAS_PRIESTLY;
280         }
281
282         break;
283     case 9:
284     case 10:
285         if (one_in_(4)) {
286             o_ptr->art_flags.set(TR_KILL_ORC);
287         } else {
288             o_ptr->art_flags.set(TR_SLAY_ORC);
289         }
290
291         break;
292     case 11:
293     case 12:
294         if (one_in_(4)) {
295             o_ptr->art_flags.set(TR_KILL_TROLL);
296         } else {
297             o_ptr->art_flags.set(TR_SLAY_TROLL);
298         }
299
300         break;
301     case 13:
302     case 14:
303         if (one_in_(4)) {
304             o_ptr->art_flags.set(TR_KILL_GIANT);
305         } else {
306             o_ptr->art_flags.set(TR_SLAY_GIANT);
307         }
308
309         break;
310     case 15:
311     case 16:
312         o_ptr->art_flags.set(TR_SLAY_DRAGON);
313         break;
314     case 17:
315         o_ptr->art_flags.set(TR_KILL_DRAGON);
316         break;
317     case 18:
318     case 19:
319         if (o_ptr->bi_key.tval() != ItemKindType::SWORD) {
320             random_slay(o_ptr);
321             break;
322         }
323
324         o_ptr->art_flags.set(TR_VORPAL);
325         if ((o_ptr->artifact_bias == BIAS_NONE) && one_in_(9)) {
326             o_ptr->artifact_bias = BIAS_WARRIOR;
327         }
328
329         break;
330     case 20:
331         o_ptr->art_flags.set(TR_EARTHQUAKE);
332         break;
333     case 21:
334     case 22:
335         o_ptr->art_flags.set(TR_BRAND_FIRE);
336         if (o_ptr->artifact_bias == BIAS_NONE) {
337             o_ptr->artifact_bias = BIAS_FIRE;
338         }
339
340         break;
341     case 23:
342     case 24:
343         o_ptr->art_flags.set(TR_BRAND_COLD);
344         if (o_ptr->artifact_bias == BIAS_NONE) {
345             o_ptr->artifact_bias = BIAS_COLD;
346         }
347
348         break;
349     case 25:
350     case 26:
351         o_ptr->art_flags.set(TR_BRAND_ELEC);
352         if (o_ptr->artifact_bias == BIAS_NONE) {
353             o_ptr->artifact_bias = BIAS_ELEC;
354         }
355
356         break;
357     case 27:
358     case 28:
359         o_ptr->art_flags.set(TR_BRAND_ACID);
360         if (!o_ptr->artifact_bias) {
361             o_ptr->artifact_bias = BIAS_ACID;
362         }
363
364         break;
365     case 29:
366     case 30:
367         o_ptr->art_flags.set(TR_BRAND_POIS);
368         if ((o_ptr->artifact_bias == BIAS_NONE) && !one_in_(3)) {
369             o_ptr->artifact_bias = BIAS_POIS;
370             break;
371         }
372
373         if ((o_ptr->artifact_bias == BIAS_NONE) && one_in_(6)) {
374             o_ptr->artifact_bias = BIAS_NECROMANTIC;
375             break;
376         }
377
378         if (o_ptr->artifact_bias == BIAS_NONE) {
379             o_ptr->artifact_bias = BIAS_ROGUE;
380         }
381
382         break;
383     case 31:
384         o_ptr->art_flags.set(TR_VAMPIRIC);
385         if (o_ptr->artifact_bias == BIAS_NONE) {
386             o_ptr->artifact_bias = BIAS_NECROMANTIC;
387         }
388
389         break;
390     case 32:
391         o_ptr->art_flags.set(TR_FORCE_WEAPON);
392         if (o_ptr->artifact_bias == BIAS_NONE) {
393             o_ptr->artifact_bias = (one_in_(2) ? BIAS_MAGE : BIAS_PRIESTLY);
394         }
395
396         break;
397     case 33:
398     case 34:
399         if (one_in_(4)) {
400             o_ptr->art_flags.set(TR_KILL_HUMAN);
401         } else {
402             o_ptr->art_flags.set(TR_SLAY_HUMAN);
403         }
404
405         break;
406     case 35:
407         o_ptr->art_flags.set(TR_BRAND_MAGIC);
408         if (o_ptr->artifact_bias == BIAS_NONE) {
409             o_ptr->artifact_bias = BIAS_MAGE;
410         }
411         break;
412     case 36:
413     case 37:
414         o_ptr->art_flags.set(TR_CHAOTIC);
415         if (o_ptr->artifact_bias == BIAS_NONE) {
416             o_ptr->artifact_bias = BIAS_CHAOS;
417         }
418
419         break;
420     default:
421         if (one_in_(8)) {
422             o_ptr->art_flags.set(TR_KILL_GOOD);
423         } else {
424             o_ptr->art_flags.set(TR_SLAY_GOOD);
425         }
426
427         if ((o_ptr->artifact_bias == BIAS_NONE) && one_in_(2)) {
428             o_ptr->artifact_bias = BIAS_POIS;
429             break;
430         }
431
432         if ((o_ptr->artifact_bias == BIAS_NONE) && one_in_(9)) {
433             o_ptr->artifact_bias = BIAS_ROGUE;
434         }
435
436         break;
437     }
438 }