1 #include "window/main-window-stat-poster.h"
2 #include "io/input-key-requester.h"
3 #include "mind/stances-table.h"
4 #include "monster/monster-status.h"
5 #include "player/attack-defense-types.h"
6 #include "player/player-status-table.h"
7 #include "realm/realm-hex-numbers.h"
8 #include "realm/realm-types.h"
9 #include "spell-realm/spells-hex.h"
10 #include "status/element-resistance.h"
11 #include "system/floor-type-definition.h"
12 #include "term/screen-processor.h"
13 #include "term/term-color-types.h"
14 #include "window/main-window-row-column.h"
15 #include "view/status-bars-table.h"
16 #include "world/world.h"
19 * @brief 32ビット変数配列の指定位置のビットフラグを1にする。
20 * @param FLG フラグ位置(ビット)
23 #define ADD_BAR_FLAG(FLG) (bar_flags[FLG / 32] |= (1L << (FLG % 32)))
26 * @brief 32ビット変数配列の指定位置のビットフラグが1かどうかを返す。
27 * @param FLG フラグ位置(ビット)
30 #define IS_BAR_FLAG(FLG) (bar_flags[FLG / 32] & (1L << (FLG % 32)))
33 * @brief プレイヤー能力値を描画する / Print character stat in given row, column
34 * @param stat 描画するステータスのID
37 void print_stat(player_type *creature_ptr, int stat)
40 if (creature_ptr->stat_cur[stat] < creature_ptr->stat_max[stat]) {
41 put_str(stat_names_reduced[stat], ROW_STAT + stat, 0);
42 cnv_stat(creature_ptr->stat_use[stat], tmp);
43 c_put_str(TERM_YELLOW, tmp, ROW_STAT + stat, COL_STAT + 6);
45 put_str(stat_names[stat], ROW_STAT + stat, 0);
46 cnv_stat(creature_ptr->stat_use[stat], tmp);
47 c_put_str(TERM_L_GREEN, tmp, ROW_STAT + stat, COL_STAT + 6);
50 if (creature_ptr->stat_max[stat] != creature_ptr->stat_max_max[stat])
54 /* 日本語にかぶらないように表示位置を変更 */
55 put_str("!", ROW_STAT + stat, 5);
57 put_str("!", ROW_STAT + stat, 3);
62 * @brief プレイヤーの負傷状態を表示する
65 void print_cut(player_type *creature_ptr)
67 int c = creature_ptr->cut;
69 c_put_str(TERM_L_RED, _("致命傷 ", "Mortal wound"), ROW_CUT, COL_CUT);
74 c_put_str(TERM_RED, _("ひどい深手 ", "Deep gash "), ROW_CUT, COL_CUT);
79 c_put_str(TERM_RED, _("重傷 ", "Severe cut "), ROW_CUT, COL_CUT);
84 c_put_str(TERM_ORANGE, _("大変な傷 ", "Nasty cut "), ROW_CUT, COL_CUT);
89 c_put_str(TERM_ORANGE, _("ひどい傷 ", "Bad cut "), ROW_CUT, COL_CUT);
94 c_put_str(TERM_YELLOW, _("軽傷 ", "Light cut "), ROW_CUT, COL_CUT);
99 c_put_str(TERM_YELLOW, _("かすり傷 ", "Graze "), ROW_CUT, COL_CUT);
103 put_str(" ", ROW_CUT, COL_CUT);
107 * @brief プレイヤーの朦朧状態を表示する
110 void print_stun(player_type *creature_ptr)
112 int s = creature_ptr->stun;
114 c_put_str(TERM_RED, _("意識不明瞭 ", "Knocked out "), ROW_STUN, COL_STUN);
119 c_put_str(TERM_ORANGE, _("ひどく朦朧 ", "Heavy stun "), ROW_STUN, COL_STUN);
124 c_put_str(TERM_ORANGE, _("朦朧 ", "Stun "), ROW_STUN, COL_STUN);
128 put_str(" ", ROW_STUN, COL_STUN);
132 * @brief プレイヤーの空腹状態を表示する / Prints status of hunger
133 * @param player_ptr プレーヤーへの参照ポインタ
136 void print_hunger(player_type *player_ptr)
138 if (current_world_ptr->wizard && player_ptr->current_floor_ptr->inside_arena)
141 if (player_ptr->food < PY_FOOD_FAINT) {
142 c_put_str(TERM_RED, _("衰弱 ", "Weak "), ROW_HUNGRY, COL_HUNGRY);
146 if (player_ptr->food < PY_FOOD_WEAK) {
147 c_put_str(TERM_ORANGE, _("衰弱 ", "Weak "), ROW_HUNGRY, COL_HUNGRY);
151 if (player_ptr->food < PY_FOOD_ALERT) {
152 c_put_str(TERM_YELLOW, _("空腹 ", "Hungry"), ROW_HUNGRY, COL_HUNGRY);
156 if (player_ptr->food < PY_FOOD_FULL) {
157 c_put_str(TERM_L_GREEN, " ", ROW_HUNGRY, COL_HUNGRY);
161 if (player_ptr->food < PY_FOOD_MAX) {
162 c_put_str(TERM_L_GREEN, _("満腹 ", "Full "), ROW_HUNGRY, COL_HUNGRY);
166 c_put_str(TERM_GREEN, _("食過ぎ", "Gorged"), ROW_HUNGRY, COL_HUNGRY);
170 * @brief プレイヤーの行動状態を表示する / Prints Searching, Resting, Paralysis, or 'count' status
171 * @param player_ptr プレーヤーへの参照ポインタ
174 * Display is always exactly 10 characters wide (see below)
175 * This function was a major bottleneck when resting, so a lot of
176 * the text formatting code was optimized in place below.
178 void print_state(player_type *player_ptr)
180 TERM_COLOR attr = TERM_WHITE;
183 if (command_rep > 999) {
184 (void)sprintf(text, "%2d00", command_rep / 100);
186 (void)sprintf(text, " %2d", command_rep);
189 c_put_str(attr, format("%5.5s", text), ROW_STATE, COL_STATE);
193 switch (player_ptr->action) {
194 case ACTION_SEARCH: {
195 strcpy(text, _("探索", "Sear"));
199 strcpy(text, _(" ", " "));
200 if (player_ptr->resting > 0) {
201 sprintf(text, "%4d", player_ptr->resting);
202 } else if (player_ptr->resting == COMMAND_ARG_REST_FULL_HEALING) {
203 text[0] = text[1] = text[2] = text[3] = '*';
204 } else if (player_ptr->resting == COMMAND_ARG_REST_UNTIL_DONE) {
205 text[0] = text[1] = text[2] = text[3] = '&';
211 strcpy(text, _("学習", "lear"));
212 if (player_ptr->new_mane)
217 strcpy(text, _("釣り", "fish"));
222 for (i = 0; i < MAX_KAMAE; i++)
223 if (player_ptr->special_defense & (KAMAE_GENBU << i))
240 strcpy(text, monk_stances[i].desc);
245 for (i = 0; i < MAX_KATA; i++)
246 if (player_ptr->special_defense & (KATA_IAI << i))
249 strcpy(text, samurai_stances[i].desc);
253 strcpy(text, _("歌 ", "Sing"));
256 case ACTION_HAYAGAKE: {
257 strcpy(text, _("速駆", "Fast"));
261 strcpy(text, _("詠唱", "Spel"));
270 c_put_str(attr, format("%5.5s", text), ROW_STATE, COL_STATE);
274 * @brief プレイヤーの行動速度を表示する / Prints the speed of a character. -CJS-
275 * @param player_ptr プレーヤーへの参照ポインタ
278 void print_speed(player_type *player_ptr)
281 term_get_size(&wid, &hgt);
282 TERM_LEN col_speed = wid + COL_SPEED;
283 TERM_LEN row_speed = hgt + ROW_SPEED;
285 int i = player_ptr->pspeed;
286 if (player_ptr->action == ACTION_SEARCH && !player_ptr->lightspeed)
289 floor_type *floor_ptr = player_ptr->current_floor_ptr;
290 bool is_player_fast = is_fast(player_ptr);
292 TERM_COLOR attr = TERM_WHITE;
294 if (player_ptr->riding) {
295 monster_type *m_ptr = &floor_ptr->m_list[player_ptr->riding];
296 if (monster_fast_remaining(m_ptr) && !monster_slow_remaining(m_ptr))
298 else if (monster_slow_remaining(m_ptr) && !monster_fast_remaining(m_ptr))
302 } else if ((is_player_fast && !player_ptr->slow) || player_ptr->lightspeed)
304 else if (player_ptr->slow && !is_player_fast)
308 sprintf(buf, "%s(+%d)", (player_ptr->riding ? _("乗馬", "Ride") : _("加速", "Fast")), (i - 110));
309 } else if (i < 110) {
310 if (player_ptr->riding) {
311 monster_type *m_ptr = &floor_ptr->m_list[player_ptr->riding];
312 if (monster_fast_remaining(m_ptr) && !monster_slow_remaining(m_ptr))
314 else if (monster_slow_remaining(m_ptr) && !monster_fast_remaining(m_ptr))
318 } else if (is_player_fast && !player_ptr->slow)
320 else if (player_ptr->slow && !is_player_fast)
324 sprintf(buf, "%s(-%d)", (player_ptr->riding ? _("乗馬", "Ride") : _("減速", "Slow")), (110 - i));
325 } else if (player_ptr->riding) {
327 strcpy(buf, _("乗馬中", "Riding"));
330 c_put_str(attr, format("%-9s", buf), row_speed, col_speed);
334 * @brief プレイヤーの呪文学習可能状態を表示する
335 * @param player_ptr プレーヤーへの参照ポインタ
338 void print_study(player_type *player_ptr)
341 term_get_size(&wid, &hgt);
342 TERM_LEN col_study = wid + COL_STUDY;
343 TERM_LEN row_study = hgt + ROW_STUDY;
345 if (player_ptr->new_spells) {
346 put_str(_("学習", "Stud"), row_study, col_study);
348 put_str(" ", row_study, col_study);
353 * @brief プレイヤーのものまね可能状態を表示する
354 * @param player_ptr プレーヤーへの参照ポインタ
357 void print_imitation(player_type *player_ptr)
360 term_get_size(&wid, &hgt);
361 TERM_LEN col_study = wid + COL_STUDY;
362 TERM_LEN row_study = hgt + ROW_STUDY;
364 if (player_ptr->pclass != CLASS_IMITATOR)
367 if (player_ptr->mane_num != 0) {
368 put_str(" ", row_study, col_study);
373 if (player_ptr->new_mane)
377 c_put_str(attr, _("まね", "Imit"), row_study, col_study);
381 * @brief 下部に状態表示を行う / Show status bar
384 void print_status(player_type *creature_ptr)
387 term_get_size(&wid, &hgt);
388 TERM_LEN row_statbar = hgt + ROW_STATBAR;
389 TERM_LEN max_col_statbar = wid + MAX_COL_STATBAR;
391 term_erase(0, row_statbar, max_col_statbar);
393 BIT_FLAGS bar_flags[3];
394 bar_flags[0] = bar_flags[1] = bar_flags[2] = 0L;
396 if (creature_ptr->tsuyoshi)
397 ADD_BAR_FLAG(BAR_TSUYOSHI);
399 if (creature_ptr->image)
400 ADD_BAR_FLAG(BAR_HALLUCINATION);
402 if (creature_ptr->blind)
403 ADD_BAR_FLAG(BAR_BLINDNESS);
405 if (creature_ptr->paralyzed)
406 ADD_BAR_FLAG(BAR_PARALYZE);
408 if (creature_ptr->confused)
409 ADD_BAR_FLAG(BAR_CONFUSE);
411 if (creature_ptr->poisoned)
412 ADD_BAR_FLAG(BAR_POISONED);
414 if (creature_ptr->tim_invis)
415 ADD_BAR_FLAG(BAR_SENSEUNSEEN);
417 if (creature_ptr->concent >= CONCENT_RADAR_THRESHOLD)
419 ADD_BAR_FLAG(BAR_SENSEUNSEEN);
420 ADD_BAR_FLAG(BAR_NIGHTSIGHT);
423 if (is_time_limit_esp(creature_ptr))
424 ADD_BAR_FLAG(BAR_TELEPATHY);
426 if (creature_ptr->tim_regen)
427 ADD_BAR_FLAG(BAR_REGENERATION);
429 if (creature_ptr->tim_infra)
430 ADD_BAR_FLAG(BAR_INFRAVISION);
432 if (creature_ptr->protevil)
433 ADD_BAR_FLAG(BAR_PROTEVIL);
435 if (is_invuln(creature_ptr))
436 ADD_BAR_FLAG(BAR_INVULN);
438 if (creature_ptr->wraith_form)
439 ADD_BAR_FLAG(BAR_WRAITH);
441 if (creature_ptr->tim_pass_wall)
442 ADD_BAR_FLAG(BAR_PASSWALL);
444 if (creature_ptr->tim_reflect)
445 ADD_BAR_FLAG(BAR_REFLECTION);
447 if (is_hero(creature_ptr))
448 ADD_BAR_FLAG(BAR_HEROISM);
450 if (is_shero(creature_ptr))
451 ADD_BAR_FLAG(BAR_BERSERK);
453 if (is_blessed(creature_ptr))
454 ADD_BAR_FLAG(BAR_BLESSED);
456 if (creature_ptr->magicdef)
457 ADD_BAR_FLAG(BAR_MAGICDEFENSE);
459 if (creature_ptr->tsubureru)
460 ADD_BAR_FLAG(BAR_EXPAND);
462 if (creature_ptr->shield)
463 ADD_BAR_FLAG(BAR_STONESKIN);
465 if (creature_ptr->special_defense & NINJA_KAWARIMI)
466 ADD_BAR_FLAG(BAR_KAWARIMI);
468 if (creature_ptr->special_defense & DEFENSE_ACID)
469 ADD_BAR_FLAG(BAR_IMMACID);
470 if (is_oppose_acid(creature_ptr))
471 ADD_BAR_FLAG(BAR_RESACID);
473 if (creature_ptr->special_defense & DEFENSE_ELEC)
474 ADD_BAR_FLAG(BAR_IMMELEC);
475 if (is_oppose_elec(creature_ptr))
476 ADD_BAR_FLAG(BAR_RESELEC);
478 if (creature_ptr->special_defense & DEFENSE_FIRE)
479 ADD_BAR_FLAG(BAR_IMMFIRE);
480 if (is_oppose_fire(creature_ptr))
481 ADD_BAR_FLAG(BAR_RESFIRE);
483 if (creature_ptr->special_defense & DEFENSE_COLD)
484 ADD_BAR_FLAG(BAR_IMMCOLD);
485 if (is_oppose_cold(creature_ptr))
486 ADD_BAR_FLAG(BAR_RESCOLD);
488 if (is_oppose_pois(creature_ptr))
489 ADD_BAR_FLAG(BAR_RESPOIS);
491 if (creature_ptr->word_recall)
492 ADD_BAR_FLAG(BAR_RECALL);
494 if (creature_ptr->alter_reality)
495 ADD_BAR_FLAG(BAR_ALTER);
497 if (creature_ptr->afraid)
498 ADD_BAR_FLAG(BAR_AFRAID);
500 if (creature_ptr->tim_res_time)
501 ADD_BAR_FLAG(BAR_RESTIME);
503 if (creature_ptr->multishadow)
504 ADD_BAR_FLAG(BAR_MULTISHADOW);
506 if (creature_ptr->special_attack & ATTACK_CONFUSE)
507 ADD_BAR_FLAG(BAR_ATTKCONF);
509 if (creature_ptr->resist_magic)
510 ADD_BAR_FLAG(BAR_REGMAGIC);
512 if (creature_ptr->ult_res)
513 ADD_BAR_FLAG(BAR_ULTIMATE);
515 if (creature_ptr->tim_levitation)
516 ADD_BAR_FLAG(BAR_LEVITATE);
518 if (creature_ptr->tim_res_nether)
519 ADD_BAR_FLAG(BAR_RESNETH);
521 if (creature_ptr->dustrobe)
522 ADD_BAR_FLAG(BAR_DUSTROBE);
524 if (creature_ptr->special_attack & ATTACK_FIRE)
525 ADD_BAR_FLAG(BAR_ATTKFIRE);
526 if (creature_ptr->special_attack & ATTACK_COLD)
527 ADD_BAR_FLAG(BAR_ATTKCOLD);
528 if (creature_ptr->special_attack & ATTACK_ELEC)
529 ADD_BAR_FLAG(BAR_ATTKELEC);
530 if (creature_ptr->special_attack & ATTACK_ACID)
531 ADD_BAR_FLAG(BAR_ATTKACID);
532 if (creature_ptr->special_attack & ATTACK_POIS)
533 ADD_BAR_FLAG(BAR_ATTKPOIS);
534 if (creature_ptr->special_defense & NINJA_S_STEALTH)
535 ADD_BAR_FLAG(BAR_SUPERSTEALTH);
537 if (creature_ptr->tim_sh_fire)
538 ADD_BAR_FLAG(BAR_SHFIRE);
540 if (is_time_limit_stealth(creature_ptr))
541 ADD_BAR_FLAG(BAR_STEALTH);
543 if (creature_ptr->tim_sh_touki)
544 ADD_BAR_FLAG(BAR_TOUKI);
546 if (creature_ptr->tim_sh_holy)
547 ADD_BAR_FLAG(BAR_SHHOLY);
549 if (creature_ptr->tim_eyeeye)
550 ADD_BAR_FLAG(BAR_EYEEYE);
552 if (creature_ptr->realm1 == REALM_HEX) {
553 if (hex_spelling(creature_ptr, HEX_BLESS))
554 ADD_BAR_FLAG(BAR_BLESSED);
555 if (hex_spelling(creature_ptr, HEX_DEMON_AURA)) {
556 ADD_BAR_FLAG(BAR_SHFIRE);
557 ADD_BAR_FLAG(BAR_REGENERATION);
559 if (hex_spelling(creature_ptr, HEX_XTRA_MIGHT))
560 ADD_BAR_FLAG(BAR_MIGHT);
561 if (hex_spelling(creature_ptr, HEX_DETECT_EVIL))
562 ADD_BAR_FLAG(BAR_ESP_EVIL);
563 if (hex_spelling(creature_ptr, HEX_ICE_ARMOR))
564 ADD_BAR_FLAG(BAR_SHCOLD);
565 if (hex_spelling(creature_ptr, HEX_RUNESWORD))
566 ADD_BAR_FLAG(BAR_RUNESWORD);
567 if (hex_spelling(creature_ptr, HEX_BUILDING))
568 ADD_BAR_FLAG(BAR_BUILD);
569 if (hex_spelling(creature_ptr, HEX_ANTI_TELE))
570 ADD_BAR_FLAG(BAR_ANTITELE);
571 if (hex_spelling(creature_ptr, HEX_SHOCK_CLOAK))
572 ADD_BAR_FLAG(BAR_SHELEC);
573 if (hex_spelling(creature_ptr, HEX_SHADOW_CLOAK))
574 ADD_BAR_FLAG(BAR_SHSHADOW);
575 if (hex_spelling(creature_ptr, HEX_CONFUSION))
576 ADD_BAR_FLAG(BAR_ATTKCONF);
577 if (hex_spelling(creature_ptr, HEX_EYE_FOR_EYE))
578 ADD_BAR_FLAG(BAR_EYEEYE);
579 if (hex_spelling(creature_ptr, HEX_ANTI_MULTI))
580 ADD_BAR_FLAG(BAR_ANTIMULTI);
581 if (hex_spelling(creature_ptr, HEX_VAMP_BLADE))
582 ADD_BAR_FLAG(BAR_VAMPILIC);
583 if (hex_spelling(creature_ptr, HEX_ANTI_MAGIC))
584 ADD_BAR_FLAG(BAR_ANTIMAGIC);
585 if (hex_spelling(creature_ptr, HEX_CURE_LIGHT) || hex_spelling(creature_ptr, HEX_CURE_SERIOUS) || hex_spelling(creature_ptr, HEX_CURE_CRITICAL))
586 ADD_BAR_FLAG(BAR_CURE);
588 if (hex_revenge_turn(creature_ptr)) {
589 if (hex_revenge_type(creature_ptr) == 1)
590 ADD_BAR_FLAG(BAR_PATIENCE);
591 if (hex_revenge_type(creature_ptr) == 2)
592 ADD_BAR_FLAG(BAR_REVENGE);
596 TERM_LEN col = 0, num = 0;
597 for (int i = 0; stat_bars[i].sstr; i++) {
598 if (IS_BAR_FLAG(i)) {
599 col += strlen(stat_bars[i].lstr) + 1;
605 if (col - 1 > max_col_statbar) {
609 for (int i = 0; stat_bars[i].sstr; i++) {
610 if (IS_BAR_FLAG(i)) {
611 col += strlen(stat_bars[i].sstr);
615 if (col - 1 <= max_col_statbar - (num - 1)) {
621 col = (max_col_statbar - col) / 2;
622 for (int i = 0; stat_bars[i].sstr; i++) {
628 str = stat_bars[i].lstr;
630 str = stat_bars[i].sstr;
632 c_put_str(stat_bars[i].attr, str, row_statbar, col);
636 if (col > max_col_statbar)
642 * @brief プレイヤーのステータスを一括表示する(下部分) / Display extra info (mostly below map)
643 * @param player_ptr プレーヤーへの参照ポインタ
646 void print_frame_extra(player_type *player_ptr)
648 print_cut(player_ptr);
649 print_stun(player_ptr);
650 print_hunger(player_ptr);
651 print_state(player_ptr);
652 print_speed(player_ptr);
653 print_study(player_ptr);
654 print_imitation(player_ptr);
655 print_status(player_ptr);