OSDN Git Service

Merge remote-tracking branch 'remotes/hengbandosx/english-mspell-edits' into feature...
[hengband/hengband.git] / src / mspell / mspell-damage-calculator.c
1 #include "mspell/mspell-damage-calculator.h"
2 #include "inventory/inventory-slot-types.h"
3 #include "game-option/birth-options.h"
4 #include "monster-race/monster-race.h"
5 #include "monster-race/race-flags2.h"
6 #include "monster/monster-status.h"
7 #include "system/floor-type-definition.h"
8 #include "system/object-type-definition.h"
9
10 /*!
11  * @brief モンスターの使う呪文の威力を決定する /
12  * @param dam 定数値
13  * @param dice_num ダイス数
14  * @param dice_side ダイス面
15  * @param mult ダイス倍率
16  * @param div ダイス倍率
17  * @param TYPE  DAM_MAXで最大値を返し、DAM_MINで最小値を返す。DAM_ROLLはダイスを振って値を決定する。
18  * @return 攻撃呪文のダメージを返す。攻撃呪文以外は-1を返す。
19  */
20 static HIT_POINT monspell_damage_roll(HIT_POINT dam, int dice_num, int dice_side, int mult, int div, int TYPE)
21 {
22     switch (TYPE) {
23     case DAM_MAX:
24         dam += maxroll(dice_num, dice_side) * mult / div;
25         break;
26     case DAM_MIN:
27         dam += dice_num * 1 * mult / div;
28         break;
29     case DAM_ROLL:
30         dam += damroll(dice_num, dice_side) * mult / div;
31         break;
32     case DICE_NUM:
33         return dice_num;
34     case DICE_SIDE:
35         return dice_side;
36     case DICE_MULT:
37         return mult;
38     case DICE_DIV:
39         return div;
40     case BASE_DAM:
41         return dam;
42     }
43
44     if (dam < 1)
45         dam = 1;
46     return dam;
47 }
48
49 /*!
50  * @brief モンスターの使う呪文の威力を返す /
51  * @param target_ptr プレーヤーへの参照ポインタ (破滅の手用)
52  * @param SPELL_NUM 呪文番号
53  * @param hp 呪文を唱えるモンスターの体力
54  * @param rlev 呪文を唱えるモンスターのレベル
55  * @param powerful 呪文を唱えるモンスターのpowerfulフラグ
56  * @param shoot_dd 射撃のダイス数
57  * @param shoot_ds 射撃のダイス面
58  * @param shoot_base 射撃の固定威力値
59  * @param TYPE  DAM_MAXで最大値を返し、DAM_MINで最小値を返す。DAM_ROLLはダイスを振って値を決定する。
60  * @return 攻撃呪文のダメージを返す。攻撃呪文以外は-1を返す。
61  */
62 static HIT_POINT monspell_damage_base(
63     player_type *target_ptr, monster_spell_type ms_type, int hp, int rlev, bool powerful, int shoot_dd, int shoot_ds, int shoot_base, int TYPE)
64 {
65     HIT_POINT dam = 0, dice_num = 0, dice_side = 0, mult = 1, div = 1;
66
67     switch (ms_type) {
68     case MS_SHRIEK:
69         return -1;
70     case MS_XXX1:
71         return -1;
72     case MS_DISPEL:
73         return -1;
74     case MS_ROCKET:
75         dam = (hp / 4) > 800 ? 800 : (hp / 4);
76         break;
77     case MS_SHOOT:
78         dice_num = shoot_dd;
79         dice_side = shoot_ds;
80         dam = shoot_base;
81         break;
82     case MS_XXX2:
83         return -1;
84     case MS_XXX3:
85         return -1;
86     case MS_XXX4:
87         return -1;
88
89     case MS_BR_ACID:
90     case MS_BR_ELEC:
91     case MS_BR_FIRE:
92     case MS_BR_COLD:
93         dam = ((hp / 3) > 1600 ? 1600 : (hp / 3));
94         break;
95     case MS_BR_POIS:
96         dam = ((hp / 3) > 800 ? 800 : (hp / 3));
97         break;
98     case MS_BR_NETHER:
99         dam = ((hp / 6) > 550 ? 550 : (hp / 6));
100         break;
101     case MS_BR_LITE:
102     case MS_BR_DARK:
103         dam = ((hp / 6) > 400 ? 400 : (hp / 6));
104         break;
105     case MS_BR_CONF:
106     case MS_BR_SOUND:
107         dam = ((hp / 6) > 450 ? 450 : (hp / 6));
108         break;
109     case MS_BR_CHAOS:
110         dam = ((hp / 6) > 600 ? 600 : (hp / 6));
111         break;
112     case MS_BR_DISEN:
113         dam = ((hp / 6) > 500 ? 500 : (hp / 6));
114         break;
115     case MS_BR_NEXUS:
116         dam = ((hp / 3) > 250 ? 250 : (hp / 3));
117         break;
118     case MS_BR_TIME:
119         dam = ((hp / 3) > 150 ? 150 : (hp / 3));
120         break;
121     case MS_BR_INERTIA:
122     case MS_BR_GRAVITY:
123         dam = ((hp / 6) > 200 ? 200 : (hp / 6));
124         break;
125     case MS_BR_SHARDS:
126         dam = ((hp / 6) > 500 ? 500 : (hp / 6));
127         break;
128     case MS_BR_PLASMA:
129         dam = ((hp / 6) > 150 ? 150 : (hp / 6));
130         break;
131     case MS_BR_FORCE:
132         dam = ((hp / 6) > 200 ? 200 : (hp / 6));
133         break;
134     case MS_BR_MANA:
135         dam = ((hp / 3) > 250 ? 250 : (hp / 3));
136         break;
137     case MS_BALL_NUKE:
138         mult = powerful ? 2 : 1;
139         dam = rlev * (mult / div);
140         dice_num = 10;
141         dice_side = 6;
142         break;
143     case MS_BR_NUKE:
144         dam = ((hp / 3) > 800 ? 800 : (hp / 3));
145         break;
146     case MS_BALL_CHAOS:
147         dam = (powerful ? (rlev * 3) : (rlev * 2));
148         dice_num = 10;
149         dice_side = 10;
150         break;
151     case MS_BR_DISI:
152         dam = ((hp / 6) > 150 ? 150 : (hp / 6));
153         break;
154     case MS_BALL_ACID:
155         if (powerful) {
156             dam = (rlev * 4) + 50;
157             dice_num = 10;
158             dice_side = 10;
159         } else {
160             dam = 15;
161             dice_num = 1;
162             dice_side = rlev * 3;
163         }
164
165         break;
166     case MS_BALL_ELEC:
167         if (powerful) {
168             dam = (rlev * 4) + 50;
169             dice_num = 10;
170             dice_side = 10;
171         } else {
172             dam = 8;
173             dice_num = 1;
174             dice_side = rlev * 3 / 2;
175         }
176
177         break;
178     case MS_BALL_FIRE:
179         if (powerful) {
180             dam = (rlev * 4) + 50;
181             dice_num = 10;
182             dice_side = 10;
183         } else {
184             dam = 10;
185             dice_num = 1;
186             dice_side = rlev * 7 / 2;
187         }
188
189         break;
190     case MS_BALL_COLD:
191         if (powerful) {
192             dam = (rlev * 4) + 50;
193             dice_num = 10;
194             dice_side = 10;
195         } else {
196             dam = 10;
197             dice_num = 1;
198             dice_side = rlev * 3 / 2;
199         }
200
201         break;
202     case MS_BALL_POIS:
203         mult = powerful ? 2 : 1;
204         dice_num = 12;
205         dice_side = 2;
206         break;
207     case MS_BALL_NETHER:
208         dam = 50 + rlev * (powerful ? 2 : 1);
209         dice_num = 10;
210         dice_side = 10;
211         break;
212     case MS_BALL_WATER:
213         dam = 50;
214         dice_num = 1;
215         dice_side = powerful ? (rlev * 3) : (rlev * 2);
216         break;
217     case MS_BALL_MANA:
218     case MS_BALL_DARK:
219         dam = (rlev * 4) + 50;
220         dice_num = 10;
221         dice_side = 10;
222         break;
223     case MS_DRAIN_MANA:
224         dam = rlev;
225         div = 1;
226         dice_num = 1;
227         dice_side = rlev;
228         break;
229     case MS_MIND_BLAST:
230         dice_num = 7;
231         dice_side = 7;
232         break;
233     case MS_BRAIN_SMASH:
234         dice_num = 12;
235         dice_side = 12;
236         break;
237     case MS_CAUSE_1:
238         dice_num = 3;
239         dice_side = 8;
240         break;
241     case MS_CAUSE_2:
242         dice_num = 8;
243         dice_side = 8;
244         break;
245     case MS_CAUSE_3:
246         dice_num = 10;
247         dice_side = 15;
248         break;
249     case MS_CAUSE_4:
250         dice_num = 15;
251         dice_side = 15;
252         break;
253     case MS_BOLT_ACID:
254         mult = powerful ? 2 : 1;
255         dam = rlev / 3 * (mult / div);
256         dice_num = 7;
257         dice_side = 8;
258         break;
259     case MS_BOLT_ELEC:
260         mult = powerful ? 2 : 1;
261         dam = rlev / 3 * (mult / div);
262         dice_num = 4;
263         dice_side = 8;
264         break;
265     case MS_BOLT_FIRE:
266         mult = powerful ? 2 : 1;
267         dam = rlev / 3 * (mult / div);
268         dice_num = 9;
269         dice_side = 8;
270         break;
271     case MS_BOLT_COLD:
272         mult = powerful ? 2 : 1;
273         dam = rlev / 3 * (mult / div);
274         dice_num = 6;
275         dice_side = 8;
276         break;
277     case MS_STARBURST:
278         dam = (rlev * 4) + 50;
279         dice_num = 10;
280         dice_side = 10;
281         break;
282     case MS_BOLT_NETHER:
283         dam = 30 + (rlev * 4) / (powerful ? 2 : 3);
284         dice_num = 5;
285         dice_side = 5;
286         break;
287     case MS_BOLT_WATER:
288         dam = (rlev * 3 / (powerful ? 2 : 3));
289         dice_num = 10;
290         dice_side = 10;
291         break;
292     case MS_BOLT_MANA:
293         dam = 50;
294         dice_num = 1;
295         dice_side = rlev * 7 / 2;
296         break;
297     case MS_BOLT_PLASMA:
298         dam = 10 + (rlev * 3 / (powerful ? 2 : 3));
299         dice_num = 8;
300         dice_side = 7;
301         break;
302     case MS_BOLT_ICE:
303         dam = (rlev * 3 / (powerful ? 2 : 3));
304         dice_num = 6;
305         dice_side = 6;
306         break;
307     case MS_MAGIC_MISSILE:
308         dam = (rlev / 3);
309         dice_num = 2;
310         dice_side = 6;
311         break;
312     case MS_SCARE:
313         return -1;
314     case MS_BLIND:
315         return -1;
316     case MS_CONF:
317         return -1;
318     case MS_SLOW:
319         return -1;
320     case MS_SLEEP:
321         return -1;
322     case MS_SPEED:
323         return -1;
324
325     case MS_HAND_DOOM:
326         mult = target_ptr->chp;
327         div = 100;
328         dam = 40 * (mult / div);
329         dice_num = 1;
330         dice_side = 20;
331         break;
332
333     case MS_HEAL:
334         return -1;
335     case MS_INVULNER:
336         return -1;
337     case MS_BLINK:
338         return -1;
339     case MS_TELEPORT:
340         return -1;
341     case MS_WORLD:
342         return -1;
343     case MS_SPECIAL:
344         return -1;
345     case MS_TELE_TO:
346         return -1;
347     case MS_TELE_AWAY:
348         return -1;
349     case MS_TELE_LEVEL:
350         return -1;
351
352     case MS_PSY_SPEAR:
353         dam = powerful ? 150 : 100;
354         dice_num = 1;
355         dice_side = powerful ? (rlev * 2) : (rlev * 3 / 2);
356         break;
357
358     case MS_DARKNESS:
359         return -1;
360     case MS_MAKE_TRAP:
361         return -1;
362     case MS_FORGET:
363         return -1;
364     case MS_RAISE_DEAD:
365         return -1;
366     case MS_S_KIN:
367         return -1;
368     case MS_S_CYBER:
369         return -1;
370     case MS_S_MONSTER:
371         return -1;
372     case MS_S_MONSTERS:
373         return -1;
374     case MS_S_ANT:
375         return -1;
376     case MS_S_SPIDER:
377         return -1;
378     case MS_S_HOUND:
379         return -1;
380     case MS_S_HYDRA:
381         return -1;
382     case MS_S_ANGEL:
383         return -1;
384     case MS_S_DEMON:
385         return -1;
386     case MS_S_UNDEAD:
387         return -1;
388     case MS_S_DRAGON:
389         return -1;
390     case MS_S_HI_UNDEAD:
391         return -1;
392     case MS_S_HI_DRAGON:
393         return -1;
394     case MS_S_AMBERITE:
395         return -1;
396     case MS_S_UNIQUE:
397         return -1;
398     }
399
400     return monspell_damage_roll(dam, dice_num, dice_side, mult, div, TYPE);
401 }
402
403 /*!
404  * @brief モンスターの使う射撃のダイス情報を返す /
405  * @param r_ptr モンスター種族への参照ポインタ
406  * @param dd ダイス数への参照ポインタ
407  * @param ds ダイス面への参照ポインタ
408  * @return なし
409  */
410 void monspell_shoot_dice(monster_race *r_ptr, int *dd, int *ds)
411 {
412     int p = -1; /* Position of SHOOT */
413     int n = 0; /* Number of blows */
414     const int max_blows = 4;
415     for (int m = 0; m < max_blows; m++) {
416         if (r_ptr->blow[m].method != RBM_NONE)
417             n++; /* Count blows */
418
419         if (r_ptr->blow[m].method == RBM_SHOOT) {
420             p = m; /* Remember position */
421             break;
422         }
423     }
424
425     /* When full blows, use a first damage */
426     if (n == max_blows)
427         p = 0;
428
429     if (p < 0) {
430         (*dd) = 0;
431         (*ds) = 0;
432     } else {
433         (*dd) = r_ptr->blow[p].d_dice;
434         (*ds) = r_ptr->blow[p].d_side;
435     }
436 }
437
438 /*!
439  * @brief モンスターの使う呪文の威力を返す /
440  * @param target_ptr プレーヤーへの参照ポインタ
441  * @param ms_type 呪文番号
442  * @param m_idx 呪文を唱えるモンスターID
443  * @param TYPE  DAM_MAXで最大値を返し、DAM_MINで最小値を返す。DAM_ROLLはダイスを振って値を決定する。
444  * @return 攻撃呪文のダメージを返す。攻撃呪文以外は-1を返す。
445  */
446 HIT_POINT monspell_damage(player_type *target_ptr, monster_spell_type ms_type, MONSTER_IDX m_idx, int TYPE)
447 {
448     floor_type *floor_ptr = target_ptr->current_floor_ptr;
449     monster_type *m_ptr = &floor_ptr->m_list[m_idx];
450     monster_race *r_ptr = &r_info[m_ptr->r_idx];
451     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
452     HIT_POINT hp = (TYPE == DAM_ROLL) ? m_ptr->hp : m_ptr->max_maxhp;
453     int shoot_dd, shoot_ds;
454
455     monspell_shoot_dice(r_ptr, &shoot_dd, &shoot_ds);
456     return monspell_damage_base(target_ptr, ms_type, hp, rlev, monster_is_powerful(floor_ptr, m_idx), shoot_dd, shoot_ds, 0, TYPE);
457 }
458
459 /*!
460  * @brief モンスターの使う所属としての呪文の威力を返す /
461  * @param target_ptr プレーヤーへの参照ポインタ
462  * @param ms_type 呪文番号
463  * @param r_idx 呪文を唱えるモンスターの種族ID
464  * @param TYPE  DAM_MAXで最大値を返し、DAM_MINで最小値を返す。DAM_ROLLはダイスを振って値を決定する。
465  * @return 攻撃呪文のダメージを返す。攻撃呪文以外は-1を返す。
466  */
467 HIT_POINT monspell_race_damage(player_type *target_ptr, monster_spell_type ms_type, MONRACE_IDX r_idx, int TYPE)
468 {
469     monster_race *r_ptr = &r_info[r_idx];
470     DEPTH rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
471     bool powerful = r_ptr->flags2 & RF2_POWERFUL ? TRUE : FALSE;
472     HIT_POINT hp = r_ptr->hdice * (ironman_nightmare ? 2 : 1) * r_ptr->hside;
473     int shoot_dd, shoot_ds;
474
475     monspell_shoot_dice(r_ptr, &shoot_dd, &shoot_ds);
476     return monspell_damage_base(target_ptr, ms_type, MIN(30000, hp), rlev, powerful, shoot_dd, shoot_ds, 0, TYPE);
477 }
478
479 /*!
480  * @brief 青魔導師の使う呪文の威力を返す /
481  * @param target_ptr プレーヤーへの参照ポインタ
482  * @param SPELL_NUM 呪文番号
483  * @param plev 使用するレベル。2倍して扱う。
484  * @param TYPE  DAM_MAXで最大値を返し、DAM_MINで最小値を返す。DAM_ROLLはダイスを振って値を決定する。
485  * @return 攻撃呪文のダメージを返す。攻撃呪文以外は-1を返す。
486  */
487 HIT_POINT monspell_bluemage_damage(player_type *target_ptr, monster_spell_type ms_type, PLAYER_LEVEL plev, int TYPE)
488 {
489     int hp = target_ptr->chp;
490     int shoot_dd = 1, shoot_ds = 1, shoot_base = 0;
491     object_type *o_ptr = NULL;
492
493     if (has_melee_weapon(target_ptr, INVEN_MAIN_HAND))
494         o_ptr = &target_ptr->inventory_list[INVEN_MAIN_HAND];
495     else if (has_melee_weapon(target_ptr, INVEN_SUB_HAND))
496         o_ptr = &target_ptr->inventory_list[INVEN_SUB_HAND];
497
498     if (o_ptr) {
499         shoot_dd = o_ptr->dd;
500         shoot_ds = o_ptr->ds;
501         shoot_base = o_ptr->to_d;
502     }
503
504     return monspell_damage_base(target_ptr, ms_type, hp, plev * 2, FALSE, shoot_dd, shoot_ds, shoot_base, TYPE);
505 }