OSDN Git Service

[Refactor] #1172 Changed '(TRUE)', 'TRUE;' and 'FALSE;' to '(true)', 'true;' and...
[hengbandforosx/hengbandosx.git] / src / mspell / mspell-damage-calculator.cpp
1 #include "mspell/mspell-damage-calculator.h"
2 #include "game-option/birth-options.h"
3 #include "inventory/inventory-slot-types.h"
4 #include "monster-race/monster-race.h"
5 #include "monster-race/race-ability-flags.h"
6 #include "monster-race/race-flags2.h"
7 #include "monster/monster-status.h"
8 #include "player-info/equipment-info.h"
9 #include "system/floor-type-definition.h"
10 #include "system/monster-race-definition.h"
11 #include "system/monster-type-definition.h"
12 #include "system/object-type-definition.h"
13 #include "system/player-type-definition.h"
14
15 /*!
16  * @brief モンスターの使う呪文の威力を決定する /
17  * @param dam 定数値
18  * @param dice_num ダイス数
19  * @param dice_side ダイス面
20  * @param mult ダイス倍率
21  * @param div ダイス倍率
22  * @param TYPE  DAM_MAXで最大値を返し、DAM_MINで最小値を返す。DAM_ROLLはダイスを振って値を決定する。
23  * @return 攻撃呪文のダメージを返す。攻撃呪文以外は-1を返す。
24  */
25 static HIT_POINT monspell_damage_roll(HIT_POINT dam, int dice_num, int dice_side, int mult, int div, int TYPE)
26 {
27     switch (TYPE) {
28     case DAM_MAX:
29         dam += maxroll(dice_num, dice_side) * mult / div;
30         break;
31     case DAM_MIN:
32         dam += dice_num * 1 * mult / div;
33         break;
34     case DAM_ROLL:
35         dam += damroll(dice_num, dice_side) * mult / div;
36         break;
37     case DICE_NUM:
38         return dice_num;
39     case DICE_SIDE:
40         return dice_side;
41     case DICE_MULT:
42         return mult;
43     case DICE_DIV:
44         return div;
45     case BASE_DAM:
46         return dam;
47     }
48
49     if (dam < 1)
50         dam = 1;
51     return dam;
52 }
53
54 /*!
55  * @brief モンスターの使う呪文の威力を返す /
56  * @param target_ptr プレーヤーへの参照ポインタ (破滅の手用)
57  * @param SPELL_NUM 呪文番号
58  * @param hp 呪文を唱えるモンスターの体力
59  * @param rlev 呪文を唱えるモンスターのレベル
60  * @param powerful 呪文を唱えるモンスターのpowerfulフラグ
61  * @param shoot_dd 射撃のダイス数
62  * @param shoot_ds 射撃のダイス面
63  * @param shoot_base 射撃の固定威力値
64  * @param TYPE  DAM_MAXで最大値を返し、DAM_MINで最小値を返す。DAM_ROLLはダイスを振って値を決定する。
65  * @return 攻撃呪文のダメージを返す。攻撃呪文以外は-1を返す。
66  */
67 static HIT_POINT monspell_damage_base(
68     player_type *target_ptr, RF_ABILITY ms_type, int hp, int rlev, bool powerful, int shoot_dd, int shoot_ds, int shoot_base, int TYPE)
69 {
70     HIT_POINT dam = 0, dice_num = 0, dice_side = 0, mult = 1, div = 1;
71
72     switch (ms_type) {
73     case RF_ABILITY::SHRIEK:
74         return -1;
75     case RF_ABILITY::XXX1:
76         return -1;
77     case RF_ABILITY::DISPEL:
78         return -1;
79     case RF_ABILITY::ROCKET:
80         dam = (hp / 4) > 800 ? 800 : (hp / 4);
81         break;
82     case RF_ABILITY::SHOOT:
83         dice_num = shoot_dd;
84         dice_side = shoot_ds;
85         dam = shoot_base;
86         break;
87     case RF_ABILITY::XXX2:
88         return -1;
89     case RF_ABILITY::XXX3:
90         return -1;
91     case RF_ABILITY::XXX4:
92         return -1;
93
94     case RF_ABILITY::BR_ACID:
95     case RF_ABILITY::BR_ELEC:
96     case RF_ABILITY::BR_FIRE:
97     case RF_ABILITY::BR_COLD:
98         dam = ((hp / 3) > 1600 ? 1600 : (hp / 3));
99         break;
100     case RF_ABILITY::BR_POIS:
101         dam = ((hp / 3) > 800 ? 800 : (hp / 3));
102         break;
103     case RF_ABILITY::BR_NETH:
104         dam = ((hp / 6) > 550 ? 550 : (hp / 6));
105         break;
106     case RF_ABILITY::BR_LITE:
107     case RF_ABILITY::BR_DARK:
108         dam = ((hp / 6) > 400 ? 400 : (hp / 6));
109         break;
110     case RF_ABILITY::BR_CONF:
111     case RF_ABILITY::BR_SOUN:
112         dam = ((hp / 6) > 450 ? 450 : (hp / 6));
113         break;
114     case RF_ABILITY::BR_CHAO:
115         dam = ((hp / 6) > 600 ? 600 : (hp / 6));
116         break;
117     case RF_ABILITY::BR_DISE:
118         dam = ((hp / 6) > 500 ? 500 : (hp / 6));
119         break;
120     case RF_ABILITY::BR_NEXU:
121         dam = ((hp / 3) > 250 ? 250 : (hp / 3));
122         break;
123     case RF_ABILITY::BR_TIME:
124         dam = ((hp / 3) > 150 ? 150 : (hp / 3));
125         break;
126     case RF_ABILITY::BR_INER:
127     case RF_ABILITY::BR_GRAV:
128         dam = ((hp / 6) > 200 ? 200 : (hp / 6));
129         break;
130     case RF_ABILITY::BR_SHAR:
131         dam = ((hp / 6) > 500 ? 500 : (hp / 6));
132         break;
133     case RF_ABILITY::BR_PLAS:
134         dam = ((hp / 6) > 150 ? 150 : (hp / 6));
135         break;
136     case RF_ABILITY::BR_FORC:
137         dam = ((hp / 6) > 200 ? 200 : (hp / 6));
138         break;
139     case RF_ABILITY::BR_MANA:
140         dam = ((hp / 3) > 250 ? 250 : (hp / 3));
141         break;
142     case RF_ABILITY::BA_NUKE:
143         mult = powerful ? 2 : 1;
144         dam = rlev * (mult / div);
145         dice_num = 10;
146         dice_side = 6;
147         break;
148     case RF_ABILITY::BR_NUKE:
149         dam = ((hp / 3) > 800 ? 800 : (hp / 3));
150         break;
151     case RF_ABILITY::BA_CHAO:
152         dam = (powerful ? (rlev * 3) : (rlev * 2));
153         dice_num = 10;
154         dice_side = 10;
155         break;
156     case RF_ABILITY::BR_DISI:
157         dam = ((hp / 6) > 150 ? 150 : (hp / 6));
158         break;
159     case RF_ABILITY::BA_ACID:
160         if (powerful) {
161             dam = (rlev * 4) + 50;
162             dice_num = 10;
163             dice_side = 10;
164         } else {
165             dam = 15;
166             dice_num = 1;
167             dice_side = rlev * 3;
168         }
169
170         break;
171     case RF_ABILITY::BA_ELEC:
172         if (powerful) {
173             dam = (rlev * 4) + 50;
174             dice_num = 10;
175             dice_side = 10;
176         } else {
177             dam = 8;
178             dice_num = 1;
179             dice_side = rlev * 3 / 2;
180         }
181
182         break;
183     case RF_ABILITY::BA_FIRE:
184         if (powerful) {
185             dam = (rlev * 4) + 50;
186             dice_num = 10;
187             dice_side = 10;
188         } else {
189             dam = 10;
190             dice_num = 1;
191             dice_side = rlev * 7 / 2;
192         }
193
194         break;
195     case RF_ABILITY::BA_COLD:
196         if (powerful) {
197             dam = (rlev * 4) + 50;
198             dice_num = 10;
199             dice_side = 10;
200         } else {
201             dam = 10;
202             dice_num = 1;
203             dice_side = rlev * 3 / 2;
204         }
205
206         break;
207     case RF_ABILITY::BA_POIS:
208         mult = powerful ? 2 : 1;
209         dice_num = 12;
210         dice_side = 2;
211         break;
212     case RF_ABILITY::BA_NETH:
213         dam = 50 + rlev * (powerful ? 2 : 1);
214         dice_num = 10;
215         dice_side = 10;
216         break;
217     case RF_ABILITY::BA_WATE:
218         dam = 50;
219         dice_num = 1;
220         dice_side = powerful ? (rlev * 3) : (rlev * 2);
221         break;
222     case RF_ABILITY::BA_MANA:
223     case RF_ABILITY::BA_DARK:
224         dam = (rlev * 4) + 50;
225         dice_num = 10;
226         dice_side = 10;
227         break;
228     case RF_ABILITY::DRAIN_MANA:
229         dam = rlev;
230         div = 1;
231         dice_num = 1;
232         dice_side = rlev;
233         break;
234     case RF_ABILITY::MIND_BLAST:
235         dice_num = 7;
236         dice_side = 7;
237         break;
238     case RF_ABILITY::BRAIN_SMASH:
239         dice_num = 12;
240         dice_side = 12;
241         break;
242     case RF_ABILITY::CAUSE_1:
243         dice_num = 3;
244         dice_side = 8;
245         break;
246     case RF_ABILITY::CAUSE_2:
247         dice_num = 8;
248         dice_side = 8;
249         break;
250     case RF_ABILITY::CAUSE_3:
251         dice_num = 10;
252         dice_side = 15;
253         break;
254     case RF_ABILITY::CAUSE_4:
255         dice_num = 15;
256         dice_side = 15;
257         break;
258     case RF_ABILITY::BO_ACID:
259         mult = powerful ? 2 : 1;
260         dam = rlev / 3 * (mult / div);
261         dice_num = 7;
262         dice_side = 8;
263         break;
264     case RF_ABILITY::BO_ELEC:
265         mult = powerful ? 2 : 1;
266         dam = rlev / 3 * (mult / div);
267         dice_num = 4;
268         dice_side = 8;
269         break;
270     case RF_ABILITY::BO_FIRE:
271         mult = powerful ? 2 : 1;
272         dam = rlev / 3 * (mult / div);
273         dice_num = 9;
274         dice_side = 8;
275         break;
276     case RF_ABILITY::BO_COLD:
277         mult = powerful ? 2 : 1;
278         dam = rlev / 3 * (mult / div);
279         dice_num = 6;
280         dice_side = 8;
281         break;
282     case RF_ABILITY::BA_LITE:
283         dam = (rlev * 4) + 50;
284         dice_num = 10;
285         dice_side = 10;
286         break;
287     case RF_ABILITY::BO_NETH:
288         dam = 30 + (rlev * 4) / (powerful ? 2 : 3);
289         dice_num = 5;
290         dice_side = 5;
291         break;
292     case RF_ABILITY::BO_WATE:
293         dam = (rlev * 3 / (powerful ? 2 : 3));
294         dice_num = 10;
295         dice_side = 10;
296         break;
297     case RF_ABILITY::BO_MANA:
298         dam = 50;
299         dice_num = 1;
300         dice_side = rlev * 7 / 2;
301         break;
302     case RF_ABILITY::BO_PLAS:
303         dam = 10 + (rlev * 3 / (powerful ? 2 : 3));
304         dice_num = 8;
305         dice_side = 7;
306         break;
307     case RF_ABILITY::BO_ICEE:
308         dam = (rlev * 3 / (powerful ? 2 : 3));
309         dice_num = 6;
310         dice_side = 6;
311         break;
312     case RF_ABILITY::MISSILE:
313         dam = (rlev / 3);
314         dice_num = 2;
315         dice_side = 6;
316         break;
317     case RF_ABILITY::SCARE:
318         return -1;
319     case RF_ABILITY::BLIND:
320         return -1;
321     case RF_ABILITY::CONF:
322         return -1;
323     case RF_ABILITY::SLOW:
324         return -1;
325     case RF_ABILITY::HOLD:
326         return -1;
327     case RF_ABILITY::HASTE:
328         return -1;
329
330     case RF_ABILITY::HAND_DOOM:
331         mult = target_ptr->chp;
332         div = 100;
333         dam = 40 * (mult / div);
334         dice_num = 1;
335         dice_side = 20;
336         break;
337
338     case RF_ABILITY::HEAL:
339         return -1;
340     case RF_ABILITY::INVULNER:
341         return -1;
342     case RF_ABILITY::BLINK:
343         return -1;
344     case RF_ABILITY::TPORT:
345         return -1;
346     case RF_ABILITY::WORLD:
347         return -1;
348     case RF_ABILITY::SPECIAL:
349         return -1;
350     case RF_ABILITY::TELE_TO:
351         return -1;
352     case RF_ABILITY::TELE_AWAY:
353         return -1;
354     case RF_ABILITY::TELE_LEVEL:
355         return -1;
356
357     case RF_ABILITY::PSY_SPEAR:
358         dam = powerful ? 150 : 100;
359         dice_num = 1;
360         dice_side = powerful ? (rlev * 2) : (rlev * 3 / 2);
361         break;
362
363     case RF_ABILITY::DARKNESS:
364         return -1;
365     case RF_ABILITY::TRAPS:
366         return -1;
367     case RF_ABILITY::FORGET:
368         return -1;
369     case RF_ABILITY::RAISE_DEAD:
370         return -1;
371     case RF_ABILITY::S_KIN:
372         return -1;
373     case RF_ABILITY::S_CYBER:
374         return -1;
375     case RF_ABILITY::S_MONSTER:
376         return -1;
377     case RF_ABILITY::S_MONSTERS:
378         return -1;
379     case RF_ABILITY::S_ANT:
380         return -1;
381     case RF_ABILITY::S_SPIDER:
382         return -1;
383     case RF_ABILITY::S_HOUND:
384         return -1;
385     case RF_ABILITY::S_HYDRA:
386         return -1;
387     case RF_ABILITY::S_ANGEL:
388         return -1;
389     case RF_ABILITY::S_DEMON:
390         return -1;
391     case RF_ABILITY::S_UNDEAD:
392         return -1;
393     case RF_ABILITY::S_DRAGON:
394         return -1;
395     case RF_ABILITY::S_HI_UNDEAD:
396         return -1;
397     case RF_ABILITY::S_HI_DRAGON:
398         return -1;
399     case RF_ABILITY::S_AMBERITES:
400         return -1;
401     case RF_ABILITY::S_UNIQUE:
402         return -1;
403     case RF_ABILITY::MAX:
404         return -1;
405     }
406
407     return monspell_damage_roll(dam, dice_num, dice_side, mult, div, TYPE);
408 }
409
410 /*!
411  * @brief モンスターの使う射撃のダイス情報を返す /
412  * @param r_ptr モンスター種族への参照ポインタ
413  * @param dd ダイス数への参照ポインタ
414  * @param ds ダイス面への参照ポインタ
415  */
416 void monspell_shoot_dice(monster_race *r_ptr, int *dd, int *ds)
417 {
418     int p = -1; /* Position of SHOOT */
419     int n = 0; /* Number of blows */
420     const int max_blows = 4;
421     for (int m = 0; m < max_blows; m++) {
422         if (r_ptr->blow[m].method != RBM_NONE)
423             n++; /* Count blows */
424
425         if (r_ptr->blow[m].method == RBM_SHOOT) {
426             p = m; /* Remember position */
427             break;
428         }
429     }
430
431     /* When full blows, use a first damage */
432     if (n == max_blows)
433         p = 0;
434
435     if (p < 0) {
436         (*dd) = 0;
437         (*ds) = 0;
438     } else {
439         (*dd) = r_ptr->blow[p].d_dice;
440         (*ds) = r_ptr->blow[p].d_side;
441     }
442 }
443
444 /*!
445  * @brief モンスターの使う呪文の威力を返す /
446  * @param target_ptr プレーヤーへの参照ポインタ
447  * @param ms_type 呪文番号
448  * @param m_idx 呪文を唱えるモンスターID
449  * @param TYPE  DAM_MAXで最大値を返し、DAM_MINで最小値を返す。DAM_ROLLはダイスを振って値を決定する。
450  * @return 攻撃呪文のダメージを返す。攻撃呪文以外は-1を返す。
451  */
452 HIT_POINT monspell_damage(player_type *target_ptr, RF_ABILITY ms_type, MONSTER_IDX m_idx, int TYPE)
453 {
454     floor_type *floor_ptr = target_ptr->current_floor_ptr;
455     monster_type *m_ptr = &floor_ptr->m_list[m_idx];
456     monster_race *r_ptr = &r_info[m_ptr->r_idx];
457     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
458     HIT_POINT hp = (TYPE == DAM_ROLL) ? m_ptr->hp : m_ptr->max_maxhp;
459     int shoot_dd, shoot_ds;
460
461     monspell_shoot_dice(r_ptr, &shoot_dd, &shoot_ds);
462     return monspell_damage_base(target_ptr, ms_type, hp, rlev, monster_is_powerful(floor_ptr, m_idx), shoot_dd, shoot_ds, 0, TYPE);
463 }
464
465 /*!
466  * @brief モンスターの使う所属としての呪文の威力を返す /
467  * @param target_ptr プレーヤーへの参照ポインタ
468  * @param ms_type 呪文番号
469  * @param r_idx 呪文を唱えるモンスターの種族ID
470  * @param TYPE  DAM_MAXで最大値を返し、DAM_MINで最小値を返す。DAM_ROLLはダイスを振って値を決定する。
471  * @return 攻撃呪文のダメージを返す。攻撃呪文以外は-1を返す。
472  */
473 HIT_POINT monspell_race_damage(player_type *target_ptr, RF_ABILITY ms_type, MONRACE_IDX r_idx, int TYPE)
474 {
475     monster_race *r_ptr = &r_info[r_idx];
476     DEPTH rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
477     bool powerful = r_ptr->flags2 & RF2_POWERFUL ? TRUE : false;
478     HIT_POINT hp = r_ptr->hdice * (ironman_nightmare ? 2 : 1) * r_ptr->hside;
479     int shoot_dd, shoot_ds;
480
481     monspell_shoot_dice(r_ptr, &shoot_dd, &shoot_ds);
482     return monspell_damage_base(target_ptr, ms_type, MIN(30000, hp), rlev, powerful, shoot_dd, shoot_ds, 0, TYPE);
483 }
484
485 /*!
486  * @brief 青魔導師の使う呪文の威力を返す /
487  * @param target_ptr プレーヤーへの参照ポインタ
488  * @param SPELL_NUM 呪文番号
489  * @param plev 使用するレベル。2倍して扱う。
490  * @param TYPE  DAM_MAXで最大値を返し、DAM_MINで最小値を返す。DAM_ROLLはダイスを振って値を決定する。
491  * @return 攻撃呪文のダメージを返す。攻撃呪文以外は-1を返す。
492  */
493 HIT_POINT monspell_bluemage_damage(player_type *target_ptr, RF_ABILITY ms_type, PLAYER_LEVEL plev, int TYPE)
494 {
495     int hp = target_ptr->chp;
496     int shoot_dd = 1, shoot_ds = 1, shoot_base = 0;
497     object_type *o_ptr = NULL;
498
499     if (has_melee_weapon(target_ptr, INVEN_MAIN_HAND))
500         o_ptr = &target_ptr->inventory_list[INVEN_MAIN_HAND];
501     else if (has_melee_weapon(target_ptr, INVEN_SUB_HAND))
502         o_ptr = &target_ptr->inventory_list[INVEN_SUB_HAND];
503
504     if (o_ptr) {
505         shoot_dd = o_ptr->dd;
506         shoot_ds = o_ptr->ds;
507         shoot_base = o_ptr->to_d;
508     }
509
510     return monspell_damage_base(target_ptr, ms_type, hp, plev * 2, FALSE, shoot_dd, shoot_ds, shoot_base, TYPE);
511 }