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 #include "util/bit-flags-calculator.h"
17 * @brief モンスターの使う呪文の威力を決定する /
19 * @param dice_num ダイス数
20 * @param dice_side ダイス面
23 * @param TYPE DAM_MAXで最大値を返し、DAM_MINで最小値を返す。DAM_ROLLはダイスを振って値を決定する。
24 * @return 攻撃呪文のダメージを返す。攻撃呪文以外は-1を返す。
26 static HIT_POINT monspell_damage_roll(HIT_POINT dam, int dice_num, int dice_side, int mult, int div, int TYPE)
30 dam += maxroll(dice_num, dice_side) * mult / div;
33 dam += dice_num * 1 * mult / div;
36 dam += damroll(dice_num, dice_side) * mult / div;
56 * @brief モンスターの使う呪文の威力を返す /
57 * @param player_ptr プレイヤーへの参照ポインタ (破滅の手用)
58 * @param SPELL_NUM 呪文番号
59 * @param hp 呪文を唱えるモンスターの体力
60 * @param rlev 呪文を唱えるモンスターのレベル
61 * @param powerful 呪文を唱えるモンスターのpowerfulフラグ
62 * @param shoot_dd 射撃のダイス数
63 * @param shoot_ds 射撃のダイス面
64 * @param shoot_base 射撃の固定威力値
65 * @param TYPE DAM_MAXで最大値を返し、DAM_MINで最小値を返す。DAM_ROLLはダイスを振って値を決定する。
66 * @return 攻撃呪文のダメージを返す。攻撃呪文以外は-1を返す。
68 static HIT_POINT monspell_damage_base(
69 PlayerType *player_ptr, MonsterAbilityType ms_type, int hp, int rlev, bool powerful, int shoot_dd, int shoot_ds, int shoot_base, int TYPE)
71 HIT_POINT dam = 0, dice_num = 0, dice_side = 0, mult = 1, div = 1;
74 case MonsterAbilityType::SHRIEK:
76 case MonsterAbilityType::XXX1:
78 case MonsterAbilityType::DISPEL:
80 case MonsterAbilityType::ROCKET:
81 dam = (hp / 4) > 800 ? 800 : (hp / 4);
83 case MonsterAbilityType::SHOOT:
88 case MonsterAbilityType::XXX2:
90 case MonsterAbilityType::XXX3:
92 case MonsterAbilityType::XXX4:
95 case MonsterAbilityType::BR_ACID:
96 case MonsterAbilityType::BR_ELEC:
97 case MonsterAbilityType::BR_FIRE:
98 case MonsterAbilityType::BR_COLD:
99 dam = ((hp / 3) > 1600 ? 1600 : (hp / 3));
101 case MonsterAbilityType::BR_POIS:
102 dam = ((hp / 3) > 800 ? 800 : (hp / 3));
104 case MonsterAbilityType::BR_NETH:
105 dam = ((hp / 6) > 550 ? 550 : (hp / 6));
107 case MonsterAbilityType::BR_LITE:
108 case MonsterAbilityType::BR_DARK:
109 dam = ((hp / 6) > 400 ? 400 : (hp / 6));
111 case MonsterAbilityType::BR_CONF:
112 case MonsterAbilityType::BR_SOUN:
113 dam = ((hp / 6) > 450 ? 450 : (hp / 6));
115 case MonsterAbilityType::BR_CHAO:
116 dam = ((hp / 6) > 600 ? 600 : (hp / 6));
118 case MonsterAbilityType::BR_DISE:
119 dam = ((hp / 6) > 500 ? 500 : (hp / 6));
121 case MonsterAbilityType::BR_NEXU:
122 dam = ((hp / 3) > 250 ? 250 : (hp / 3));
124 case MonsterAbilityType::BR_TIME:
125 dam = ((hp / 3) > 150 ? 150 : (hp / 3));
127 case MonsterAbilityType::BR_INER:
128 case MonsterAbilityType::BR_GRAV:
129 dam = ((hp / 6) > 200 ? 200 : (hp / 6));
131 case MonsterAbilityType::BR_SHAR:
132 dam = ((hp / 6) > 500 ? 500 : (hp / 6));
134 case MonsterAbilityType::BR_PLAS:
135 dam = ((hp / 6) > 150 ? 150 : (hp / 6));
137 case MonsterAbilityType::BR_FORC:
138 dam = ((hp / 6) > 200 ? 200 : (hp / 6));
140 case MonsterAbilityType::BR_MANA:
141 dam = ((hp / 3) > 250 ? 250 : (hp / 3));
143 case MonsterAbilityType::BA_NUKE:
144 mult = powerful ? 2 : 1;
145 dam = rlev * (mult / div);
149 case MonsterAbilityType::BR_NUKE:
150 dam = ((hp / 3) > 800 ? 800 : (hp / 3));
152 case MonsterAbilityType::BA_CHAO:
153 dam = (powerful ? (rlev * 3) : (rlev * 2));
157 case MonsterAbilityType::BR_DISI:
158 dam = ((hp / 6) > 150 ? 150 : (hp / 6));
160 case MonsterAbilityType::BR_VOID:
161 dam = ((hp / 3) > 250 ? 250 : (hp / 6));
163 case MonsterAbilityType::BR_ABYSS:
164 dam = ((hp / 3) > 250 ? 250 : (hp / 6));
166 case MonsterAbilityType::BA_ACID:
168 dam = (rlev * 4) + 50;
174 dice_side = rlev * 3;
178 case MonsterAbilityType::BA_ELEC:
180 dam = (rlev * 4) + 50;
186 dice_side = rlev * 3 / 2;
190 case MonsterAbilityType::BA_FIRE:
192 dam = (rlev * 4) + 50;
198 dice_side = rlev * 7 / 2;
202 case MonsterAbilityType::BA_COLD:
204 dam = (rlev * 4) + 50;
210 dice_side = rlev * 3 / 2;
214 case MonsterAbilityType::BA_POIS:
215 mult = powerful ? 2 : 1;
219 case MonsterAbilityType::BA_NETH:
220 dam = 50 + rlev * (powerful ? 2 : 1);
224 case MonsterAbilityType::BA_WATE:
227 dice_side = powerful ? (rlev * 3) : (rlev * 2);
229 case MonsterAbilityType::BA_MANA:
230 case MonsterAbilityType::BA_DARK:
231 dam = (rlev * 4) + 50;
235 case MonsterAbilityType::BA_VOID:
236 dam = (powerful ? (rlev * 3) : (rlev * 2));
240 case MonsterAbilityType::BA_ABYSS:
241 dam = (powerful ? (rlev * 3) : (rlev * 2));
245 case MonsterAbilityType::DRAIN_MANA:
251 case MonsterAbilityType::MIND_BLAST:
255 case MonsterAbilityType::BRAIN_SMASH:
259 case MonsterAbilityType::CAUSE_1:
263 case MonsterAbilityType::CAUSE_2:
267 case MonsterAbilityType::CAUSE_3:
271 case MonsterAbilityType::CAUSE_4:
275 case MonsterAbilityType::BO_ACID:
276 mult = powerful ? 2 : 1;
277 dam = rlev / 3 * (mult / div);
281 case MonsterAbilityType::BO_ELEC:
282 mult = powerful ? 2 : 1;
283 dam = rlev / 3 * (mult / div);
287 case MonsterAbilityType::BO_FIRE:
288 mult = powerful ? 2 : 1;
289 dam = rlev / 3 * (mult / div);
293 case MonsterAbilityType::BO_COLD:
294 mult = powerful ? 2 : 1;
295 dam = rlev / 3 * (mult / div);
299 case MonsterAbilityType::BA_LITE:
300 dam = (rlev * 4) + 50;
304 case MonsterAbilityType::BO_NETH:
305 dam = 30 + (rlev * 4) / (powerful ? 2 : 3);
309 case MonsterAbilityType::BO_WATE:
310 dam = (rlev * 3 / (powerful ? 2 : 3));
314 case MonsterAbilityType::BO_MANA:
317 dice_side = rlev * 7 / 2;
319 case MonsterAbilityType::BO_PLAS:
320 dam = 10 + (rlev * 3 / (powerful ? 2 : 3));
324 case MonsterAbilityType::BO_ICEE:
325 dam = (rlev * 3 / (powerful ? 2 : 3));
329 case MonsterAbilityType::BO_VOID:
330 dam = 10 + (rlev * 3 / (powerful ? 2 : 3));
334 case MonsterAbilityType::BO_ABYSS:
335 dam = 10 + (rlev * 3 / (powerful ? 2 : 3));
339 case MonsterAbilityType::MISSILE:
344 case MonsterAbilityType::SCARE:
346 case MonsterAbilityType::BLIND:
348 case MonsterAbilityType::CONF:
350 case MonsterAbilityType::SLOW:
352 case MonsterAbilityType::HOLD:
354 case MonsterAbilityType::HASTE:
357 case MonsterAbilityType::HAND_DOOM:
358 mult = player_ptr->chp;
360 dam = 40 * (mult / div);
365 case MonsterAbilityType::HEAL:
367 case MonsterAbilityType::INVULNER:
369 case MonsterAbilityType::BLINK:
371 case MonsterAbilityType::TPORT:
373 case MonsterAbilityType::WORLD:
375 case MonsterAbilityType::SPECIAL:
377 case MonsterAbilityType::TELE_TO:
379 case MonsterAbilityType::TELE_AWAY:
381 case MonsterAbilityType::TELE_LEVEL:
384 case MonsterAbilityType::PSY_SPEAR:
385 dam = powerful ? 150 : 100;
387 dice_side = powerful ? (rlev * 2) : (rlev * 3 / 2);
390 case MonsterAbilityType::DARKNESS:
392 case MonsterAbilityType::TRAPS:
394 case MonsterAbilityType::FORGET:
396 case MonsterAbilityType::RAISE_DEAD:
398 case MonsterAbilityType::S_KIN:
400 case MonsterAbilityType::S_CYBER:
402 case MonsterAbilityType::S_MONSTER:
404 case MonsterAbilityType::S_MONSTERS:
406 case MonsterAbilityType::S_ANT:
408 case MonsterAbilityType::S_SPIDER:
410 case MonsterAbilityType::S_HOUND:
412 case MonsterAbilityType::S_HYDRA:
414 case MonsterAbilityType::S_ANGEL:
416 case MonsterAbilityType::S_DEMON:
418 case MonsterAbilityType::S_UNDEAD:
420 case MonsterAbilityType::S_DRAGON:
422 case MonsterAbilityType::S_HI_UNDEAD:
424 case MonsterAbilityType::S_HI_DRAGON:
426 case MonsterAbilityType::S_AMBERITES:
428 case MonsterAbilityType::S_UNIQUE:
430 case MonsterAbilityType::MAX:
434 return monspell_damage_roll(dam, dice_num, dice_side, mult, div, TYPE);
438 * @brief モンスターの使う射撃のダイス情報を返す /
439 * @param r_ptr モンスター種族への参照ポインタ
440 * @param dd ダイス数への参照ポインタ
441 * @param ds ダイス面への参照ポインタ
443 void monspell_shoot_dice(monster_race *r_ptr, int *dd, int *ds)
445 int p = -1; /* Position of SHOOT */
446 int n = 0; /* Number of blows */
447 const int max_blows = 4;
448 for (int m = 0; m < max_blows; m++) {
449 if (r_ptr->blow[m].method != RaceBlowMethodType::NONE)
450 n++; /* Count blows */
452 if (r_ptr->blow[m].method == RaceBlowMethodType::SHOOT) {
453 p = m; /* Remember position */
458 /* When full blows, use a first damage */
466 (*dd) = r_ptr->blow[p].d_dice;
467 (*ds) = r_ptr->blow[p].d_side;
472 * @brief モンスターの使う呪文の威力を返す /
473 * @param player_ptr プレイヤーへの参照ポインタ
474 * @param ms_type 呪文番号
475 * @param m_idx 呪文を唱えるモンスターID
476 * @param TYPE DAM_MAXで最大値を返し、DAM_MINで最小値を返す。DAM_ROLLはダイスを振って値を決定する。
477 * @return 攻撃呪文のダメージを返す。攻撃呪文以外は-1を返す。
479 HIT_POINT monspell_damage(PlayerType *player_ptr, MonsterAbilityType ms_type, MONSTER_IDX m_idx, int TYPE)
481 floor_type *floor_ptr = player_ptr->current_floor_ptr;
482 monster_type *m_ptr = &floor_ptr->m_list[m_idx];
483 monster_race *r_ptr = &r_info[m_ptr->r_idx];
484 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
485 HIT_POINT hp = (TYPE == DAM_ROLL) ? m_ptr->hp : m_ptr->max_maxhp;
486 int shoot_dd, shoot_ds;
488 monspell_shoot_dice(r_ptr, &shoot_dd, &shoot_ds);
489 return monspell_damage_base(player_ptr, ms_type, hp, rlev, monster_is_powerful(floor_ptr, m_idx), shoot_dd, shoot_ds, 0, TYPE);
493 * @brief モンスターの使う所属としての呪文の威力を返す /
494 * @param player_ptr プレイヤーへの参照ポインタ
495 * @param ms_type 呪文番号
496 * @param r_idx 呪文を唱えるモンスターの種族ID
497 * @param TYPE DAM_MAXで最大値を返し、DAM_MINで最小値を返す。DAM_ROLLはダイスを振って値を決定する。
498 * @return 攻撃呪文のダメージを返す。攻撃呪文以外は-1を返す。
500 HIT_POINT monspell_race_damage(PlayerType *player_ptr, MonsterAbilityType ms_type, MONRACE_IDX r_idx, int TYPE)
502 monster_race *r_ptr = &r_info[r_idx];
503 DEPTH rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
504 bool powerful = any_bits(r_ptr->flags2, RF2_POWERFUL);
505 HIT_POINT hp = r_ptr->hdice * (ironman_nightmare ? 2 : 1) * r_ptr->hside;
506 int shoot_dd, shoot_ds;
508 monspell_shoot_dice(r_ptr, &shoot_dd, &shoot_ds);
509 return monspell_damage_base(player_ptr, ms_type, std::min(MONSTER_MAXHP, hp), rlev, powerful, shoot_dd, shoot_ds, 0, TYPE);
513 * @brief 青魔導師の使う呪文の威力を返す /
514 * @param player_ptr プレイヤーへの参照ポインタ
515 * @param SPELL_NUM 呪文番号
516 * @param plev 使用するレベル。2倍して扱う。
517 * @param TYPE DAM_MAXで最大値を返し、DAM_MINで最小値を返す。DAM_ROLLはダイスを振って値を決定する。
518 * @return 攻撃呪文のダメージを返す。攻撃呪文以外は-1を返す。
520 HIT_POINT monspell_bluemage_damage(PlayerType *player_ptr, MonsterAbilityType ms_type, PLAYER_LEVEL plev, int TYPE)
522 int hp = player_ptr->chp;
523 int shoot_dd = 1, shoot_ds = 1, shoot_base = 0;
524 object_type *o_ptr = nullptr;
526 if (has_melee_weapon(player_ptr, INVEN_MAIN_HAND))
527 o_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND];
528 else if (has_melee_weapon(player_ptr, INVEN_SUB_HAND))
529 o_ptr = &player_ptr->inventory_list[INVEN_SUB_HAND];
532 shoot_dd = o_ptr->dd;
533 shoot_ds = o_ptr->ds;
534 shoot_base = o_ptr->to_d;
537 return monspell_damage_base(player_ptr, ms_type, hp, plev * 2, false, shoot_dd, shoot_ds, shoot_base, TYPE);