OSDN Git Service

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