OSDN Git Service

[Refactor] #39962 display_player_various() からcalc_shot_params() を分離 / Separated calc_...
[hengband/hengband.git] / src / view / status-first-page.c
1 /*!
2  * @file status-first-page.c
3  * @brief \83L\83\83\83\89\8aî\96{\8fî\95ñ\8by\82Ñ\8bZ\94\\92l\82Ì\95\\8e¦
4  * @date 2020/02/23
5  * @author Hourier
6  */
7
8 #include "angband.h"
9 #include "status-first-page.h"
10 #include "artifact.h"
11 #include "combat/melee.h"
12 #include "combat/shoot.h"
13 #include "object-hook.h"
14 #include "objectkind.h"
15
16 static TERM_COLOR likert_color = TERM_WHITE;
17
18 /*!
19  * @brief 
20  * @param creature_ptr \83v\83\8c\81[\83\84\81[\82Ö\82Ì\8eQ\8fÆ\83|\83C\83\93\83^
21  * @param o_ptr \91\95\94õ\92\86\82Ì\8b|\82Ö\82Ì\8eQ\8fÆ\83|\83C\83\93\83^
22  * @param shots \8eË\8c\82\89ñ\90\94
23  * @param shot_frac \8eË\8c\82\91¬\93x
24  * @return \82È\82µ
25  */
26 static void calc_shot_params(player_type *creature_ptr, object_type *o_ptr, int *shots, int *shot_frac)
27 {
28         if (o_ptr->k_idx == 0) return;
29
30         ENERGY energy_fire = bow_energy(o_ptr->sval);
31         *shots = creature_ptr->num_fire * 100;
32         *shot_frac = ((*shots) * 100 / energy_fire) % 100;
33         *shots = (*shots) / energy_fire;
34         if (o_ptr->name1 != ART_CRIMSON) return;
35
36         *shots = 1;
37         *shot_frac = 0;
38         if (creature_ptr->pclass != CLASS_ARCHER) return;
39
40         if (creature_ptr->lev >= 10) (*shots)++;
41         if (creature_ptr->lev >= 30) (*shots)++;
42         if (creature_ptr->lev >= 45) (*shots)++;
43 }
44
45
46 /*!
47  * @brief \8bZ\94\\83\89\83\93\83N\82Ì\95\\8e¦\8aî\8f\80\82ð\92è\82ß\82é
48  * Returns a "rating" of x depending on y
49  * @param x \8bZ\94\\92l
50  * @param y \8bZ\94\\92l\82É\91Î\82·\82é\83\89\83\93\83N\8aî\8f\80\94ä
51  * @return \82È\82µ
52  */
53 static concptr likert(int x, int y)
54 {
55         static char dummy[20] = "", dummy2[20] = "";
56         memset(dummy, 0, strlen(dummy));
57         memset(dummy2, 0, strlen(dummy2));
58         if (y <= 0) y = 1;
59
60         if (show_actual_value)
61                 sprintf(dummy, "%3d-", x);
62
63         if (x < 0)
64         {
65                 likert_color = TERM_L_DARK;
66                 strcat(dummy, _("\8dÅ\92á", "Very Bad"));
67                 return dummy;
68         }
69
70         switch ((x / y))
71         {
72         case 0:
73         case 1:
74         {
75                 likert_color = TERM_RED;
76                 strcat(dummy, _("\88«\82¢", "Bad"));
77                 break;
78
79         }
80         case 2:
81         {
82                 likert_color = TERM_L_RED;
83                 strcat(dummy, _("\97ò\82é", "Poor"));
84                 break;
85         }
86         case 3:
87         case 4:
88         {
89                 likert_color = TERM_ORANGE;
90                 strcat(dummy, _("\95\81\92Ê", "Fair"));
91                 break;
92         }
93         case 5:
94         {
95                 likert_color = TERM_YELLOW;
96                 strcat(dummy, _("\97Ç\82¢", "Good"));
97                 break;
98         }
99         case 6:
100         {
101                 likert_color = TERM_YELLOW;
102                 strcat(dummy, _("\91å\95Ï\97Ç\82¢", "Very Good"));
103                 break;
104         }
105         case 7:
106         case 8:
107         {
108                 likert_color = TERM_L_GREEN;
109                 strcat(dummy, _("\91ì\89z", "Excellent"));
110                 break;
111         }
112         case 9:
113         case 10:
114         case 11:
115         case 12:
116         case 13:
117         {
118                 likert_color = TERM_GREEN;
119                 strcat(dummy, _("\92´\89z", "Superb"));
120                 break;
121         }
122         case 14:
123         case 15:
124         case 16:
125         case 17:
126         {
127                 likert_color = TERM_BLUE;
128                 strcat(dummy, _("\89p\97Y\93I", "Heroic"));
129                 break;
130         }
131         default:
132         {
133                 likert_color = TERM_VIOLET;
134                 sprintf(dummy2, _("\93`\90à\93I[%d]", "Legendary[%d]"), (int)((((x / y) - 17) * 5) / 2));
135                 strcat(dummy, dummy2);
136                 break;
137         }
138         }
139
140         return dummy;
141 }
142
143
144 /*!
145  * @brief \83L\83\83\83\89\8aî\96{\8fî\95ñ\8by\82Ñ\8bZ\94\\92l\82ð\83\81\83C\83\93\83E\83B\83\93\83h\83E\82É\95\\8e¦\82·\82é
146  * @param creature_ptr \83v\83\8c\81[\83\84\81[\82Ö\82Ì\8eQ\8fÆ\83|\83C\83\93\83^
147  * @param xthb \95\90\8aí\93\99\82ð\8aÜ\82ß\82½\8dÅ\8fI\96½\92\86\97¦
148  * @param damage \91Å\8c\82\8fC\90³
149  * @param shots \8eË\8c\82\89ñ\90\94
150  * @param shot_frac \8eË\8c\82\91¬\93x
151  * @param display_player_one_line 1\8ds\95\\8e¦\97p\82Ì\83R\81[\83\8b\83o\83b\83N\8aÖ\90\94
152  * @return \82È\82µ
153  */
154 static void display_first_page(player_type *creature_ptr, int xthb, int *damage, int shots, int shot_frac, void(*display_player_one_line)(int, concptr, TERM_COLOR))
155 {
156         int xthn = creature_ptr->skill_thn + (creature_ptr->to_h_m * BTH_PLUS_ADJ);
157
158         int muta_att = 0;
159         if (creature_ptr->muta2 & MUT2_HORNS) muta_att++;
160         if (creature_ptr->muta2 & MUT2_SCOR_TAIL) muta_att++;
161         if (creature_ptr->muta2 & MUT2_BEAK) muta_att++;
162         if (creature_ptr->muta2 & MUT2_TRUNK) muta_att++;
163         if (creature_ptr->muta2 & MUT2_TENTACLES) muta_att++;
164
165         int blows1 = creature_ptr->migite ? creature_ptr->num_blow[0] : 0;
166         int blows2 = creature_ptr->hidarite ? creature_ptr->num_blow[1] : 0;
167         int xdis = creature_ptr->skill_dis;
168         int xdev = creature_ptr->skill_dev;
169         int xsav = creature_ptr->skill_sav;
170         int xstl = creature_ptr->skill_stl;
171         int     xsrh = creature_ptr->skill_srh;
172         int     xfos = creature_ptr->skill_fos;
173         int xdig = creature_ptr->skill_dig;
174
175         concptr desc = likert(xthn, 12);
176         (*display_player_one_line)(ENTRY_SKILL_FIGHT, desc, likert_color);
177
178         desc = likert(xthb, 12);
179         (*display_player_one_line)(ENTRY_SKILL_SHOOT, desc, likert_color);
180
181         desc = likert(xsav, 7);
182         (*display_player_one_line)(ENTRY_SKILL_SAVING, desc, likert_color);
183
184         desc = likert((xstl > 0) ? xstl : -1, 1);
185         (*display_player_one_line)(ENTRY_SKILL_STEALTH, desc, likert_color);
186
187         desc = likert(xfos, 6);
188         (*display_player_one_line)(ENTRY_SKILL_PERCEP, desc, likert_color);
189
190         desc = likert(xsrh, 6);
191         (*display_player_one_line)(ENTRY_SKILL_SEARCH, desc, likert_color);
192
193         desc = likert(xdis, 8);
194         (*display_player_one_line)(ENTRY_SKILL_DISARM, desc, likert_color);
195
196         desc = likert(xdev, 6);
197         (*display_player_one_line)(ENTRY_SKILL_DEVICE, desc, likert_color);
198
199         desc = likert(xdev, 6);
200         (*display_player_one_line)(ENTRY_SKILL_DEVICE, desc, likert_color);
201
202         desc = likert(xdig, 4);
203         (*display_player_one_line)(ENTRY_SKILL_DIG, desc, likert_color);
204
205         if (!muta_att)
206                 (*display_player_one_line)(ENTRY_BLOWS, format("%d+%d", blows1, blows2), TERM_L_BLUE);
207         else
208                 (*display_player_one_line)(ENTRY_BLOWS, format("%d+%d+%d", blows1, blows2, muta_att), TERM_L_BLUE);
209
210         (*display_player_one_line)(ENTRY_SHOTS, format("%d.%02d", shots, shot_frac), TERM_L_BLUE);
211
212         if ((damage[0] + damage[1]) == 0)
213                 desc = "nil!";
214         else
215                 desc = format("%d+%d", blows1 * damage[0] / 100, blows2 * damage[1] / 100);
216
217         (*display_player_one_line)(ENTRY_AVG_DMG, desc, TERM_L_BLUE);
218         (*display_player_one_line)(ENTRY_INFRA, format("%d feet", creature_ptr->see_infra * 10), TERM_WHITE);
219 }
220
221
222 /*!
223  * @brief \83v\83\8c\83C\83\84\81[\83X\83e\81[\83^\83X\82Ì1\83y\81[\83W\96Ú\8ae\8eí\8fÚ\8d×\82ð\82Ü\82Æ\82ß\82Ä\95\\8e¦\82·\82é
224  * Prints ratings on certain abilities
225  * @param creature_ptr \83v\83\8c\81[\83\84\81[\82Ö\82Ì\8eQ\8fÆ\83|\83C\83\93\83^
226  * @param display_player_one_line 1\8ds\95\\8e¦\97p\82Ì\83R\81[\83\8b\83o\83b\83N\8aÖ\90\94
227  * @return \82È\82µ
228  * @details
229  * This code is "imitated" elsewhere to "dump" a character sheet.
230  */
231 void display_player_various(player_type *creature_ptr, void(*display_player_one_line)(int, concptr, TERM_COLOR))
232 {
233         object_type *o_ptr;
234         o_ptr = &creature_ptr->inventory_list[INVEN_BOW];
235         int tmp = creature_ptr->to_h_b + o_ptr->to_h;
236         int     xthb = creature_ptr->skill_thb + (tmp * BTH_PLUS_ADJ);
237         int     shots = 0;
238         int shot_frac = 0;
239         calc_shot_params(creature_ptr, o_ptr, &shots, &shot_frac);
240
241         int damage[2];
242         int to_h[2];
243         BIT_FLAGS flgs[TR_FLAG_SIZE];
244         for (int i = 0; i < 2; i++)
245         {
246                 int basedam;
247                 damage[i] = creature_ptr->dis_to_d[i] * 100;
248                 if (((creature_ptr->pclass == CLASS_MONK) || (creature_ptr->pclass == CLASS_FORCETRAINER)) && (empty_hands(creature_ptr, TRUE) & EMPTY_HAND_RARM))
249                 {
250                         PLAYER_LEVEL level = creature_ptr->lev;
251                         if (i > 0)
252                         {
253                                 damage[i] = 0;
254                                 break;
255                         }
256
257                         if (creature_ptr->pclass == CLASS_FORCETRAINER) level = MAX(1, level - 3);
258                         if (creature_ptr->special_defense & KAMAE_BYAKKO)
259                                 basedam = monk_ave_damage[level][1];
260                         else if (creature_ptr->special_defense & (KAMAE_GENBU | KAMAE_SUZAKU))
261                                 basedam = monk_ave_damage[level][2];
262                         else
263                                 basedam = monk_ave_damage[level][0];
264
265                         damage[i] += basedam;
266                         if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_POISON_NEEDLE)) damage[i] = 1;
267                         if (damage[i] < 0) damage[i] = 0;
268                         continue;
269                 }
270
271                 o_ptr = &creature_ptr->inventory_list[INVEN_RARM + i];
272                 if (o_ptr->k_idx == 0)
273                 {
274                         basedam = 0;
275                         damage[i] += basedam;
276                         if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_POISON_NEEDLE)) damage[i] = 1;
277                         if (damage[i] < 0) damage[i] = 0;
278                         continue;
279                 }
280
281                 to_h[i] = 0;
282                 bool poison_needle = FALSE;
283                 if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_POISON_NEEDLE)) poison_needle = TRUE;
284                 if (object_is_known(o_ptr))
285                 {
286                         damage[i] += o_ptr->to_d * 100;
287                         to_h[i] += o_ptr->to_h;
288                 }
289
290                 basedam = ((o_ptr->dd + creature_ptr->to_dd[i]) * (o_ptr->ds + creature_ptr->to_ds[i] + 1)) * 50;
291                 object_flags_known(o_ptr, flgs);
292
293                 basedam = calc_expect_crit(creature_ptr, o_ptr->weight, to_h[i], basedam, creature_ptr->dis_to_h[i], poison_needle);
294                 if (OBJECT_IS_FULL_KNOWN(o_ptr) && ((o_ptr->name1 == ART_VORPAL_BLADE) || (o_ptr->name1 == ART_CHAINSWORD)))
295                 {
296                         /* vorpal blade */
297                         basedam *= 5;
298                         basedam /= 3;
299                 }
300                 else if (have_flag(flgs, TR_VORPAL))
301                 {
302                         /* vorpal flag only */
303                         basedam *= 11;
304                         basedam /= 9;
305                 }
306
307                 if ((creature_ptr->pclass != CLASS_SAMURAI) && have_flag(flgs, TR_FORCE_WEAPON) && (creature_ptr->csp > (o_ptr->dd * o_ptr->ds / 5)))
308                         basedam = basedam * 7 / 2;
309
310                 damage[i] += basedam;
311                 if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_POISON_NEEDLE)) damage[i] = 1;
312                 if (damage[i] < 0) damage[i] = 0;
313         }
314
315         display_first_page(creature_ptr, xthb, damage, shots, shot_frac, display_player_one_line);
316 }