OSDN Git Service

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