2 * @file status-first-page.c
3 * @brief キャラ基本情報及び技能値の表示
10 #include "status-first-page.h"
11 #include "display-util.h"
13 #include "combat/melee.h"
14 #include "combat/shoot.h"
15 #include "object-hook.h"
16 #include "object/object-kind.h"
18 static TERM_COLOR likert_color = TERM_WHITE;
22 * @param creature_ptr プレーヤーへの参照ポインタ
23 * @param o_ptr 装備中の弓への参照ポインタ
25 * @param shot_frac 射撃速度
28 static void calc_shot_params(player_type *creature_ptr, object_type *o_ptr, int *shots, int *shot_frac)
30 if (o_ptr->k_idx == 0) return;
32 ENERGY energy_fire = bow_energy(o_ptr->sval);
33 *shots = creature_ptr->num_fire * 100;
34 *shot_frac = ((*shots) * 100 / energy_fire) % 100;
35 *shots = (*shots) / energy_fire;
36 if (o_ptr->name1 != ART_CRIMSON) return;
40 if (creature_ptr->pclass != CLASS_ARCHER) return;
42 if (creature_ptr->lev >= 10) (*shots)++;
43 if (creature_ptr->lev >= 30) (*shots)++;
44 if (creature_ptr->lev >= 45) (*shots)++;
49 * @brief 武器装備に制限のあるクラスで、直接攻撃のダメージを計算する
50 * @param creature_ptr プレーヤーへの参照ポインタ
51 * @param hand 手 (利き手が0、反対の手が1…のはず)
52 * @param damage 直接攻撃のダメージ
53 * @param basedam 素手における直接攻撃のダメージ
54 * @param o_ptr 装備中の武器への参照ポインタ
55 * @return 利き手ならTRUE、反対の手ならFALSE
57 static bool calc_weapon_damage_limit(player_type *creature_ptr, int hand, int *damage, int *basedam, object_type *o_ptr)
59 PLAYER_LEVEL level = creature_ptr->lev;
66 if (creature_ptr->pclass == CLASS_FORCETRAINER) level = MAX(1, level - 3);
67 if (creature_ptr->special_defense & KAMAE_BYAKKO)
68 *basedam = monk_ave_damage[level][1];
69 else if (creature_ptr->special_defense & (KAMAE_GENBU | KAMAE_SUZAKU))
70 *basedam = monk_ave_damage[level][2];
72 *basedam = monk_ave_damage[level][0];
74 damage[hand] += *basedam;
75 if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_POISON_NEEDLE)) damage[hand] = 1;
76 if (damage[hand] < 0) damage[hand] = 0;
83 * @brief 片手あたりのダメージ量を計算する
84 * @param o_ptr 装備中の武器への参照ポインタ
86 * @param damage 直接攻撃のダメージ
87 * @param basedam 素手における直接攻撃のダメージ
88 * @return 素手ならFALSE、武器を持っていればTRUE
90 static bool calc_weapon_one_hand(object_type *o_ptr, int hand, int *damage, int *basedam)
92 if (o_ptr->k_idx == 0) return FALSE;
95 damage[hand] += *basedam;
96 if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_POISON_NEEDLE))
107 * @brief ヴォーパル武器等によるダメージ強化
108 * @param creature_ptr プレーヤーへの参照ポインタ
109 * @param o_ptr 装備中の武器への参照ポインタ
110 * @param basedam 素手における直接攻撃のダメージ
111 * @param flgs オブジェクトフラグ群
114 static int strengthen_basedam(player_type *creature_ptr, object_type *o_ptr, int basedam, BIT_FLAGS *flgs)
116 if (OBJECT_IS_FULL_KNOWN(o_ptr) && ((o_ptr->name1 == ART_VORPAL_BLADE) || (o_ptr->name1 == ART_CHAINSWORD)))
122 else if (have_flag(flgs, TR_VORPAL))
124 /* vorpal flag only */
130 bool is_force = creature_ptr->pclass != CLASS_SAMURAI;
131 is_force &= have_flag(flgs, TR_FORCE_WEAPON);
132 is_force &= creature_ptr->csp > (o_ptr->dd * o_ptr->ds / 5);
133 if (is_force) basedam = basedam * 7 / 2;
140 * @brief 技能ランクの表示基準を定める
141 * Returns a "rating" of x depending on y
143 * @param y 技能値に対するランク基準比
146 static concptr likert(int x, int y)
148 static char dummy[20] = "", dummy2[20] = "";
149 memset(dummy, 0, strlen(dummy));
150 memset(dummy2, 0, strlen(dummy2));
153 if (show_actual_value)
154 sprintf(dummy, "%3d-", x);
158 likert_color = TERM_L_DARK;
159 strcat(dummy, _("最低", "Very Bad"));
168 likert_color = TERM_RED;
169 strcat(dummy, _("悪い", "Bad"));
175 likert_color = TERM_L_RED;
176 strcat(dummy, _("劣る", "Poor"));
182 likert_color = TERM_ORANGE;
183 strcat(dummy, _("普通", "Fair"));
188 likert_color = TERM_YELLOW;
189 strcat(dummy, _("良い", "Good"));
194 likert_color = TERM_YELLOW;
195 strcat(dummy, _("大変良い", "Very Good"));
201 likert_color = TERM_L_GREEN;
202 strcat(dummy, _("卓越", "Excellent"));
211 likert_color = TERM_GREEN;
212 strcat(dummy, _("超越", "Superb"));
220 likert_color = TERM_BLUE;
221 strcat(dummy, _("英雄的", "Heroic"));
226 likert_color = TERM_VIOLET;
227 sprintf(dummy2, _("伝説的[%d]", "Legendary[%d]"), (int)((((x / y) - 17) * 5) / 2));
228 strcat(dummy, dummy2);
238 * @brief 弓+両手の武器それぞれについてダメージを計算する
239 * @param creature_ptr プレーヤーへの参照ポインタ
240 * @param damage 直接攻撃のダメージ
244 static void calc_two_hands(player_type *creature_ptr, int *damage, int *to_h)
247 o_ptr = &creature_ptr->inventory_list[INVEN_BOW];
248 BIT_FLAGS flgs[TR_FLAG_SIZE];
249 for (int i = 0; i < 2; i++)
252 damage[i] = creature_ptr->dis_to_d[i] * 100;
253 if (((creature_ptr->pclass == CLASS_MONK) || (creature_ptr->pclass == CLASS_FORCETRAINER)) && (empty_hands(creature_ptr, TRUE) & EMPTY_HAND_RARM))
255 if (!calc_weapon_damage_limit(creature_ptr, i, damage, &basedam, o_ptr))
261 o_ptr = &creature_ptr->inventory_list[INVEN_RARM + i];
262 if (calc_weapon_one_hand(o_ptr, i, damage, &basedam)) continue;
265 bool poison_needle = FALSE;
266 if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_POISON_NEEDLE)) poison_needle = TRUE;
267 if (object_is_known(o_ptr))
269 damage[i] += o_ptr->to_d * 100;
270 to_h[i] += o_ptr->to_h;
273 basedam = ((o_ptr->dd + creature_ptr->to_dd[i]) * (o_ptr->ds + creature_ptr->to_ds[i] + 1)) * 50;
274 object_flags_known(o_ptr, flgs);
276 basedam = calc_expect_crit(creature_ptr, o_ptr->weight, to_h[i], basedam, creature_ptr->dis_to_h[i], poison_needle);
277 basedam = strengthen_basedam(creature_ptr, o_ptr, basedam, flgs);
278 damage[i] += basedam;
279 if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_POISON_NEEDLE)) damage[i] = 1;
280 if (damage[i] < 0) damage[i] = 0;
286 * @brief キャラ基本情報及び技能値をメインウィンドウに表示する
287 * @param creature_ptr プレーヤーへの参照ポインタ
288 * @param xthb 武器等を含めた最終命中率
291 * @param shot_frac 射撃速度
292 * @param display_player_one_line 1行表示用のコールバック関数
295 static void display_first_page(player_type *creature_ptr, int xthb, int *damage, int shots, int shot_frac)
297 int xthn = creature_ptr->skill_thn + (creature_ptr->to_h_m * BTH_PLUS_ADJ);
300 if (creature_ptr->muta2 & MUT2_HORNS) muta_att++;
301 if (creature_ptr->muta2 & MUT2_SCOR_TAIL) muta_att++;
302 if (creature_ptr->muta2 & MUT2_BEAK) muta_att++;
303 if (creature_ptr->muta2 & MUT2_TRUNK) muta_att++;
304 if (creature_ptr->muta2 & MUT2_TENTACLES) muta_att++;
306 int blows1 = creature_ptr->migite ? creature_ptr->num_blow[0] : 0;
307 int blows2 = creature_ptr->hidarite ? creature_ptr->num_blow[1] : 0;
308 int xdis = creature_ptr->skill_dis;
309 int xdev = creature_ptr->skill_dev;
310 int xsav = creature_ptr->skill_sav;
311 int xstl = creature_ptr->skill_stl;
312 int xsrh = creature_ptr->skill_srh;
313 int xfos = creature_ptr->skill_fos;
314 int xdig = creature_ptr->skill_dig;
316 concptr desc = likert(xthn, 12);
317 display_player_one_line(ENTRY_SKILL_FIGHT, desc, likert_color);
319 desc = likert(xthb, 12);
320 display_player_one_line(ENTRY_SKILL_SHOOT, desc, likert_color);
322 desc = likert(xsav, 7);
323 display_player_one_line(ENTRY_SKILL_SAVING, desc, likert_color);
325 desc = likert((xstl > 0) ? xstl : -1, 1);
326 display_player_one_line(ENTRY_SKILL_STEALTH, desc, likert_color);
328 desc = likert(xfos, 6);
329 display_player_one_line(ENTRY_SKILL_PERCEP, desc, likert_color);
331 desc = likert(xsrh, 6);
332 display_player_one_line(ENTRY_SKILL_SEARCH, desc, likert_color);
334 desc = likert(xdis, 8);
335 display_player_one_line(ENTRY_SKILL_DISARM, desc, likert_color);
337 desc = likert(xdev, 6);
338 display_player_one_line(ENTRY_SKILL_DEVICE, desc, likert_color);
340 desc = likert(xdev, 6);
341 display_player_one_line(ENTRY_SKILL_DEVICE, desc, likert_color);
343 desc = likert(xdig, 4);
344 display_player_one_line(ENTRY_SKILL_DIG, desc, likert_color);
347 display_player_one_line(ENTRY_BLOWS, format("%d+%d", blows1, blows2), TERM_L_BLUE);
349 display_player_one_line(ENTRY_BLOWS, format("%d+%d+%d", blows1, blows2, muta_att), TERM_L_BLUE);
351 display_player_one_line(ENTRY_SHOTS, format("%d.%02d", shots, shot_frac), TERM_L_BLUE);
353 if ((damage[0] + damage[1]) == 0)
356 desc = format("%d+%d", blows1 * damage[0] / 100, blows2 * damage[1] / 100);
358 display_player_one_line(ENTRY_AVG_DMG, desc, TERM_L_BLUE);
359 display_player_one_line(ENTRY_INFRA, format("%d feet", creature_ptr->see_infra * 10), TERM_WHITE);
364 * @brief プレイヤーステータスの1ページ目各種詳細をまとめて表示する
365 * Prints ratings on certain abilities
366 * @param creature_ptr プレーヤーへの参照ポインタ
367 * @param display_player_one_line 1行表示用のコールバック関数
370 * This code is "imitated" elsewhere to "dump" a character sheet.
372 void display_player_various(player_type *creature_ptr)
375 o_ptr = &creature_ptr->inventory_list[INVEN_BOW];
376 int tmp = creature_ptr->to_h_b + o_ptr->to_h;
377 int xthb = creature_ptr->skill_thb + (tmp * BTH_PLUS_ADJ);
380 calc_shot_params(creature_ptr, o_ptr, &shots, &shot_frac);
384 calc_two_hands(creature_ptr, damage, to_h);
385 display_first_page(creature_ptr, xthb, damage, shots, shot_frac);