OSDN Git Service

[Refactor] #37353 コメント整理。 / Refactor comments.
[hengband/hengband.git] / src / view-mainwindow.c
1 /*!
2  * @file xtra1.c
3  * @brief プレイヤーのステータス処理 / status
4  * @date 2018/09/25
5  * @author
6  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke\n
7  * This software may be copied and distributed for educational, research, and\n
8  * not for profit purposes provided that this copyright and statement are\n
9  * included in all such copies.\n
10  * 2014 Deskull rearranged comment for Doxygen.
11  */
12
13 #include "angband.h"
14 #include "world.h"
15 #include "quest.h"
16 #include "artifact.h"
17 #include "avatar.h"
18 #include "player-status.h"
19
20  /*
21   * Some screen locations for various display routines
22   * Currently, row 8 and 15 are the only "blank" rows.
23   * That leaves a "border" around the "stat" values.
24   */
25
26 #define ROW_RACE                1
27 #define COL_RACE                0       /* <race name> */
28
29   /*#define ROW_CLASS               2 */
30   /*#define COL_CLASS               0 */      /* <class name> */
31
32 #define ROW_TITLE               2
33 #define COL_TITLE               0       /* <title> or <mode> */
34
35 /*#define ROW_SEIKAKU           4 */
36 /*#define COL_SEIKAKU           0*/     /* <seikaku> */
37
38 #define ROW_DAY                 21
39 #define COL_DAY                 0       /* day */
40
41 #define ROW_DUNGEON             22
42 #define COL_DUNGEON             0       /* dungeon */
43
44 #define ROW_LEVEL               3
45 #define COL_LEVEL               0       /* "LEVEL xxxxxx" */
46
47 #define ROW_EXP                 4
48 #define COL_EXP                 0       /* "EXP xxxxxxxx" */
49
50 #define ROW_GOLD                5
51 #define COL_GOLD                0       /* "AU xxxxxxxxx" */
52
53 #define ROW_EQUIPPY             6
54 #define COL_EQUIPPY             0       /* equippy chars */
55
56 #define ROW_STAT                7
57 #define COL_STAT                0       /* "xxx   xxxxxx" */
58
59 #define ROW_AC                  13
60 #define COL_AC                  0       /* "Cur AC xxxxx" */
61
62 #define ROW_HPMP                14
63 #define COL_HPMP                0
64
65 #define ROW_CURHP               14
66 #define COL_CURHP               0       /* "Cur HP xxxxx" */
67
68 #define ROW_CURSP               15
69 #define COL_CURSP               0       /* "Cur SP xxxxx" */
70
71 #define ROW_RIDING_INFO         16
72 #define COL_RIDING_INFO         0       /* "xxxxxxxxxxxx" */
73
74 #define ROW_INFO                17
75 #define COL_INFO                0       /* "xxxxxxxxxxxx" */
76
77 #define ROW_CUT                 18
78 #define COL_CUT                 0       /* <cut> */
79
80 #define ROW_STUN                19
81 #define COL_STUN                0       /* <stun> */
82
83 #define ROW_HUNGRY              20
84 #define COL_HUNGRY              0       /* "Weak" / "Hungry" / "Full" / "Gorged" */
85
86 #define ROW_STATE               20
87 #define COL_STATE                7      /* <state> */
88
89 #define ROW_SPEED               (-1)
90 #define COL_SPEED               (-24)      /* "Slow (-NN)" or "Fast (+NN)" */
91
92 #define ROW_STUDY               (-1)
93 #define COL_STUDY               (-13)      /* "Study" */
94
95 #define ROW_DEPTH               (-1)
96 #define COL_DEPTH               (-8)      /* "Lev NNN" / "NNNN ft" */
97
98 #define ROW_STATBAR             (-1)
99 #define COL_STATBAR              0
100 #define MAX_COL_STATBAR         (-26)
101 /*!
102  * @brief 現在の修正後能力値を3~17及び18/xxx形式に変換する / Converts stat num into a six-char (right justified) string
103  * @param val 能力値
104  * @param out_val 出力先文字列ポインタ
105  * @return なし
106  */
107 void cnv_stat(int val, char *out_val)
108 {
109         /* Above 18 */
110         if (val > 18)
111         {
112                 int bonus = (val - 18);
113
114                 if (bonus >= 220)
115                 {
116                         sprintf(out_val, "18/%3s", "***");
117                 }
118                 else if (bonus >= 100)
119                 {
120                         sprintf(out_val, "18/%03d", bonus);
121                 }
122                 else
123                 {
124                         sprintf(out_val, " 18/%02d", bonus);
125                 }
126         }
127
128         /* From 3 to 18 */
129         else
130         {
131                 sprintf(out_val, "    %2d", val);
132         }
133 }
134
135 /*!
136  * @brief 能力値現在値から3~17及び18/xxx様式に基づく加減算を行う。
137  * Modify a stat value by a "modifier", return new value
138  * @param value 現在値
139  * @param amount 加減算値
140  * @return 加減算後の値
141  * @details
142  * <pre>
143  * Stats go up: 3,4,...,17,18,18/10,18/20,...,18/220
144  * Or even: 18/13, 18/23, 18/33, ..., 18/220
145  * Stats go down: 18/220, 18/210,..., 18/10, 18, 17, ..., 3
146  * Or even: 18/13, 18/03, 18, 17, ..., 3
147  * </pre>
148  */
149 s16b modify_stat_value(int value, int amount)
150 {
151         int    i;
152
153         /* Reward */
154         if (amount > 0)
155         {
156                 /* Apply each point */
157                 for (i = 0; i < amount; i++)
158                 {
159                         /* One point at a time */
160                         if (value < 18) value++;
161
162                         /* Ten "points" at a time */
163                         else value += 10;
164                 }
165         }
166
167         /* Penalty */
168         else if (amount < 0)
169         {
170                 /* Apply each point */
171                 for (i = 0; i < (0 - amount); i++)
172                 {
173                         /* Ten points at a time */
174                         if (value >= 18+10) value -= 10;
175
176                         /* Hack -- prevent weirdness */
177                         else if (value > 18) value = 18;
178
179                         /* One point at a time */
180                         else if (value > 3) value--;
181                 }
182         }
183
184         /* Return new value */
185         return (s16b)(value);
186 }
187
188
189
190 /*!
191  * @brief 画面左の能力値表示を行うために指定位置から13キャラ分を空白消去後指定のメッセージを明るい青で描画する /
192  * Print character info at given row, column in a 13 char field
193  * @param info 表示文字列
194  * @param row 描画列
195  * @param col 描画行
196  * @return なし
197  */
198 static void prt_field(concptr info, TERM_LEN row, TERM_LEN col)
199 {
200         /* Dump 13 spaces to clear */
201         c_put_str(TERM_WHITE, "             ", row, col);
202
203         /* Dump the info itself */
204         c_put_str(TERM_L_BLUE, info, row, col);
205 }
206
207 /*!
208  * @brief ゲーム時刻を表示する /
209  * Print time
210  * @return なし
211  */
212 void prt_time(void)
213 {
214         int day, hour, min;
215
216         /* Dump 13 spaces to clear */
217         c_put_str(TERM_WHITE, "             ", ROW_DAY, COL_DAY);
218
219         extract_day_hour_min(&day, &hour, &min);
220
221         /* Dump the info itself */
222         if (day < 1000) c_put_str(TERM_WHITE, format(_("%2d日目", "Day%3d"), day), ROW_DAY, COL_DAY);
223         else c_put_str(TERM_WHITE, _("***日目", "Day***"), ROW_DAY, COL_DAY);
224
225         c_put_str(TERM_WHITE, format("%2d:%02d", hour, min), ROW_DAY, COL_DAY+7);
226 }
227
228 /*!
229  * @brief 現在のマップ名を返す /
230  * @return マップ名の文字列参照ポインタ
231  */
232 concptr map_name(void)
233 {
234         if (p_ptr->inside_quest && is_fixed_quest_idx(p_ptr->inside_quest)
235             && (quest[p_ptr->inside_quest].flags & QUEST_FLAG_PRESET))
236                 return _("クエスト", "Quest");
237         else if (p_ptr->wild_mode)
238                 return _("地上", "Surface");
239         else if (p_ptr->inside_arena)
240                 return _("アリーナ", "Arena");
241         else if (p_ptr->inside_battle)
242                 return _("闘技場", "Monster Arena");
243         else if (!current_floor_ptr->dun_level && p_ptr->town_num)
244                 return town_info[p_ptr->town_num].name;
245         else
246                 return d_name+d_info[p_ptr->dungeon_idx].name;
247 }
248
249 /*!
250  * @brief 現在のマップ名を描画する / Print dungeon
251  * @return なし
252  */
253 static void prt_dungeon(void)
254 {
255         concptr dungeon_name;
256         TERM_LEN col;
257
258         /* Dump 13 spaces to clear */
259         c_put_str(TERM_WHITE, "             ", ROW_DUNGEON, COL_DUNGEON);
260
261         dungeon_name = map_name();
262
263         col = COL_DUNGEON + 6 - strlen(dungeon_name)/2;
264         if (col < 0) col = 0;
265
266         /* Dump the info itself */
267         c_put_str(TERM_L_UMBER, format("%s",dungeon_name),
268                   ROW_DUNGEON, col);
269 }
270
271
272 /*!
273  * @brief プレイヤー能力値を描画する / Print character stat in given row, column
274  * @param stat 描画するステータスのID
275  * @return なし
276  */
277 static void prt_stat(int stat)
278 {
279         GAME_TEXT tmp[32];
280
281         /* Display "injured" stat */
282         if (p_ptr->stat_cur[stat] < p_ptr->stat_max[stat])
283         {
284                 put_str(stat_names_reduced[stat], ROW_STAT + stat, 0);
285                 cnv_stat(p_ptr->stat_use[stat], tmp);
286                 c_put_str(TERM_YELLOW, tmp, ROW_STAT + stat, COL_STAT + 6);
287         }
288
289         /* Display "healthy" stat */
290         else
291         {
292                 put_str(stat_names[stat], ROW_STAT + stat, 0);
293                 cnv_stat(p_ptr->stat_use[stat], tmp);
294                 c_put_str(TERM_L_GREEN, tmp, ROW_STAT + stat, COL_STAT + 6);
295         }
296
297         /* Indicate natural maximum */
298         if (p_ptr->stat_max[stat] == p_ptr->stat_max_max[stat])
299         {
300 #ifdef JP
301                 /* 日本語にかぶらないように表示位置を変更 */
302                 put_str("!", ROW_STAT + stat, 5);
303 #else
304                 put_str("!", ROW_STAT + stat, 3);
305 #endif
306
307         }
308 }
309
310
311 /*
312  * 画面下部に表示する状態表示定義ID / Data structure for status bar
313  */
314 #define BAR_TSUYOSHI 0      /*!< 下部ステータス表示: オクレ兄さん状態 */
315 #define BAR_HALLUCINATION 1 /*!< 下部ステータス表示: 幻覚 */
316 #define BAR_BLINDNESS 2     /*!< 下部ステータス表示: 盲目 */
317 #define BAR_PARALYZE 3      /*!< 下部ステータス表示: 麻痺 */
318 #define BAR_CONFUSE 4       /*!< 下部ステータス表示: 混乱 */
319 #define BAR_POISONED 5      /*!< 下部ステータス表示: 毒 */
320 #define BAR_AFRAID 6        /*!< 下部ステータス表示: 恐怖 */
321 #define BAR_LEVITATE 7      /*!< 下部ステータス表示: 浮遊 */
322 #define BAR_REFLECTION 8    /*!< 下部ステータス表示: 反射 */
323 #define BAR_PASSWALL 9      /*!< 下部ステータス表示: 壁抜け */
324 #define BAR_WRAITH 10       /*!< 下部ステータス表示: 幽体化 */
325 #define BAR_PROTEVIL 11     /*!< 下部ステータス表示: 対邪悪結界 */
326 #define BAR_KAWARIMI 12     /*!< 下部ステータス表示: 変わり身 */
327 #define BAR_MAGICDEFENSE 13 /*!< 下部ステータス表示: 魔法の鎧 */
328 #define BAR_EXPAND 14       /*!< 下部ステータス表示: 横伸び */
329 #define BAR_STONESKIN 15    /*!< 下部ステータス表示: 石肌化 */
330 #define BAR_MULTISHADOW 16  /*!< 下部ステータス表示: 影分身 */
331 #define BAR_REGMAGIC 17     /*!< 下部ステータス表示: 魔法防御 */
332 #define BAR_ULTIMATE 18     /*!< 下部ステータス表示: 究極の耐性 */
333 #define BAR_INVULN 19       /*!< 下部ステータス表示: 無敵化 */
334 #define BAR_IMMACID 20      /*!< 下部ステータス表示: 酸免疫 */
335 #define BAR_RESACID 21      /*!< 下部ステータス表示: 酸耐性 */
336 #define BAR_IMMELEC 22      /*!< 下部ステータス表示: 電撃免疫 */
337 #define BAR_RESELEC 23      /*!< 下部ステータス表示: 電撃耐性 */
338 #define BAR_IMMFIRE 24      /*!< 下部ステータス表示: 火炎免疫 */
339 #define BAR_RESFIRE 25      /*!< 下部ステータス表示: 火炎耐性 */
340 #define BAR_IMMCOLD 26      /*!< 下部ステータス表示: 冷気免疫 */
341 #define BAR_RESCOLD 27      /*!< 下部ステータス表示: 冷気耐性 */
342 #define BAR_RESPOIS 28      /*!< 下部ステータス表示: 毒耐性 */
343 #define BAR_RESNETH 29      /*!< 下部ステータス表示: 地獄耐性 */
344 #define BAR_RESTIME 30      /*!< 下部ステータス表示: 時間逆転耐性 */
345 #define BAR_DUSTROBE 31     /*!< 下部ステータス表示: 破片オーラ */
346 #define BAR_SHFIRE 32       /*!< 下部ステータス表示: 火炎オーラ */
347 #define BAR_TOUKI 33        /*!< 下部ステータス表示: 闘気 */
348 #define BAR_SHHOLY 34       /*!< 下部ステータス表示: 聖なるオーラ */
349 #define BAR_EYEEYE 35       /*!< 下部ステータス表示: 目には目を */
350 #define BAR_BLESSED 36      /*!< 下部ステータス表示: 祝福 */
351 #define BAR_HEROISM 37      /*!< 下部ステータス表示: 士気高揚 */
352 #define BAR_BERSERK 38      /*!< 下部ステータス表示: 狂戦士化 */
353 #define BAR_ATTKFIRE 39     /*!< 下部ステータス表示: 焼棄スレイ */
354 #define BAR_ATTKCOLD 40     /*!< 下部ステータス表示: 冷凍スレイ */
355 #define BAR_ATTKELEC 41     /*!< 下部ステータス表示: 電撃スレイ */
356 #define BAR_ATTKACID 42     /*!< 下部ステータス表示: 溶解スレイ */
357 #define BAR_ATTKPOIS 43     /*!< 下部ステータス表示: 毒殺スレイ */
358 #define BAR_ATTKCONF 44     /*!< 下部ステータス表示: 混乱打撃 */
359 #define BAR_SENSEUNSEEN 45  /*!< 下部ステータス表示: 透明視 */
360 #define BAR_TELEPATHY 46    /*!< 下部ステータス表示: テレパシー */
361 #define BAR_REGENERATION 47 /*!< 下部ステータス表示: 急回復 */
362 #define BAR_INFRAVISION 48  /*!< 下部ステータス表示: 赤外線視力 */
363 #define BAR_STEALTH 49      /*!< 下部ステータス表示: 隠密 */
364 #define BAR_SUPERSTEALTH 50 /*!< 下部ステータス表示: 超隠密 */
365 #define BAR_RECALL 51       /*!< 下部ステータス表示: 帰還待ち */
366 #define BAR_ALTER 52        /*!< 下部ステータス表示: 現実変容待ち */
367 #define BAR_SHCOLD 53       /*!< 下部ステータス表示: 冷気オーラ */
368 #define BAR_SHELEC 54       /*!< 下部ステータス表示: 電撃オーラ */
369 #define BAR_SHSHADOW 55     /*!< 下部ステータス表示: 影のオーラ */
370 #define BAR_MIGHT 56        /*!< 下部ステータス表示: 腕力強化 */
371 #define BAR_BUILD 57        /*!< 下部ステータス表示: 肉体強化 */
372 #define BAR_ANTIMULTI 58    /*!< 下部ステータス表示: 反増殖 */
373 #define BAR_ANTITELE 59     /*!< 下部ステータス表示: 反テレポート */
374 #define BAR_ANTIMAGIC 60    /*!< 下部ステータス表示: 反魔法 */
375 #define BAR_PATIENCE 61     /*!< 下部ステータス表示: 我慢 */
376 #define BAR_REVENGE 62      /*!< 下部ステータス表示: 宣告 */
377 #define BAR_RUNESWORD 63    /*!< 下部ステータス表示: 魔剣化 */
378 #define BAR_VAMPILIC 64     /*!< 下部ステータス表示: 吸血 */
379 #define BAR_CURE 65         /*!< 下部ステータス表示: 回復 */
380 #define BAR_ESP_EVIL 66     /*!< 下部ステータス表示: 邪悪感知 */
381
382 static struct {
383         TERM_COLOR attr;
384         concptr sstr;
385         concptr lstr;
386 } bar[]
387 #ifdef JP
388 = {
389         {TERM_YELLOW, "つ", "つよし"},
390         {TERM_VIOLET, "幻", "幻覚"},
391         {TERM_L_DARK, "盲", "盲目"},
392         {TERM_RED, "痺", "麻痺"},
393         {TERM_VIOLET, "乱", "混乱"},
394         {TERM_GREEN, "毒", "毒"},
395         {TERM_BLUE, "恐", "恐怖"},
396         {TERM_L_BLUE, "浮", "浮遊"},
397         {TERM_SLATE, "反", "反射"},
398         {TERM_SLATE, "壁", "壁抜け"},
399         {TERM_L_DARK, "幽", "幽体"},
400         {TERM_SLATE, "邪", "防邪"},
401         {TERM_VIOLET, "変", "変わり身"},
402         {TERM_YELLOW, "魔", "魔法鎧"},
403         {TERM_L_UMBER, "伸", "伸び"},
404         {TERM_WHITE, "石", "石肌"},
405         {TERM_L_BLUE, "分", "分身"},
406         {TERM_SLATE, "防", "魔法防御"},
407         {TERM_YELLOW, "究", "究極"},
408         {TERM_YELLOW, "無", "無敵"},
409         {TERM_L_GREEN, "酸", "酸免疫"},
410         {TERM_GREEN, "酸", "耐酸"},
411         {TERM_L_BLUE, "電", "電免疫"},
412         {TERM_BLUE, "電", "耐電"},
413         {TERM_L_RED, "火", "火免疫"},
414         {TERM_RED, "火", "耐火"},
415         {TERM_WHITE, "冷", "冷免疫"},
416         {TERM_SLATE, "冷", "耐冷"},
417         {TERM_GREEN, "毒", "耐毒"},
418         {TERM_L_DARK, "獄", "耐地獄"},
419         {TERM_L_BLUE, "時", "耐時間"},
420         {TERM_L_DARK, "鏡", "鏡オーラ"},
421         {TERM_L_RED, "オ", "火オーラ"},
422         {TERM_WHITE, "闘", "闘気"},
423         {TERM_WHITE, "聖", "聖オーラ"},
424         {TERM_VIOLET, "目", "目には目"},
425         {TERM_WHITE, "祝", "祝福"},
426         {TERM_WHITE, "勇", "勇"},
427         {TERM_RED, "狂", "狂乱"},
428         {TERM_L_RED, "火", "魔剣火"},
429         {TERM_WHITE, "冷", "魔剣冷"},
430         {TERM_L_BLUE, "電", "魔剣電"},
431         {TERM_SLATE, "酸", "魔剣酸"},
432         {TERM_L_GREEN, "毒", "魔剣毒"},
433         {TERM_RED, "乱", "混乱打撃"},
434         {TERM_L_BLUE, "視", "透明視"},
435         {TERM_ORANGE, "テ", "テレパシ"},
436         {TERM_L_BLUE, "回", "回復"},
437         {TERM_L_RED, "赤", "赤外"},
438         {TERM_UMBER, "隠", "隠密"},
439         {TERM_YELLOW, "隠", "超隠密"},
440         {TERM_WHITE, "帰", "帰還"},
441         {TERM_WHITE, "現", "現実変容"},
442         /* Hex */
443         {TERM_WHITE, "オ", "氷オーラ"},
444         {TERM_BLUE, "オ", "電オーラ"},
445         {TERM_L_DARK, "オ", "影オーラ"},
446         {TERM_YELLOW, "腕", "腕力強化"},
447         {TERM_RED, "肉", "肉体強化"},
448         {TERM_L_DARK, "殖", "反増殖"},
449         {TERM_ORANGE, "テ", "反テレポ"},
450         {TERM_RED, "魔", "反魔法"},
451         {TERM_SLATE, "我", "我慢"},
452         {TERM_SLATE, "宣", "宣告"},
453         {TERM_L_DARK, "剣", "魔剣化"},
454         {TERM_RED, "吸", "吸血打撃"},
455         {TERM_WHITE, "回", "回復"},
456         {TERM_L_DARK, "感", "邪悪感知"},
457         {0, NULL, NULL}
458 };
459 #else
460 = {
461         {TERM_YELLOW, "Ts", "Tsuyoshi"},
462         {TERM_VIOLET, "Ha", "Halluc"},
463         {TERM_L_DARK, "Bl", "Blind"},
464         {TERM_RED, "Pa", "Paralyzed"},
465         {TERM_VIOLET, "Cf", "Confused"},
466         {TERM_GREEN, "Po", "Poisoned"},
467         {TERM_BLUE, "Af", "Afraid"},
468         {TERM_L_BLUE, "Lv", "Levit"},
469         {TERM_SLATE, "Rf", "Reflect"},
470         {TERM_SLATE, "Pw", "PassWall"},
471         {TERM_L_DARK, "Wr", "Wraith"},
472         {TERM_SLATE, "Ev", "PrtEvl"},
473         {TERM_VIOLET, "Kw", "Kawarimi"},
474         {TERM_YELLOW, "Md", "MgcArm"},
475         {TERM_L_UMBER, "Eh", "Expand"},
476         {TERM_WHITE, "Ss", "StnSkn"},
477         {TERM_L_BLUE, "Ms", "MltShdw"},
478         {TERM_SLATE, "Rm", "ResMag"},
479         {TERM_YELLOW, "Ul", "Ultima"},
480         {TERM_YELLOW, "Iv", "Invuln"},
481         {TERM_L_GREEN, "IAc", "ImmAcid"},
482         {TERM_GREEN, "Ac", "Acid"},
483         {TERM_L_BLUE, "IEl", "ImmElec"},
484         {TERM_BLUE, "El", "Elec"},
485         {TERM_L_RED, "IFi", "ImmFire"},
486         {TERM_RED, "Fi", "Fire"},
487         {TERM_WHITE, "ICo", "ImmCold"},
488         {TERM_SLATE, "Co", "Cold"},
489         {TERM_GREEN, "Po", "Pois"},
490         {TERM_L_DARK, "Nt", "Nthr"},
491         {TERM_L_BLUE, "Ti", "Time"},
492         {TERM_L_DARK, "Mr", "Mirr"},
493         {TERM_L_RED, "SFi", "SFire"},
494         {TERM_WHITE, "Fo", "Force"},
495         {TERM_WHITE, "Ho", "Holy"},
496         {TERM_VIOLET, "Ee", "EyeEye"},
497         {TERM_WHITE, "Bs", "Bless"},
498         {TERM_WHITE, "He", "Hero"},
499         {TERM_RED, "Br", "Berserk"},
500         {TERM_L_RED, "BFi", "BFire"},
501         {TERM_WHITE, "BCo", "BCold"},
502         {TERM_L_BLUE, "BEl", "BElec"},
503         {TERM_SLATE, "BAc", "BAcid"},
504         {TERM_L_GREEN, "BPo", "BPois"},
505         {TERM_RED, "TCf", "TchCnf"},
506         {TERM_L_BLUE, "Se", "SInv"},
507         {TERM_ORANGE, "Te", "Telepa"},
508         {TERM_L_BLUE, "Rg", "Regen"},
509         {TERM_L_RED, "If", "Infr"},
510         {TERM_UMBER, "Sl", "Stealth"},
511         {TERM_YELLOW, "Stlt", "Stealth"},
512         {TERM_WHITE, "Rc", "Recall"},
513         {TERM_WHITE, "Al", "Alter"},
514         /* Hex */
515         {TERM_WHITE, "SCo", "SCold"},
516         {TERM_BLUE, "SEl", "SElec"},
517         {TERM_L_DARK, "SSh", "SShadow"},
518         {TERM_YELLOW, "EMi", "ExMight"},
519         {TERM_RED, "Bu", "BuildUp"},
520         {TERM_L_DARK, "AMl", "AntiMulti"},
521         {TERM_ORANGE, "AT", "AntiTele"},
522         {TERM_RED, "AM", "AntiMagic"},
523         {TERM_SLATE, "Pa", "Patience"},
524         {TERM_SLATE, "Rv", "Revenge"},
525         {TERM_L_DARK, "Rs", "RuneSword"},
526         {TERM_RED, "Vm", "Vampiric"},
527         {TERM_WHITE, "Cu", "Cure"},
528         {TERM_L_DARK, "ET", "EvilTele"},
529         {0, NULL, NULL}
530 };
531 #endif
532
533 /*!
534  * @brief 32ビット変数配列の指定位置のビットフラグを1にする。
535  * @param FLG フラグ位置(ビット)
536  * @return なし
537  */
538 #define ADD_FLG(FLG) (bar_flags[FLG / 32] |= (1L << (FLG % 32)))
539
540 /*!
541  * @brief 32ビット変数配列の指定位置のビットフラグが1かどうかを返す。
542  * @param FLG フラグ位置(ビット)
543  * @return 1ならば0以外を返す
544  */
545 #define IS_FLG(FLG) (bar_flags[FLG / 32] & (1L << (FLG % 32)))
546
547
548 /*!
549  * @brief 下部に状態表示を行う / Show status bar
550  * @return なし
551  */
552 static void prt_status(void)
553 {
554         BIT_FLAGS bar_flags[3];
555         TERM_LEN wid, hgt, row_statbar, max_col_statbar;
556         int i;
557         TERM_LEN col = 0, num = 0;
558         int space = 2;
559
560         Term_get_size(&wid, &hgt);
561         row_statbar = hgt + ROW_STATBAR;
562         max_col_statbar = wid + MAX_COL_STATBAR;
563
564         Term_erase(0, row_statbar, max_col_statbar);
565
566         bar_flags[0] = bar_flags[1] = bar_flags[2] = 0L;
567
568         /* Tsuyoshi  */
569         if (p_ptr->tsuyoshi) ADD_FLG(BAR_TSUYOSHI);
570
571         /* Hallucinating */
572         if (p_ptr->image) ADD_FLG(BAR_HALLUCINATION);
573
574         /* Blindness */
575         if (p_ptr->blind) ADD_FLG(BAR_BLINDNESS);
576
577         /* Paralysis */
578         if (p_ptr->paralyzed) ADD_FLG(BAR_PARALYZE);
579
580         /* Confusion */
581         if (p_ptr->confused) ADD_FLG(BAR_CONFUSE);
582
583         /* Posioned */
584         if (p_ptr->poisoned) ADD_FLG(BAR_POISONED);
585
586         /* Times see-invisible */
587         if (p_ptr->tim_invis) ADD_FLG(BAR_SENSEUNSEEN);
588
589         /* Timed esp */
590         if (IS_TIM_ESP()) ADD_FLG(BAR_TELEPATHY);
591
592         /* Timed regenerate */
593         if (p_ptr->tim_regen) ADD_FLG(BAR_REGENERATION);
594
595         /* Timed infra-vision */
596         if (p_ptr->tim_infra) ADD_FLG(BAR_INFRAVISION);
597
598         /* Protection from evil */
599         if (p_ptr->protevil) ADD_FLG(BAR_PROTEVIL);
600
601         /* Invulnerability */
602         if (IS_INVULN()) ADD_FLG(BAR_INVULN);
603
604         /* Wraith form */
605         if (p_ptr->wraith_form) ADD_FLG(BAR_WRAITH);
606
607         /* Kabenuke */
608         if (p_ptr->kabenuke) ADD_FLG(BAR_PASSWALL);
609
610         if (p_ptr->tim_reflect) ADD_FLG(BAR_REFLECTION);
611
612         /* Heroism */
613         if (IS_HERO()) ADD_FLG(BAR_HEROISM);
614
615         /* Super Heroism / berserk */
616         if (p_ptr->shero) ADD_FLG(BAR_BERSERK);
617
618         /* Blessed */
619         if (IS_BLESSED()) ADD_FLG(BAR_BLESSED);
620
621         /* Shield */
622         if (p_ptr->magicdef) ADD_FLG(BAR_MAGICDEFENSE);
623
624         if (p_ptr->tsubureru) ADD_FLG(BAR_EXPAND);
625
626         if (p_ptr->shield) ADD_FLG(BAR_STONESKIN);
627         
628         if (p_ptr->special_defense & NINJA_KAWARIMI) ADD_FLG(BAR_KAWARIMI);
629
630         /* Oppose Acid */
631         if (p_ptr->special_defense & DEFENSE_ACID) ADD_FLG(BAR_IMMACID);
632         if (IS_OPPOSE_ACID()) ADD_FLG(BAR_RESACID);
633
634         /* Oppose Lightning */
635         if (p_ptr->special_defense & DEFENSE_ELEC) ADD_FLG(BAR_IMMELEC);
636         if (IS_OPPOSE_ELEC()) ADD_FLG(BAR_RESELEC);
637
638         /* Oppose Fire */
639         if (p_ptr->special_defense & DEFENSE_FIRE) ADD_FLG(BAR_IMMFIRE);
640         if (IS_OPPOSE_FIRE()) ADD_FLG(BAR_RESFIRE);
641
642         /* Oppose Cold */
643         if (p_ptr->special_defense & DEFENSE_COLD) ADD_FLG(BAR_IMMCOLD);
644         if (IS_OPPOSE_COLD()) ADD_FLG(BAR_RESCOLD);
645
646         /* Oppose Poison */
647         if (IS_OPPOSE_POIS()) ADD_FLG(BAR_RESPOIS);
648
649         /* Word of Recall */
650         if (p_ptr->word_recall) ADD_FLG(BAR_RECALL);
651
652         /* Alter realiry */
653         if (p_ptr->alter_reality) ADD_FLG(BAR_ALTER);
654
655         /* Afraid */
656         if (p_ptr->afraid) ADD_FLG(BAR_AFRAID);
657
658         /* Resist time */
659         if (p_ptr->tim_res_time) ADD_FLG(BAR_RESTIME);
660
661         if (p_ptr->multishadow) ADD_FLG(BAR_MULTISHADOW);
662
663         /* Confusing Hands */
664         if (p_ptr->special_attack & ATTACK_CONFUSE) ADD_FLG(BAR_ATTKCONF);
665
666         if (p_ptr->resist_magic) ADD_FLG(BAR_REGMAGIC);
667
668         /* Ultimate-resistance */
669         if (p_ptr->ult_res) ADD_FLG(BAR_ULTIMATE);
670
671         /* tim levitation */
672         if (p_ptr->tim_levitation) ADD_FLG(BAR_LEVITATE);
673
674         if (p_ptr->tim_res_nether) ADD_FLG(BAR_RESNETH);
675
676         if (p_ptr->dustrobe) ADD_FLG(BAR_DUSTROBE);
677
678         /* Mahouken */
679         if (p_ptr->special_attack & ATTACK_FIRE) ADD_FLG(BAR_ATTKFIRE);
680         if (p_ptr->special_attack & ATTACK_COLD) ADD_FLG(BAR_ATTKCOLD);
681         if (p_ptr->special_attack & ATTACK_ELEC) ADD_FLG(BAR_ATTKELEC);
682         if (p_ptr->special_attack & ATTACK_ACID) ADD_FLG(BAR_ATTKACID);
683         if (p_ptr->special_attack & ATTACK_POIS) ADD_FLG(BAR_ATTKPOIS);
684         if (p_ptr->special_defense & NINJA_S_STEALTH) ADD_FLG(BAR_SUPERSTEALTH);
685
686         if (p_ptr->tim_sh_fire) ADD_FLG(BAR_SHFIRE);
687
688         /* tim stealth */
689         if (IS_TIM_STEALTH()) ADD_FLG(BAR_STEALTH);
690
691         if (p_ptr->tim_sh_touki) ADD_FLG(BAR_TOUKI);
692
693         /* Holy aura */
694         if (p_ptr->tim_sh_holy) ADD_FLG(BAR_SHHOLY);
695
696         /* An Eye for an Eye */
697         if (p_ptr->tim_eyeeye) ADD_FLG(BAR_EYEEYE);
698
699         /* Hex spells */
700         if (p_ptr->realm1 == REALM_HEX)
701         {
702                 if (hex_spelling(HEX_BLESS)) ADD_FLG(BAR_BLESSED);
703                 if (hex_spelling(HEX_DEMON_AURA)) { ADD_FLG(BAR_SHFIRE); ADD_FLG(BAR_REGENERATION); }
704                 if (hex_spelling(HEX_XTRA_MIGHT)) ADD_FLG(BAR_MIGHT);
705                 if (hex_spelling(HEX_DETECT_EVIL)) ADD_FLG(BAR_ESP_EVIL);
706                 if (hex_spelling(HEX_ICE_ARMOR)) ADD_FLG(BAR_SHCOLD);
707                 if (hex_spelling(HEX_RUNESWORD)) ADD_FLG(BAR_RUNESWORD);
708                 if (hex_spelling(HEX_BUILDING)) ADD_FLG(BAR_BUILD);
709                 if (hex_spelling(HEX_ANTI_TELE)) ADD_FLG(BAR_ANTITELE);
710                 if (hex_spelling(HEX_SHOCK_CLOAK)) ADD_FLG(BAR_SHELEC);
711                 if (hex_spelling(HEX_SHADOW_CLOAK)) ADD_FLG(BAR_SHSHADOW);
712                 if (hex_spelling(HEX_CONFUSION)) ADD_FLG(BAR_ATTKCONF);
713                 if (hex_spelling(HEX_EYE_FOR_EYE)) ADD_FLG(BAR_EYEEYE);
714                 if (hex_spelling(HEX_ANTI_MULTI)) ADD_FLG(BAR_ANTIMULTI);
715                 if (hex_spelling(HEX_VAMP_BLADE)) ADD_FLG(BAR_VAMPILIC);
716                 if (hex_spelling(HEX_ANTI_MAGIC)) ADD_FLG(BAR_ANTIMAGIC);
717                 if (hex_spelling(HEX_CURE_LIGHT) ||
718                         hex_spelling(HEX_CURE_SERIOUS) ||
719                         hex_spelling(HEX_CURE_CRITICAL)) ADD_FLG(BAR_CURE);
720
721                 if (HEX_REVENGE_TURN(p_ptr))
722                 {
723                         if (HEX_REVENGE_TYPE(p_ptr) == 1) ADD_FLG(BAR_PATIENCE);
724                         if (HEX_REVENGE_TYPE(p_ptr) == 2) ADD_FLG(BAR_REVENGE);
725                 }
726         }
727
728         /* Calcurate length */
729         for (i = 0; bar[i].sstr; i++)
730         {
731                 if (IS_FLG(i))
732                 {
733                         col += strlen(bar[i].lstr) + 1;
734                         num++;
735                 }
736         }
737
738         /* If there are not excess spaces for long strings, use short one */
739         if (col - 1 > max_col_statbar)
740         {
741                 space = 0;
742                 col = 0;
743
744                 for (i = 0; bar[i].sstr; i++)
745                 {
746                         if (IS_FLG(i))
747                         {
748                                 col += strlen(bar[i].sstr);
749                         }
750                 }
751
752                 /* If there are excess spaces for short string, use more */
753                 if (col - 1 <= max_col_statbar - (num-1))
754                 {
755                         space = 1;
756                         col += num - 1;
757                 }
758         }
759
760
761         /* Centering display column */
762         col = (max_col_statbar - col) / 2;
763
764         /* Display status bar */
765         for (i = 0; bar[i].sstr; i++)
766         {
767                 if (IS_FLG(i))
768                 {
769                         concptr str;
770                         if (space == 2) str = bar[i].lstr;
771                         else str = bar[i].sstr;
772
773                         c_put_str(bar[i].attr, str, row_statbar, col);
774                         col += strlen(str);
775                         if (space > 0) col++;
776                         if (col > max_col_statbar) break;
777                 }
778         }
779 }
780
781
782 /*!
783  * @brief プレイヤーの称号を表示する / Prints "title", including "wizard" or "winner" as needed.
784  * @return なし
785  */
786 static void prt_title(void)
787 {
788         concptr p = "";
789         GAME_TEXT str[14];
790
791         if (p_ptr->wizard)
792         {
793                 p = _("[ウィザード]", "[=-WIZARD-=]");
794         }
795         else if (p_ptr->total_winner || (p_ptr->lev > PY_MAX_LEVEL))
796         {
797                 if (p_ptr->arena_number > MAX_ARENA_MONS + 2)
798                 {
799                         p = _("*真・勝利者*", "*TRUEWINNER*");
800                 }
801                 else
802                 {
803                         p = _("***勝利者***", "***WINNER***");
804                 }
805         }
806
807         /* Normal */
808         else
809         {
810                 my_strcpy(str, player_title[p_ptr->pclass][(p_ptr->lev - 1) / 5], sizeof(str));
811                 p = str;
812         }
813
814         prt_field(p, ROW_TITLE, COL_TITLE);
815 }
816
817
818 /*!
819  * @brief プレイヤーのレベルを表示する / Prints level
820  * @return なし
821  */
822 static void prt_level(void)
823 {
824         char tmp[32];
825
826         sprintf(tmp, _("%5d", "%6d"), p_ptr->lev);
827
828         if (p_ptr->lev >= p_ptr->max_plv)
829         {
830                 put_str(_("レベル ", "LEVEL "), ROW_LEVEL, 0);
831                 c_put_str(TERM_L_GREEN, tmp, ROW_LEVEL, COL_LEVEL + 7);
832         }
833         else
834         {
835                 put_str(_("xレベル", "Level "), ROW_LEVEL, 0);
836                 c_put_str(TERM_YELLOW, tmp, ROW_LEVEL, COL_LEVEL + 7);
837         }
838 }
839
840
841 /*!
842  * @brief プレイヤーの経験値を表示する / Display the experience
843  * @return なし
844  */
845 static void prt_exp(void)
846 {
847         char out_val[32];
848
849         if ((!exp_need)||(p_ptr->prace == RACE_ANDROID))
850         {
851                 (void)sprintf(out_val, "%8ld", (long)p_ptr->exp);
852         }
853         else
854         {
855                 if (p_ptr->lev >= PY_MAX_LEVEL)
856                 {
857                         (void)sprintf(out_val, "********");
858                 }
859                 else
860                 {
861                         (void)sprintf(out_val, "%8ld", (long)(player_exp [p_ptr->lev - 1] * p_ptr->expfact / 100L) - p_ptr->exp);
862                 }
863         }
864
865         if (p_ptr->exp >= p_ptr->max_exp)
866         {
867                 if (p_ptr->prace == RACE_ANDROID) put_str(_("強化 ", "Cst "), ROW_EXP, 0);
868                 else put_str(_("経験 ", "EXP "), ROW_EXP, 0);
869                 c_put_str(TERM_L_GREEN, out_val, ROW_EXP, COL_EXP + 4);
870         }
871         else
872         {
873                 put_str(_("x経験", "Exp "), ROW_EXP, 0);
874                 c_put_str(TERM_YELLOW, out_val, ROW_EXP, COL_EXP + 4);
875         }
876 }
877
878 /*!
879  * @brief プレイヤーの所持金を表示する / Prints current gold
880  * @return なし
881  */
882 static void prt_gold(void)
883 {
884         char tmp[32];
885         put_str(_("$ ", "AU "), ROW_GOLD, COL_GOLD);
886         sprintf(tmp, "%9ld", (long)p_ptr->au);
887         c_put_str(TERM_L_GREEN, tmp, ROW_GOLD, COL_GOLD + 3);
888 }
889
890
891 /*!
892  * @brief プレイヤーのACを表示する / Prints current AC
893  * @return なし
894  */
895 static void prt_ac(void)
896 {
897         char tmp[32];
898
899 #ifdef JP
900 /* AC の表示方式を変更している */
901         put_str(" AC(     )", ROW_AC, COL_AC);
902         sprintf(tmp, "%5d", p_ptr->dis_ac + p_ptr->dis_to_a);
903         c_put_str(TERM_L_GREEN, tmp, ROW_AC, COL_AC + 6);
904 #else
905         put_str("Cur AC ", ROW_AC, COL_AC);
906         sprintf(tmp, "%5d", p_ptr->dis_ac + p_ptr->dis_to_a);
907         c_put_str(TERM_L_GREEN, tmp, ROW_AC, COL_AC + 7);
908 #endif
909
910 }
911
912
913 /*!
914  * @brief プレイヤーのHPを表示する / Prints Cur/Max hit points
915  * @return なし
916  */
917 static void prt_hp(void)
918 {
919         /* ヒットポイントの表示方法を変更 */
920         char tmp[32];
921   
922         TERM_COLOR color;
923   
924         /* タイトル */
925         put_str("HP", ROW_CURHP, COL_CURHP);
926
927         /* 現在のヒットポイント */
928         sprintf(tmp, "%4ld", (long int)p_ptr->chp);
929
930         if (p_ptr->chp >= p_ptr->mhp)
931         {
932                 color = TERM_L_GREEN;
933         }
934         else if (p_ptr->chp > (p_ptr->mhp * hitpoint_warn) / 10)
935         {
936                 color = TERM_YELLOW;
937         }
938         else
939         {
940                 color = TERM_RED;
941         }
942
943         c_put_str(color, tmp, ROW_CURHP, COL_CURHP+3);
944
945         /* 区切り */
946         put_str( "/", ROW_CURHP, COL_CURHP + 7 );
947
948         /* 最大ヒットポイント */
949         sprintf(tmp, "%4ld", (long int)p_ptr->mhp);
950         color = TERM_L_GREEN;
951
952         c_put_str(color, tmp, ROW_CURHP, COL_CURHP + 8 );
953 }
954
955
956 /*!
957  * @brief プレイヤーのMPを表示する / Prints players max/cur spell points
958  * @return なし
959  */
960 static void prt_sp(void)
961 {
962 /* マジックポイントの表示方法を変更している */
963         char tmp[32];
964         byte color;
965
966
967         /* Do not show mana unless it matters */
968         if (!mp_ptr->spell_book) return;
969
970         /* タイトル */
971         put_str(_("MP", "SP"), ROW_CURSP, COL_CURSP);
972
973         /* 現在のマジックポイント */
974         sprintf(tmp, "%4ld", (long int)p_ptr->csp);
975
976         if (p_ptr->csp >= p_ptr->msp)
977         {
978                 color = TERM_L_GREEN;
979         }
980         else if (p_ptr->csp > (p_ptr->msp * mana_warn) / 10)
981         {
982                 color = TERM_YELLOW;
983         }
984         else
985         {
986                 color = TERM_RED;
987         }
988
989         c_put_str(color, tmp, ROW_CURSP, COL_CURSP+3);
990
991         /* 区切り */
992         put_str( "/", ROW_CURSP, COL_CURSP + 7 );
993
994         /* 最大マジックポイント */
995         sprintf(tmp, "%4ld", (long int)p_ptr->msp);
996         color = TERM_L_GREEN;
997
998         c_put_str(color, tmp, ROW_CURSP, COL_CURSP + 8);
999 }
1000
1001
1002 /*!
1003  * @brief 現在のフロアの深さを表示する / Prints depth in stat area
1004  * @return なし
1005  */
1006 static void prt_depth(void)
1007 {
1008         char depths[32];
1009         TERM_LEN wid, hgt, row_depth, col_depth;
1010         TERM_COLOR attr = TERM_WHITE;
1011
1012         Term_get_size(&wid, &hgt);
1013         col_depth = wid + COL_DEPTH;
1014         row_depth = hgt + ROW_DEPTH;
1015
1016         if (!current_floor_ptr->dun_level)
1017         {
1018                 strcpy(depths, _("地上", "Surf."));
1019         }
1020         else if (p_ptr->inside_quest && !p_ptr->dungeon_idx)
1021         {
1022                 strcpy(depths, _("地上", "Quest"));
1023         }
1024         else
1025         {
1026                 if (depth_in_feet) (void)sprintf(depths, _("%d ft", "%d ft"), (int)current_floor_ptr->dun_level * 50);
1027                 else (void)sprintf(depths, _("%d 階", "Lev %d"), (int)current_floor_ptr->dun_level);
1028
1029                 /* Get color of level based on feeling  -JSV- */
1030                 switch (p_ptr->feeling)
1031                 {
1032                 case  0: attr = TERM_SLATE;   break; /* Unknown */
1033                 case  1: attr = TERM_L_BLUE;  break; /* Special */
1034                 case  2: attr = TERM_VIOLET;  break; /* Horrible visions */
1035                 case  3: attr = TERM_RED;     break; /* Very dangerous */
1036                 case  4: attr = TERM_L_RED;   break; /* Very bad feeling */
1037                 case  5: attr = TERM_ORANGE;  break; /* Bad feeling */
1038                 case  6: attr = TERM_YELLOW;  break; /* Nervous */
1039                 case  7: attr = TERM_L_UMBER; break; /* Luck is turning */
1040                 case  8: attr = TERM_L_WHITE; break; /* Don't like */
1041                 case  9: attr = TERM_WHITE;   break; /* Reasonably safe */
1042                 case 10: attr = TERM_WHITE;   break; /* Boring place */
1043                 }
1044         }
1045
1046         /* Right-Adjust the "depth", and clear old values */
1047         c_prt(attr, format("%7s", depths), row_depth, col_depth);
1048 }
1049
1050
1051 /*!
1052  * @brief プレイヤーの空腹状態を表示する / Prints status of hunger
1053  * @return なし
1054  */
1055 static void prt_hunger(void)
1056 {
1057         if(p_ptr->wizard && p_ptr->inside_arena) return;
1058
1059         /* Fainting / Starving */
1060         if (p_ptr->food < PY_FOOD_FAINT)
1061         {
1062                 c_put_str(TERM_RED, _("衰弱  ", "Weak  "), ROW_HUNGRY, COL_HUNGRY);
1063         }
1064
1065         /* Weak */
1066         else if (p_ptr->food < PY_FOOD_WEAK)
1067         {
1068                 c_put_str(TERM_ORANGE, _("衰弱  ", "Weak  "), ROW_HUNGRY, COL_HUNGRY);
1069         }
1070
1071         /* Hungry */
1072         else if (p_ptr->food < PY_FOOD_ALERT)
1073         {
1074                 c_put_str(TERM_YELLOW, _("空腹  ", "Hungry"), ROW_HUNGRY, COL_HUNGRY);
1075         }
1076
1077         /* Normal */
1078         else if (p_ptr->food < PY_FOOD_FULL)
1079         {
1080                 c_put_str(TERM_L_GREEN, "      ", ROW_HUNGRY, COL_HUNGRY);
1081         }
1082
1083         /* Full */
1084         else if (p_ptr->food < PY_FOOD_MAX)
1085         {
1086                 c_put_str(TERM_L_GREEN, _("満腹  ", "Full  "), ROW_HUNGRY, COL_HUNGRY);
1087         }
1088
1089         /* Gorged */
1090         else
1091         {
1092                 c_put_str(TERM_GREEN, _("食過ぎ", "Gorged"), ROW_HUNGRY, COL_HUNGRY);
1093         }
1094 }
1095
1096
1097 /*!
1098  * @brief プレイヤーの行動状態を表示する / Prints Searching, Resting, Paralysis, or 'count' status
1099  * @return なし
1100  * @details
1101  * Display is always exactly 10 characters wide (see below)
1102  * This function was a major bottleneck when resting, so a lot of
1103  * the text formatting code was optimized in place below.
1104  */
1105 static void prt_state(void)
1106 {
1107         TERM_COLOR attr = TERM_WHITE;
1108         GAME_TEXT text[16];
1109
1110         /* Repeating */
1111         if (command_rep)
1112         {
1113                 if (command_rep > 999)
1114                 {
1115                         (void)sprintf(text, "%2d00", command_rep / 100);
1116                 }
1117                 else
1118                 {
1119                         (void)sprintf(text, "  %2d", command_rep);
1120                 }
1121         }
1122
1123         /* Action */
1124         else
1125         {
1126                 switch(p_ptr->action)
1127                 {
1128                         case ACTION_SEARCH:
1129                         {
1130                                 strcpy(text, _("探索", "Sear"));
1131                                 break;
1132                         }
1133                         case ACTION_REST:
1134                                 /* Start with "Rest" */
1135                                 strcpy(text, _("    ", "    "));
1136
1137                                 if (p_ptr->resting > 0)
1138                                 {
1139                                         sprintf(text, "%4d", p_ptr->resting);
1140                                 }
1141                                 else if (p_ptr->resting == COMMAND_ARG_REST_FULL_HEALING)
1142                                 {
1143                                         text[0] = text[1] = text[2] = text[3] = '*';
1144                                 }
1145                                 else if (p_ptr->resting == COMMAND_ARG_REST_UNTIL_DONE)
1146                                 {
1147                                         text[0] = text[1] = text[2] = text[3] = '&';
1148                                 }
1149                                 break;
1150
1151                         case ACTION_LEARN:
1152                         {
1153                                 strcpy(text, _("学習", "lear"));
1154                                 if (new_mane) attr = TERM_L_RED;
1155                                 break;
1156                         }
1157                         case ACTION_FISH:
1158                         {
1159                                 strcpy(text, _("釣り", "fish"));
1160                                 break;
1161                         }
1162                         case ACTION_KAMAE:
1163                         {
1164                                 int i;
1165                                 for (i = 0; i < MAX_KAMAE; i++)
1166                                         if (p_ptr->special_defense & (KAMAE_GENBU << i)) break;
1167                                 switch (i)
1168                                 {
1169                                         case 0: attr = TERM_GREEN;break;
1170                                         case 1: attr = TERM_WHITE;break;
1171                                         case 2: attr = TERM_L_BLUE;break;
1172                                         case 3: attr = TERM_L_RED;break;
1173                                 }
1174                                 strcpy(text, kamae_shurui[i].desc);
1175                                 break;
1176                         }
1177                         case ACTION_KATA:
1178                         {
1179                                 int i;
1180                                 for (i = 0; i < MAX_KATA; i++)
1181                                         if (p_ptr->special_defense & (KATA_IAI << i)) break;
1182                                 strcpy(text, kata_shurui[i].desc);
1183                                 break;
1184                         }
1185                         case ACTION_SING:
1186                         {
1187                                 strcpy(text, _("歌  ", "Sing"));
1188                                 break;
1189                         }
1190                         case ACTION_HAYAGAKE:
1191                         {
1192                                 strcpy(text, _("速駆", "Fast"));
1193                                 break;
1194                         }
1195                         case ACTION_SPELL:
1196                         {
1197                                 strcpy(text, _("詠唱", "Spel"));
1198                                 break;
1199                         }
1200                         default:
1201                         {
1202                                 strcpy(text, "    ");
1203                                 break;
1204                         }
1205                 }
1206         }
1207
1208         /* Display the info (or blanks) */
1209         c_put_str(attr, format("%5.5s",text), ROW_STATE, COL_STATE);
1210 }
1211
1212
1213 /*!
1214  * @brief プレイヤーの行動速度を表示する / Prints the speed of a character.                      -CJS-
1215  * @return なし
1216  */
1217 static void prt_speed(void)
1218 {
1219         int i = p_ptr->pspeed;
1220         bool is_fast = IS_FAST();
1221
1222         TERM_COLOR attr = TERM_WHITE;
1223         char buf[32] = "";
1224         TERM_LEN wid, hgt, row_speed, col_speed;
1225
1226         Term_get_size(&wid, &hgt);
1227         col_speed = wid + COL_SPEED;
1228         row_speed = hgt + ROW_SPEED;
1229
1230         /* Hack -- Visually "undo" the Search Mode Slowdown */
1231         if (p_ptr->action == ACTION_SEARCH && !p_ptr->lightspeed) i += 10;
1232
1233         /* Fast */
1234         if (i > 110)
1235         {
1236                 if (p_ptr->riding)
1237                 {
1238                         monster_type *m_ptr = &current_floor_ptr->m_list[p_ptr->riding];
1239                         if (MON_FAST(m_ptr) && !MON_SLOW(m_ptr)) attr = TERM_L_BLUE;
1240                         else if (MON_SLOW(m_ptr) && !MON_FAST(m_ptr)) attr = TERM_VIOLET;
1241                         else attr = TERM_GREEN;
1242                 }
1243                 else if ((is_fast && !p_ptr->slow) || p_ptr->lightspeed) attr = TERM_YELLOW;
1244                 else if (p_ptr->slow && !is_fast) attr = TERM_VIOLET;
1245                 else attr = TERM_L_GREEN;
1246                 sprintf(buf, "%s(+%d)", (p_ptr->riding ? _("乗馬", "Ride") : _("加速", "Fast")), (i - 110));
1247         }
1248
1249         /* Slow */
1250         else if (i < 110)
1251         {
1252                 if (p_ptr->riding)
1253                 {
1254                         monster_type *m_ptr = &current_floor_ptr->m_list[p_ptr->riding];
1255                         if (MON_FAST(m_ptr) && !MON_SLOW(m_ptr)) attr = TERM_L_BLUE;
1256                         else if (MON_SLOW(m_ptr) && !MON_FAST(m_ptr)) attr = TERM_VIOLET;
1257                         else attr = TERM_RED;
1258                 }
1259                 else if (is_fast && !p_ptr->slow) attr = TERM_YELLOW;
1260                 else if (p_ptr->slow && !is_fast) attr = TERM_VIOLET;
1261                 else attr = TERM_L_UMBER;
1262                 sprintf(buf, "%s(-%d)", (p_ptr->riding ? _("乗馬", "Ride") : _("減速", "Slow")), (110 - i));
1263         }
1264         else if (p_ptr->riding)
1265         {
1266                 attr = TERM_GREEN;
1267                 strcpy(buf, _("乗馬中", "Riding"));
1268         }
1269
1270         /* Display the speed */
1271         c_put_str(attr, format("%-9s", buf), row_speed, col_speed);
1272 }
1273
1274
1275 /*!
1276  * @brief プレイヤーの呪文学習可能状態を表示する
1277  * @return なし
1278  */
1279 static void prt_study(void)
1280 {
1281         TERM_LEN wid, hgt, row_study, col_study;
1282
1283         Term_get_size(&wid, &hgt);
1284         col_study = wid + COL_STUDY;
1285         row_study = hgt + ROW_STUDY;
1286
1287         if (p_ptr->new_spells)
1288         {
1289                 put_str(_("学習", "Stud"), row_study, col_study);
1290         }
1291         else
1292         {
1293                 put_str("    ", row_study, col_study);
1294         }
1295 }
1296
1297
1298 /*!
1299  * @brief プレイヤーのものまね可能状態を表示する
1300  * @return なし
1301  */
1302 static void prt_imitation(void)
1303 {
1304         TERM_LEN wid, hgt, row_study, col_study;
1305
1306         Term_get_size(&wid, &hgt);
1307         col_study = wid + COL_STUDY;
1308         row_study = hgt + ROW_STUDY;
1309
1310         if (p_ptr->pclass == CLASS_IMITATOR)
1311         {
1312                 if (p_ptr->mane_num)
1313                 {
1314                         TERM_COLOR attr;
1315                         if (new_mane) attr = TERM_L_RED;
1316                         else attr = TERM_WHITE;
1317                         c_put_str(attr, _("まね", "Imit"), row_study, col_study);
1318                 }
1319                 else
1320                 {
1321                         put_str("    ", row_study, col_study);
1322                 }
1323         }
1324 }
1325
1326 /*!
1327  * @brief プレイヤーの負傷状態を表示する
1328  * @return なし
1329  */
1330 static void prt_cut(void)
1331 {
1332         int c = p_ptr->cut;
1333
1334         if (c > 1000)
1335         {
1336                 c_put_str(TERM_L_RED, _("致命傷      ", "Mortal wound"), ROW_CUT, COL_CUT);
1337         }
1338         else if (c > 200)
1339         {
1340                 c_put_str(TERM_RED, _("ひどい深手  ", "Deep gash   "), ROW_CUT, COL_CUT);
1341         }
1342         else if (c > 100)
1343         {
1344                 c_put_str(TERM_RED, _("重傷        ", "Severe cut  "), ROW_CUT, COL_CUT);
1345         }
1346         else if (c > 50)
1347         {
1348                 c_put_str(TERM_ORANGE, _("大変な傷    ", "Nasty cut   "), ROW_CUT, COL_CUT);
1349         }
1350         else if (c > 25)
1351         {
1352                 c_put_str(TERM_ORANGE, _("ひどい傷    ", "Bad cut     "), ROW_CUT, COL_CUT);
1353         }
1354         else if (c > 10)
1355         {
1356                 c_put_str(TERM_YELLOW, _("軽傷        ", "Light cut   "), ROW_CUT, COL_CUT);
1357         }
1358         else if (c)
1359         {
1360                 c_put_str(TERM_YELLOW, _("かすり傷    ", "Graze       "), ROW_CUT, COL_CUT);
1361         }
1362         else
1363         {
1364                 put_str("            ", ROW_CUT, COL_CUT);
1365         }
1366 }
1367
1368
1369 /*!
1370  * @brief プレイヤーの朦朧状態を表示する
1371  * @return なし
1372  */
1373 static void prt_stun(void)
1374 {
1375         int s = p_ptr->stun;
1376
1377         if (s > 100)
1378         {
1379                 c_put_str(TERM_RED, _("意識不明瞭  ", "Knocked out "), ROW_STUN, COL_STUN);
1380         }
1381         else if (s > 50)
1382         {
1383                 c_put_str(TERM_ORANGE, _("ひどく朦朧  ", "Heavy stun  "), ROW_STUN, COL_STUN);
1384         }
1385         else if (s)
1386         {
1387                 c_put_str(TERM_ORANGE, _("朦朧        ", "Stun        "), ROW_STUN, COL_STUN);
1388         }
1389         else
1390         {
1391                 put_str("            ", ROW_STUN, COL_STUN);
1392         }
1393 }
1394
1395
1396
1397 /*!
1398  * @brief モンスターの体力ゲージを表示する
1399  * @param riding TRUEならば騎乗中のモンスターの体力、FALSEならターゲットモンスターの体力を表示する。表示位置は固定。
1400  * @return なし
1401  * @details
1402  * <pre>
1403  * Redraw the "monster health bar"      -DRS-
1404  * Rather extensive modifications by    -BEN-
1405  *
1406  * The "monster health bar" provides visual feedback on the "health"
1407  * of the monster currently being "tracked".  There are several ways
1408  * to "track" a monster, including targetting it, attacking it, and
1409  * affecting it (and nobody else) with a ranged attack.
1410  *
1411  * Display the monster health bar (affectionately known as the
1412  * "health-o-meter").  Clear health bar if nothing is being tracked.
1413  * Auto-track current target monster when bored.  Note that the
1414  * health-bar stops tracking any monster that "disappears".
1415  * </pre>
1416  */
1417 static void health_redraw(bool riding)
1418 {
1419         s16b health_who;
1420         int row, col;
1421         monster_type *m_ptr;
1422
1423         if (riding)
1424         {
1425                 health_who = p_ptr->riding;
1426                 row = ROW_RIDING_INFO;
1427                 col = COL_RIDING_INFO;
1428         }
1429         else
1430         {
1431                 health_who = p_ptr->health_who;
1432                 row = ROW_INFO;
1433                 col = COL_INFO;
1434         }
1435
1436         m_ptr = &current_floor_ptr->m_list[health_who];
1437
1438         if (p_ptr->wizard && p_ptr->inside_battle)
1439         {
1440                 row = ROW_INFO - 2;
1441                 col = COL_INFO + 2;
1442
1443                 Term_putstr(col - 2, row, 12, TERM_WHITE, "      /     ");
1444                 Term_putstr(col - 2, row + 1, 12, TERM_WHITE, "      /     ");
1445                 Term_putstr(col - 2, row + 2, 12, TERM_WHITE, "      /     ");
1446                 Term_putstr(col - 2, row + 3, 12, TERM_WHITE, "      /     ");
1447
1448                 if(current_floor_ptr->m_list[1].r_idx)
1449                 {
1450                         Term_putstr(col - 2, row, 2, r_info[current_floor_ptr->m_list[1].r_idx].x_attr, format("%c", r_info[current_floor_ptr->m_list[1].r_idx].x_char));
1451                         Term_putstr(col - 1, row, 5, TERM_WHITE, format("%5d", current_floor_ptr->m_list[1].hp));
1452                         Term_putstr(col + 5, row, 6, TERM_WHITE, format("%5d", current_floor_ptr->m_list[1].max_maxhp));
1453                 }
1454
1455                 if(current_floor_ptr->m_list[2].r_idx)
1456                 {
1457                         Term_putstr(col - 2, row + 1, 2, r_info[current_floor_ptr->m_list[2].r_idx].x_attr, format("%c", r_info[current_floor_ptr->m_list[2].r_idx].x_char));
1458                         Term_putstr(col - 1, row + 1, 5, TERM_WHITE, format("%5d", current_floor_ptr->m_list[2].hp));
1459                         Term_putstr(col + 5, row + 1, 6, TERM_WHITE, format("%5d", current_floor_ptr->m_list[2].max_maxhp));
1460                 }
1461
1462                 if(current_floor_ptr->m_list[3].r_idx)
1463                 {
1464                         Term_putstr(col - 2, row + 2, 2, r_info[current_floor_ptr->m_list[3].r_idx].x_attr, format("%c", r_info[current_floor_ptr->m_list[3].r_idx].x_char));
1465                         Term_putstr(col - 1, row + 2, 5, TERM_WHITE, format("%5d", current_floor_ptr->m_list[3].hp));
1466                         Term_putstr(col + 5, row + 2, 6, TERM_WHITE, format("%5d", current_floor_ptr->m_list[3].max_maxhp));
1467                 }
1468
1469                 if(current_floor_ptr->m_list[4].r_idx)
1470                 {
1471                         Term_putstr(col - 2, row + 3, 2, r_info[current_floor_ptr->m_list[4].r_idx].x_attr, format("%c", r_info[current_floor_ptr->m_list[4].r_idx].x_char));
1472                         Term_putstr(col - 1, row + 3, 5, TERM_WHITE, format("%5d", current_floor_ptr->m_list[4].hp));
1473                         Term_putstr(col + 5, row + 3, 6, TERM_WHITE, format("%5d", current_floor_ptr->m_list[4].max_maxhp));
1474                 }
1475         }
1476         else
1477         {
1478
1479                 /* Not tracking */
1480                 if (!health_who)
1481                 {
1482                         /* Erase the health bar */
1483                         Term_erase(col, row, 12);
1484                 }
1485
1486                 /* Tracking an unseen monster */
1487                 else if (!m_ptr->ml)
1488                 {
1489                         /* Indicate that the monster health is "unknown" */
1490                         Term_putstr(col, row, 12, TERM_WHITE, "[----------]");
1491                 }
1492
1493                 /* Tracking a hallucinatory monster */
1494                 else if (p_ptr->image)
1495                 {
1496                         /* Indicate that the monster health is "unknown" */
1497                         Term_putstr(col, row, 12, TERM_WHITE, "[----------]");
1498                 }
1499
1500                 /* Tracking a dead monster (???) */
1501                 else if (m_ptr->hp < 0)
1502                 {
1503                         /* Indicate that the monster health is "unknown" */
1504                         Term_putstr(col, row, 12, TERM_WHITE, "[----------]");
1505                 }
1506
1507                 /* Tracking a visible monster */
1508                 else
1509                 {
1510                         /* Extract the "percent" of health */
1511                         int pct = m_ptr->maxhp > 0 ? 100L * m_ptr->hp / m_ptr->maxhp : 0;
1512                         int pct2 = m_ptr->maxhp > 0 ? 100L * m_ptr->hp / m_ptr->max_maxhp: 0;
1513
1514                         /* Convert percent into "health" */
1515                         int len = (pct2 < 10) ? 1 : (pct2 < 90) ? (pct2 / 10 + 1) : 10;
1516
1517                         /* Default to almost dead */
1518                         TERM_COLOR attr = TERM_RED;
1519
1520                         /* Invulnerable */
1521                         if (MON_INVULNER(m_ptr)) attr = TERM_WHITE;
1522
1523                         /* Asleep */
1524                         else if (MON_CSLEEP(m_ptr)) attr = TERM_BLUE;
1525
1526                         /* Afraid */
1527                         else if (MON_MONFEAR(m_ptr)) attr = TERM_VIOLET;
1528
1529                         /* Healthy */
1530                         else if (pct >= 100) attr = TERM_L_GREEN;
1531
1532                         /* Somewhat Wounded */
1533                         else if (pct >= 60) attr = TERM_YELLOW;
1534
1535                         /* Wounded */
1536                         else if (pct >= 25) attr = TERM_ORANGE;
1537
1538                         /* Badly wounded */
1539                         else if (pct >= 10) attr = TERM_L_RED;
1540
1541                         /* Default to "unknown" */
1542                         Term_putstr(col, row, 12, TERM_WHITE, "[----------]");
1543
1544                         /* Dump the current "health" (use '*' symbols) */
1545                         Term_putstr(col + 1, row, len, attr, "**********");
1546                 }
1547         }
1548 }
1549
1550
1551
1552 /*!
1553  * @brief プレイヤーのステータスを一括表示する(左側部分) / Display basic info (mostly left of map)
1554  * @return なし
1555  */
1556 static void prt_frame_basic(void)
1557 {
1558         int i;
1559         if (p_ptr->mimic_form)
1560                 prt_field(mimic_info[p_ptr->mimic_form].title, ROW_RACE, COL_RACE);
1561         else
1562         {
1563                 char str[14];
1564                 my_strcpy(str, rp_ptr->title, sizeof(str));
1565                 prt_field(str, ROW_RACE, COL_RACE);
1566         }
1567
1568         prt_title();
1569         prt_level();
1570         prt_exp();
1571         for (i = 0; i < A_MAX; i++) prt_stat(i);
1572         prt_ac();
1573         prt_hp();
1574         prt_sp();
1575         prt_gold();
1576         prt_depth();
1577         health_redraw(FALSE);
1578         health_redraw(TRUE);
1579 }
1580
1581
1582 /*!
1583  * @brief プレイヤーのステータスを一括表示する(下部分) / Display extra info (mostly below map)
1584  * @return なし
1585  */
1586 static void prt_frame_extra(void)
1587 {
1588         prt_cut();
1589         prt_stun();
1590         prt_hunger();
1591         prt_state();
1592         prt_speed();
1593         prt_study();
1594         prt_imitation();
1595         prt_status();
1596 }
1597
1598
1599 /*!
1600  * @brief サブウィンドウに所持品一覧を表示する / Hack -- display inventory in sub-windows
1601  * @return なし
1602  */
1603 static void fix_inven(void)
1604 {
1605         int j;
1606
1607         /* Scan windows */
1608         for (j = 0; j < 8; j++)
1609         {
1610                 term *old = Term;
1611
1612                 /* No window */
1613                 if (!angband_term[j]) continue;
1614
1615                 /* No relevant flags */
1616                 if (!(window_flag[j] & (PW_INVEN))) continue;
1617
1618                 /* Activate */
1619                 Term_activate(angband_term[j]);
1620
1621                 /* Display inventory */
1622                 display_inven();
1623                 Term_fresh();
1624                 Term_activate(old);
1625         }
1626 }
1627
1628
1629 /*!
1630  * @brief モンスターの現在数を一行で表現する / Print monster info in line
1631  * @param x 表示列
1632  * @param y 表示行
1633  * @param m_ptr 思い出を表示するモンスター情報の参照ポインタ
1634  * @param n_same モンスターの数の現在数
1635  * @details
1636  * <pre>
1637  * nnn X LV name
1638  *  nnn : number or unique(U) or wanted unique(W)
1639  *  X   : symbol of monster
1640  *  LV  : monster lv if known
1641  *  name: name of monster
1642  * @return なし
1643  * </pre>
1644  */
1645 static void print_monster_line(TERM_LEN x, TERM_LEN y, monster_type* m_ptr, int n_same){
1646         char buf[256];
1647         int i;
1648         MONRACE_IDX r_idx = m_ptr->ap_r_idx;
1649         monster_race* r_ptr = &r_info[r_idx];
1650  
1651         Term_gotoxy(x, y);
1652         if(!r_ptr)return;
1653         //Number of 'U'nique
1654         if(r_ptr->flags1&RF1_UNIQUE){//unique
1655                 bool is_kubi = FALSE;
1656                 for(i=0;i<MAX_KUBI;i++){
1657                         if(current_world_ptr->bounty_r_idx[i] == r_idx){
1658                                 is_kubi = TRUE;
1659                                 break;
1660                         }
1661                 }
1662                 Term_addstr(-1, TERM_WHITE, is_kubi?"  W":"  U");
1663         }else{
1664                 sprintf(buf, "%3d", n_same);
1665                 Term_addstr(-1, TERM_WHITE, buf);
1666         }
1667         //symbol
1668         Term_addstr(-1, TERM_WHITE, " ");
1669         //Term_add_bigch(r_ptr->d_attr, r_ptr->d_char);
1670         //Term_addstr(-1, TERM_WHITE, "/");
1671         Term_add_bigch(r_ptr->x_attr, r_ptr->x_char);
1672         //LV
1673         if (r_ptr->r_tkills && !(m_ptr->mflag2 & MFLAG2_KAGE)){
1674                 sprintf(buf, " %2d", (int)r_ptr->level);
1675         }else{
1676                 strcpy(buf, " ??");
1677         }
1678         Term_addstr(-1, TERM_WHITE, buf);
1679         //name
1680         sprintf(buf, " %s ", r_name+r_ptr->name);
1681         Term_addstr(-1, TERM_WHITE, buf);
1682  
1683         //Term_addstr(-1, TERM_WHITE, look_mon_desc(m_ptr, 0));
1684 }
1685
1686 /*!
1687  * @brief モンスターの出現リストを表示する / Print monster info in line
1688  * @param x 表示列
1689  * @param y 表示行
1690  * @param max_lines 最大何行描画するか
1691  */
1692 void print_monster_list(TERM_LEN x, TERM_LEN y, TERM_LEN max_lines){
1693         TERM_LEN line = y;
1694         monster_type* last_mons = NULL;
1695         monster_type* m_ptr = NULL;
1696         int n_same = 0;
1697         int i;
1698
1699         for(i=0;i<tmp_pos.n;i++){
1700                 grid_type* g_ptr = &current_floor_ptr->grid_array[tmp_pos.y[i]][tmp_pos.x[i]];
1701                 if(!g_ptr->m_idx || !current_floor_ptr->m_list[g_ptr->m_idx].ml)continue;//no mons or cannot look
1702                 m_ptr = &current_floor_ptr->m_list[g_ptr->m_idx];
1703                 if(is_pet(m_ptr))continue;//pet
1704                 if(!m_ptr->r_idx)continue;//dead?
1705                 {
1706                         /*
1707                         MONRACE_IDX r_idx = m_ptr->ap_r_idx;
1708                         monster_race* r_ptr = &r_info[r_idx];
1709                         concptr name = (r_name + r_ptr->name);
1710                         concptr ename = (r_name + r_ptr->name);
1711                         //ミミック類や「それ」等は、一覧に出てはいけない
1712                         if(r_ptr->flags1&RF1_CHAR_CLEAR)continue;
1713                         if((r_ptr->flags1&RF1_NEVER_MOVE)&&(r_ptr->flags2&RF2_CHAR_MULTI))continue;
1714                         //『ヌル』は、一覧に出てはいけない
1715                         if((strcmp(name, "生ける虚無『ヌル』")==0)||
1716                            (strcmp(ename, "Null the Living Void")==0))continue;
1717                         //"金無垢の指輪"は、一覧に出てはいけない
1718                         if((strcmp(name, "金無垢の指輪")==0)||
1719                                 (strcmp(ename, "Plain Gold Ring")==0))continue;
1720                         */
1721                 }
1722
1723                 //ソート済みなので同じモンスターは連続する.これを利用して同じモンスターをカウント,まとめて表示する.
1724                 if(!last_mons){//先頭モンスター
1725                         last_mons = m_ptr;
1726                         n_same = 1;
1727                         continue;
1728                 }
1729                 //same race?
1730                 if(last_mons->ap_r_idx == m_ptr->ap_r_idx){
1731                         n_same++;
1732                         continue;//表示処理を次に回す
1733                 }
1734                 //print last mons info
1735                 print_monster_line(x, line++, last_mons, n_same);
1736                 n_same = 1;
1737                 last_mons = m_ptr;
1738                 if(line-y-1==max_lines){//残り1行
1739                         break;
1740                 }
1741         }
1742         if(line-y-1==max_lines && i!=tmp_pos.n){
1743                 Term_gotoxy(x, line);
1744                 Term_addstr(-1, TERM_WHITE, "-- and more --");
1745         }else{
1746                 if(last_mons)print_monster_line(x, line++, last_mons, n_same);
1747         }
1748 }
1749
1750 /*!
1751  * @brief 出現中モンスターのリストをサブウィンドウに表示する / Hack -- display monster list in sub-windows
1752  * @return なし
1753  */
1754 static void fix_monster_list(void)
1755 {
1756         int j;
1757         int w, h;
1758
1759         /* Scan windows */
1760         for (j = 0; j < 8; j++)
1761         {
1762                 term *old = Term;
1763
1764                 /* No window */
1765                 if (!angband_term[j]) continue;
1766
1767                 /* No relevant flags */
1768                 if (!(window_flag[j] & (PW_MONSTER_LIST))) continue;
1769
1770                 /* Activate */
1771                 Term_activate(angband_term[j]);
1772                 Term_get_size(&w, &h);
1773
1774                 Term_clear();
1775
1776                 target_set_prepare_look();//モンスター一覧を生成,ソート
1777                 print_monster_list(0, 0, h);
1778                 Term_fresh();
1779                 Term_activate(old);
1780         }
1781 }
1782
1783
1784
1785 /*!
1786  * @brief 現在の装備品をサブウィンドウに表示する / 
1787  * Hack -- display equipment in sub-windows
1788  * @return なし
1789  */
1790 static void fix_equip(void)
1791 {
1792         int j;
1793
1794         /* Scan windows */
1795         for (j = 0; j < 8; j++)
1796         {
1797                 term *old = Term;
1798
1799                 /* No window */
1800                 if (!angband_term[j]) continue;
1801
1802                 /* No relevant flags */
1803                 if (!(window_flag[j] & (PW_EQUIP))) continue;
1804
1805                 /* Activate */
1806                 Term_activate(angband_term[j]);
1807
1808                 /* Display equipment */
1809                 display_equip();
1810                 Term_fresh();
1811                 Term_activate(old);
1812         }
1813 }
1814
1815
1816 /*!
1817  * @brief 現在の習得済魔法をサブウィンドウに表示する / 
1818  * Hack -- display spells in sub-windows
1819  * @return なし
1820  */
1821 static void fix_spell(void)
1822 {
1823         int j;
1824
1825         /* Scan windows */
1826         for (j = 0; j < 8; j++)
1827         {
1828                 term *old = Term;
1829
1830                 /* No window */
1831                 if (!angband_term[j]) continue;
1832
1833                 /* No relevant flags */
1834                 if (!(window_flag[j] & (PW_SPELL))) continue;
1835
1836                 /* Activate */
1837                 Term_activate(angband_term[j]);
1838
1839                 /* Display spell list */
1840                 display_spell_list();
1841                 Term_fresh();
1842                 Term_activate(old);
1843         }
1844 }
1845
1846
1847 /*!
1848  * @brief 現在のプレイヤーステータスをサブウィンドウに表示する / 
1849  * Hack -- display character in sub-windows
1850  * @return なし
1851  */
1852 static void fix_player(void)
1853 {
1854         int j;
1855
1856         /* Scan windows */
1857         for (j = 0; j < 8; j++)
1858         {
1859                 term *old = Term;
1860
1861                 /* No window */
1862                 if (!angband_term[j]) continue;
1863
1864                 /* No relevant flags */
1865                 if (!(window_flag[j] & (PW_PLAYER))) continue;
1866
1867                 /* Activate */
1868                 Term_activate(angband_term[j]);
1869
1870                 update_playtime();
1871                 display_player(0);
1872                 Term_fresh();
1873                 Term_activate(old);
1874         }
1875 }
1876
1877 /*!
1878  * @brief ゲームメッセージ履歴をサブウィンドウに表示する / 
1879  * Hack -- display recent messages in sub-windows
1880  * Adjust for width and split messages
1881  * @return なし
1882  */
1883 static void fix_message(void)
1884 {
1885         int j, i;
1886         TERM_LEN w, h;
1887         TERM_LEN x, y;
1888
1889         /* Scan windows */
1890         for (j = 0; j < 8; j++)
1891         {
1892                 term *old = Term;
1893
1894                 /* No window */
1895                 if (!angband_term[j]) continue;
1896
1897                 /* No relevant flags */
1898                 if (!(window_flag[j] & (PW_MESSAGE))) continue;
1899
1900                 /* Activate */
1901                 Term_activate(angband_term[j]);
1902
1903                 Term_get_size(&w, &h);
1904
1905                 /* Dump messages */
1906                 for (i = 0; i < h; i++)
1907                 {
1908                         /* Dump the message on the appropriate line */
1909                         Term_putstr(0, (h - 1) - i, -1, (byte)((i < now_message) ? TERM_WHITE : TERM_SLATE), message_str((s16b)i));
1910
1911                         /* Cursor */
1912                         Term_locate(&x, &y);
1913
1914                         /* Clear to end of line */
1915                         Term_erase(x, y, 255);
1916                 }
1917                 Term_fresh();
1918                 Term_activate(old);
1919         }
1920 }
1921
1922
1923 /*!
1924  * @brief 簡易マップをサブウィンドウに表示する / 
1925  * Hack -- display overhead view in sub-windows
1926  * Adjust for width and split messages
1927  * @return なし
1928  * @details
1929  * Note that the "player" symbol does NOT appear on the map.
1930  */
1931 static void fix_overhead(void)
1932 {
1933         int j;
1934         int cy, cx;
1935
1936         /* Scan windows */
1937         for (j = 0; j < 8; j++)
1938         {
1939                 term *old = Term;
1940                 TERM_LEN wid, hgt;
1941
1942                 /* No window */
1943                 if (!angband_term[j]) continue;
1944
1945                 /* No relevant flags */
1946                 if (!(window_flag[j] & (PW_OVERHEAD))) continue;
1947
1948                 /* Activate */
1949                 Term_activate(angband_term[j]);
1950
1951                 /* Full map in too small window is useless  */
1952                 Term_get_size(&wid, &hgt);
1953                 if (wid > COL_MAP + 2 && hgt > ROW_MAP + 2)
1954                 {
1955
1956                         display_map(&cy, &cx);
1957                         Term_fresh();
1958                 }
1959                 Term_activate(old);
1960         }
1961 }
1962
1963
1964 /*!
1965  * @brief ダンジョンの地形をサブウィンドウに表示する / 
1966  * Hack -- display dungeon view in sub-windows
1967  * @return なし
1968  */
1969 static void fix_dungeon(void)
1970 {
1971         int j;
1972
1973         /* Scan windows */
1974         for (j = 0; j < 8; j++)
1975         {
1976                 term *old = Term;
1977
1978                 /* No window */
1979                 if (!angband_term[j]) continue;
1980
1981                 /* No relevant flags */
1982                 if (!(window_flag[j] & (PW_DUNGEON))) continue;
1983
1984                 /* Activate */
1985                 Term_activate(angband_term[j]);
1986
1987                 /* Redraw dungeon view */
1988                 display_dungeon();
1989                 Term_fresh();
1990                 Term_activate(old);
1991         }
1992 }
1993
1994
1995 /*!
1996  * @brief モンスターの思い出をサブウィンドウに表示する / 
1997  * Hack -- display dungeon view in sub-windows
1998  * @return なし
1999  */
2000 static void fix_monster(void)
2001 {
2002         int j;
2003
2004         /* Scan windows */
2005         for (j = 0; j < 8; j++)
2006         {
2007                 term *old = Term;
2008
2009                 /* No window */
2010                 if (!angband_term[j]) continue;
2011
2012                 /* No relevant flags */
2013                 if (!(window_flag[j] & (PW_MONSTER))) continue;
2014
2015                 /* Activate */
2016                 Term_activate(angband_term[j]);
2017
2018                 /* Display monster race info */
2019                 if (p_ptr->monster_race_idx) display_roff(p_ptr->monster_race_idx);
2020                 Term_fresh();
2021                 Term_activate(old);
2022         }
2023 }
2024
2025
2026 /*!
2027  * @brief ベースアイテム情報をサブウィンドウに表示する / 
2028  * Hack -- display object recall in sub-windows
2029  * @return なし
2030  */
2031 static void fix_object(void)
2032 {
2033         int j;
2034
2035         /* Scan windows */
2036         for (j = 0; j < 8; j++)
2037         {
2038                 term *old = Term;
2039
2040                 /* No window */
2041                 if (!angband_term[j]) continue;
2042
2043                 /* No relevant flags */
2044                 if (!(window_flag[j] & (PW_OBJECT))) continue;
2045
2046                 /* Activate */
2047                 Term_activate(angband_term[j]);
2048
2049                 /* Display monster race info */
2050                 if (p_ptr->object_kind_idx) display_koff(p_ptr->object_kind_idx);
2051                 Term_fresh();
2052                 Term_activate(old);
2053         }
2054 }
2055
2056
2057
2058 /*!
2059  * @brief 射撃武器がプレイヤーにとって重すぎるかどうかの判定 /
2060  * @param o_ptr 判定する射撃武器のアイテム情報参照ポインタ
2061  * @return 重すぎるならばTRUE
2062  */
2063 bool is_heavy_shoot(object_type *o_ptr)
2064 {
2065         int hold = adj_str_hold[p_ptr->stat_ind[A_STR]];
2066         /* It is hard to carholdry a heavy bow */
2067         return (hold < o_ptr->weight / 10);
2068 }
2069
2070 /*!
2071  * @brief 射撃武器に対応する矢/弾薬のベースアイテムIDを返す /
2072  * @param o_ptr 判定する射撃武器のアイテム情報参照ポインタ
2073  * @return 対応する矢/弾薬のベースアイテムID
2074  */
2075 int bow_tval_ammo(object_type *o_ptr)
2076 {
2077         /* Analyze the launcher */
2078         switch (o_ptr->sval)
2079         {
2080                 case SV_SLING:
2081                 {
2082                         return TV_SHOT;
2083                 }
2084
2085                 case SV_SHORT_BOW:
2086                 case SV_LONG_BOW:
2087                 case SV_NAMAKE_BOW:
2088                 {
2089                         return TV_ARROW;
2090                 }
2091
2092                 case SV_LIGHT_XBOW:
2093                 case SV_HEAVY_XBOW:
2094                 {
2095                         return TV_BOLT;
2096                 }
2097                 case SV_CRIMSON:
2098                 case SV_HARP:
2099                 {
2100                         return TV_NO_AMMO;
2101                 }
2102         }
2103         
2104         return 0;
2105 }
2106
2107
2108 /*! 
2109  * @brief p_ptr->redraw のフラグに応じた更新をまとめて行う / Handle "p_ptr->redraw"
2110  * @return なし
2111  * @details 更新処理の対象はゲーム中の全描画処理
2112  */
2113 static void redraw_stuff(void)
2114 {
2115         if (!p_ptr->redraw) return;
2116
2117         /* Character is not ready yet, no screen updates */
2118         if (!character_generated) return;
2119
2120         /* Character is in "icky" mode, no screen updates */
2121         if (character_icky) return;
2122
2123         /* Hack -- clear the screen */
2124         if (p_ptr->redraw & (PR_WIPE))
2125         {
2126                 p_ptr->redraw &= ~(PR_WIPE);
2127                 msg_print(NULL);
2128                 Term_clear();
2129         }
2130
2131         if (p_ptr->redraw & (PR_MAP))
2132         {
2133                 p_ptr->redraw &= ~(PR_MAP);
2134                 prt_map();
2135         }
2136
2137         if (p_ptr->redraw & (PR_BASIC))
2138         {
2139                 p_ptr->redraw &= ~(PR_BASIC);
2140                 p_ptr->redraw &= ~(PR_MISC | PR_TITLE | PR_STATS);
2141                 p_ptr->redraw &= ~(PR_LEV | PR_EXP | PR_GOLD);
2142                 p_ptr->redraw &= ~(PR_ARMOR | PR_HP | PR_MANA);
2143                 p_ptr->redraw &= ~(PR_DEPTH | PR_HEALTH | PR_UHEALTH);
2144                 prt_frame_basic();
2145                 prt_time();
2146                 prt_dungeon();
2147         }
2148
2149         if (p_ptr->redraw & (PR_EQUIPPY))
2150         {
2151                 p_ptr->redraw &= ~(PR_EQUIPPY);
2152                 print_equippy(); /* To draw / delete equippy chars */
2153         }
2154
2155         if (p_ptr->redraw & (PR_MISC))
2156         {
2157                 p_ptr->redraw &= ~(PR_MISC);
2158                 prt_field(rp_ptr->title, ROW_RACE, COL_RACE);
2159 /*              prt_field(cp_ptr->title, ROW_CLASS, COL_CLASS); */
2160         }
2161
2162         if (p_ptr->redraw & (PR_TITLE))
2163         {
2164                 p_ptr->redraw &= ~(PR_TITLE);
2165                 prt_title();
2166         }
2167
2168         if (p_ptr->redraw & (PR_LEV))
2169         {
2170                 p_ptr->redraw &= ~(PR_LEV);
2171                 prt_level();
2172         }
2173
2174         if (p_ptr->redraw & (PR_EXP))
2175         {
2176                 p_ptr->redraw &= ~(PR_EXP);
2177                 prt_exp();
2178         }
2179
2180         if (p_ptr->redraw & (PR_STATS))
2181         {
2182                 p_ptr->redraw &= ~(PR_STATS);
2183                 prt_stat(A_STR);
2184                 prt_stat(A_INT);
2185                 prt_stat(A_WIS);
2186                 prt_stat(A_DEX);
2187                 prt_stat(A_CON);
2188                 prt_stat(A_CHR);
2189         }
2190
2191         if (p_ptr->redraw & (PR_STATUS))
2192         {
2193                 p_ptr->redraw &= ~(PR_STATUS);
2194                 prt_status();
2195         }
2196
2197         if (p_ptr->redraw & (PR_ARMOR))
2198         {
2199                 p_ptr->redraw &= ~(PR_ARMOR);
2200                 prt_ac();
2201         }
2202
2203         if (p_ptr->redraw & (PR_HP))
2204         {
2205                 p_ptr->redraw &= ~(PR_HP);
2206                 prt_hp();
2207         }
2208
2209         if (p_ptr->redraw & (PR_MANA))
2210         {
2211                 p_ptr->redraw &= ~(PR_MANA);
2212                 prt_sp();
2213         }
2214
2215         if (p_ptr->redraw & (PR_GOLD))
2216         {
2217                 p_ptr->redraw &= ~(PR_GOLD);
2218                 prt_gold();
2219         }
2220
2221         if (p_ptr->redraw & (PR_DEPTH))
2222         {
2223                 p_ptr->redraw &= ~(PR_DEPTH);
2224                 prt_depth();
2225         }
2226
2227         if (p_ptr->redraw & (PR_HEALTH))
2228         {
2229                 p_ptr->redraw &= ~(PR_HEALTH);
2230                 health_redraw(FALSE);
2231         }
2232
2233         if (p_ptr->redraw & (PR_UHEALTH))
2234         {
2235                 p_ptr->redraw &= ~(PR_UHEALTH);
2236                 health_redraw(TRUE);
2237         }
2238
2239         if (p_ptr->redraw & (PR_EXTRA))
2240         {
2241                 p_ptr->redraw &= ~(PR_EXTRA);
2242                 p_ptr->redraw &= ~(PR_CUT | PR_STUN);
2243                 p_ptr->redraw &= ~(PR_HUNGER);
2244                 p_ptr->redraw &= ~(PR_STATE | PR_SPEED | PR_STUDY | PR_IMITATION | PR_STATUS);
2245                 prt_frame_extra();
2246         }
2247
2248         if (p_ptr->redraw & (PR_CUT))
2249         {
2250                 p_ptr->redraw &= ~(PR_CUT);
2251                 prt_cut();
2252         }
2253
2254         if (p_ptr->redraw & (PR_STUN))
2255         {
2256                 p_ptr->redraw &= ~(PR_STUN);
2257                 prt_stun();
2258         }
2259
2260         if (p_ptr->redraw & (PR_HUNGER))
2261         {
2262                 p_ptr->redraw &= ~(PR_HUNGER);
2263                 prt_hunger();
2264         }
2265
2266         if (p_ptr->redraw & (PR_STATE))
2267         {
2268                 p_ptr->redraw &= ~(PR_STATE);
2269                 prt_state();
2270         }
2271
2272         if (p_ptr->redraw & (PR_SPEED))
2273         {
2274                 p_ptr->redraw &= ~(PR_SPEED);
2275                 prt_speed();
2276         }
2277
2278         if (p_ptr->pclass == CLASS_IMITATOR)
2279         {
2280                 if (p_ptr->redraw & (PR_IMITATION))
2281                 {
2282                         p_ptr->redraw &= ~(PR_IMITATION);
2283                         prt_imitation();
2284                 }
2285         }
2286         else if (p_ptr->redraw & (PR_STUDY))
2287         {
2288                 p_ptr->redraw &= ~(PR_STUDY);
2289                 prt_study();
2290         }
2291 }
2292
2293 /*! 
2294  * @brief p_ptr->window のフラグに応じた更新をまとめて行う / Handle "p_ptr->window"
2295  * @return なし
2296  * @details 更新処理の対象はサブウィンドウ全般
2297  */
2298 static void window_stuff(void)
2299 {
2300         int j;
2301         BIT_FLAGS mask = 0L;
2302
2303         /* Nothing to do */
2304         if (!p_ptr->window) return;
2305
2306         /* Scan windows */
2307         for (j = 0; j < 8; j++)
2308         {
2309                 /* Save usable flags */
2310                 if (angband_term[j]) mask |= window_flag[j];
2311         }
2312
2313         /* Apply usable flags */
2314         p_ptr->window &= mask;
2315
2316         /* Nothing to do */
2317         if (!p_ptr->window) return;
2318
2319         /* Display inventory */
2320         if (p_ptr->window & (PW_INVEN))
2321         {
2322                 p_ptr->window &= ~(PW_INVEN);
2323                 fix_inven();
2324         }
2325
2326         /* Display equipment */
2327         if (p_ptr->window & (PW_EQUIP))
2328         {
2329                 p_ptr->window &= ~(PW_EQUIP);
2330                 fix_equip();
2331         }
2332
2333         /* Display spell list */
2334         if (p_ptr->window & (PW_SPELL))
2335         {
2336                 p_ptr->window &= ~(PW_SPELL);
2337                 fix_spell();
2338         }
2339
2340         /* Display player */
2341         if (p_ptr->window & (PW_PLAYER))
2342         {
2343                 p_ptr->window &= ~(PW_PLAYER);
2344                 fix_player();
2345         }
2346         
2347         /* Display monster list */
2348         if (p_ptr->window & (PW_MONSTER_LIST))
2349         {
2350                 p_ptr->window &= ~(PW_MONSTER_LIST);
2351                 fix_monster_list();
2352         }
2353         
2354         /* Display overhead view */
2355         if (p_ptr->window & (PW_MESSAGE))
2356         {
2357                 p_ptr->window &= ~(PW_MESSAGE);
2358                 fix_message();
2359         }
2360
2361         /* Display overhead view */
2362         if (p_ptr->window & (PW_OVERHEAD))
2363         {
2364                 p_ptr->window &= ~(PW_OVERHEAD);
2365                 fix_overhead();
2366         }
2367
2368         /* Display overhead view */
2369         if (p_ptr->window & (PW_DUNGEON))
2370         {
2371                 p_ptr->window &= ~(PW_DUNGEON);
2372                 fix_dungeon();
2373         }
2374
2375         /* Display monster recall */
2376         if (p_ptr->window & (PW_MONSTER))
2377         {
2378                 p_ptr->window &= ~(PW_MONSTER);
2379                 fix_monster();
2380         }
2381
2382         /* Display object recall */
2383         if (p_ptr->window & (PW_OBJECT))
2384         {
2385                 p_ptr->window &= ~(PW_OBJECT);
2386                 fix_object();
2387         }
2388 }
2389
2390
2391 /*!
2392  * @brief 全更新処理をチェックして処理していく
2393  * Handle "p_ptr->update" and "p_ptr->redraw" and "p_ptr->window"
2394  * @return なし
2395  */
2396 void handle_stuff(void)
2397 {
2398         if (p_ptr->update) update_creature(p_ptr);
2399         if (p_ptr->redraw) redraw_stuff();
2400         if (p_ptr->window) window_stuff();
2401 }
2402
2403 void update_output(void)
2404 {
2405         if (p_ptr->redraw) redraw_stuff();
2406         if (p_ptr->window) window_stuff();
2407 }
2408
2409 /*!
2410  * @brief 実ゲームプレイ時間を更新する
2411  */
2412 void update_playtime(void)
2413 {
2414         /* Check if the game has started */
2415         if (start_time != 0)
2416         {
2417                 u32b tmp = (u32b)time(NULL);
2418                 current_world_ptr->play_time += (tmp - start_time);
2419                 start_time = tmp;
2420         }
2421 }
2422
2423
2424
2425 /*!
2426  * @brief コンソールのリサイズに合わせてマップを再描画する /
2427  * Map resizing whenever the main term changes size
2428  * @return なし
2429  */
2430 void resize_map(void)
2431 {
2432         /* Only if the dungeon exists */
2433         if (!character_dungeon) return;
2434
2435         /* Mega-Hack -- no panel yet */
2436         panel_row_max = 0;
2437         panel_col_max = 0;
2438
2439         /* Reset the panels */
2440         panel_row_min = current_floor_ptr->height;
2441         panel_col_min = current_floor_ptr->width;
2442
2443         verify_panel();
2444
2445         p_ptr->update |= (PU_TORCH | PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
2446         p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
2447         p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
2448         p_ptr->update |= (PU_MONSTERS);
2449         p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
2450
2451         handle_stuff();
2452         Term_redraw();
2453
2454         /*
2455          * Waiting command;
2456          * Place the cursor on the player
2457          */
2458         if (can_save) move_cursor_relative(p_ptr->y, p_ptr->x);
2459
2460         Term_fresh();
2461 }
2462
2463 /*!
2464  * @brief コンソールを再描画する /
2465  * Redraw a term when it is resized
2466  * @return なし
2467  */
2468 void redraw_window(void)
2469 {
2470         /* Only if the dungeon exists */
2471         if (!character_dungeon) return;
2472
2473         p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
2474         p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
2475
2476         handle_stuff();
2477         Term_redraw();
2478 }
2479
2480
2481 /*!
2482  * @brief フォーカスを当てるべきマップ描画の基準座標を指定する(サブルーチン)
2483  * @param dy 変更先のフロアY座標
2484  * @param dx 変更先のフロアX座標
2485  * Handle a request to change the current panel
2486  * Return TRUE if the panel was changed.
2487  * Also used in do_cmd_locate
2488  * @return 実際に再描画が必要だった場合TRUEを返す
2489  */
2490 bool change_panel(POSITION dy, POSITION dx)
2491 {
2492         POSITION y, x;
2493         TERM_LEN wid, hgt;
2494
2495         get_screen_size(&wid, &hgt);
2496
2497         /* Apply the motion */
2498         y = panel_row_min + dy * hgt / 2;
2499         x = panel_col_min + dx * wid / 2;
2500
2501         /* Verify the row */
2502         if (y > current_floor_ptr->height - hgt) y = current_floor_ptr->height - hgt;
2503         if (y < 0) y = 0;
2504
2505         /* Verify the col */
2506         if (x > current_floor_ptr->width - wid) x = current_floor_ptr->width - wid;
2507         if (x < 0) x = 0;
2508
2509         /* Handle "changes" */
2510         if ((y != panel_row_min) || (x != panel_col_min))
2511         {
2512                 /* Save the new panel info */
2513                 panel_row_min = y;
2514                 panel_col_min = x;
2515
2516                 panel_bounds_center();
2517
2518                 p_ptr->update |= (PU_MONSTERS);
2519                 p_ptr->redraw |= (PR_MAP);
2520                 handle_stuff();
2521
2522                 /* Success */
2523                 return (TRUE);
2524         }
2525
2526         /* No change */
2527         return (FALSE);
2528 }
2529
2530 /*!
2531  * @brief プレイヤーの装備一覧シンボルを固定位置に表示する
2532  * @return なし
2533  */
2534 void print_equippy(void)
2535 {
2536         display_player_equippy(ROW_EQUIPPY, COL_EQUIPPY, 0);
2537 }
2538
2539 /*!
2540  * @brief 現在のコンソール表示の縦横を返す。 /
2541  * Get term size and calculate screen size
2542  * @param wid_p コンソールの表示幅文字数を返す
2543  * @param hgt_p コンソールの表示行数を返す
2544  * @return なし
2545  */
2546 void get_screen_size(TERM_LEN *wid_p, TERM_LEN *hgt_p)
2547 {
2548         Term_get_size(wid_p, hgt_p);
2549         *hgt_p -= ROW_MAP + 2;
2550         *wid_p -= COL_MAP + 2;
2551         if (use_bigtile) *wid_p /= 2;
2552 }