OSDN Git Service

[Refactor] #37287 #37353 型の置換。 / Type replacement.
[hengband/hengband.git] / src / shoot.c
1 #include "angband.h"
2
3 /*!
4 * @brief プレイヤーからモンスターへの射撃命中判定 /
5 * Determine if the player "hits" a monster (normal combat).
6 * @param chance 基本命中値
7 * @param m_ptr モンスターの構造体参照ポインタ
8 * @param vis 目標を視界に捕らえているならばTRUEを指定
9 * @param o_name メッセージ表示時のモンスター名
10 * @return 命中と判定された場合TRUEを返す
11 * @note Always miss 5%, always hit 5%, otherwise random.
12 */
13 bool test_hit_fire(int chance, monster_type *m_ptr, int vis, char* o_name)
14 {
15         int k, ac;
16         monster_race *r_ptr = &r_info[m_ptr->r_idx];
17
18         /* Percentile dice */
19         k = randint1(100);
20
21         /* Snipers with high-concentration reduce instant miss percentage.*/
22         k += p_ptr->concent;
23
24         /* Hack -- Instant miss or hit */
25         if (k <= 5) return (FALSE);
26         if (k > 95) return (TRUE);
27
28         if (p_ptr->pseikaku == SEIKAKU_NAMAKE)
29                 if (one_in_(20)) return (FALSE);
30
31         /* Never hit */
32         if (chance <= 0) return (FALSE);
33
34         ac = r_ptr->ac;
35         if (p_ptr->concent)
36         {
37                 ac *= (8 - p_ptr->concent);
38                 ac /= 8;
39         }
40
41         if (m_ptr->r_idx == MON_GOEMON && !MON_CSLEEP(m_ptr)) ac *= 3;
42
43         /* Invisible monsters are harder to hit */
44         if (!vis) chance = (chance + 1) / 2;
45
46         /* Power competes against armor */
47         if (randint0(chance) < (ac * 3 / 4))
48         {
49                 if (m_ptr->r_idx == MON_GOEMON && !MON_CSLEEP(m_ptr))
50                 {
51                         char m_name[80];
52
53                         /* Extract monster name */
54                         monster_desc(m_name, m_ptr, 0);
55                         msg_format(_("%sは%sを斬り捨てた!", "%s cuts down %s!"), m_name, o_name);
56                 }
57                 return (FALSE);
58         }
59
60         /* Assume hit */
61         return (TRUE);
62 }
63
64
65
66
67 /*!
68 * @brief プレイヤーからモンスターへの射撃クリティカル判定 /
69 * Critical hits (from objects thrown by player) Factor in item weight, total plusses, and player level.
70 * @param weight 矢弾の重量
71 * @param plus_ammo 矢弾の命中修正
72 * @param plus_bow 弓の命中修正
73 * @param dam 現在算出中のダメージ値
74 * @return クリティカル修正が入ったダメージ値
75 */
76 HIT_POINT critical_shot(int weight, int plus_ammo, int plus_bow, HIT_POINT dam)
77 {
78         int i, k;
79         object_type *j_ptr = &inventory[INVEN_BOW];
80
81         /* Extract "shot" power */
82         i = p_ptr->to_h_b + plus_ammo;
83
84         if (p_ptr->tval_ammo == TV_BOLT)
85                 i = (p_ptr->skill_thb + (p_ptr->weapon_exp[0][j_ptr->sval] / 400 + i) * BTH_PLUS_ADJ);
86         else
87                 i = (p_ptr->skill_thb + ((p_ptr->weapon_exp[0][j_ptr->sval] - (WEAPON_EXP_MASTER / 2)) / 200 + i) * BTH_PLUS_ADJ);
88
89
90         /* Snipers can shot more critically with crossbows */
91         if (p_ptr->concent) i += ((i * p_ptr->concent) / 5);
92         if ((p_ptr->pclass == CLASS_SNIPER) && (p_ptr->tval_ammo == TV_BOLT)) i *= 2;
93
94         /* Good bow makes more critical */
95         i += plus_bow * 8 * (p_ptr->concent ? p_ptr->concent + 5 : 5);
96
97         /* Critical hit */
98         if (randint1(10000) <= i)
99         {
100                 k = weight * randint1(500);
101
102                 if (k < 900)
103                 {
104                         msg_print(_("手ごたえがあった!", "It was a good hit!"));
105                         dam += (dam / 2);
106                 }
107                 else if (k < 1350)
108                 {
109                         msg_print(_("かなりの手ごたえがあった!", "It was a great hit!"));
110                         dam *= 2;
111                 }
112                 else
113                 {
114                         msg_print(_("会心の一撃だ!", "It was a superb hit!"));
115                         dam *= 3;
116                 }
117         }
118
119         return (dam);
120 }
121
122