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 (is_time_limit_esp(creature_ptr))
418 ADD_BAR_FLAG(BAR_TELEPATHY);
420 if (creature_ptr->tim_regen)
421 ADD_BAR_FLAG(BAR_REGENERATION);
423 if (creature_ptr->tim_infra)
424 ADD_BAR_FLAG(BAR_INFRAVISION);
426 if (creature_ptr->protevil)
427 ADD_BAR_FLAG(BAR_PROTEVIL);
429 if (is_invuln(creature_ptr))
430 ADD_BAR_FLAG(BAR_INVULN);
432 if (creature_ptr->wraith_form)
433 ADD_BAR_FLAG(BAR_WRAITH);
435 if (creature_ptr->tim_pass_wall)
436 ADD_BAR_FLAG(BAR_PASSWALL);
438 if (creature_ptr->tim_reflect)
439 ADD_BAR_FLAG(BAR_REFLECTION);
441 if (is_hero(creature_ptr))
442 ADD_BAR_FLAG(BAR_HEROISM);
444 if (creature_ptr->shero)
445 ADD_BAR_FLAG(BAR_BERSERK);
447 if (is_blessed(creature_ptr))
448 ADD_BAR_FLAG(BAR_BLESSED);
450 if (creature_ptr->magicdef)
451 ADD_BAR_FLAG(BAR_MAGICDEFENSE);
453 if (creature_ptr->tsubureru)
454 ADD_BAR_FLAG(BAR_EXPAND);
456 if (creature_ptr->shield)
457 ADD_BAR_FLAG(BAR_STONESKIN);
459 if (creature_ptr->special_defense & NINJA_KAWARIMI)
460 ADD_BAR_FLAG(BAR_KAWARIMI);
462 if (creature_ptr->special_defense & DEFENSE_ACID)
463 ADD_BAR_FLAG(BAR_IMMACID);
464 if (is_oppose_acid(creature_ptr))
465 ADD_BAR_FLAG(BAR_RESACID);
467 if (creature_ptr->special_defense & DEFENSE_ELEC)
468 ADD_BAR_FLAG(BAR_IMMELEC);
469 if (is_oppose_elec(creature_ptr))
470 ADD_BAR_FLAG(BAR_RESELEC);
472 if (creature_ptr->special_defense & DEFENSE_FIRE)
473 ADD_BAR_FLAG(BAR_IMMFIRE);
474 if (is_oppose_fire(creature_ptr))
475 ADD_BAR_FLAG(BAR_RESFIRE);
477 if (creature_ptr->special_defense & DEFENSE_COLD)
478 ADD_BAR_FLAG(BAR_IMMCOLD);
479 if (is_oppose_cold(creature_ptr))
480 ADD_BAR_FLAG(BAR_RESCOLD);
482 if (is_oppose_pois(creature_ptr))
483 ADD_BAR_FLAG(BAR_RESPOIS);
485 if (creature_ptr->word_recall)
486 ADD_BAR_FLAG(BAR_RECALL);
488 if (creature_ptr->alter_reality)
489 ADD_BAR_FLAG(BAR_ALTER);
491 if (creature_ptr->afraid)
492 ADD_BAR_FLAG(BAR_AFRAID);
494 if (creature_ptr->tim_res_time)
495 ADD_BAR_FLAG(BAR_RESTIME);
497 if (creature_ptr->multishadow)
498 ADD_BAR_FLAG(BAR_MULTISHADOW);
500 if (creature_ptr->special_attack & ATTACK_CONFUSE)
501 ADD_BAR_FLAG(BAR_ATTKCONF);
503 if (creature_ptr->resist_magic)
504 ADD_BAR_FLAG(BAR_REGMAGIC);
506 if (creature_ptr->ult_res)
507 ADD_BAR_FLAG(BAR_ULTIMATE);
509 if (creature_ptr->tim_levitation)
510 ADD_BAR_FLAG(BAR_LEVITATE);
512 if (creature_ptr->tim_res_nether)
513 ADD_BAR_FLAG(BAR_RESNETH);
515 if (creature_ptr->dustrobe)
516 ADD_BAR_FLAG(BAR_DUSTROBE);
518 if (creature_ptr->special_attack & ATTACK_FIRE)
519 ADD_BAR_FLAG(BAR_ATTKFIRE);
520 if (creature_ptr->special_attack & ATTACK_COLD)
521 ADD_BAR_FLAG(BAR_ATTKCOLD);
522 if (creature_ptr->special_attack & ATTACK_ELEC)
523 ADD_BAR_FLAG(BAR_ATTKELEC);
524 if (creature_ptr->special_attack & ATTACK_ACID)
525 ADD_BAR_FLAG(BAR_ATTKACID);
526 if (creature_ptr->special_attack & ATTACK_POIS)
527 ADD_BAR_FLAG(BAR_ATTKPOIS);
528 if (creature_ptr->special_defense & NINJA_S_STEALTH)
529 ADD_BAR_FLAG(BAR_SUPERSTEALTH);
531 if (creature_ptr->tim_sh_fire)
532 ADD_BAR_FLAG(BAR_SHFIRE);
534 if (is_time_limit_stealth(creature_ptr))
535 ADD_BAR_FLAG(BAR_STEALTH);
537 if (creature_ptr->tim_sh_touki)
538 ADD_BAR_FLAG(BAR_TOUKI);
540 if (creature_ptr->tim_sh_holy)
541 ADD_BAR_FLAG(BAR_SHHOLY);
543 if (creature_ptr->tim_eyeeye)
544 ADD_BAR_FLAG(BAR_EYEEYE);
546 if (creature_ptr->realm1 == REALM_HEX) {
547 if (hex_spelling(creature_ptr, HEX_BLESS))
548 ADD_BAR_FLAG(BAR_BLESSED);
549 if (hex_spelling(creature_ptr, HEX_DEMON_AURA)) {
550 ADD_BAR_FLAG(BAR_SHFIRE);
551 ADD_BAR_FLAG(BAR_REGENERATION);
553 if (hex_spelling(creature_ptr, HEX_XTRA_MIGHT))
554 ADD_BAR_FLAG(BAR_MIGHT);
555 if (hex_spelling(creature_ptr, HEX_DETECT_EVIL))
556 ADD_BAR_FLAG(BAR_ESP_EVIL);
557 if (hex_spelling(creature_ptr, HEX_ICE_ARMOR))
558 ADD_BAR_FLAG(BAR_SHCOLD);
559 if (hex_spelling(creature_ptr, HEX_RUNESWORD))
560 ADD_BAR_FLAG(BAR_RUNESWORD);
561 if (hex_spelling(creature_ptr, HEX_BUILDING))
562 ADD_BAR_FLAG(BAR_BUILD);
563 if (hex_spelling(creature_ptr, HEX_ANTI_TELE))
564 ADD_BAR_FLAG(BAR_ANTITELE);
565 if (hex_spelling(creature_ptr, HEX_SHOCK_CLOAK))
566 ADD_BAR_FLAG(BAR_SHELEC);
567 if (hex_spelling(creature_ptr, HEX_SHADOW_CLOAK))
568 ADD_BAR_FLAG(BAR_SHSHADOW);
569 if (hex_spelling(creature_ptr, HEX_CONFUSION))
570 ADD_BAR_FLAG(BAR_ATTKCONF);
571 if (hex_spelling(creature_ptr, HEX_EYE_FOR_EYE))
572 ADD_BAR_FLAG(BAR_EYEEYE);
573 if (hex_spelling(creature_ptr, HEX_ANTI_MULTI))
574 ADD_BAR_FLAG(BAR_ANTIMULTI);
575 if (hex_spelling(creature_ptr, HEX_VAMP_BLADE))
576 ADD_BAR_FLAG(BAR_VAMPILIC);
577 if (hex_spelling(creature_ptr, HEX_ANTI_MAGIC))
578 ADD_BAR_FLAG(BAR_ANTIMAGIC);
579 if (hex_spelling(creature_ptr, HEX_CURE_LIGHT) || hex_spelling(creature_ptr, HEX_CURE_SERIOUS) || hex_spelling(creature_ptr, HEX_CURE_CRITICAL))
580 ADD_BAR_FLAG(BAR_CURE);
582 if (hex_revenge_turn(creature_ptr)) {
583 if (hex_revenge_type(creature_ptr) == 1)
584 ADD_BAR_FLAG(BAR_PATIENCE);
585 if (hex_revenge_type(creature_ptr) == 2)
586 ADD_BAR_FLAG(BAR_REVENGE);
590 TERM_LEN col = 0, num = 0;
591 for (int i = 0; stat_bars[i].sstr; i++) {
592 if (IS_BAR_FLAG(i)) {
593 col += strlen(stat_bars[i].lstr) + 1;
599 if (col - 1 > max_col_statbar) {
603 for (int i = 0; stat_bars[i].sstr; i++) {
604 if (IS_BAR_FLAG(i)) {
605 col += strlen(stat_bars[i].sstr);
609 if (col - 1 <= max_col_statbar - (num - 1)) {
615 col = (max_col_statbar - col) / 2;
616 for (int i = 0; stat_bars[i].sstr; i++) {
622 str = stat_bars[i].lstr;
624 str = stat_bars[i].sstr;
626 c_put_str(stat_bars[i].attr, str, row_statbar, col);
630 if (col > max_col_statbar)
636 * @brief プレイヤーのステータスを一括表示する(下部分) / Display extra info (mostly below map)
637 * @param player_ptr プレーヤーへの参照ポインタ
640 void print_frame_extra(player_type *player_ptr)
642 print_cut(player_ptr);
643 print_stun(player_ptr);
644 print_hunger(player_ptr);
645 print_state(player_ptr);
646 print_speed(player_ptr);
647 print_study(player_ptr);
648 print_imitation(player_ptr);
649 print_status(player_ptr);