OSDN Git Service

Merge pull request #3532 from sikabane-works/release/3.0.0.87-alpha
[hengbandforosx/hengbandosx.git] / src / timed-effect / player-cut.cpp
1 #include "timed-effect/player-cut.h"
2 #include "system/angband-exceptions.h"
3 #include "system/angband.h"
4
5 PlayerCutRank PlayerCut::get_rank(short value)
6 {
7     if (value > 1000) {
8         return PlayerCutRank::MORTAL;
9     }
10
11     if (value > 200) {
12         return PlayerCutRank::DEEP;
13     }
14
15     if (value > 100) {
16         return PlayerCutRank::SEVERE;
17     }
18
19     if (value > 50) {
20         return PlayerCutRank::NASTY;
21     }
22
23     if (value > 25) {
24         return PlayerCutRank::BAD;
25     }
26
27     if (value > 10) {
28         return PlayerCutRank::LIGHT;
29     }
30
31     if (value > 0) {
32         return PlayerCutRank::GRAZING;
33     }
34
35     return PlayerCutRank::NONE;
36 }
37
38 std::string PlayerCut::get_cut_mes(PlayerCutRank stun_rank)
39 {
40     switch (stun_rank) {
41     case PlayerCutRank::NONE:
42         return "";
43     case PlayerCutRank::GRAZING:
44         return _("かすり傷を負ってしまった。", "You have been given a graze.");
45     case PlayerCutRank::LIGHT:
46         return _("軽い傷を負ってしまった。", "You have been given a light cut.");
47     case PlayerCutRank::BAD:
48         return _("ひどい傷を負ってしまった。", "You have been given a bad cut.");
49     case PlayerCutRank::NASTY:
50         return _("大変な傷を負ってしまった。", "You have been given a nasty cut.");
51     case PlayerCutRank::SEVERE:
52         return _("重大な傷を負ってしまった。", "You have been given a severe cut.");
53     case PlayerCutRank::DEEP:
54         return _("ひどい深手を負ってしまった。", "You have been given a deep gash.");
55     case PlayerCutRank::MORTAL:
56         return _("致命的な傷を負ってしまった。", "You have been given a mortal wound.");
57     default:
58         THROW_EXCEPTION(std::logic_error, "Invalid CutRank is specified!");
59     }
60 }
61
62 /*!
63  * @brief モンスター打撃による切り傷値を返す.
64  * @param total 痛恨の一撃でない場合の最大ダメージ (ダイスXdY に対し、X*Y)
65  * @param dam プレイヤーに与えた実際のダメージ
66  * @return 切り傷値
67  */
68 short PlayerCut::get_accumulation(int total, int damage)
69 {
70     auto rank = get_accumulation_rank(total, damage);
71     switch (rank) {
72     case 0:
73         return 0;
74     case 1:
75         return randint1(5);
76     case 2:
77         return randint1(5) + 5;
78     case 3:
79         return randint1(20) + 20;
80     case 4:
81         return randint1(50) + 50;
82     case 5:
83         return randint1(100) + 100;
84     case 6:
85         return 300;
86     default: // 7 or more.
87         return 500;
88     }
89 }
90
91 short PlayerCut::current() const
92 {
93     return this->cut;
94 }
95
96 PlayerCutRank PlayerCut::get_rank() const
97 {
98     return this->get_rank(this->cut);
99 }
100
101 bool PlayerCut::is_cut() const
102 {
103     return this->cut > 0;
104 }
105
106 std::tuple<term_color_type, std::string> PlayerCut::get_expr() const
107 {
108     switch (this->get_rank()) {
109     case PlayerCutRank::NONE: // dummy.
110         return std::make_tuple(TERM_WHITE, "");
111     case PlayerCutRank::GRAZING:
112         return std::make_tuple(TERM_YELLOW, _("かすり傷    ", "Graze       "));
113     case PlayerCutRank::LIGHT:
114         return std::make_tuple(TERM_YELLOW, _("軽傷        ", "Light cut   "));
115     case PlayerCutRank::BAD:
116         return std::make_tuple(TERM_ORANGE, _("ひどい傷    ", "Bad cut     "));
117     case PlayerCutRank::NASTY:
118         return std::make_tuple(TERM_ORANGE, _("大変な傷    ", "Nasty cut   "));
119     case PlayerCutRank::SEVERE:
120         return std::make_tuple(TERM_RED, _("重傷        ", "Severe cut  "));
121     case PlayerCutRank::DEEP:
122         return std::make_tuple(TERM_RED, _("ひどい深手  ", "Deep gash   "));
123     case PlayerCutRank::MORTAL:
124         return std::make_tuple(TERM_L_RED, _("致命傷      ", "Mortal wound"));
125     default:
126         THROW_EXCEPTION(std::logic_error, "Invalid CutRank is specified!");
127     }
128 }
129
130 int PlayerCut::get_damage() const
131 {
132     switch (this->get_rank()) {
133     case PlayerCutRank::NONE:
134         return 0;
135     case PlayerCutRank::GRAZING:
136         return 1;
137     case PlayerCutRank::LIGHT:
138         return 3;
139     case PlayerCutRank::BAD:
140         return 7;
141     case PlayerCutRank::NASTY:
142         return 16;
143     case PlayerCutRank::SEVERE:
144         return 32;
145     case PlayerCutRank::DEEP:
146         return 80;
147     case PlayerCutRank::MORTAL:
148         return 200;
149     default:
150         THROW_EXCEPTION(std::logic_error, "Invalid CutRank is specified!");
151     }
152 }
153
154 void PlayerCut::set(short value)
155 {
156     this->cut = value;
157 }
158
159 void PlayerCut::reset()
160 {
161     this->set(0);
162 }
163
164 /*!
165  * @brief モンスター打撃の切り傷蓄積ランクを返す.
166  * @param total 痛恨の一撃でない場合の最大ダメージ (ダイスXdY に対し、X*Y)
167  * @param dam プレイヤーに与えた実際のダメージ
168  * @return 切り傷蓄積ランク
169  * @details v3.0.0 Alpha40時点では朦朧と異なりv2.2.1までの仕様と同一
170  */
171 int PlayerCut::get_accumulation_rank(int total, int damage)
172 {
173     if (damage < total * 19 / 20) {
174         return 0;
175     }
176
177     if ((damage < 20) && (damage <= randint0(100))) {
178         return 0;
179     }
180
181     auto max = 0;
182     if ((damage >= total) && (damage >= 40)) {
183         max++;
184     }
185
186     if (damage >= 20) {
187         while (randint0(100) < 2) {
188             max++;
189         }
190     }
191
192     if (damage > 45) {
193         return 6 + max;
194     }
195
196     if (damage > 33) {
197         return 5 + max;
198     }
199
200     if (damage > 25) {
201         return 4 + max;
202     }
203
204     if (damage > 18) {
205         return 3 + max;
206     }
207
208     if (damage > 11) {
209         return 2 + max;
210     }
211
212     return 1 + max;
213 }