1 #include "window/main-window-left-frame.h"
2 #include "game-option/special-options.h"
3 #include "game-option/text-display-options.h"
4 #include "market/arena-info-table.h"
5 #include "monster-race/monster-race.h"
6 #include "monster/monster-status.h"
7 #include "player-base/player-race.h"
8 #include "player-info/class-info.h"
9 #include "player-info/mimic-info-table.h"
10 #include "player/player-status-table.h"
11 #include "system/floor-type-definition.h"
12 #include "system/monster-race-definition.h"
13 #include "system/monster-type-definition.h"
14 #include "system/player-type-definition.h"
15 #include "term/screen-processor.h"
16 #include "term/term-color-types.h"
17 #include "timed-effect/player-hallucination.h"
18 #include "timed-effect/timed-effects.h"
19 #include "util/string-processor.h"
20 #include "window/main-window-row-column.h"
21 #include "window/main-window-stat-poster.h"
22 #include "window/main-window-util.h"
23 #include "world/world.h"
26 * @brief プレイヤーの称号を表示する / Prints "title", including "wizard" or "winner" as needed.
28 void print_title(PlayerType *player_ptr)
33 p = _("[ウィザード]", "[=-WIZARD-=]");
34 } else if (w_ptr->total_winner) {
35 if (player_ptr->is_true_winner()) {
36 p = _("*真・勝利者*", "*TRUEWINNER*");
38 p = _("***勝利者***", "***WINNER***");
41 angband_strcpy(str, player_titles[enum2i(player_ptr->pclass)][(player_ptr->lev - 1) / 5].data(), sizeof(str));
45 print_field(p, ROW_TITLE, COL_TITLE);
49 * @brief プレイヤーのレベルを表示する / Prints level
51 void print_level(PlayerType *player_ptr)
54 sprintf(tmp, "%5d", player_ptr->lev);
55 if (player_ptr->lev >= player_ptr->max_plv) {
56 put_str(_("レベル ", "LEVEL "), ROW_LEVEL, 0);
57 c_put_str(TERM_L_GREEN, tmp, ROW_LEVEL, COL_LEVEL + 7);
59 put_str(_("xレベル", "Level "), ROW_LEVEL, 0);
60 c_put_str(TERM_YELLOW, tmp, ROW_LEVEL, COL_LEVEL + 7);
65 * @brief プレイヤーの経験値を表示する / Display the experience
67 void print_exp(PlayerType *player_ptr)
71 PlayerRace pr(player_ptr);
72 if ((!exp_need) || pr.equals(PlayerRaceType::ANDROID)) {
73 (void)sprintf(out_val, "%8ld", (long)player_ptr->exp);
75 if (player_ptr->lev >= PY_MAX_LEVEL) {
76 (void)sprintf(out_val, "********");
78 (void)sprintf(out_val, "%8ld", (long)(player_exp[player_ptr->lev - 1] * player_ptr->expfact / 100L) - player_ptr->exp);
82 if (player_ptr->exp >= player_ptr->max_exp) {
83 if (pr.equals(PlayerRaceType::ANDROID)) {
84 put_str(_("強化 ", "Cst "), ROW_EXP, 0);
86 put_str(_("経験 ", "EXP "), ROW_EXP, 0);
88 c_put_str(TERM_L_GREEN, out_val, ROW_EXP, COL_EXP + 4);
90 put_str(_("x経験", "Exp "), ROW_EXP, 0);
91 c_put_str(TERM_YELLOW, out_val, ROW_EXP, COL_EXP + 4);
96 * @brief プレイヤーのACを表示する / Prints current AC
98 void print_ac(PlayerType *player_ptr)
103 /* AC の表示方式を変更している */
104 put_str(" AC( )", ROW_AC, COL_AC);
105 sprintf(tmp, "%5d", player_ptr->dis_ac + player_ptr->dis_to_a);
106 c_put_str(TERM_L_GREEN, tmp, ROW_AC, COL_AC + 6);
108 put_str("Cur AC ", ROW_AC, COL_AC);
109 sprintf(tmp, "%5d", player_ptr->dis_ac + player_ptr->dis_to_a);
110 c_put_str(TERM_L_GREEN, tmp, ROW_AC, COL_AC + 7);
115 * @brief プレイヤーのHPを表示する / Prints Cur/Max hit points
117 void print_hp(PlayerType *player_ptr)
120 put_str("HP", ROW_CURHP, COL_CURHP);
121 sprintf(tmp, "%4ld", (long int)player_ptr->chp);
123 if (player_ptr->chp >= player_ptr->mhp) {
124 color = TERM_L_GREEN;
125 } else if (player_ptr->chp > (player_ptr->mhp * hitpoint_warn) / 10) {
131 c_put_str(color, tmp, ROW_CURHP, COL_CURHP + 3);
132 put_str("/", ROW_CURHP, COL_CURHP + 7);
133 sprintf(tmp, "%4ld", (long int)player_ptr->mhp);
134 color = TERM_L_GREEN;
135 c_put_str(color, tmp, ROW_CURHP, COL_CURHP + 8);
139 * @brief プレイヤーのMPを表示する / Prints players max/cur spell points
141 void print_sp(PlayerType *player_ptr)
145 if ((mp_ptr->spell_book == ItemKindType::NONE) && mp_ptr->spell_first == SPELL_FIRST_NO_SPELL) {
149 put_str(_("MP", "SP"), ROW_CURSP, COL_CURSP);
150 sprintf(tmp, "%4ld", (long int)player_ptr->csp);
151 if (player_ptr->csp >= player_ptr->msp) {
152 color = TERM_L_GREEN;
153 } else if (player_ptr->csp > (player_ptr->msp * mana_warn) / 10) {
159 c_put_str(color, tmp, ROW_CURSP, COL_CURSP + 3);
160 put_str("/", ROW_CURSP, COL_CURSP + 7);
161 sprintf(tmp, "%4ld", (long int)player_ptr->msp);
162 color = TERM_L_GREEN;
163 c_put_str(color, tmp, ROW_CURSP, COL_CURSP + 8);
167 * @brief プレイヤーの所持金を表示する / Prints current gold
168 * @param player_ptr プレイヤーへの参照ポインタ
170 void print_gold(PlayerType *player_ptr)
173 put_str(_("$ ", "AU "), ROW_GOLD, COL_GOLD);
174 sprintf(tmp, "%9ld", (long)player_ptr->au);
175 c_put_str(TERM_L_GREEN, tmp, ROW_GOLD, COL_GOLD + 3);
179 * @brief 現在のフロアの深さを表示する / Prints depth in stat area
180 * @param player_ptr プレイヤーへの参照ポインタ
182 void print_depth(PlayerType *player_ptr)
185 TERM_COLOR attr = TERM_WHITE;
188 term_get_size(&wid, &hgt);
189 TERM_LEN col_depth = wid + COL_DEPTH;
190 TERM_LEN row_depth = hgt + ROW_DEPTH;
192 auto *floor_ptr = player_ptr->current_floor_ptr;
193 if (!floor_ptr->dun_level) {
194 strcpy(depths, _("地上", "Surf."));
195 c_prt(attr, format("%7s", depths), row_depth, col_depth);
199 if (inside_quest(floor_ptr->quest_number) && !player_ptr->dungeon_idx) {
200 strcpy(depths, _("地上", "Quest"));
201 c_prt(attr, format("%7s", depths), row_depth, col_depth);
206 (void)sprintf(depths, _("%d ft", "%d ft"), (int)floor_ptr->dun_level * 50);
208 (void)sprintf(depths, _("%d 階", "Lev %d"), (int)floor_ptr->dun_level);
211 switch (player_ptr->feeling) {
220 break; /* Horrible visions */
223 break; /* Very dangerous */
226 break; /* Very bad feeling */
229 break; /* Bad feeling */
235 break; /* Luck is turning */
238 break; /* Don't like */
241 break; /* Reasonably safe */
244 break; /* Boring place */
247 c_prt(attr, format("%7s", depths), row_depth, col_depth);
251 * @brief プレイヤーのステータスを一括表示する(左側部分) / Display basic info (mostly left of map)
252 * @param player_ptr プレイヤーへの参照ポインタ
254 void print_frame_basic(PlayerType *player_ptr)
256 if (player_ptr->mimic_form != MimicKindType::NONE) {
257 print_field(mimic_info.at(player_ptr->mimic_form).title, ROW_RACE, COL_RACE);
260 angband_strcpy(str, rp_ptr->title, sizeof(str));
261 print_field(str, ROW_RACE, COL_RACE);
264 print_title(player_ptr);
265 print_level(player_ptr);
266 print_exp(player_ptr);
267 for (int i = 0; i < A_MAX; i++) {
268 print_stat(player_ptr, i);
271 print_ac(player_ptr);
272 print_hp(player_ptr);
273 print_sp(player_ptr);
274 print_gold(player_ptr);
275 print_depth(player_ptr);
276 health_redraw(player_ptr, false);
277 health_redraw(player_ptr, true);
281 * @brief モンスターの体力ゲージを表示する
282 * @param riding TRUEならば騎乗中のモンスターの体力、FALSEならターゲットモンスターの体力を表示する。表示位置は固定。
285 * Redraw the "monster health bar" -DRS-
286 * Rather extensive modifications by -BEN-
288 * The "monster health bar" provides visual feedback on the "health"
289 * of the monster currently being "tracked". There are several ways
290 * to "track" a monster, including targetting it, attacking it, and
291 * affecting it (and nobody else) with a ranged attack.
293 * Display the monster health bar (affectionately known as the
294 * "health-o-meter"). Clear health bar if nothing is being tracked.
295 * Auto-track current target monster when bored. Note that the
296 * health-bar stops tracking any monster that "disappears".
299 void health_redraw(PlayerType *player_ptr, bool riding)
305 health_who = player_ptr->riding;
306 row = ROW_RIDING_INFO;
307 col = COL_RIDING_INFO;
309 health_who = player_ptr->health_who;
315 m_ptr = &player_ptr->current_floor_ptr->m_list[health_who];
317 if (w_ptr->wizard && player_ptr->phase_out) {
321 term_putstr(col - 2, row, 12, TERM_WHITE, " / ");
322 term_putstr(col - 2, row + 1, 12, TERM_WHITE, " / ");
323 term_putstr(col - 2, row + 2, 12, TERM_WHITE, " / ");
324 term_putstr(col - 2, row + 3, 12, TERM_WHITE, " / ");
326 if (MonsterRace(player_ptr->current_floor_ptr->m_list[1].r_idx).is_valid()) {
327 term_putstr(col - 2, row, 2, r_info[player_ptr->current_floor_ptr->m_list[1].r_idx].x_attr,
328 format("%c", r_info[player_ptr->current_floor_ptr->m_list[1].r_idx].x_char));
329 term_putstr(col - 1, row, 5, TERM_WHITE, format("%5d", player_ptr->current_floor_ptr->m_list[1].hp));
330 term_putstr(col + 5, row, 6, TERM_WHITE, format("%5d", player_ptr->current_floor_ptr->m_list[1].max_maxhp));
333 if (MonsterRace(player_ptr->current_floor_ptr->m_list[2].r_idx).is_valid()) {
334 term_putstr(col - 2, row + 1, 2, r_info[player_ptr->current_floor_ptr->m_list[2].r_idx].x_attr,
335 format("%c", r_info[player_ptr->current_floor_ptr->m_list[2].r_idx].x_char));
336 term_putstr(col - 1, row + 1, 5, TERM_WHITE, format("%5d", player_ptr->current_floor_ptr->m_list[2].hp));
337 term_putstr(col + 5, row + 1, 6, TERM_WHITE, format("%5d", player_ptr->current_floor_ptr->m_list[2].max_maxhp));
340 if (MonsterRace(player_ptr->current_floor_ptr->m_list[3].r_idx).is_valid()) {
341 term_putstr(col - 2, row + 2, 2, r_info[player_ptr->current_floor_ptr->m_list[3].r_idx].x_attr,
342 format("%c", r_info[player_ptr->current_floor_ptr->m_list[3].r_idx].x_char));
343 term_putstr(col - 1, row + 2, 5, TERM_WHITE, format("%5d", player_ptr->current_floor_ptr->m_list[3].hp));
344 term_putstr(col + 5, row + 2, 6, TERM_WHITE, format("%5d", player_ptr->current_floor_ptr->m_list[3].max_maxhp));
347 if (MonsterRace(player_ptr->current_floor_ptr->m_list[4].r_idx).is_valid()) {
348 term_putstr(col - 2, row + 3, 2, r_info[player_ptr->current_floor_ptr->m_list[4].r_idx].x_attr,
349 format("%c", r_info[player_ptr->current_floor_ptr->m_list[4].r_idx].x_char));
350 term_putstr(col - 1, row + 3, 5, TERM_WHITE, format("%5d", player_ptr->current_floor_ptr->m_list[4].hp));
351 term_putstr(col + 5, row + 3, 6, TERM_WHITE, format("%5d", player_ptr->current_floor_ptr->m_list[4].max_maxhp));
358 term_erase(col, row, 12);
363 term_putstr(col, row, 12, TERM_WHITE, "[----------]");
367 if (player_ptr->effects()->hallucination()->is_hallucinated()) {
368 term_putstr(col, row, 12, TERM_WHITE, "[----------]");
373 term_putstr(col, row, 12, TERM_WHITE, "[----------]");
377 int pct = m_ptr->maxhp > 0 ? 100L * m_ptr->hp / m_ptr->maxhp : 0;
378 int pct2 = m_ptr->maxhp > 0 ? 100L * m_ptr->hp / m_ptr->max_maxhp : 0;
379 int len = (pct2 < 10) ? 1 : (pct2 < 90) ? (pct2 / 10 + 1)
381 TERM_COLOR attr = TERM_RED;
382 if (monster_invulner_remaining(m_ptr)) {
384 } else if (m_ptr->is_asleep()) {
386 } else if (monster_fear_remaining(m_ptr)) {
388 } else if (pct >= 100) {
390 } else if (pct >= 60) {
392 } else if (pct >= 25) {
394 } else if (pct >= 10) {
398 term_putstr(col, row, 12, TERM_WHITE, "[----------]");
399 term_putstr(col + 1, row, len, attr, "**********");