OSDN Git Service

[Refactor] #40413 Renamed my_f*() to angband_f*() in util.c/h; propably f means fuxk...
[hengband/hengband.git] / src / view / display-main-window.c
1 /*!
2  * @brief プレイヤーのステータス処理 / status
3  * @date 2018/09/25
4  * @author
5  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke\n
6  * This software may be copied and distributed for educational, research, and\n
7  * not for profit purposes provided that this copyright and statement are\n
8  * included in all such copies.\n
9  * 2014 Deskull rearranged comment for Doxygen.
10  */
11
12 #include "view/display-main-window.h"
13 #include "autopick/autopick-finder.h"
14 #include "autopick/autopick-methods-table.h"
15 #include "autopick/autopick-util.h"
16 #include "cmd-building/cmd-building.h"
17 #include "core/player-processor.h"
18 #include "core/stuff-handler.h"
19 #include "dungeon/dungeon.h"
20 #include "dungeon/quest.h"
21 #include "effect/effect-characteristics.h"
22 #include "effect/spells-effect-util.h"
23 #include "floor/floor-town.h"
24 #include "floor/floor.h"
25 #include "game-option/map-screen-options.h"
26 #include "game-option/option-flags.h"
27 #include "game-option/special-options.h"
28 #include "game-option/text-display-options.h"
29 #include "grid/feature.h"
30 #include "grid/grid.h"
31 #include "inventory/player-inventory.h"
32 #include "io/files-util.h"
33 #include "io/input-key-processor.h"
34 #include "io/targeting.h"
35 #include "market/arena-info-table.h"
36 #include "monster-race/race-flags1.h"
37 #include "monster-race/race-flags2.h"
38 #include "monster/monster-flag-types.h"
39 #include "monster/monster-info.h"
40 #include "monster/monster-status.h"
41 #include "monster/monster-update.h"
42 #include "monster/smart-learn-types.h"
43 #include "object/object-flavor.h"
44 #include "object/object-kind.h"
45 #include "object/object-mark-types.h"
46 #include "object/object-info.h"
47 #include "player/avatar.h"
48 #include "player/mimic-info-table.h"
49 #include "player/player-class.h"
50 #include "player/player-effects.h"
51 #include "player/player-races-table.h"
52 #include "player/player-status.h"
53 #include "realm/realm-hex-numbers.h"
54 #include "realm/realm-song-numbers.h"
55 #include "spell-realm/spells-hex.h"
56 #include "spell/spells3.h"
57 #include "system/system-variables.h"
58 #include "term/gameterm.h"
59 #include "term/term-color-types.h"
60 #include "util/util.h"
61 #include "view/display-lore.h"
62 #include "view/display-player.h"
63 #include "view/object-describer.h"
64 #include "world/world.h"
65
66  /*
67   * Not using graphical tiles for this feature?
68   */
69 #define IS_ASCII_GRAPHICS(A) (!((A) & 0x80))
70
71 static int feat_priority; /*!< マップ縮小表示時に表示すべき地形の優先度を保管する */
72 static byte display_autopick; /*!< 自動拾い状態の設定フラグ */
73 static int match_autopick;
74 static object_type *autopick_obj; /*!< 各種自動拾い処理時に使うオブジェクトポインタ */
75
76 /*
77  * Dungeon size info
78  */
79 POSITION panel_row_min, panel_row_max;
80 POSITION panel_col_min, panel_col_max;
81 POSITION panel_col_prt, panel_row_prt;
82
83 /*
84  * Some screen locations for various display routines
85  * Currently, row 8 and 15 are the only "blank" rows.
86  * That leaves a "border" around the "stat" values.
87  */
88
89 #define ROW_RACE                1
90 #define COL_RACE                0       /* <race name> */
91
92  /*#define ROW_CLASS               2 */
93  /*#define COL_CLASS               0 */      /* <class name> */
94
95 #define ROW_TITLE               2
96 #define COL_TITLE               0       /* <title> or <mode> */
97
98 /*#define ROW_SEIKAKU           4 */
99 /*#define COL_SEIKAKU           0*/     /* <seikaku> */
100
101 #define ROW_DAY                 21
102 #define COL_DAY                 0       /* day */
103
104 #define ROW_DUNGEON             22
105 #define COL_DUNGEON             0       /* dungeon */
106
107 #define ROW_LEVEL               3
108 #define COL_LEVEL               0       /* "LEVEL xxxxxx" */
109
110 #define ROW_EXP                 4
111 #define COL_EXP                 0       /* "EXP xxxxxxxx" */
112
113 #define ROW_GOLD                5
114 #define COL_GOLD                0       /* "AU xxxxxxxxx" */
115
116 #define ROW_EQUIPPY             6
117 #define COL_EQUIPPY             0       /* equippy chars */
118
119 #define ROW_STAT                7
120 #define COL_STAT                0       /* "xxx   xxxxxx" */
121
122 #define ROW_AC                  13
123 #define COL_AC                  0       /* "Cur AC xxxxx" */
124
125 #define ROW_HPMP                14
126 #define COL_HPMP                0
127
128 #define ROW_CURHP               14
129 #define COL_CURHP               0       /* "Cur HP xxxxx" */
130
131 #define ROW_CURSP               15
132 #define COL_CURSP               0       /* "Cur SP xxxxx" */
133
134 #define ROW_RIDING_INFO         16
135 #define COL_RIDING_INFO         0       /* "xxxxxxxxxxxx" */
136
137 #define ROW_INFO                17
138 #define COL_INFO                0       /* "xxxxxxxxxxxx" */
139
140 #define ROW_CUT                 18
141 #define COL_CUT                 0       /* <cut> */
142
143 #define ROW_STUN                19
144 #define COL_STUN                0       /* <stun> */
145
146 #define ROW_HUNGRY              20
147 #define COL_HUNGRY              0       /* "Weak" / "Hungry" / "Full" / "Gorged" */
148
149 #define ROW_STATE               20
150 #define COL_STATE                7      /* <state> */
151
152 #define ROW_SPEED               (-1)
153 #define COL_SPEED               (-24)      /* "Slow (-NN)" or "Fast (+NN)" */
154
155 #define ROW_STUDY               (-1)
156 #define COL_STUDY               (-13)      /* "Study" */
157
158 #define ROW_DEPTH               (-1)
159 #define COL_DEPTH               (-8)      /* "Lev NNN" / "NNNN ft" */
160
161 #define ROW_STATBAR             (-1)
162 #define COL_STATBAR              0
163 #define MAX_COL_STATBAR         (-26)
164
165 void print_equippy(player_type *creature_ptr);
166 void print_map(player_type *player_ptr);
167 void display_map(player_type *player_ptr, int *cy, int *cx);
168 void set_term_color(player_type *player_ptr, POSITION y, POSITION x, TERM_COLOR *ap, SYMBOL_CODE *cp);
169
170 /*!
171  * @brief 画面左の能力値表示を行うために指定位置から13キャラ分を空白消去後指定のメッセージを明るい青で描画する /
172  * Print character info at given row, column in a 13 char field
173  * @param info 表示文字列
174  * @param row 描画列
175  * @param col 描画行
176  * @return なし
177  */
178 static void print_field(concptr info, TERM_LEN row, TERM_LEN col)
179 {
180         /* Dump 13 spaces to clear */
181         c_put_str(TERM_WHITE, "             ", row, col);
182
183         /* Dump the info itself */
184         c_put_str(TERM_L_BLUE, info, row, col);
185 }
186
187
188 /*!
189  * @brief ゲーム時刻を表示する /
190  * Print time
191  * @return なし
192  */
193 void print_time(player_type *player_ptr)
194 {
195         int day, hour, min;
196
197         /* Dump 13 spaces to clear */
198         c_put_str(TERM_WHITE, "             ", ROW_DAY, COL_DAY);
199
200         extract_day_hour_min(player_ptr, &day, &hour, &min);
201
202         /* Dump the info itself */
203         if (day < 1000) c_put_str(TERM_WHITE, format(_("%2d日目", "Day%3d"), day), ROW_DAY, COL_DAY);
204         else c_put_str(TERM_WHITE, _("***日目", "Day***"), ROW_DAY, COL_DAY);
205
206         c_put_str(TERM_WHITE, format("%2d:%02d", hour, min), ROW_DAY, COL_DAY + 7);
207 }
208
209
210 /*!
211  * @brief 現在のマップ名を返す /
212  * @param creature_ptr プレーヤーへの参照ポインタ
213  * @return マップ名の文字列参照ポインタ
214  */
215 concptr map_name(player_type *creature_ptr)
216 {
217         floor_type *floor_ptr = creature_ptr->current_floor_ptr;
218         if (floor_ptr->inside_quest && is_fixed_quest_idx(floor_ptr->inside_quest)
219                 && (quest[floor_ptr->inside_quest].flags & QUEST_FLAG_PRESET))
220                 return _("クエスト", "Quest");
221         else if (creature_ptr->wild_mode)
222                 return _("地上", "Surface");
223         else if (creature_ptr->current_floor_ptr->inside_arena)
224                 return _("アリーナ", "Arena");
225         else if (creature_ptr->phase_out)
226                 return _("闘技場", "Monster Arena");
227         else if (!floor_ptr->dun_level && creature_ptr->town_num)
228                 return town_info[creature_ptr->town_num].name;
229         else
230                 return d_name + d_info[creature_ptr->dungeon_idx].name;
231 }
232
233
234 /*!
235  * @brief 現在のマップ名を描画する / Print dungeon
236  * @param creature_ptr プレーヤーへの参照ポインタ
237  * @return なし
238  */
239 static void print_dungeon(player_type *creature_ptr)
240 {
241         /* Dump 13 spaces to clear */
242         c_put_str(TERM_WHITE, "             ", ROW_DUNGEON, COL_DUNGEON);
243
244         concptr dungeon_name = map_name(creature_ptr);
245
246         TERM_LEN col = COL_DUNGEON + 6 - strlen(dungeon_name) / 2;
247         if (col < 0) col = 0;
248
249         /* Dump the info itself */
250         c_put_str(TERM_L_UMBER, format("%s", dungeon_name),
251                 ROW_DUNGEON, col);
252 }
253
254
255 /*!
256  * @brief プレイヤー能力値を描画する / Print character stat in given row, column
257  * @param stat 描画するステータスのID
258  * @return なし
259  */
260 static void print_stat(player_type *creature_ptr, int stat)
261 {
262         GAME_TEXT tmp[32];
263
264         /* Display "injured" stat */
265         if (creature_ptr->stat_cur[stat] < creature_ptr->stat_max[stat])
266         {
267                 put_str(stat_names_reduced[stat], ROW_STAT + stat, 0);
268                 cnv_stat(creature_ptr->stat_use[stat], tmp);
269                 c_put_str(TERM_YELLOW, tmp, ROW_STAT + stat, COL_STAT + 6);
270         }
271
272         /* Display "healthy" stat */
273         else
274         {
275                 put_str(stat_names[stat], ROW_STAT + stat, 0);
276                 cnv_stat(creature_ptr->stat_use[stat], tmp);
277                 c_put_str(TERM_L_GREEN, tmp, ROW_STAT + stat, COL_STAT + 6);
278         }
279
280         /* Indicate natural maximum */
281         if (creature_ptr->stat_max[stat] != creature_ptr->stat_max_max[stat])
282                 return;
283
284 #ifdef JP
285         /* 日本語にかぶらないように表示位置を変更 */
286         put_str("!", ROW_STAT + stat, 5);
287 #else
288         put_str("!", ROW_STAT + stat, 3);
289 #endif
290 }
291
292
293 /*
294  * 画面下部に表示する状態表示定義ID / Data structure for status bar
295  */
296 #define BAR_TSUYOSHI 0      /*!< 下部ステータス表示: オクレ兄さん状態 */
297 #define BAR_HALLUCINATION 1 /*!< 下部ステータス表示: 幻覚 */
298 #define BAR_BLINDNESS 2     /*!< 下部ステータス表示: 盲目 */
299 #define BAR_PARALYZE 3      /*!< 下部ステータス表示: 麻痺 */
300 #define BAR_CONFUSE 4       /*!< 下部ステータス表示: 混乱 */
301 #define BAR_POISONED 5      /*!< 下部ステータス表示: 毒 */
302 #define BAR_AFRAID 6        /*!< 下部ステータス表示: 恐怖 */
303 #define BAR_LEVITATE 7      /*!< 下部ステータス表示: 浮遊 */
304 #define BAR_REFLECTION 8    /*!< 下部ステータス表示: 反射 */
305 #define BAR_PASSWALL 9      /*!< 下部ステータス表示: 壁抜け */
306 #define BAR_WRAITH 10       /*!< 下部ステータス表示: 幽体化 */
307 #define BAR_PROTEVIL 11     /*!< 下部ステータス表示: 対邪悪結界 */
308 #define BAR_KAWARIMI 12     /*!< 下部ステータス表示: 変わり身 */
309 #define BAR_MAGICDEFENSE 13 /*!< 下部ステータス表示: 魔法の鎧 */
310 #define BAR_EXPAND 14       /*!< 下部ステータス表示: 横伸び */
311 #define BAR_STONESKIN 15    /*!< 下部ステータス表示: 石肌化 */
312 #define BAR_MULTISHADOW 16  /*!< 下部ステータス表示: 影分身 */
313 #define BAR_REGMAGIC 17     /*!< 下部ステータス表示: 魔法防御 */
314 #define BAR_ULTIMATE 18     /*!< 下部ステータス表示: 究極の耐性 */
315 #define BAR_INVULN 19       /*!< 下部ステータス表示: 無敵化 */
316 #define BAR_IMMACID 20      /*!< 下部ステータス表示: 酸免疫 */
317 #define BAR_RESACID 21      /*!< 下部ステータス表示: 酸耐性 */
318 #define BAR_IMMELEC 22      /*!< 下部ステータス表示: 電撃免疫 */
319 #define BAR_RESELEC 23      /*!< 下部ステータス表示: 電撃耐性 */
320 #define BAR_IMMFIRE 24      /*!< 下部ステータス表示: 火炎免疫 */
321 #define BAR_RESFIRE 25      /*!< 下部ステータス表示: 火炎耐性 */
322 #define BAR_IMMCOLD 26      /*!< 下部ステータス表示: 冷気免疫 */
323 #define BAR_RESCOLD 27      /*!< 下部ステータス表示: 冷気耐性 */
324 #define BAR_RESPOIS 28      /*!< 下部ステータス表示: 毒耐性 */
325 #define BAR_RESNETH 29      /*!< 下部ステータス表示: 地獄耐性 */
326 #define BAR_RESTIME 30      /*!< 下部ステータス表示: 時間逆転耐性 */
327 #define BAR_DUSTROBE 31     /*!< 下部ステータス表示: 破片オーラ */
328 #define BAR_SHFIRE 32       /*!< 下部ステータス表示: 火炎オーラ */
329 #define BAR_TOUKI 33        /*!< 下部ステータス表示: 闘気 */
330 #define BAR_SHHOLY 34       /*!< 下部ステータス表示: 聖なるオーラ */
331 #define BAR_EYEEYE 35       /*!< 下部ステータス表示: 目には目を */
332 #define BAR_BLESSED 36      /*!< 下部ステータス表示: 祝福 */
333 #define BAR_HEROISM 37      /*!< 下部ステータス表示: 士気高揚 */
334 #define BAR_BERSERK 38      /*!< 下部ステータス表示: 狂戦士化 */
335 #define BAR_ATTKFIRE 39     /*!< 下部ステータス表示: 焼棄スレイ */
336 #define BAR_ATTKCOLD 40     /*!< 下部ステータス表示: 冷凍スレイ */
337 #define BAR_ATTKELEC 41     /*!< 下部ステータス表示: 電撃スレイ */
338 #define BAR_ATTKACID 42     /*!< 下部ステータス表示: 溶解スレイ */
339 #define BAR_ATTKPOIS 43     /*!< 下部ステータス表示: 毒殺スレイ */
340 #define BAR_ATTKCONF 44     /*!< 下部ステータス表示: 混乱打撃 */
341 #define BAR_SENSEUNSEEN 45  /*!< 下部ステータス表示: 透明視 */
342 #define BAR_TELEPATHY 46    /*!< 下部ステータス表示: テレパシー */
343 #define BAR_REGENERATION 47 /*!< 下部ステータス表示: 急回復 */
344 #define BAR_INFRAVISION 48  /*!< 下部ステータス表示: 赤外線視力 */
345 #define BAR_STEALTH 49      /*!< 下部ステータス表示: 隠密 */
346 #define BAR_SUPERSTEALTH 50 /*!< 下部ステータス表示: 超隠密 */
347 #define BAR_RECALL 51       /*!< 下部ステータス表示: 帰還待ち */
348 #define BAR_ALTER 52        /*!< 下部ステータス表示: 現実変容待ち */
349 #define BAR_SHCOLD 53       /*!< 下部ステータス表示: 冷気オーラ */
350 #define BAR_SHELEC 54       /*!< 下部ステータス表示: 電撃オーラ */
351 #define BAR_SHSHADOW 55     /*!< 下部ステータス表示: 影のオーラ */
352 #define BAR_MIGHT 56        /*!< 下部ステータス表示: 腕力強化 */
353 #define BAR_BUILD 57        /*!< 下部ステータス表示: 肉体強化 */
354 #define BAR_ANTIMULTI 58    /*!< 下部ステータス表示: 反増殖 */
355 #define BAR_ANTITELE 59     /*!< 下部ステータス表示: 反テレポート */
356 #define BAR_ANTIMAGIC 60    /*!< 下部ステータス表示: 反魔法 */
357 #define BAR_PATIENCE 61     /*!< 下部ステータス表示: 我慢 */
358 #define BAR_REVENGE 62      /*!< 下部ステータス表示: 宣告 */
359 #define BAR_RUNESWORD 63    /*!< 下部ステータス表示: 魔剣化 */
360 #define BAR_VAMPILIC 64     /*!< 下部ステータス表示: 吸血 */
361 #define BAR_CURE 65         /*!< 下部ステータス表示: 回復 */
362 #define BAR_ESP_EVIL 66     /*!< 下部ステータス表示: 邪悪感知 */
363
364 static struct {
365         TERM_COLOR attr;
366         concptr sstr;
367         concptr lstr;
368 } bar[]
369 #ifdef JP
370 = {
371         {TERM_YELLOW, "つ", "つよし"},
372         {TERM_VIOLET, "幻", "幻覚"},
373         {TERM_L_DARK, "盲", "盲目"},
374         {TERM_RED, "痺", "麻痺"},
375         {TERM_VIOLET, "乱", "混乱"},
376         {TERM_GREEN, "毒", "毒"},
377         {TERM_BLUE, "恐", "恐怖"},
378         {TERM_L_BLUE, "浮", "浮遊"},
379         {TERM_SLATE, "反", "反射"},
380         {TERM_SLATE, "壁", "壁抜け"},
381         {TERM_L_DARK, "幽", "幽体"},
382         {TERM_SLATE, "邪", "防邪"},
383         {TERM_VIOLET, "変", "変わり身"},
384         {TERM_YELLOW, "魔", "魔法鎧"},
385         {TERM_L_UMBER, "伸", "伸び"},
386         {TERM_WHITE, "石", "石肌"},
387         {TERM_L_BLUE, "分", "分身"},
388         {TERM_SLATE, "防", "魔法防御"},
389         {TERM_YELLOW, "究", "究極"},
390         {TERM_YELLOW, "無", "無敵"},
391         {TERM_L_GREEN, "酸", "酸免疫"},
392         {TERM_GREEN, "酸", "耐酸"},
393         {TERM_L_BLUE, "電", "電免疫"},
394         {TERM_BLUE, "電", "耐電"},
395         {TERM_L_RED, "火", "火免疫"},
396         {TERM_RED, "火", "耐火"},
397         {TERM_WHITE, "冷", "冷免疫"},
398         {TERM_SLATE, "冷", "耐冷"},
399         {TERM_GREEN, "毒", "耐毒"},
400         {TERM_L_DARK, "獄", "耐地獄"},
401         {TERM_L_BLUE, "時", "耐時間"},
402         {TERM_L_DARK, "鏡", "鏡オーラ"},
403         {TERM_L_RED, "オ", "火オーラ"},
404         {TERM_WHITE, "闘", "闘気"},
405         {TERM_WHITE, "聖", "聖オーラ"},
406         {TERM_VIOLET, "目", "目には目"},
407         {TERM_WHITE, "祝", "祝福"},
408         {TERM_WHITE, "勇", "勇"},
409         {TERM_RED, "狂", "狂乱"},
410         {TERM_L_RED, "火", "魔剣火"},
411         {TERM_WHITE, "冷", "魔剣冷"},
412         {TERM_L_BLUE, "電", "魔剣電"},
413         {TERM_SLATE, "酸", "魔剣酸"},
414         {TERM_L_GREEN, "毒", "魔剣毒"},
415         {TERM_RED, "乱", "混乱打撃"},
416         {TERM_L_BLUE, "視", "透明視"},
417         {TERM_ORANGE, "テ", "テレパシ"},
418         {TERM_L_BLUE, "回", "回復"},
419         {TERM_L_RED, "赤", "赤外"},
420         {TERM_UMBER, "隠", "隠密"},
421         {TERM_YELLOW, "隠", "超隠密"},
422         {TERM_WHITE, "帰", "帰還"},
423         {TERM_WHITE, "現", "現実変容"},
424         {TERM_WHITE, "オ", "氷オーラ"},
425         {TERM_BLUE, "オ", "電オーラ"},
426         {TERM_L_DARK, "オ", "影オーラ"},
427         {TERM_YELLOW, "腕", "腕力強化"},
428         {TERM_RED, "肉", "肉体強化"},
429         {TERM_L_DARK, "殖", "反増殖"},
430         {TERM_ORANGE, "テ", "反テレポ"},
431         {TERM_RED, "魔", "反魔法"},
432         {TERM_SLATE, "我", "我慢"},
433         {TERM_SLATE, "宣", "宣告"},
434         {TERM_L_DARK, "剣", "魔剣化"},
435         {TERM_RED, "吸", "吸血打撃"},
436         {TERM_WHITE, "回", "回復"},
437         {TERM_L_DARK, "感", "邪悪感知"},
438         {0, NULL, NULL}
439 };
440 #else
441 = {
442         {TERM_YELLOW, "Ts", "Tsuyoshi"},
443         {TERM_VIOLET, "Ha", "Halluc"},
444         {TERM_L_DARK, "Bl", "Blind"},
445         {TERM_RED, "Pa", "Paralyzed"},
446         {TERM_VIOLET, "Cf", "Confused"},
447         {TERM_GREEN, "Po", "Poisoned"},
448         {TERM_BLUE, "Af", "Afraid"},
449         {TERM_L_BLUE, "Lv", "Levit"},
450         {TERM_SLATE, "Rf", "Reflect"},
451         {TERM_SLATE, "Pw", "PassWall"},
452         {TERM_L_DARK, "Wr", "Wraith"},
453         {TERM_SLATE, "Ev", "PrtEvl"},
454         {TERM_VIOLET, "Kw", "Kawarimi"},
455         {TERM_YELLOW, "Md", "MgcArm"},
456         {TERM_L_UMBER, "Eh", "Expand"},
457         {TERM_WHITE, "Ss", "StnSkn"},
458         {TERM_L_BLUE, "Ms", "MltShdw"},
459         {TERM_SLATE, "Rm", "ResMag"},
460         {TERM_YELLOW, "Ul", "Ultima"},
461         {TERM_YELLOW, "Iv", "Invuln"},
462         {TERM_L_GREEN, "IAc", "ImmAcid"},
463         {TERM_GREEN, "Ac", "Acid"},
464         {TERM_L_BLUE, "IEl", "ImmElec"},
465         {TERM_BLUE, "El", "Elec"},
466         {TERM_L_RED, "IFi", "ImmFire"},
467         {TERM_RED, "Fi", "Fire"},
468         {TERM_WHITE, "ICo", "ImmCold"},
469         {TERM_SLATE, "Co", "Cold"},
470         {TERM_GREEN, "Po", "Pois"},
471         {TERM_L_DARK, "Nt", "Nthr"},
472         {TERM_L_BLUE, "Ti", "Time"},
473         {TERM_L_DARK, "Mr", "Mirr"},
474         {TERM_L_RED, "SFi", "SFire"},
475         {TERM_WHITE, "Fo", "Force"},
476         {TERM_WHITE, "Ho", "Holy"},
477         {TERM_VIOLET, "Ee", "EyeEye"},
478         {TERM_WHITE, "Bs", "Bless"},
479         {TERM_WHITE, "He", "Hero"},
480         {TERM_RED, "Br", "Berserk"},
481         {TERM_L_RED, "BFi", "BFire"},
482         {TERM_WHITE, "BCo", "BCold"},
483         {TERM_L_BLUE, "BEl", "BElec"},
484         {TERM_SLATE, "BAc", "BAcid"},
485         {TERM_L_GREEN, "BPo", "BPois"},
486         {TERM_RED, "TCf", "TchCnf"},
487         {TERM_L_BLUE, "Se", "SInv"},
488         {TERM_ORANGE, "Te", "Telepa"},
489         {TERM_L_BLUE, "Rg", "Regen"},
490         {TERM_L_RED, "If", "Infr"},
491         {TERM_UMBER, "Sl", "Stealth"},
492         {TERM_YELLOW, "Stlt", "Stealth"},
493         {TERM_WHITE, "Rc", "Recall"},
494         {TERM_WHITE, "Al", "Alter"},
495         {TERM_WHITE, "SCo", "SCold"},
496         {TERM_BLUE, "SEl", "SElec"},
497         {TERM_L_DARK, "SSh", "SShadow"},
498         {TERM_YELLOW, "EMi", "ExMight"},
499         {TERM_RED, "Bu", "BuildUp"},
500         {TERM_L_DARK, "AMl", "AntiMulti"},
501         {TERM_ORANGE, "AT", "AntiTele"},
502         {TERM_RED, "AM", "AntiMagic"},
503         {TERM_SLATE, "Pa", "Patience"},
504         {TERM_SLATE, "Rv", "Revenge"},
505         {TERM_L_DARK, "Rs", "RuneSword"},
506         {TERM_RED, "Vm", "Vampiric"},
507         {TERM_WHITE, "Cu", "Cure"},
508         {TERM_L_DARK, "ET", "EvilTele"},
509         {0, NULL, NULL}
510 };
511 #endif
512
513 /*!
514  * @brief 32ビット変数配列の指定位置のビットフラグを1にする。
515  * @param FLG フラグ位置(ビット)
516  * @return なし
517  */
518 #define ADD_FLG(FLG) (bar_flags[FLG / 32] |= (1L << (FLG % 32)))
519
520  /*!
521   * @brief 32ビット変数配列の指定位置のビットフラグが1かどうかを返す。
522   * @param FLG フラグ位置(ビット)
523   * @return 1ならば0以外を返す
524   */
525 #define IS_FLG(FLG) (bar_flags[FLG / 32] & (1L << (FLG % 32)))
526
527
528   /*!
529    * @brief 下部に状態表示を行う / Show status bar
530    * @return なし
531    */
532 static void print_status(player_type *creature_ptr)
533 {
534         TERM_LEN wid, hgt;
535         Term_get_size(&wid, &hgt);
536         TERM_LEN row_statbar = hgt + ROW_STATBAR;
537         TERM_LEN max_col_statbar = wid + MAX_COL_STATBAR;
538
539         Term_erase(0, row_statbar, max_col_statbar);
540
541         BIT_FLAGS bar_flags[3];
542         bar_flags[0] = bar_flags[1] = bar_flags[2] = 0L;
543
544         /* Tsuyoshi  */
545         if (creature_ptr->tsuyoshi) ADD_FLG(BAR_TSUYOSHI);
546
547         /* Hallucinating */
548         if (creature_ptr->image) ADD_FLG(BAR_HALLUCINATION);
549
550         /* Blindness */
551         if (creature_ptr->blind) ADD_FLG(BAR_BLINDNESS);
552
553         /* Paralysis */
554         if (creature_ptr->paralyzed) ADD_FLG(BAR_PARALYZE);
555
556         /* Confusion */
557         if (creature_ptr->confused) ADD_FLG(BAR_CONFUSE);
558
559         /* Posioned */
560         if (creature_ptr->poisoned) ADD_FLG(BAR_POISONED);
561
562         /* Times see-invisible */
563         if (creature_ptr->tim_invis) ADD_FLG(BAR_SENSEUNSEEN);
564
565         /* Timed esp */
566         if (is_time_limit_esp(creature_ptr)) ADD_FLG(BAR_TELEPATHY);
567
568         /* Timed regenerate */
569         if (creature_ptr->tim_regen) ADD_FLG(BAR_REGENERATION);
570
571         /* Timed infra-vision */
572         if (creature_ptr->tim_infra) ADD_FLG(BAR_INFRAVISION);
573
574         /* Protection from evil */
575         if (creature_ptr->protevil) ADD_FLG(BAR_PROTEVIL);
576
577         /* Invulnerability */
578         if (IS_INVULN(creature_ptr)) ADD_FLG(BAR_INVULN);
579
580         /* Wraith form */
581         if (creature_ptr->wraith_form) ADD_FLG(BAR_WRAITH);
582
583         /* Kabenuke */
584         if (creature_ptr->kabenuke) ADD_FLG(BAR_PASSWALL);
585
586         if (creature_ptr->tim_reflect) ADD_FLG(BAR_REFLECTION);
587
588         /* Heroism */
589         if (IS_HERO(creature_ptr)) ADD_FLG(BAR_HEROISM);
590
591         /* Super Heroism / berserk */
592         if (creature_ptr->shero) ADD_FLG(BAR_BERSERK);
593
594         /* Blessed */
595         if (is_blessed(creature_ptr)) ADD_FLG(BAR_BLESSED);
596
597         /* Shield */
598         if (creature_ptr->magicdef) ADD_FLG(BAR_MAGICDEFENSE);
599
600         if (creature_ptr->tsubureru) ADD_FLG(BAR_EXPAND);
601
602         if (creature_ptr->shield) ADD_FLG(BAR_STONESKIN);
603
604         if (creature_ptr->special_defense & NINJA_KAWARIMI) ADD_FLG(BAR_KAWARIMI);
605
606         /* Oppose Acid */
607         if (creature_ptr->special_defense & DEFENSE_ACID) ADD_FLG(BAR_IMMACID);
608         if (is_oppose_acid(creature_ptr)) ADD_FLG(BAR_RESACID);
609
610         /* Oppose Lightning */
611         if (creature_ptr->special_defense & DEFENSE_ELEC) ADD_FLG(BAR_IMMELEC);
612         if (is_oppose_elec(creature_ptr)) ADD_FLG(BAR_RESELEC);
613
614         /* Oppose Fire */
615         if (creature_ptr->special_defense & DEFENSE_FIRE) ADD_FLG(BAR_IMMFIRE);
616         if (is_oppose_fire(creature_ptr)) ADD_FLG(BAR_RESFIRE);
617
618         /* Oppose Cold */
619         if (creature_ptr->special_defense & DEFENSE_COLD) ADD_FLG(BAR_IMMCOLD);
620         if (is_oppose_cold(creature_ptr)) ADD_FLG(BAR_RESCOLD);
621
622         /* Oppose Poison */
623         if (is_oppose_pois(creature_ptr)) ADD_FLG(BAR_RESPOIS);
624
625         /* Word of Recall */
626         if (creature_ptr->word_recall) ADD_FLG(BAR_RECALL);
627
628         /* Alter realiry */
629         if (creature_ptr->alter_reality) ADD_FLG(BAR_ALTER);
630
631         /* Afraid */
632         if (creature_ptr->afraid) ADD_FLG(BAR_AFRAID);
633
634         /* Resist time */
635         if (creature_ptr->tim_res_time) ADD_FLG(BAR_RESTIME);
636
637         if (creature_ptr->multishadow) ADD_FLG(BAR_MULTISHADOW);
638
639         /* Confusing Hands */
640         if (creature_ptr->special_attack & ATTACK_CONFUSE) ADD_FLG(BAR_ATTKCONF);
641
642         if (creature_ptr->resist_magic) ADD_FLG(BAR_REGMAGIC);
643
644         /* Ultimate-resistance */
645         if (creature_ptr->ult_res) ADD_FLG(BAR_ULTIMATE);
646
647         /* tim levitation */
648         if (creature_ptr->tim_levitation) ADD_FLG(BAR_LEVITATE);
649
650         if (creature_ptr->tim_res_nether) ADD_FLG(BAR_RESNETH);
651
652         if (creature_ptr->dustrobe) ADD_FLG(BAR_DUSTROBE);
653
654         /* Mahouken */
655         if (creature_ptr->special_attack & ATTACK_FIRE) ADD_FLG(BAR_ATTKFIRE);
656         if (creature_ptr->special_attack & ATTACK_COLD) ADD_FLG(BAR_ATTKCOLD);
657         if (creature_ptr->special_attack & ATTACK_ELEC) ADD_FLG(BAR_ATTKELEC);
658         if (creature_ptr->special_attack & ATTACK_ACID) ADD_FLG(BAR_ATTKACID);
659         if (creature_ptr->special_attack & ATTACK_POIS) ADD_FLG(BAR_ATTKPOIS);
660         if (creature_ptr->special_defense & NINJA_S_STEALTH) ADD_FLG(BAR_SUPERSTEALTH);
661
662         if (creature_ptr->tim_sh_fire) ADD_FLG(BAR_SHFIRE);
663
664         /* tim stealth */
665         if (is_time_limit_stealth(creature_ptr)) ADD_FLG(BAR_STEALTH);
666
667         if (creature_ptr->tim_sh_touki) ADD_FLG(BAR_TOUKI);
668
669         /* Holy aura */
670         if (creature_ptr->tim_sh_holy) ADD_FLG(BAR_SHHOLY);
671
672         /* An Eye for an Eye */
673         if (creature_ptr->tim_eyeeye) ADD_FLG(BAR_EYEEYE);
674
675         /* Hex spells */
676         if (creature_ptr->realm1 == REALM_HEX)
677         {
678                 if (hex_spelling(creature_ptr, HEX_BLESS)) ADD_FLG(BAR_BLESSED);
679                 if (hex_spelling(creature_ptr, HEX_DEMON_AURA)) { ADD_FLG(BAR_SHFIRE); ADD_FLG(BAR_REGENERATION); }
680                 if (hex_spelling(creature_ptr, HEX_XTRA_MIGHT)) ADD_FLG(BAR_MIGHT);
681                 if (hex_spelling(creature_ptr, HEX_DETECT_EVIL)) ADD_FLG(BAR_ESP_EVIL);
682                 if (hex_spelling(creature_ptr, HEX_ICE_ARMOR)) ADD_FLG(BAR_SHCOLD);
683                 if (hex_spelling(creature_ptr, HEX_RUNESWORD)) ADD_FLG(BAR_RUNESWORD);
684                 if (hex_spelling(creature_ptr, HEX_BUILDING)) ADD_FLG(BAR_BUILD);
685                 if (hex_spelling(creature_ptr, HEX_ANTI_TELE)) ADD_FLG(BAR_ANTITELE);
686                 if (hex_spelling(creature_ptr, HEX_SHOCK_CLOAK)) ADD_FLG(BAR_SHELEC);
687                 if (hex_spelling(creature_ptr, HEX_SHADOW_CLOAK)) ADD_FLG(BAR_SHSHADOW);
688                 if (hex_spelling(creature_ptr, HEX_CONFUSION)) ADD_FLG(BAR_ATTKCONF);
689                 if (hex_spelling(creature_ptr, HEX_EYE_FOR_EYE)) ADD_FLG(BAR_EYEEYE);
690                 if (hex_spelling(creature_ptr, HEX_ANTI_MULTI)) ADD_FLG(BAR_ANTIMULTI);
691                 if (hex_spelling(creature_ptr, HEX_VAMP_BLADE)) ADD_FLG(BAR_VAMPILIC);
692                 if (hex_spelling(creature_ptr, HEX_ANTI_MAGIC)) ADD_FLG(BAR_ANTIMAGIC);
693                 if (hex_spelling(creature_ptr, HEX_CURE_LIGHT) ||
694                         hex_spelling(creature_ptr, HEX_CURE_SERIOUS) ||
695                         hex_spelling(creature_ptr, HEX_CURE_CRITICAL)) ADD_FLG(BAR_CURE);
696
697                 if (hex_revenge_turn(creature_ptr))
698                 {
699                         if (hex_revenge_type(creature_ptr) == 1) ADD_FLG(BAR_PATIENCE);
700                         if (hex_revenge_type(creature_ptr) == 2) ADD_FLG(BAR_REVENGE);
701                 }
702         }
703
704         /* Calcurate length */
705         TERM_LEN col = 0, num = 0;
706         for (int i = 0; bar[i].sstr; i++)
707         {
708                 if (IS_FLG(i))
709                 {
710                         col += strlen(bar[i].lstr) + 1;
711                         num++;
712                 }
713         }
714
715         /* If there are not excess spaces for long strings, use short one */
716         int space = 2;
717         if (col - 1 > max_col_statbar)
718         {
719                 space = 0;
720                 col = 0;
721
722                 for (int i = 0; bar[i].sstr; i++)
723                 {
724                         if (IS_FLG(i))
725                         {
726                                 col += strlen(bar[i].sstr);
727                         }
728                 }
729
730                 /* If there are excess spaces for short string, use more */
731                 if (col - 1 <= max_col_statbar - (num - 1))
732                 {
733                         space = 1;
734                         col += num - 1;
735                 }
736         }
737
738         /* Centering display column */
739         col = (max_col_statbar - col) / 2;
740
741         /* Display status bar */
742         for (int i = 0; bar[i].sstr; i++)
743         {
744                 if (!IS_FLG(i)) continue;
745
746                 concptr str;
747                 if (space == 2) str = bar[i].lstr;
748                 else str = bar[i].sstr;
749
750                 c_put_str(bar[i].attr, str, row_statbar, col);
751                 col += strlen(str);
752                 if (space > 0) col++;
753                 if (col > max_col_statbar) break;
754         }
755 }
756
757
758 /*!
759  * @brief プレイヤーの称号を表示する / Prints "title", including "wizard" or "winner" as needed.
760  * @return なし
761  */
762 static void print_title(player_type *creature_ptr)
763 {
764         GAME_TEXT str[14];
765
766         concptr p = "";
767         if (current_world_ptr->wizard)
768         {
769                 p = _("[ウィザード]", "[=-WIZARD-=]");
770         }
771         else if (current_world_ptr->total_winner || (creature_ptr->lev > PY_MAX_LEVEL))
772         {
773                 if (creature_ptr->arena_number > MAX_ARENA_MONS + 2)
774                 {
775                         p = _("*真・勝利者*", "*TRUEWINNER*");
776                 }
777                 else
778                 {
779                         p = _("***勝利者***", "***WINNER***");
780                 }
781         }
782         else
783         {
784                 angband_strcpy(str, player_title[creature_ptr->pclass][(creature_ptr->lev - 1) / 5], sizeof(str));
785                 p = str;
786         }
787
788         print_field(p, ROW_TITLE, COL_TITLE);
789 }
790
791
792 /*!
793  * @brief プレイヤーのレベルを表示する / Prints level
794  * @return なし
795  */
796 static void print_level(player_type *creature_ptr)
797 {
798         char tmp[32];
799         sprintf(tmp, "%5d", creature_ptr->lev);
800         if (creature_ptr->lev >= creature_ptr->max_plv)
801         {
802                 put_str(_("レベル ", "LEVEL "), ROW_LEVEL, 0);
803                 c_put_str(TERM_L_GREEN, tmp, ROW_LEVEL, COL_LEVEL + 7);
804         }
805         else
806         {
807                 put_str(_("xレベル", "Level "), ROW_LEVEL, 0);
808                 c_put_str(TERM_YELLOW, tmp, ROW_LEVEL, COL_LEVEL + 7);
809         }
810 }
811
812
813 /*!
814  * @brief プレイヤーの経験値を表示する / Display the experience
815  * @return なし
816  */
817 static void print_exp(player_type *creature_ptr)
818 {
819         char out_val[32];
820
821         if ((!exp_need) || (creature_ptr->prace == RACE_ANDROID))
822         {
823                 (void)sprintf(out_val, "%8ld", (long)creature_ptr->exp);
824         }
825         else
826         {
827                 if (creature_ptr->lev >= PY_MAX_LEVEL)
828                 {
829                         (void)sprintf(out_val, "********");
830                 }
831                 else
832                 {
833                         (void)sprintf(out_val, "%8ld", (long)(player_exp[creature_ptr->lev - 1] * creature_ptr->expfact / 100L) - creature_ptr->exp);
834                 }
835         }
836
837         if (creature_ptr->exp >= creature_ptr->max_exp)
838         {
839                 if (creature_ptr->prace == RACE_ANDROID) put_str(_("強化 ", "Cst "), ROW_EXP, 0);
840                 else put_str(_("経験 ", "EXP "), ROW_EXP, 0);
841                 c_put_str(TERM_L_GREEN, out_val, ROW_EXP, COL_EXP + 4);
842         }
843         else
844         {
845                 put_str(_("x経験", "Exp "), ROW_EXP, 0);
846                 c_put_str(TERM_YELLOW, out_val, ROW_EXP, COL_EXP + 4);
847         }
848 }
849
850
851 /*!
852  * @brief プレイヤーの所持金を表示する / Prints current gold
853  * @param creature_ptr プレーヤーへの参照ポインタ
854  * @return なし
855  */
856 static void print_gold(player_type *creature_ptr)
857 {
858         char tmp[32];
859         put_str(_("$ ", "AU "), ROW_GOLD, COL_GOLD);
860         sprintf(tmp, "%9ld", (long)creature_ptr->au);
861         c_put_str(TERM_L_GREEN, tmp, ROW_GOLD, COL_GOLD + 3);
862 }
863
864
865 /*!
866  * @brief プレイヤーのACを表示する / Prints current AC
867  * @return なし
868  */
869 static void print_ac(player_type *creature_ptr)
870 {
871         char tmp[32];
872
873 #ifdef JP
874         /* AC の表示方式を変更している */
875         put_str(" AC(     )", ROW_AC, COL_AC);
876         sprintf(tmp, "%5d", creature_ptr->dis_ac + creature_ptr->dis_to_a);
877         c_put_str(TERM_L_GREEN, tmp, ROW_AC, COL_AC + 6);
878 #else
879         put_str("Cur AC ", ROW_AC, COL_AC);
880         sprintf(tmp, "%5d", creature_ptr->dis_ac + creature_ptr->dis_to_a);
881         c_put_str(TERM_L_GREEN, tmp, ROW_AC, COL_AC + 7);
882 #endif
883
884 }
885
886
887 /*!
888  * @brief プレイヤーのHPを表示する / Prints Cur/Max hit points
889  * @return なし
890  */
891 static void print_hp(player_type *creature_ptr)
892 {
893         /* ヒットポイントの表示方法を変更 */
894         char tmp[32];
895
896         /* タイトル */
897         put_str("HP", ROW_CURHP, COL_CURHP);
898
899         /* 現在のヒットポイント */
900         sprintf(tmp, "%4ld", (long int)creature_ptr->chp);
901
902         TERM_COLOR color;
903         if (creature_ptr->chp >= creature_ptr->mhp)
904         {
905                 color = TERM_L_GREEN;
906         }
907         else if (creature_ptr->chp > (creature_ptr->mhp * hitpoint_warn) / 10)
908         {
909                 color = TERM_YELLOW;
910         }
911         else
912         {
913                 color = TERM_RED;
914         }
915
916         c_put_str(color, tmp, ROW_CURHP, COL_CURHP + 3);
917
918         /* 区切り */
919         put_str("/", ROW_CURHP, COL_CURHP + 7);
920
921         /* 最大ヒットポイント */
922         sprintf(tmp, "%4ld", (long int)creature_ptr->mhp);
923         color = TERM_L_GREEN;
924
925         c_put_str(color, tmp, ROW_CURHP, COL_CURHP + 8);
926 }
927
928
929 /*!
930  * @brief プレイヤーのMPを表示する / Prints players max/cur spell points
931  * @return なし
932  */
933 static void print_sp(player_type *creature_ptr)
934 {
935         /* マジックポイントの表示方法を変更している */
936         char tmp[32];
937         byte color;
938
939         /* Do not show mana unless it matters */
940         if (!mp_ptr->spell_book) return;
941
942         /* タイトル */
943         put_str(_("MP", "SP"), ROW_CURSP, COL_CURSP);
944
945         /* 現在のマジックポイント */
946         sprintf(tmp, "%4ld", (long int)creature_ptr->csp);
947
948         if (creature_ptr->csp >= creature_ptr->msp)
949         {
950                 color = TERM_L_GREEN;
951         }
952         else if (creature_ptr->csp > (creature_ptr->msp * mana_warn) / 10)
953         {
954                 color = TERM_YELLOW;
955         }
956         else
957         {
958                 color = TERM_RED;
959         }
960
961         c_put_str(color, tmp, ROW_CURSP, COL_CURSP + 3);
962
963         /* 区切り */
964         put_str("/", ROW_CURSP, COL_CURSP + 7);
965
966         /* 最大マジックポイント */
967         sprintf(tmp, "%4ld", (long int)creature_ptr->msp);
968         color = TERM_L_GREEN;
969
970         c_put_str(color, tmp, ROW_CURSP, COL_CURSP + 8);
971 }
972
973
974 /*!
975  * @brief 現在のフロアの深さを表示する / Prints depth in stat area
976  * @param creature_ptr プレーヤーへの参照ポインタ
977  * @return なし
978  */
979 static void print_depth(player_type *creature_ptr)
980 {
981         char depths[32];
982         TERM_COLOR attr = TERM_WHITE;
983
984         TERM_LEN wid, hgt;
985         Term_get_size(&wid, &hgt);
986         TERM_LEN col_depth = wid + COL_DEPTH;
987         TERM_LEN row_depth = hgt + ROW_DEPTH;
988
989         floor_type *floor_ptr = creature_ptr->current_floor_ptr;
990         if (!floor_ptr->dun_level)
991         {
992                 strcpy(depths, _("地上", "Surf."));
993                 c_prt(attr, format("%7s", depths), row_depth, col_depth);
994                 return;
995         }
996
997         if (floor_ptr->inside_quest && !creature_ptr->dungeon_idx)
998         {
999                 strcpy(depths, _("地上", "Quest"));
1000                 c_prt(attr, format("%7s", depths), row_depth, col_depth);
1001                 return;
1002         }
1003
1004         if (depth_in_feet) (void)sprintf(depths, _("%d ft", "%d ft"), (int)floor_ptr->dun_level * 50);
1005         else (void)sprintf(depths, _("%d 階", "Lev %d"), (int)floor_ptr->dun_level);
1006
1007         /* Get color of level based on feeling  -JSV- */
1008         switch (creature_ptr->feeling)
1009         {
1010         case  0: attr = TERM_SLATE;   break; /* Unknown */
1011         case  1: attr = TERM_L_BLUE;  break; /* Special */
1012         case  2: attr = TERM_VIOLET;  break; /* Horrible visions */
1013         case  3: attr = TERM_RED;     break; /* Very dangerous */
1014         case  4: attr = TERM_L_RED;   break; /* Very bad feeling */
1015         case  5: attr = TERM_ORANGE;  break; /* Bad feeling */
1016         case  6: attr = TERM_YELLOW;  break; /* Nervous */
1017         case  7: attr = TERM_L_UMBER; break; /* Luck is turning */
1018         case  8: attr = TERM_L_WHITE; break; /* Don't like */
1019         case  9: attr = TERM_WHITE;   break; /* Reasonably safe */
1020         case 10: attr = TERM_WHITE;   break; /* Boring place */
1021         }
1022
1023         c_prt(attr, format("%7s", depths), row_depth, col_depth);
1024 }
1025
1026
1027 /*!
1028  * @brief プレイヤーの空腹状態を表示する / Prints status of hunger
1029  * @param player_ptr プレーヤーへの参照ポインタ
1030  * @return なし
1031  */
1032 static void print_hunger(player_type *player_ptr)
1033 {
1034         if (current_world_ptr->wizard && player_ptr->current_floor_ptr->inside_arena) return;
1035
1036         if (player_ptr->food < PY_FOOD_FAINT)
1037         {
1038                 c_put_str(TERM_RED, _("衰弱  ", "Weak  "), ROW_HUNGRY, COL_HUNGRY);
1039                 return;
1040         }
1041
1042         if (player_ptr->food < PY_FOOD_WEAK)
1043         {
1044                 c_put_str(TERM_ORANGE, _("衰弱  ", "Weak  "), ROW_HUNGRY, COL_HUNGRY);
1045                 return;
1046         }
1047
1048         if (player_ptr->food < PY_FOOD_ALERT)
1049         {
1050                 c_put_str(TERM_YELLOW, _("空腹  ", "Hungry"), ROW_HUNGRY, COL_HUNGRY);
1051                 return;
1052         }
1053
1054         if (player_ptr->food < PY_FOOD_FULL)
1055         {
1056                 c_put_str(TERM_L_GREEN, "      ", ROW_HUNGRY, COL_HUNGRY);
1057                 return;
1058         }
1059
1060         if (player_ptr->food < PY_FOOD_MAX)
1061         {
1062                 c_put_str(TERM_L_GREEN, _("満腹  ", "Full  "), ROW_HUNGRY, COL_HUNGRY);
1063                 return;
1064         }
1065
1066         c_put_str(TERM_GREEN, _("食過ぎ", "Gorged"), ROW_HUNGRY, COL_HUNGRY);
1067 }
1068
1069
1070 /*!
1071  * @brief プレイヤーの行動状態を表示する / Prints Searching, Resting, Paralysis, or 'count' status
1072  * @param player_ptr プレーヤーへの参照ポインタ
1073  * @return なし
1074  * @details
1075  * Display is always exactly 10 characters wide (see below)
1076  * This function was a major bottleneck when resting, so a lot of
1077  * the text formatting code was optimized in place below.
1078  */
1079 static void print_state(player_type *player_ptr)
1080 {
1081         TERM_COLOR attr = TERM_WHITE;
1082         GAME_TEXT text[16];
1083
1084         /* Repeating */
1085         if (command_rep)
1086         {
1087                 if (command_rep > 999)
1088                 {
1089                         (void)sprintf(text, "%2d00", command_rep / 100);
1090                 }
1091                 else
1092                 {
1093                         (void)sprintf(text, "  %2d", command_rep);
1094                 }
1095
1096                 c_put_str(attr, format("%5.5s", text), ROW_STATE, COL_STATE);
1097                 return;
1098         }
1099
1100         /* Action */
1101         switch (player_ptr->action)
1102         {
1103         case ACTION_SEARCH:
1104         {
1105                 strcpy(text, _("探索", "Sear"));
1106                 break;
1107         }
1108         case ACTION_REST:
1109                 /* Start with "Rest" */
1110                 strcpy(text, _("    ", "    "));
1111
1112                 if (player_ptr->resting > 0)
1113                 {
1114                         sprintf(text, "%4d", player_ptr->resting);
1115                 }
1116                 else if (player_ptr->resting == COMMAND_ARG_REST_FULL_HEALING)
1117                 {
1118                         text[0] = text[1] = text[2] = text[3] = '*';
1119                 }
1120                 else if (player_ptr->resting == COMMAND_ARG_REST_UNTIL_DONE)
1121                 {
1122                         text[0] = text[1] = text[2] = text[3] = '&';
1123                 }
1124                 break;
1125
1126         case ACTION_LEARN:
1127         {
1128                 strcpy(text, _("学習", "lear"));
1129                 if (player_ptr->new_mane) attr = TERM_L_RED;
1130                 break;
1131         }
1132         case ACTION_FISH:
1133         {
1134                 strcpy(text, _("釣り", "fish"));
1135                 break;
1136         }
1137         case ACTION_KAMAE:
1138         {
1139                 int i;
1140                 for (i = 0; i < MAX_KAMAE; i++)
1141                         if (player_ptr->special_defense & (KAMAE_GENBU << i)) break;
1142                 switch (i)
1143                 {
1144                 case 0: attr = TERM_GREEN; break;
1145                 case 1: attr = TERM_WHITE; break;
1146                 case 2: attr = TERM_L_BLUE; break;
1147                 case 3: attr = TERM_L_RED; break;
1148                 }
1149                 strcpy(text, kamae_shurui[i].desc);
1150                 break;
1151         }
1152         case ACTION_KATA:
1153         {
1154                 int i;
1155                 for (i = 0; i < MAX_KATA; i++)
1156                         if (player_ptr->special_defense & (KATA_IAI << i)) break;
1157                 strcpy(text, kata_shurui[i].desc);
1158                 break;
1159         }
1160         case ACTION_SING:
1161         {
1162                 strcpy(text, _("歌  ", "Sing"));
1163                 break;
1164         }
1165         case ACTION_HAYAGAKE:
1166         {
1167                 strcpy(text, _("速駆", "Fast"));
1168                 break;
1169         }
1170         case ACTION_SPELL:
1171         {
1172                 strcpy(text, _("詠唱", "Spel"));
1173                 break;
1174         }
1175         default:
1176         {
1177                 strcpy(text, "    ");
1178                 break;
1179         }
1180         }
1181
1182         c_put_str(attr, format("%5.5s", text), ROW_STATE, COL_STATE);
1183 }
1184
1185
1186 /*!
1187  * @brief プレイヤーの行動速度を表示する / Prints the speed of a character.                      -CJS-
1188  * @param player_ptr プレーヤーへの参照ポインタ
1189  * @return なし
1190  */
1191 static void print_speed(player_type *player_ptr)
1192 {
1193         TERM_LEN wid, hgt;
1194         Term_get_size(&wid, &hgt);
1195         TERM_LEN col_speed = wid + COL_SPEED;
1196         TERM_LEN row_speed = hgt + ROW_SPEED;
1197
1198         /* Hack -- Visually "undo" the Search Mode Slowdown */
1199         int i = player_ptr->pspeed;
1200         if (player_ptr->action == ACTION_SEARCH && !player_ptr->lightspeed) i += 10;
1201
1202         /* Fast */
1203         floor_type *floor_ptr = player_ptr->current_floor_ptr;
1204         bool is_fast = IS_FAST(player_ptr);
1205         char buf[32] = "";
1206         TERM_COLOR attr = TERM_WHITE;
1207         if (i > 110)
1208         {
1209                 if (player_ptr->riding)
1210                 {
1211                         monster_type *m_ptr = &floor_ptr->m_list[player_ptr->riding];
1212                         if (monster_fast_remaining(m_ptr) && !monster_slow_remaining(m_ptr)) attr = TERM_L_BLUE;
1213                         else if (monster_slow_remaining(m_ptr) && !monster_fast_remaining(m_ptr)) attr = TERM_VIOLET;
1214                         else attr = TERM_GREEN;
1215                 }
1216                 else if ((is_fast && !player_ptr->slow) || player_ptr->lightspeed) attr = TERM_YELLOW;
1217                 else if (player_ptr->slow && !is_fast) attr = TERM_VIOLET;
1218                 else attr = TERM_L_GREEN;
1219                 sprintf(buf, "%s(+%d)", (player_ptr->riding ? _("乗馬", "Ride") : _("加速", "Fast")), (i - 110));
1220         }
1221
1222         /* Slow */
1223         else if (i < 110)
1224         {
1225                 if (player_ptr->riding)
1226                 {
1227                         monster_type *m_ptr = &floor_ptr->m_list[player_ptr->riding];
1228                         if (monster_fast_remaining(m_ptr) && !monster_slow_remaining(m_ptr)) attr = TERM_L_BLUE;
1229                         else if (monster_slow_remaining(m_ptr) && !monster_fast_remaining(m_ptr)) attr = TERM_VIOLET;
1230                         else attr = TERM_RED;
1231                 }
1232                 else if (is_fast && !player_ptr->slow) attr = TERM_YELLOW;
1233                 else if (player_ptr->slow && !is_fast) attr = TERM_VIOLET;
1234                 else attr = TERM_L_UMBER;
1235                 sprintf(buf, "%s(-%d)", (player_ptr->riding ? _("乗馬", "Ride") : _("減速", "Slow")), (110 - i));
1236         }
1237         else if (player_ptr->riding)
1238         {
1239                 attr = TERM_GREEN;
1240                 strcpy(buf, _("乗馬中", "Riding"));
1241         }
1242
1243         c_put_str(attr, format("%-9s", buf), row_speed, col_speed);
1244 }
1245
1246
1247 /*!
1248  * @brief プレイヤーの呪文学習可能状態を表示する
1249  * @param player_ptr プレーヤーへの参照ポインタ
1250  * @return なし
1251  */
1252 static void print_study(player_type *player_ptr)
1253 {
1254         TERM_LEN wid, hgt;
1255         Term_get_size(&wid, &hgt);
1256         TERM_LEN col_study = wid + COL_STUDY;
1257         TERM_LEN row_study = hgt + ROW_STUDY;
1258
1259         if (player_ptr->new_spells)
1260         {
1261                 put_str(_("学習", "Stud"), row_study, col_study);
1262         }
1263         else
1264         {
1265                 put_str("    ", row_study, col_study);
1266         }
1267 }
1268
1269
1270 /*!
1271  * @brief プレイヤーのものまね可能状態を表示する
1272  * @param player_ptr プレーヤーへの参照ポインタ
1273  * @return なし
1274  */
1275 static void print_imitation(player_type *player_ptr)
1276 {
1277         TERM_LEN wid, hgt;
1278         Term_get_size(&wid, &hgt);
1279         TERM_LEN col_study = wid + COL_STUDY;
1280         TERM_LEN row_study = hgt + ROW_STUDY;
1281
1282         if (player_ptr->pclass != CLASS_IMITATOR) return;
1283
1284         if (player_ptr->mane_num != 0)
1285         {
1286                 put_str("    ", row_study, col_study);
1287                 return;
1288         }
1289
1290         TERM_COLOR attr;
1291         if (player_ptr->new_mane) attr = TERM_L_RED;
1292         else attr = TERM_WHITE;
1293         c_put_str(attr, _("まね", "Imit"), row_study, col_study);
1294 }
1295
1296 /*!
1297  * @brief プレイヤーの負傷状態を表示する
1298  * @return なし
1299  */
1300 static void print_cut(player_type *creature_ptr)
1301 {
1302         int c = creature_ptr->cut;
1303         if (c > 1000)
1304         {
1305                 c_put_str(TERM_L_RED, _("致命傷      ", "Mortal wound"), ROW_CUT, COL_CUT);
1306                 return;
1307         }
1308
1309         if (c > 200)
1310         {
1311                 c_put_str(TERM_RED, _("ひどい深手  ", "Deep gash   "), ROW_CUT, COL_CUT);
1312                 return;
1313         }
1314
1315         if (c > 100)
1316         {
1317                 c_put_str(TERM_RED, _("重傷        ", "Severe cut  "), ROW_CUT, COL_CUT);
1318                 return;
1319         }
1320
1321         if (c > 50)
1322         {
1323                 c_put_str(TERM_ORANGE, _("大変な傷    ", "Nasty cut   "), ROW_CUT, COL_CUT);
1324                 return;
1325         }
1326
1327         if (c > 25)
1328         {
1329                 c_put_str(TERM_ORANGE, _("ひどい傷    ", "Bad cut     "), ROW_CUT, COL_CUT);
1330                 return;
1331         }
1332
1333         if (c > 10)
1334         {
1335                 c_put_str(TERM_YELLOW, _("軽傷        ", "Light cut   "), ROW_CUT, COL_CUT);
1336                 return;
1337         }
1338
1339         if (c)
1340         {
1341                 c_put_str(TERM_YELLOW, _("かすり傷    ", "Graze       "), ROW_CUT, COL_CUT);
1342                 return;
1343         }
1344
1345         put_str("            ", ROW_CUT, COL_CUT);
1346 }
1347
1348
1349 /*!
1350  * @brief プレイヤーの朦朧状態を表示する
1351  * @return なし
1352  */
1353 static void print_stun(player_type *creature_ptr)
1354 {
1355         int s = creature_ptr->stun;
1356         if (s > 100)
1357         {
1358                 c_put_str(TERM_RED, _("意識不明瞭  ", "Knocked out "), ROW_STUN, COL_STUN);
1359                 return;
1360         }
1361
1362         if (s > 50)
1363         {
1364                 c_put_str(TERM_ORANGE, _("ひどく朦朧  ", "Heavy stun  "), ROW_STUN, COL_STUN);
1365                 return;
1366         }
1367
1368         if (s)
1369         {
1370                 c_put_str(TERM_ORANGE, _("朦朧        ", "Stun        "), ROW_STUN, COL_STUN);
1371                 return;
1372         }
1373
1374         put_str("            ", ROW_STUN, COL_STUN);
1375 }
1376
1377
1378 /*!
1379  * @brief モンスターの体力ゲージを表示する
1380  * @param riding TRUEならば騎乗中のモンスターの体力、FALSEならターゲットモンスターの体力を表示する。表示位置は固定。
1381  * @return なし
1382  * @details
1383  * <pre>
1384  * Redraw the "monster health bar"      -DRS-
1385  * Rather extensive modifications by    -BEN-
1386  *
1387  * The "monster health bar" provides visual feedback on the "health"
1388  * of the monster currently being "tracked".  There are several ways
1389  * to "track" a monster, including targetting it, attacking it, and
1390  * affecting it (and nobody else) with a ranged attack.
1391  *
1392  * Display the monster health bar (affectionately known as the
1393  * "health-o-meter").  Clear health bar if nothing is being tracked.
1394  * Auto-track current target monster when bored.  Note that the
1395  * health-bar stops tracking any monster that "disappears".
1396  * </pre>
1397  */
1398 static void health_redraw(player_type *creature_ptr, bool riding)
1399 {
1400         s16b health_who;
1401         int row, col;
1402
1403         if (riding)
1404         {
1405                 health_who = creature_ptr->riding;
1406                 row = ROW_RIDING_INFO;
1407                 col = COL_RIDING_INFO;
1408         }
1409         else
1410         {
1411                 health_who = creature_ptr->health_who;
1412                 row = ROW_INFO;
1413                 col = COL_INFO;
1414         }
1415
1416         monster_type *m_ptr;
1417         m_ptr = &creature_ptr->current_floor_ptr->m_list[health_who];
1418
1419         if (current_world_ptr->wizard && creature_ptr->phase_out)
1420         {
1421                 row = ROW_INFO - 2;
1422                 col = COL_INFO + 2;
1423
1424                 Term_putstr(col - 2, row, 12, TERM_WHITE, "      /     ");
1425                 Term_putstr(col - 2, row + 1, 12, TERM_WHITE, "      /     ");
1426                 Term_putstr(col - 2, row + 2, 12, TERM_WHITE, "      /     ");
1427                 Term_putstr(col - 2, row + 3, 12, TERM_WHITE, "      /     ");
1428
1429                 if (creature_ptr->current_floor_ptr->m_list[1].r_idx)
1430                 {
1431                         Term_putstr(col - 2, row, 2, r_info[creature_ptr->current_floor_ptr->m_list[1].r_idx].x_attr, format("%c", r_info[creature_ptr->current_floor_ptr->m_list[1].r_idx].x_char));
1432                         Term_putstr(col - 1, row, 5, TERM_WHITE, format("%5d", creature_ptr->current_floor_ptr->m_list[1].hp));
1433                         Term_putstr(col + 5, row, 6, TERM_WHITE, format("%5d", creature_ptr->current_floor_ptr->m_list[1].max_maxhp));
1434                 }
1435
1436                 if (creature_ptr->current_floor_ptr->m_list[2].r_idx)
1437                 {
1438                         Term_putstr(col - 2, row + 1, 2, r_info[creature_ptr->current_floor_ptr->m_list[2].r_idx].x_attr, format("%c", r_info[creature_ptr->current_floor_ptr->m_list[2].r_idx].x_char));
1439                         Term_putstr(col - 1, row + 1, 5, TERM_WHITE, format("%5d", creature_ptr->current_floor_ptr->m_list[2].hp));
1440                         Term_putstr(col + 5, row + 1, 6, TERM_WHITE, format("%5d", creature_ptr->current_floor_ptr->m_list[2].max_maxhp));
1441                 }
1442
1443                 if (creature_ptr->current_floor_ptr->m_list[3].r_idx)
1444                 {
1445                         Term_putstr(col - 2, row + 2, 2, r_info[creature_ptr->current_floor_ptr->m_list[3].r_idx].x_attr, format("%c", r_info[creature_ptr->current_floor_ptr->m_list[3].r_idx].x_char));
1446                         Term_putstr(col - 1, row + 2, 5, TERM_WHITE, format("%5d", creature_ptr->current_floor_ptr->m_list[3].hp));
1447                         Term_putstr(col + 5, row + 2, 6, TERM_WHITE, format("%5d", creature_ptr->current_floor_ptr->m_list[3].max_maxhp));
1448                 }
1449
1450                 if (creature_ptr->current_floor_ptr->m_list[4].r_idx)
1451                 {
1452                         Term_putstr(col - 2, row + 3, 2, r_info[creature_ptr->current_floor_ptr->m_list[4].r_idx].x_attr, format("%c", r_info[creature_ptr->current_floor_ptr->m_list[4].r_idx].x_char));
1453                         Term_putstr(col - 1, row + 3, 5, TERM_WHITE, format("%5d", creature_ptr->current_floor_ptr->m_list[4].hp));
1454                         Term_putstr(col + 5, row + 3, 6, TERM_WHITE, format("%5d", creature_ptr->current_floor_ptr->m_list[4].max_maxhp));
1455                 }
1456
1457                 return;
1458         }
1459
1460         /* Not tracking */
1461         if (!health_who)
1462         {
1463                 /* Erase the health bar */
1464                 Term_erase(col, row, 12);
1465                 return;
1466         }
1467
1468         /* Tracking an unseen monster */
1469         if (!m_ptr->ml)
1470         {
1471                 /* Indicate that the monster health is "unknown" */
1472                 Term_putstr(col, row, 12, TERM_WHITE, "[----------]");
1473                 return;
1474         }
1475
1476         /* Tracking a hallucinatory monster */
1477         if (creature_ptr->image)
1478         {
1479                 /* Indicate that the monster health is "unknown" */
1480                 Term_putstr(col, row, 12, TERM_WHITE, "[----------]");
1481                 return;
1482         }
1483
1484         /* Tracking a dead monster (???) */
1485         if (m_ptr->hp < 0)
1486         {
1487                 /* Indicate that the monster health is "unknown" */
1488                 Term_putstr(col, row, 12, TERM_WHITE, "[----------]");
1489                 return;
1490         }
1491
1492         /* Tracking a visible monster */
1493         /* Extract the "percent" of health */
1494         int pct = m_ptr->maxhp > 0 ? 100L * m_ptr->hp / m_ptr->maxhp : 0;
1495         int pct2 = m_ptr->maxhp > 0 ? 100L * m_ptr->hp / m_ptr->max_maxhp : 0;
1496
1497         /* Convert percent into "health" */
1498         int len = (pct2 < 10) ? 1 : (pct2 < 90) ? (pct2 / 10 + 1) : 10;
1499
1500         /* Default to almost dead */
1501         TERM_COLOR attr = TERM_RED;
1502
1503         /* Invulnerable */
1504         if (monster_invulner_remaining(m_ptr)) attr = TERM_WHITE;
1505
1506         /* Asleep */
1507         else if (monster_csleep_remaining(m_ptr)) attr = TERM_BLUE;
1508
1509         /* Afraid */
1510         else if (monster_fear_remaining(m_ptr)) attr = TERM_VIOLET;
1511
1512         /* Healthy */
1513         else if (pct >= 100) attr = TERM_L_GREEN;
1514
1515         /* Somewhat Wounded */
1516         else if (pct >= 60) attr = TERM_YELLOW;
1517
1518         /* Wounded */
1519         else if (pct >= 25) attr = TERM_ORANGE;
1520
1521         /* Badly wounded */
1522         else if (pct >= 10) attr = TERM_L_RED;
1523
1524         /* Default to "unknown" */
1525         Term_putstr(col, row, 12, TERM_WHITE, "[----------]");
1526
1527         /* Dump the current "health" (use '*' symbols) */
1528         Term_putstr(col + 1, row, len, attr, "**********");
1529 }
1530
1531
1532
1533 /*!
1534  * @brief プレイヤーのステータスを一括表示する(左側部分) / Display basic info (mostly left of map)
1535  * @param creature_ptr プレーヤーへの参照ポインタ
1536  * @return なし
1537  */
1538 static void print_frame_basic(player_type *creature_ptr)
1539 {
1540         if (creature_ptr->mimic_form)
1541         {
1542                 print_field(mimic_info[creature_ptr->mimic_form].title, ROW_RACE, COL_RACE);
1543         }
1544         else
1545         {
1546                 char str[14];
1547                 angband_strcpy(str, rp_ptr->title, sizeof(str));
1548                 print_field(str, ROW_RACE, COL_RACE);
1549         }
1550
1551         print_title(creature_ptr);
1552         print_level(creature_ptr);
1553         print_exp(creature_ptr);
1554         for (int i = 0; i < A_MAX; i++)
1555                 print_stat(creature_ptr, i);
1556         print_ac(creature_ptr);
1557         print_hp(creature_ptr);
1558         print_sp(creature_ptr);
1559         print_gold(creature_ptr);
1560         print_depth(creature_ptr);
1561         health_redraw(creature_ptr, FALSE);
1562         health_redraw(creature_ptr, TRUE);
1563 }
1564
1565
1566 /*!
1567  * @brief プレイヤーのステータスを一括表示する(下部分) / Display extra info (mostly below map)
1568  * @param player_ptr プレーヤーへの参照ポインタ
1569  * @return なし
1570  */
1571 static void print_frame_extra(player_type *player_ptr)
1572 {
1573         print_cut(player_ptr);
1574         print_stun(player_ptr);
1575         print_hunger(player_ptr);
1576         print_state(player_ptr);
1577         print_speed(player_ptr);
1578         print_study(player_ptr);
1579         print_imitation(player_ptr);
1580         print_status(player_ptr);
1581 }
1582
1583
1584 /*!
1585  * @brief サブウィンドウに所持品一覧を表示する / Hack -- display inventory in sub-windows
1586  * @param player_ptr プレーヤーへの参照ポインタ
1587  * @return なし
1588  */
1589 static void fix_inventory(player_type *player_ptr, tval_type item_tester_tval)
1590 {
1591         /* Scan windows */
1592         for (int j = 0; j < 8; j++)
1593         {
1594                 term *old = Term;
1595
1596                 /* No window */
1597                 if (!angband_term[j]) continue;
1598
1599                 /* No relevant flags */
1600                 if (!(window_flag[j] & (PW_INVEN))) continue;
1601
1602                 /* Activate */
1603                 Term_activate(angband_term[j]);
1604
1605                 display_inventory(player_ptr, item_tester_tval);
1606                 Term_fresh();
1607                 Term_activate(old);
1608         }
1609 }
1610
1611
1612 /*!
1613  * @brief モンスターの現在数を一行で表現する / Print monster info in line
1614  * @param x 表示列
1615  * @param y 表示行
1616  * @param m_ptr 思い出を表示するモンスター情報の参照ポインタ
1617  * @param n_same モンスターの数の現在数
1618  * @details
1619  * <pre>
1620  * nnn X LV name
1621  *  nnn : number or unique(U) or wanted unique(W)
1622  *  X   : symbol of monster
1623  *  LV  : monster lv if known
1624  *  name: name of monster
1625  * @return なし
1626  * </pre>
1627  */
1628 static void print_monster_line(TERM_LEN x, TERM_LEN y, monster_type* m_ptr, int n_same) {
1629         char buf[256];
1630         MONRACE_IDX r_idx = m_ptr->ap_r_idx;
1631         monster_race* r_ptr = &r_info[r_idx];
1632
1633         Term_gotoxy(x, y);
1634         if (!r_ptr)return;
1635         //Number of 'U'nique
1636         //unique
1637         if (r_ptr->flags1 & RF1_UNIQUE)
1638         {
1639                 bool is_bounty = FALSE;
1640                 for (int i = 0; i < MAX_BOUNTY; i++)
1641                 {
1642                         if (current_world_ptr->bounty_r_idx[i] == r_idx)
1643                         {
1644                                 is_bounty = TRUE;
1645                                 break;
1646                         }
1647                 }
1648
1649                 Term_addstr(-1, TERM_WHITE, is_bounty ? "  W" : "  U");
1650         }
1651         else
1652         {
1653                 sprintf(buf, "%3d", n_same);
1654                 Term_addstr(-1, TERM_WHITE, buf);
1655         }
1656
1657         //symbol
1658         Term_addstr(-1, TERM_WHITE, " ");
1659         Term_add_bigch(r_ptr->x_attr, r_ptr->x_char);
1660
1661         //LV
1662         if (r_ptr->r_tkills && !(m_ptr->mflag2 & MFLAG2_KAGE))
1663         {
1664                 sprintf(buf, " %2d", (int)r_ptr->level);
1665         }
1666         else
1667         {
1668                 strcpy(buf, " ??");
1669         }
1670
1671         Term_addstr(-1, TERM_WHITE, buf);
1672
1673         //name
1674         sprintf(buf, " %s ", r_name + r_ptr->name);
1675         Term_addstr(-1, TERM_WHITE, buf);
1676 }
1677
1678
1679 /*!
1680  * @brief モンスターの出現リストを表示する / Print monster info in line
1681  * @param x 表示列
1682  * @param y 表示行
1683  * @param max_lines 最大何行描画するか
1684  */
1685 void print_monster_list(floor_type *floor_ptr, TERM_LEN x, TERM_LEN y, TERM_LEN max_lines) {
1686         TERM_LEN line = y;
1687         monster_type* last_mons = NULL;
1688         monster_type* m_ptr = NULL;
1689         int n_same = 0;
1690         int i;
1691         for (i = 0; i < tmp_pos.n; i++)
1692         {
1693                 grid_type* g_ptr = &floor_ptr->grid_array[tmp_pos.y[i]][tmp_pos.x[i]];
1694                 if (!g_ptr->m_idx || !floor_ptr->m_list[g_ptr->m_idx].ml)
1695                         continue;//no mons or cannot look
1696                 m_ptr = &floor_ptr->m_list[g_ptr->m_idx];
1697                 if (is_pet(m_ptr)) continue;//pet
1698                 if (!m_ptr->r_idx) continue;//dead?
1699
1700                 //ソート済みなので同じモンスターは連続する.これを利用して同じモンスターをカウント,まとめて表示する.
1701
1702                 //先頭モンスター
1703                 if (!last_mons)
1704                 {
1705                         last_mons = m_ptr;
1706                         n_same = 1;
1707                         continue;
1708                 }
1709
1710                 //same race?
1711                 if (last_mons->ap_r_idx == m_ptr->ap_r_idx)
1712                 {
1713                         n_same++;
1714                         continue;//表示処理を次に回す
1715                 }
1716
1717                 //print last mons info
1718                 print_monster_line(x, line++, last_mons, n_same);
1719                 n_same = 1;
1720                 last_mons = m_ptr;
1721                 if (line - y - 1 == max_lines) break;
1722         }
1723
1724         if (line - y - 1 == max_lines && i != tmp_pos.n)
1725         {
1726                 Term_gotoxy(x, line);
1727                 Term_addstr(-1, TERM_WHITE, "-- and more --");
1728         }
1729         else
1730         {
1731                 if (last_mons)
1732                         print_monster_line(x, line++, last_mons, n_same);
1733         }
1734 }
1735
1736
1737 /*!
1738  * @brief 出現中モンスターのリストをサブウィンドウに表示する / Hack -- display monster list in sub-windows
1739  * @param player_ptr プレーヤーへの参照ポインタ
1740  * @return なし
1741  */
1742 static void fix_monster_list(player_type *player_ptr)
1743 {
1744         /* Scan windows */
1745         for (int j = 0; j < 8; j++)
1746         {
1747                 term *old = Term;
1748
1749                 /* No window */
1750                 if (!angband_term[j]) continue;
1751
1752                 /* No relevant flags */
1753                 if (!(window_flag[j] & (PW_MONSTER_LIST))) continue;
1754
1755                 /* Activate */
1756                 Term_activate(angband_term[j]);
1757                 int w, h;
1758                 Term_get_size(&w, &h);
1759
1760                 Term_clear();
1761
1762                 target_set_prepare_look(player_ptr);//モンスター一覧を生成,ソート
1763                 print_monster_list(player_ptr->current_floor_ptr, 0, 0, h);
1764                 Term_fresh();
1765                 Term_activate(old);
1766         }
1767 }
1768
1769
1770 /*!
1771  * @brief 現在の装備品をサブウィンドウに表示する /
1772  * Hack -- display equipment in sub-windows
1773  * @param player_ptr プレーヤーへの参照ポインタ
1774  * @return なし
1775  */
1776 static void fix_equip(player_type *player_ptr, tval_type item_tester_tval)
1777 {
1778         /* Scan windows */
1779         for (int j = 0; j < 8; j++)
1780         {
1781                 term *old = Term;
1782
1783                 /* No window */
1784                 if (!angband_term[j]) continue;
1785
1786                 /* No relevant flags */
1787                 if (!(window_flag[j] & (PW_EQUIP))) continue;
1788
1789                 /* Activate */
1790                 Term_activate(angband_term[j]);
1791
1792                 /* Display equipment */
1793                 display_equipment(player_ptr, item_tester_tval);
1794                 Term_fresh();
1795                 Term_activate(old);
1796         }
1797 }
1798
1799
1800 /*!
1801  * @brief 現在の習得済魔法をサブウィンドウに表示する /
1802  * @param player_ptr プレーヤーへの参照ポインタ
1803  * Hack -- display spells in sub-windows
1804  * @return なし
1805  */
1806 static void fix_spell(player_type *player_ptr)
1807 {
1808         /* Scan windows */
1809         for (int j = 0; j < 8; j++)
1810         {
1811                 term *old = Term;
1812
1813                 /* No window */
1814                 if (!angband_term[j]) continue;
1815
1816                 /* No relevant flags */
1817                 if (!(window_flag[j] & (PW_SPELL))) continue;
1818
1819                 /* Activate */
1820                 Term_activate(angband_term[j]);
1821
1822                 /* Display spell list */
1823                 display_spell_list(player_ptr);
1824                 Term_fresh();
1825                 Term_activate(old);
1826         }
1827 }
1828
1829
1830 /*!
1831  * @brief 現在のプレイヤーステータスをサブウィンドウに表示する /
1832  * @param player_ptr プレーヤーへの参照ポインタ
1833  * Hack -- display character in sub-windows
1834  * @return なし
1835  */
1836 static void fix_player(player_type *player_ptr)
1837 {
1838         /* Scan windows */
1839         for (int j = 0; j < 8; j++)
1840         {
1841                 term *old = Term;
1842
1843                 /* No window */
1844                 if (!angband_term[j]) continue;
1845
1846                 /* No relevant flags */
1847                 if (!(window_flag[j] & (PW_PLAYER))) continue;
1848
1849                 /* Activate */
1850                 Term_activate(angband_term[j]);
1851
1852                 update_playtime();
1853                 display_player(player_ptr, 0, map_name);
1854                 Term_fresh();
1855                 Term_activate(old);
1856         }
1857 }
1858
1859
1860 /*!
1861  * @brief ゲームメッセージ履歴をサブウィンドウに表示する /
1862  * Hack -- display recent messages in sub-windows
1863  * Adjust for width and split messages
1864  * @return なし
1865  */
1866 static void fix_message(void)
1867 {
1868         /* Scan windows */
1869         for (int j = 0; j < 8; j++)
1870         {
1871                 term *old = Term;
1872
1873                 /* No window */
1874                 if (!angband_term[j]) continue;
1875
1876                 /* No relevant flags */
1877                 if (!(window_flag[j] & (PW_MESSAGE))) continue;
1878
1879                 /* Activate */
1880                 Term_activate(angband_term[j]);
1881
1882                 TERM_LEN w, h;
1883                 Term_get_size(&w, &h);
1884
1885                 /* Dump messages */
1886                 for (int i = 0; i < h; i++)
1887                 {
1888                         /* Dump the message on the appropriate line */
1889                         Term_putstr(0, (h - 1) - i, -1, (byte)((i < now_message) ? TERM_WHITE : TERM_SLATE), message_str((s16b)i));
1890
1891                         /* Cursor */
1892                         TERM_LEN x, y;
1893                         Term_locate(&x, &y);
1894
1895                         /* Clear to end of line */
1896                         Term_erase(x, y, 255);
1897                 }
1898
1899                 Term_fresh();
1900                 Term_activate(old);
1901         }
1902 }
1903
1904
1905 /*!
1906  * @brief 簡易マップをサブウィンドウに表示する /
1907  * Hack -- display overhead view in sub-windows
1908  * Adjust for width and split messages
1909  * @param player_ptr プレーヤーへの参照ポインタ
1910  * @return なし
1911  * @details
1912  * Note that the "player" symbol does NOT appear on the map.
1913  */
1914 static void fix_overhead(player_type *player_ptr)
1915 {
1916         /* Scan windows */
1917         for (int j = 0; j < 8; j++)
1918         {
1919                 term *old = Term;
1920                 TERM_LEN wid, hgt;
1921
1922                 /* No window */
1923                 if (!angband_term[j]) continue;
1924
1925                 /* No relevant flags */
1926                 if (!(window_flag[j] & (PW_OVERHEAD))) continue;
1927
1928                 /* Activate */
1929                 Term_activate(angband_term[j]);
1930
1931                 /* Full map in too small window is useless  */
1932                 Term_get_size(&wid, &hgt);
1933                 if (wid > COL_MAP + 2 && hgt > ROW_MAP + 2)
1934                 {
1935                         int cy, cx;
1936                         display_map(player_ptr, &cy, &cx);
1937                         Term_fresh();
1938                 }
1939
1940                 Term_activate(old);
1941         }
1942 }
1943
1944 static void display_dungeon(player_type *player_ptr)
1945 {
1946         TERM_COLOR ta = 0;
1947         SYMBOL_CODE tc = '\0';
1948
1949         for (TERM_LEN x = player_ptr->x - Term->wid / 2 + 1; x <= player_ptr->x + Term->wid / 2; x++)
1950         {
1951                 for (TERM_LEN y = player_ptr->y - Term->hgt / 2 + 1; y <= player_ptr->y + Term->hgt / 2; y++)
1952                 {
1953                         TERM_COLOR a;
1954                         SYMBOL_CODE c;
1955                         if (!in_bounds2(player_ptr->current_floor_ptr, y, x))
1956                         {
1957                                 feature_type *f_ptr = &f_info[feat_none];
1958                                 a = f_ptr->x_attr[F_LIT_STANDARD];
1959                                 c = f_ptr->x_char[F_LIT_STANDARD];
1960                                 Term_queue_char(x - player_ptr->x + Term->wid / 2 - 1, y - player_ptr->y + Term->hgt / 2 - 1, a, c, ta, tc);
1961                                 continue;
1962                         }
1963
1964                         map_info(player_ptr, y, x, &a, &c, &ta, &tc);
1965
1966                         if (!use_graphics)
1967                         {
1968                                 if (current_world_ptr->timewalk_m_idx) a = TERM_DARK;
1969                                 else if (IS_INVULN(player_ptr) || player_ptr->timewalk) a = TERM_WHITE;
1970                                 else if (player_ptr->wraith_form) a = TERM_L_DARK;
1971                         }
1972
1973                         Term_queue_char(x - player_ptr->x + Term->wid / 2 - 1, y - player_ptr->y + Term->hgt / 2 - 1, a, c, ta, tc);
1974                 }
1975         }
1976 }
1977
1978 /*!
1979  * @brief ダンジョンの地形をサブウィンドウに表示する /
1980  * Hack -- display dungeon view in sub-windows
1981  * @param player_ptr プレーヤーへの参照ポインタ
1982  * @return なし
1983  */
1984 static void fix_dungeon(player_type *player_ptr)
1985 {
1986         /* Scan windows */
1987         for (int j = 0; j < 8; j++)
1988         {
1989                 term *old = Term;
1990
1991                 /* No window */
1992                 if (!angband_term[j]) continue;
1993
1994                 /* No relevant flags */
1995                 if (!(window_flag[j] & (PW_DUNGEON))) continue;
1996
1997                 /* Activate */
1998                 Term_activate(angband_term[j]);
1999
2000                 /* Redraw dungeon view */
2001                 display_dungeon(player_ptr);
2002                 Term_fresh();
2003                 Term_activate(old);
2004         }
2005 }
2006
2007
2008 /*!
2009  * @brief モンスターの思い出をサブウィンドウに表示する /
2010  * Hack -- display dungeon view in sub-windows
2011  * @param player_ptr プレーヤーへの参照ポインタ
2012  * @return なし
2013  */
2014 static void fix_monster(player_type *player_ptr)
2015 {
2016         /* Scan windows */
2017         for (int j = 0; j < 8; j++)
2018         {
2019                 term *old = Term;
2020
2021                 /* No window */
2022                 if (!angband_term[j]) continue;
2023
2024                 /* No relevant flags */
2025                 if (!(window_flag[j] & (PW_MONSTER))) continue;
2026
2027                 /* Activate */
2028                 Term_activate(angband_term[j]);
2029
2030                 /* Display monster race info */
2031                 if (player_ptr->monster_race_idx) display_roff(player_ptr);
2032                 Term_fresh();
2033                 Term_activate(old);
2034         }
2035 }
2036
2037
2038 /*!
2039  * @brief ベースアイテム情報をサブウィンドウに表示する /
2040  * Hack -- display object recall in sub-windows
2041  * @param player_ptr プレーヤーへの参照ポインタ
2042  * @return なし
2043  */
2044 static void fix_object(player_type *player_ptr)
2045 {
2046         /* Scan windows */
2047         for (int j = 0; j < 8; j++)
2048         {
2049                 term *old = Term;
2050
2051                 /* No window */
2052                 if (!angband_term[j]) continue;
2053
2054                 /* No relevant flags */
2055                 if (!(window_flag[j] & (PW_OBJECT))) continue;
2056
2057                 /* Activate */
2058                 Term_activate(angband_term[j]);
2059
2060                 /* Display monster race info */
2061                 if (player_ptr->object_kind_idx) display_koff(player_ptr, player_ptr->object_kind_idx);
2062                 Term_fresh();
2063                 Term_activate(old);
2064         }
2065 }
2066
2067
2068 /*!
2069  * @brief 射撃武器がプレイヤーにとって重すぎるかどうかの判定 /
2070  * @param o_ptr 判定する射撃武器のアイテム情報参照ポインタ
2071  * @return 重すぎるならばTRUE
2072  */
2073 bool is_heavy_shoot(player_type *creature_ptr, object_type *o_ptr)
2074 {
2075         int hold = adj_str_hold[creature_ptr->stat_ind[A_STR]];
2076         /* It is hard to carholdry a heavy bow */
2077         return (hold < o_ptr->weight / 10);
2078 }
2079
2080
2081 /*!
2082  * @brief redraw のフラグに応じた更新をまとめて行う / Handle "redraw"
2083  * @return なし
2084  * @details 更新処理の対象はゲーム中の全描画処理
2085  */
2086 void redraw_stuff(player_type *creature_ptr)
2087 {
2088         if (!creature_ptr->redraw) return;
2089
2090         /* Character is not ready yet, no screen updates */
2091         if (!current_world_ptr->character_generated) return;
2092
2093         /* Character is in "icky" mode, no screen updates */
2094         if (current_world_ptr->character_icky) return;
2095
2096         /* Hack -- clear the screen */
2097         if (creature_ptr->redraw & (PR_WIPE))
2098         {
2099                 creature_ptr->redraw &= ~(PR_WIPE);
2100                 msg_print(NULL);
2101                 Term_clear();
2102         }
2103
2104         if (creature_ptr->redraw & (PR_MAP))
2105         {
2106                 creature_ptr->redraw &= ~(PR_MAP);
2107                 print_map(creature_ptr);
2108         }
2109
2110         if (creature_ptr->redraw & (PR_BASIC))
2111         {
2112                 creature_ptr->redraw &= ~(PR_BASIC);
2113                 creature_ptr->redraw &= ~(PR_MISC | PR_TITLE | PR_STATS);
2114                 creature_ptr->redraw &= ~(PR_LEV | PR_EXP | PR_GOLD);
2115                 creature_ptr->redraw &= ~(PR_ARMOR | PR_HP | PR_MANA);
2116                 creature_ptr->redraw &= ~(PR_DEPTH | PR_HEALTH | PR_UHEALTH);
2117                 print_frame_basic(creature_ptr);
2118                 print_time(creature_ptr);
2119                 print_dungeon(creature_ptr);
2120         }
2121
2122         if (creature_ptr->redraw & (PR_EQUIPPY))
2123         {
2124                 creature_ptr->redraw &= ~(PR_EQUIPPY);
2125                 print_equippy(creature_ptr); /* To draw / delete equippy chars */
2126         }
2127
2128         if (creature_ptr->redraw & (PR_MISC))
2129         {
2130                 creature_ptr->redraw &= ~(PR_MISC);
2131                 print_field(rp_ptr->title, ROW_RACE, COL_RACE);
2132         }
2133
2134         if (creature_ptr->redraw & (PR_TITLE))
2135         {
2136                 creature_ptr->redraw &= ~(PR_TITLE);
2137                 print_title(creature_ptr);
2138         }
2139
2140         if (creature_ptr->redraw & (PR_LEV))
2141         {
2142                 creature_ptr->redraw &= ~(PR_LEV);
2143                 print_level(creature_ptr);
2144         }
2145
2146         if (creature_ptr->redraw & (PR_EXP))
2147         {
2148                 creature_ptr->redraw &= ~(PR_EXP);
2149                 print_exp(creature_ptr);
2150         }
2151
2152         if (creature_ptr->redraw & (PR_STATS))
2153         {
2154                 creature_ptr->redraw &= ~(PR_STATS);
2155                 print_stat(creature_ptr, A_STR);
2156                 print_stat(creature_ptr, A_INT);
2157                 print_stat(creature_ptr, A_WIS);
2158                 print_stat(creature_ptr, A_DEX);
2159                 print_stat(creature_ptr, A_CON);
2160                 print_stat(creature_ptr, A_CHR);
2161         }
2162
2163         if (creature_ptr->redraw & (PR_STATUS))
2164         {
2165                 creature_ptr->redraw &= ~(PR_STATUS);
2166                 print_status(creature_ptr);
2167         }
2168
2169         if (creature_ptr->redraw & (PR_ARMOR))
2170         {
2171                 creature_ptr->redraw &= ~(PR_ARMOR);
2172                 print_ac(creature_ptr);
2173         }
2174
2175         if (creature_ptr->redraw & (PR_HP))
2176         {
2177                 creature_ptr->redraw &= ~(PR_HP);
2178                 print_hp(creature_ptr);
2179         }
2180
2181         if (creature_ptr->redraw & (PR_MANA))
2182         {
2183                 creature_ptr->redraw &= ~(PR_MANA);
2184                 print_sp(creature_ptr);
2185         }
2186
2187         if (creature_ptr->redraw & (PR_GOLD))
2188         {
2189                 creature_ptr->redraw &= ~(PR_GOLD);
2190                 print_gold(creature_ptr);
2191         }
2192
2193         if (creature_ptr->redraw & (PR_DEPTH))
2194         {
2195                 creature_ptr->redraw &= ~(PR_DEPTH);
2196                 print_depth(creature_ptr);
2197         }
2198
2199         if (creature_ptr->redraw & (PR_HEALTH))
2200         {
2201                 creature_ptr->redraw &= ~(PR_HEALTH);
2202                 health_redraw(creature_ptr, FALSE);
2203         }
2204
2205         if (creature_ptr->redraw & (PR_UHEALTH))
2206         {
2207                 creature_ptr->redraw &= ~(PR_UHEALTH);
2208                 health_redraw(creature_ptr, TRUE);
2209         }
2210
2211         if (creature_ptr->redraw & (PR_EXTRA))
2212         {
2213                 creature_ptr->redraw &= ~(PR_EXTRA);
2214                 creature_ptr->redraw &= ~(PR_CUT | PR_STUN);
2215                 creature_ptr->redraw &= ~(PR_HUNGER);
2216                 creature_ptr->redraw &= ~(PR_STATE | PR_SPEED | PR_STUDY | PR_IMITATION | PR_STATUS);
2217                 print_frame_extra(creature_ptr);
2218         }
2219
2220         if (creature_ptr->redraw & (PR_CUT))
2221         {
2222                 creature_ptr->redraw &= ~(PR_CUT);
2223                 print_cut(creature_ptr);
2224         }
2225
2226         if (creature_ptr->redraw & (PR_STUN))
2227         {
2228                 creature_ptr->redraw &= ~(PR_STUN);
2229                 print_stun(creature_ptr);
2230         }
2231
2232         if (creature_ptr->redraw & (PR_HUNGER))
2233         {
2234                 creature_ptr->redraw &= ~(PR_HUNGER);
2235                 print_hunger(creature_ptr);
2236         }
2237
2238         if (creature_ptr->redraw & (PR_STATE))
2239         {
2240                 creature_ptr->redraw &= ~(PR_STATE);
2241                 print_state(creature_ptr);
2242         }
2243
2244         if (creature_ptr->redraw & (PR_SPEED))
2245         {
2246                 creature_ptr->redraw &= ~(PR_SPEED);
2247                 print_speed(creature_ptr);
2248         }
2249
2250         if (creature_ptr->pclass == CLASS_IMITATOR)
2251         {
2252                 if (creature_ptr->redraw & (PR_IMITATION))
2253                 {
2254                         creature_ptr->redraw &= ~(PR_IMITATION);
2255                         print_imitation(creature_ptr);
2256                 }
2257
2258                 return;
2259         }
2260
2261         if (creature_ptr->redraw & (PR_STUDY))
2262         {
2263                 creature_ptr->redraw &= ~(PR_STUDY);
2264                 print_study(creature_ptr);
2265         }
2266 }
2267
2268
2269 /*!
2270  * @brief player_ptr->window のフラグに応じた更新をまとめて行う / Handle "player_ptr->window"
2271  * @param player_ptr プレーヤーへの参照ポインタ
2272  * @return なし
2273  * @details 更新処理の対象はサブウィンドウ全般
2274  */
2275 void window_stuff(player_type *player_ptr)
2276 {
2277         if (!player_ptr->window) return;
2278
2279         /* Scan windows */
2280         BIT_FLAGS mask = 0L;
2281         for (int j = 0; j < 8; j++)
2282         {
2283                 /* Save usable flags */
2284                 if (angband_term[j]) mask |= window_flag[j];
2285         }
2286
2287         /* Apply usable flags */
2288         player_ptr->window &= mask;
2289
2290         /* Nothing to do */
2291         if (!player_ptr->window) return;
2292
2293         if (player_ptr->window & (PW_INVEN))
2294         {
2295                 player_ptr->window &= ~(PW_INVEN);
2296                 fix_inventory(player_ptr, 0); // TODO:2.2.2 まともなtval参照手段を確保
2297         }
2298
2299         /* Display equipment */
2300         if (player_ptr->window & (PW_EQUIP))
2301         {
2302                 player_ptr->window &= ~(PW_EQUIP);
2303                 fix_equip(player_ptr, 0);  // TODO:2.2.2 まともなtval参照手段を確保
2304         }
2305
2306         /* Display spell list */
2307         if (player_ptr->window & (PW_SPELL))
2308         {
2309                 player_ptr->window &= ~(PW_SPELL);
2310                 fix_spell(player_ptr);
2311         }
2312
2313         /* Display player */
2314         if (player_ptr->window & (PW_PLAYER))
2315         {
2316                 player_ptr->window &= ~(PW_PLAYER);
2317                 fix_player(player_ptr);
2318         }
2319
2320         /* Display monster list */
2321         if (player_ptr->window & (PW_MONSTER_LIST))
2322         {
2323                 player_ptr->window &= ~(PW_MONSTER_LIST);
2324                 fix_monster_list(player_ptr);
2325         }
2326
2327         /* Display overhead view */
2328         if (player_ptr->window & (PW_MESSAGE))
2329         {
2330                 player_ptr->window &= ~(PW_MESSAGE);
2331                 fix_message();
2332         }
2333
2334         /* Display overhead view */
2335         if (player_ptr->window & (PW_OVERHEAD))
2336         {
2337                 player_ptr->window &= ~(PW_OVERHEAD);
2338                 fix_overhead(player_ptr);
2339         }
2340
2341         /* Display overhead view */
2342         if (player_ptr->window & (PW_DUNGEON))
2343         {
2344                 player_ptr->window &= ~(PW_DUNGEON);
2345                 fix_dungeon(player_ptr);
2346         }
2347
2348         /* Display monster recall */
2349         if (player_ptr->window & (PW_MONSTER))
2350         {
2351                 player_ptr->window &= ~(PW_MONSTER);
2352                 fix_monster(player_ptr);
2353         }
2354
2355         /* Display object recall */
2356         if (player_ptr->window & (PW_OBJECT))
2357         {
2358                 player_ptr->window &= ~(PW_OBJECT);
2359                 fix_object(player_ptr);
2360         }
2361 }
2362
2363
2364 /*!
2365  * todo ここにplayer_type を追加するとz-termに影響が行くので保留
2366  * @brief コンソールのリサイズに合わせてマップを再描画する /
2367  * Map resizing whenever the main term changes size
2368  * @return なし
2369  */
2370 void resize_map()
2371 {
2372         /* Only if the dungeon exists */
2373         if (!current_world_ptr->character_dungeon) return;
2374
2375         /* Mega-Hack -- no panel yet */
2376         panel_row_max = 0;
2377         panel_col_max = 0;
2378
2379         /* Reset the panels */
2380         panel_row_min = p_ptr->current_floor_ptr->height;
2381         panel_col_min = p_ptr->current_floor_ptr->width;
2382
2383         verify_panel(p_ptr);
2384
2385         p_ptr->update |= (PU_TORCH | PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
2386         p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
2387         p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
2388         p_ptr->update |= (PU_MONSTERS);
2389         p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
2390
2391         handle_stuff(p_ptr);
2392         Term_redraw();
2393
2394         /*
2395          * Waiting command;
2396          * Place the cursor on the player
2397          */
2398         if (can_save) move_cursor_relative(p_ptr->y, p_ptr->x);
2399
2400         Term_fresh();
2401 }
2402
2403
2404 /*!
2405  * todo ここにplayer_type を追加するとz-termに影響が行くので保留
2406  * @brief コンソールを再描画する /
2407  * Redraw a term when it is resized
2408  * @return なし
2409  */
2410 void redraw_window(void)
2411 {
2412         /* Only if the dungeon exists */
2413         if (!current_world_ptr->character_dungeon) return;
2414
2415         p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
2416         p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
2417
2418         handle_stuff(p_ptr);
2419         Term_redraw();
2420 }
2421
2422
2423 /*!
2424  * @brief フォーカスを当てるべきマップ描画の基準座標を指定する(サブルーチン)
2425  * @param creature_ptr プレーヤーへの参照ポインタ
2426  * @param dy 変更先のフロアY座標
2427  * @param dx 変更先のフロアX座標
2428  * Handle a request to change the current panel
2429  * Return TRUE if the panel was changed.
2430  * Also used in do_cmd_locate
2431  * @return 実際に再描画が必要だった場合TRUEを返す
2432  */
2433 bool change_panel(player_type *player_ptr, POSITION dy, POSITION dx)
2434 {
2435         TERM_LEN wid, hgt;
2436         get_screen_size(&wid, &hgt);
2437
2438         /* Apply the motion */
2439         POSITION y = panel_row_min + dy * hgt / 2;
2440         POSITION x = panel_col_min + dx * wid / 2;
2441
2442         /* Verify the row */
2443         floor_type *floor_ptr = player_ptr->current_floor_ptr;
2444         if (y > floor_ptr->height - hgt) y = floor_ptr->height - hgt;
2445         if (y < 0) y = 0;
2446
2447         /* Verify the col */
2448         if (x > floor_ptr->width - wid) x = floor_ptr->width - wid;
2449         if (x < 0) x = 0;
2450
2451         if ((y == panel_row_min) && (x == panel_col_min))
2452                 return FALSE;
2453
2454         panel_row_min = y;
2455         panel_col_min = x;
2456         panel_bounds_center();
2457
2458         player_ptr->update |= (PU_MONSTERS);
2459         player_ptr->redraw |= (PR_MAP);
2460         handle_stuff(player_ptr);
2461         return TRUE;
2462 }
2463
2464
2465 /*!
2466  * @brief プレイヤーの装備一覧シンボルを固定位置に表示する
2467  * @param creature_ptr プレーヤーへの参照ポインタ
2468  * @return なし
2469  */
2470 void print_equippy(player_type *creature_ptr)
2471 {
2472         display_player_equippy(creature_ptr, ROW_EQUIPPY, COL_EQUIPPY, 0);
2473 }
2474
2475
2476 /*!
2477  * @brief 現在のコンソール表示の縦横を返す。 /
2478  * Get term size and calculate screen size
2479  * @param wid_p コンソールの表示幅文字数を返す
2480  * @param hgt_p コンソールの表示行数を返す
2481  * @return なし
2482  */
2483 void get_screen_size(TERM_LEN *wid_p, TERM_LEN *hgt_p)
2484 {
2485         Term_get_size(wid_p, hgt_p);
2486         *hgt_p -= ROW_MAP + 2;
2487         *wid_p -= COL_MAP + 2;
2488         if (use_bigtile) *wid_p /= 2;
2489 }
2490
2491
2492 /*
2493  * Calculate panel colum of a location in the map
2494  */
2495 int panel_col_of(int col)
2496 {
2497         col -= panel_col_min;
2498         if (use_bigtile) col *= 2;
2499         return col + 13;
2500 }
2501
2502
2503 /*
2504  * Prints the map of the dungeon
2505  *
2506  * Note that, for efficiency, we contain an "optimized" version
2507  * of both "lite_spot()" and "print_rel()", and that we use the
2508  * "lite_spot()" function to display the player grid, if needed.
2509  */
2510 void print_map(player_type *player_ptr)
2511 {
2512         TERM_LEN wid, hgt;
2513         Term_get_size(&wid, &hgt);
2514
2515         /* Remove map offset */
2516         wid -= COL_MAP + 2;
2517         hgt -= ROW_MAP + 2;
2518
2519         /* Access the cursor state */
2520         int v;
2521         (void)Term_get_cursor(&v);
2522
2523         /* Hide the cursor */
2524         (void)Term_set_cursor(0);
2525
2526         /* Get bounds */
2527         floor_type *floor_ptr = player_ptr->current_floor_ptr;
2528         POSITION xmin = (0 < panel_col_min) ? panel_col_min : 0;
2529         POSITION xmax = (floor_ptr->width - 1 > panel_col_max) ? panel_col_max : floor_ptr->width - 1;
2530         POSITION ymin = (0 < panel_row_min) ? panel_row_min : 0;
2531         POSITION ymax = (floor_ptr->height - 1 > panel_row_max) ? panel_row_max : floor_ptr->height - 1;
2532
2533         /* Bottom section of screen */
2534         for (POSITION y = 1; y <= ymin - panel_row_prt; y++)
2535         {
2536                 /* Erase the section */
2537                 Term_erase(COL_MAP, y, wid);
2538         }
2539
2540         /* Top section of screen */
2541         for (POSITION y = ymax - panel_row_prt; y <= hgt; y++)
2542         {
2543                 /* Erase the section */
2544                 Term_erase(COL_MAP, y, wid);
2545         }
2546
2547         /* Dump the map */
2548         for (POSITION y = ymin; y <= ymax; y++)
2549         {
2550                 /* Scan the columns of row "y" */
2551                 for (POSITION x = xmin; x <= xmax; x++)
2552                 {
2553                         TERM_COLOR a;
2554                         SYMBOL_CODE c;
2555
2556                         TERM_COLOR ta;
2557                         SYMBOL_CODE tc;
2558
2559                         /* Determine what is there */
2560                         map_info(player_ptr, y, x, &a, &c, &ta, &tc);
2561
2562                         /* Hack -- fake monochrome */
2563                         if (!use_graphics)
2564                         {
2565                                 if (current_world_ptr->timewalk_m_idx) a = TERM_DARK;
2566                                 else if (IS_INVULN(player_ptr) || player_ptr->timewalk) a = TERM_WHITE;
2567                                 else if (player_ptr->wraith_form) a = TERM_L_DARK;
2568                         }
2569
2570                         /* Efficiency -- Redraw that grid of the map */
2571                         Term_queue_bigchar(panel_col_of(x), y - panel_row_prt, a, c, ta, tc);
2572                 }
2573         }
2574
2575         /* Display player */
2576         lite_spot(player_ptr, player_ptr->y, player_ptr->x);
2577
2578         /* Restore the cursor */
2579         (void)Term_set_cursor(v);
2580 }
2581
2582
2583 /*!
2584  * 一般的にモンスターシンボルとして扱われる記号を定義する(幻覚処理向け) / Hack -- Legal monster codes
2585  */
2586 static char image_monster_hack[] = \
2587 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
2588
2589
2590 /*!
2591  * 一般的にオブジェクトシンボルとして扱われる記号を定義する(幻覚処理向け) /  Hack -- Legal object codes
2592  */
2593 static char image_object_hack[] = "?/|\\\"!$()_-=[]{},~";
2594
2595
2596 /*!
2597  * @brief モンスターの表示を幻覚状態に差し替える / Mega-Hack -- Hallucinatory monster
2598  * @param ap 本来の色
2599  * @param cp 本来のシンボル
2600  * @return なし
2601  */
2602 static void image_monster(TERM_COLOR *ap, SYMBOL_CODE *cp)
2603 {
2604         if (use_graphics)
2605         {
2606                 monster_race *r_ptr = &r_info[randint1(max_r_idx - 1)];
2607                 *cp = r_ptr->x_char;
2608                 *ap = r_ptr->x_attr;
2609                 return;
2610         }
2611
2612         *cp = (one_in_(25) ?
2613                 image_object_hack[randint0(sizeof(image_object_hack) - 1)] :
2614                 image_monster_hack[randint0(sizeof(image_monster_hack) - 1)]);
2615         *ap = randint1(15);
2616 }
2617
2618
2619 /*!
2620  * @brief オブジェクトの表示を幻覚状態に差し替える / Hallucinatory object
2621  * @param ap 本来の色
2622  * @param cp 本来のシンボル
2623  * @return なし
2624  */
2625 static void image_object(TERM_COLOR *ap, SYMBOL_CODE *cp)
2626 {
2627         if (use_graphics)
2628         {
2629                 object_kind *k_ptr = &k_info[randint1(max_k_idx - 1)];
2630                 *cp = k_ptr->x_char;
2631                 *ap = k_ptr->x_attr;
2632                 return;
2633         }
2634
2635         int n = sizeof(image_object_hack) - 1;
2636         *cp = image_object_hack[randint0(n)];
2637         *ap = randint1(15);
2638 }
2639
2640
2641 /*!
2642  * @brief オブジェクト&モンスターの表示を幻覚状態に差し替える / Hack -- Random hallucination
2643  * @param ap 本来の色
2644  * @param cp 本来のシンボル
2645  * @return なし
2646  */
2647 static void image_random(TERM_COLOR *ap, SYMBOL_CODE *cp)
2648 {
2649         /* Normally, assume monsters */
2650         if (randint0(100) < 75)
2651         {
2652                 image_monster(ap, cp);
2653         }
2654
2655         /* Otherwise, assume objects */
2656         else
2657         {
2658                 image_object(ap, cp);
2659         }
2660 }
2661
2662 /*!
2663  * 照明の表現を行うための色合いの関係を{暗闇時, 照明時} で定義する /
2664  * This array lists the effects of "brightness" on various "base" colours.\n
2665  *\n
2666  * This is used to do dynamic lighting effects in ascii :-)\n
2667  * At the moment, only the various "floor" tiles are affected.\n
2668  *\n
2669  * The layout of the array is [x][0] = light and [x][1] = dark.\n
2670  */
2671 static TERM_COLOR lighting_colours[16][2] =
2672 {
2673         /* TERM_DARK */
2674         {TERM_L_DARK, TERM_DARK},
2675
2676         /* TERM_WHITE */
2677         {TERM_YELLOW, TERM_SLATE},
2678
2679         /* TERM_SLATE */
2680         {TERM_WHITE, TERM_L_DARK},
2681
2682         /* TERM_ORANGE */
2683         {TERM_L_UMBER, TERM_UMBER},
2684
2685         /* TERM_RED */
2686         {TERM_RED, TERM_RED},
2687
2688         /* TERM_GREEN */
2689         {TERM_L_GREEN, TERM_GREEN},
2690
2691         /* TERM_BLUE */
2692         {TERM_BLUE, TERM_BLUE},
2693
2694         /* TERM_UMBER */
2695         {TERM_L_UMBER, TERM_RED},
2696
2697         /* TERM_L_DARK */
2698         {TERM_SLATE, TERM_L_DARK},
2699
2700         /* TERM_L_WHITE */
2701         {TERM_WHITE, TERM_SLATE},
2702
2703         /* TERM_VIOLET */
2704         {TERM_L_RED, TERM_BLUE},
2705
2706         /* TERM_YELLOW */
2707         {TERM_YELLOW, TERM_ORANGE},
2708
2709         /* TERM_L_RED */
2710         {TERM_L_RED, TERM_L_RED},
2711
2712         /* TERM_L_GREEN */
2713         {TERM_L_GREEN, TERM_GREEN},
2714
2715         /* TERM_L_BLUE */
2716         {TERM_L_BLUE, TERM_L_BLUE},
2717
2718         /* TERM_L_UMBER */
2719         {TERM_L_UMBER, TERM_UMBER}
2720 };
2721
2722
2723 /*!
2724  * @brief 調査中
2725  * @todo コメントを付加すること
2726  */
2727 void apply_default_feat_lighting(TERM_COLOR f_attr[F_LIT_MAX], SYMBOL_CODE f_char[F_LIT_MAX])
2728 {
2729         TERM_COLOR s_attr = f_attr[F_LIT_STANDARD];
2730         SYMBOL_CODE s_char = f_char[F_LIT_STANDARD];
2731
2732         if (IS_ASCII_GRAPHICS(s_attr)) /* For ASCII */
2733         {
2734                 f_attr[F_LIT_LITE] = lighting_colours[s_attr & 0x0f][0];
2735                 f_attr[F_LIT_DARK] = lighting_colours[s_attr & 0x0f][1];
2736                 for (int i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++) f_char[i] = s_char;
2737         }
2738         else /* For tile graphics */
2739         {
2740                 for (int i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++) f_attr[i] = s_attr;
2741                 f_char[F_LIT_LITE] = s_char + 2;
2742                 f_char[F_LIT_DARK] = s_char + 1;
2743         }
2744 }
2745
2746
2747 /*!
2748  * @brief Mコマンドによる縮小マップの表示を行う / Extract the attr/char to display at the given (legal) map location
2749  * @details
2750  * Basically, we "paint" the chosen attr/char in several passes, starting\n
2751  * with any known "terrain features" (defaulting to darkness), then adding\n
2752  * any known "objects", and finally, adding any known "monsters".  This\n
2753  * is not the fastest method but since most of the calls to this function\n
2754  * are made for grids with no monsters or objects, it is fast enough.\n
2755  *\n
2756  * Note that this function, if used on the grid containing the "player",\n
2757  * will return the attr/char of the grid underneath the player, and not\n
2758  * the actual player attr/char itself, allowing a lot of optimization\n
2759  * in various "display" functions.\n
2760  *\n
2761  * Note that the "zero" entry in the feature/object/monster arrays are\n
2762  * used to provide "special" attr/char codes, with "monster zero" being\n
2763  * used for the player attr/char, "object zero" being used for the "stack"\n
2764  * attr/char, and "feature zero" being used for the "nothing" attr/char,\n
2765  * though this function makes use of only "feature zero".\n
2766  *\n
2767  * Note that monsters can have some "special" flags, including "ATTR_MULTI",\n
2768  * which means their color changes, and "ATTR_CLEAR", which means they take\n
2769  * the color of whatever is under them, and "CHAR_CLEAR", which means that\n
2770  * they take the symbol of whatever is under them.  Technically, the flag\n
2771  * "CHAR_MULTI" is supposed to indicate that a monster looks strange when\n
2772  * examined, but this flag is currently ignored.\n
2773  *\n
2774  * Currently, we do nothing with multi-hued objects, because there are\n
2775  * not any.  If there were, they would have to set "shimmer_objects"\n
2776  * when they were created, and then new "shimmer" code in "dungeon.c"\n
2777  * would have to be created handle the "shimmer" effect, and the code\n
2778  * in floor would have to be updated to create the shimmer effect.\n
2779  *\n
2780  * Note the effects of hallucination.  Objects always appear as random\n
2781  * "objects", monsters as random "monsters", and normal grids occasionally\n
2782  * appear as random "monsters" or "objects", but note that these random\n
2783  * "monsters" and "objects" are really just "colored ascii symbols".\n
2784  *\n
2785  * Note that "floors" and "invisible traps" (and "zero" features) are\n
2786  * drawn as "floors" using a special check for optimization purposes,\n
2787  * and these are the only features which get drawn using the special\n
2788  * lighting effects activated by "view_special_lite".\n
2789  *\n
2790  * Note the use of the "mimic" field in the "terrain feature" processing,\n
2791  * which allows any feature to "pretend" to be another feature.  This is\n
2792  * used to "hide" secret doors, and to make all "doors" appear the same,\n
2793  * and all "walls" appear the same, and "hidden" treasure stay hidden.\n
2794  * It is possible to use this field to make a feature "look" like a floor,\n
2795  * but the "special lighting effects" for floors will not be used.\n
2796  *\n
2797  * Note the use of the new "terrain feature" information.  Note that the\n
2798  * assumption that all interesting "objects" and "terrain features" are\n
2799  * memorized allows extremely optimized processing below.  Note the use\n
2800  * of separate flags on objects to mark them as memorized allows a grid\n
2801  * to have memorized "terrain" without granting knowledge of any object\n
2802  * which may appear in that grid.\n
2803  *\n
2804  * Note the efficient code used to determine if a "floor" grid is\n
2805  * "memorized" or "viewable" by the player, where the test for the\n
2806  * grid being "viewable" is based on the facts that (1) the grid\n
2807  * must be "lit" (torch-lit or perma-lit), (2) the grid must be in\n
2808  * line of sight, and (3) the player must not be blind, and uses the\n
2809  * assumption that all torch-lit grids are in line of sight.\n
2810  *\n
2811  * Note that floors (and invisible traps) are the only grids which are\n
2812  * not memorized when seen, so only these grids need to check to see if\n
2813  * the grid is "viewable" to the player (if it is not memorized).  Since\n
2814  * most non-memorized grids are in fact walls, this induces *massive*\n
2815  * efficiency, at the cost of *forcing* the memorization of non-floor\n
2816  * grids when they are first seen.  Note that "invisible traps" are\n
2817  * always treated exactly like "floors", which prevents "cheating".\n
2818  *\n
2819  * Note the "special lighting effects" which can be activated for floor\n
2820  * grids using the "view_special_lite" option (for "white" floor grids),\n
2821  * causing certain grids to be displayed using special colors.  If the\n
2822  * player is "blind", we will use "dark gray", else if the grid is lit\n
2823  * by the torch, and the "view_yellow_lite" option is set, we will use\n
2824  * "yellow", else if the grid is "dark", we will use "dark gray", else\n
2825  * if the grid is not "viewable", and the "view_bright_lite" option is\n
2826  * set, and the we will use "slate" (gray).  We will use "white" for all\n
2827  * other cases, in particular, for illuminated viewable floor grids.\n
2828  *\n
2829  * Note the "special lighting effects" which can be activated for wall\n
2830  * grids using the "view_granite_lite" option (for "white" wall grids),\n
2831  * causing certain grids to be displayed using special colors.  If the\n
2832  * player is "blind", we will use "dark gray", else if the grid is lit\n
2833  * by the torch, and the "view_yellow_lite" option is set, we will use\n
2834  * "yellow", else if the "view_bright_lite" option is set, and the grid\n
2835  * is not "viewable", or is "dark", or is glowing, but not when viewed\n
2836  * from the player's current location, we will use "slate" (gray).  We\n
2837  * will use "white" for all other cases, in particular, for correctly\n
2838  * illuminated viewable wall grids.\n
2839  *\n
2840  * Note that, when "view_granite_lite" is set, we use an inline version\n
2841  * of the "player_can_see_bold()" function to check the "viewability" of\n
2842  * grids when the "view_bright_lite" option is set, and we do NOT use\n
2843  * any special colors for "dark" wall grids, since this would allow the\n
2844  * player to notice the walls of illuminated rooms from a hallway that\n
2845  * happened to run beside the room.  The alternative, by the way, would\n
2846  * be to prevent the generation of hallways next to rooms, but this\n
2847  * would still allow problems when digging towards a room.\n
2848  *\n
2849  * Note that bizarre things must be done when the "attr" and/or "char"\n
2850  * codes have the "high-bit" set, since these values are used to encode\n
2851  * various "special" pictures in some versions, and certain situations,\n
2852  * such as "multi-hued" or "clear" monsters, cause the attr/char codes\n
2853  * to be "scrambled" in various ways.\n
2854  *\n
2855  * Note that eventually we may use the "&" symbol for embedded treasure,\n
2856  * and use the "*" symbol to indicate multiple objects, though this will\n
2857  * have to wait for Angband 2.8.0 or later.  Note that currently, this\n
2858  * is not important, since only one object or terrain feature is allowed\n
2859  * in each grid.  If needed, "k_info[0]" will hold the "stack" attr/char.\n
2860  *\n
2861  * Note the assumption that doing "x_ptr = &x_info[x]" plus a few of\n
2862  * "x_ptr->xxx", is quicker than "x_info[x].xxx", if this is incorrect\n
2863  * then a whole lot of code should be changed...  XXX XXX\n
2864  */
2865 void map_info(player_type *player_ptr, POSITION y, POSITION x, TERM_COLOR *ap, SYMBOL_CODE *cp, TERM_COLOR *tap, SYMBOL_CODE *tcp)
2866 {
2867         floor_type *floor_ptr = player_ptr->current_floor_ptr;
2868         grid_type *g_ptr = &floor_ptr->grid_array[y][x];
2869
2870         OBJECT_IDX this_o_idx, next_o_idx = 0;
2871
2872         /* Feature code (applying "mimic" field) */
2873         FEAT_IDX feat = get_feat_mimic(g_ptr);
2874
2875         /* Access floor */
2876         feature_type *f_ptr = &f_info[feat];
2877
2878         TERM_COLOR a;
2879         SYMBOL_CODE c;
2880
2881         /* Boring grids (floors, etc) */
2882         if (!have_flag(f_ptr->flags, FF_REMEMBER))
2883         {
2884                 /*
2885                  * Handle Memorized or visible floor
2886                  *
2887                  * No visual when blinded.
2888                  *   (to prevent strange effects on darkness breath)
2889                  * otherwise,
2890                  * - Can see grids with CAVE_MARK.
2891                  * - Can see grids with CAVE_LITE or CAVE_MNLT.
2892                  *   (Such grids also have CAVE_VIEW)
2893                  * - Can see grids with CAVE_VIEW unless darkened by monsters.
2894                  */
2895                 if (!player_ptr->blind &&
2896                         ((g_ptr->info & (CAVE_MARK | CAVE_LITE | CAVE_MNLT)) ||
2897                         ((g_ptr->info & CAVE_VIEW) && (((g_ptr->info & (CAVE_GLOW | CAVE_MNDK)) == CAVE_GLOW) || player_ptr->see_nocto))))
2898                 {
2899                         /* Normal attr/char */
2900                         a = f_ptr->x_attr[F_LIT_STANDARD];
2901                         c = f_ptr->x_char[F_LIT_STANDARD];
2902
2903                         if (player_ptr->wild_mode)
2904                         {
2905                                 /* Special lighting effects */
2906                                 /* Handle "night" */
2907                                 if (view_special_lite && !is_daytime())
2908                                 {
2909                                         /* Use a darkened colour/tile */
2910                                         a = f_ptr->x_attr[F_LIT_DARK];
2911                                         c = f_ptr->x_char[F_LIT_DARK];
2912                                 }
2913                         }
2914
2915                         /* Mega-Hack -- Handle "in-sight" and "darkened" grids */
2916                         else if (darkened_grid(player_ptr, g_ptr))
2917                         {
2918                                 /* Unsafe grid -- idea borrowed from Unangband */
2919                                 feat = (view_unsafe_grids && (g_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
2920
2921                                 /* Access darkness */
2922                                 f_ptr = &f_info[feat];
2923
2924                                 /* Char and attr of darkness */
2925                                 a = f_ptr->x_attr[F_LIT_STANDARD];
2926                                 c = f_ptr->x_char[F_LIT_STANDARD];
2927                         }
2928
2929                         /* Special lighting effects */
2930                         else if (view_special_lite)
2931                         {
2932                                 /* Handle "torch-lit" grids */
2933                                 if (g_ptr->info & (CAVE_LITE | CAVE_MNLT))
2934                                 {
2935                                         /* Torch lite */
2936                                         if (view_yellow_lite)
2937                                         {
2938                                                 /* Use a brightly lit colour/tile */
2939                                                 a = f_ptr->x_attr[F_LIT_LITE];
2940                                                 c = f_ptr->x_char[F_LIT_LITE];
2941                                         }
2942                                 }
2943
2944                                 /* Handle "dark" grids */
2945                                 else if ((g_ptr->info & (CAVE_GLOW | CAVE_MNDK)) != CAVE_GLOW)
2946                                 {
2947                                         /* Use a darkened colour/tile */
2948                                         a = f_ptr->x_attr[F_LIT_DARK];
2949                                         c = f_ptr->x_char[F_LIT_DARK];
2950                                 }
2951
2952                                 /* Handle "out-of-sight" grids */
2953                                 else if (!(g_ptr->info & CAVE_VIEW))
2954                                 {
2955                                         /* Special flag */
2956                                         if (view_bright_lite)
2957                                         {
2958                                                 /* Use a darkened colour/tile */
2959                                                 a = f_ptr->x_attr[F_LIT_DARK];
2960                                                 c = f_ptr->x_char[F_LIT_DARK];
2961                                         }
2962                                 }
2963                         }
2964                 }
2965
2966                 /* Unknown */
2967                 else
2968                 {
2969                         /* Unsafe grid -- idea borrowed from Unangband */
2970                         feat = (view_unsafe_grids && (g_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
2971
2972                         /* Access darkness */
2973                         f_ptr = &f_info[feat];
2974
2975                         /* Normal attr/char */
2976                         a = f_ptr->x_attr[F_LIT_STANDARD];
2977                         c = f_ptr->x_char[F_LIT_STANDARD];
2978                 }
2979         }
2980
2981         /* Interesting grids (non-floors) */
2982         else
2983         {
2984                 /* Memorized grids */
2985                 if (g_ptr->info & CAVE_MARK)
2986                 {
2987                         /* Normal attr/char */
2988                         a = f_ptr->x_attr[F_LIT_STANDARD];
2989                         c = f_ptr->x_char[F_LIT_STANDARD];
2990
2991                         if (player_ptr->wild_mode)
2992                         {
2993                                 /* Special lighting effects */
2994                                 /* Handle "blind" or "night" */
2995                                 if (view_granite_lite && (player_ptr->blind || !is_daytime()))
2996                                 {
2997                                         /* Use a darkened colour/tile */
2998                                         a = f_ptr->x_attr[F_LIT_DARK];
2999                                         c = f_ptr->x_char[F_LIT_DARK];
3000                                 }
3001                         }
3002
3003                         /* Mega-Hack -- Handle "in-sight" and "darkened" grids */
3004                         else if (darkened_grid(player_ptr, g_ptr) && !player_ptr->blind)
3005                         {
3006                                 if (have_flag(f_ptr->flags, FF_LOS) && have_flag(f_ptr->flags, FF_PROJECT))
3007                                 {
3008                                         /* Unsafe grid -- idea borrowed from Unangband */
3009                                         feat = (view_unsafe_grids && (g_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
3010
3011                                         /* Access darkness */
3012                                         f_ptr = &f_info[feat];
3013
3014                                         /* Char and attr of darkness */
3015                                         a = f_ptr->x_attr[F_LIT_STANDARD];
3016                                         c = f_ptr->x_char[F_LIT_STANDARD];
3017                                 }
3018                                 else if (view_granite_lite && view_bright_lite)
3019                                 {
3020                                         /* Use a darkened colour/tile */
3021                                         a = f_ptr->x_attr[F_LIT_DARK];
3022                                         c = f_ptr->x_char[F_LIT_DARK];
3023                                 }
3024                         }
3025
3026                         /* Special lighting effects */
3027                         else if (view_granite_lite)
3028                         {
3029                                 /* Handle "blind" */
3030                                 if (player_ptr->blind)
3031                                 {
3032                                         /* Use a darkened colour/tile */
3033                                         a = f_ptr->x_attr[F_LIT_DARK];
3034                                         c = f_ptr->x_char[F_LIT_DARK];
3035                                 }
3036
3037                                 /* Handle "torch-lit" grids */
3038                                 else if (g_ptr->info & (CAVE_LITE | CAVE_MNLT))
3039                                 {
3040                                         /* Torch lite */
3041                                         if (view_yellow_lite)
3042                                         {
3043                                                 /* Use a brightly lit colour/tile */
3044                                                 a = f_ptr->x_attr[F_LIT_LITE];
3045                                                 c = f_ptr->x_char[F_LIT_LITE];
3046                                         }
3047                                 }
3048
3049                                 /* Handle "view_bright_lite" */
3050                                 else if (view_bright_lite)
3051                                 {
3052                                         /* Not viewable */
3053                                         if (!(g_ptr->info & CAVE_VIEW))
3054                                         {
3055                                                 /* Use a darkened colour/tile */
3056                                                 a = f_ptr->x_attr[F_LIT_DARK];
3057                                                 c = f_ptr->x_char[F_LIT_DARK];
3058                                         }
3059
3060                                         /* Not glowing */
3061                                         else if ((g_ptr->info & (CAVE_GLOW | CAVE_MNDK)) != CAVE_GLOW)
3062                                         {
3063                                                 /* Use a darkened colour/tile */
3064                                                 a = f_ptr->x_attr[F_LIT_DARK];
3065                                                 c = f_ptr->x_char[F_LIT_DARK];
3066                                         }
3067
3068                                         /* Not glowing correctly */
3069                                         else if (!have_flag(f_ptr->flags, FF_LOS) && !check_local_illumination(player_ptr, y, x))
3070                                         {
3071                                                 /* Use a darkened colour/tile */
3072                                                 a = f_ptr->x_attr[F_LIT_DARK];
3073                                                 c = f_ptr->x_char[F_LIT_DARK];
3074                                         }
3075                                 }
3076                         }
3077                 }
3078
3079                 /* Unknown */
3080                 else
3081                 {
3082                         /* Unsafe grid -- idea borrowed from Unangband */
3083                         feat = (view_unsafe_grids && (g_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
3084
3085                         /* Access feature */
3086                         f_ptr = &f_info[feat];
3087
3088                         /* Normal attr/char */
3089                         a = f_ptr->x_attr[F_LIT_STANDARD];
3090                         c = f_ptr->x_char[F_LIT_STANDARD];
3091                 }
3092         }
3093
3094         if (feat_priority == -1) feat_priority = f_ptr->priority;
3095
3096         /* Save the terrain info for the transparency effects */
3097         (*tap) = a;
3098         (*tcp) = c;
3099
3100         /* Save the info */
3101         (*ap) = a;
3102         (*cp) = c;
3103
3104         /* Hack -- rare random hallucination, except on outer dungeon walls */
3105         if (player_ptr->image && one_in_(256))
3106                 image_random(ap, cp);
3107
3108         /* Objects */
3109         for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
3110         {
3111                 object_type *o_ptr;
3112                 o_ptr = &floor_ptr->o_list[this_o_idx];
3113                 next_o_idx = o_ptr->next_o_idx;
3114
3115                 /* Memorized objects */
3116                 if (!(o_ptr->marked & OM_FOUND)) continue;
3117
3118                 if (display_autopick)
3119                 {
3120                         byte act;
3121
3122                         match_autopick = find_autopick_list(player_ptr, o_ptr);
3123                         if (match_autopick == -1)
3124                                 continue;
3125
3126                         act = autopick_list[match_autopick].action;
3127
3128                         if ((act & DO_DISPLAY) && (act & display_autopick))
3129                         {
3130                                 autopick_obj = o_ptr;
3131                         }
3132                         else
3133                         {
3134                                 match_autopick = -1;
3135                                 continue;
3136                         }
3137                 }
3138
3139                 /* Normal char */
3140                 (*cp) = object_char(o_ptr);
3141
3142                 /* Normal attr */
3143                 (*ap) = object_attr(o_ptr);
3144
3145                 feat_priority = 20;
3146
3147                 /* Hack -- hallucination */
3148                 if (player_ptr->image) image_object(ap, cp);
3149
3150                 break;
3151         }
3152
3153         /* Handle monsters */
3154         if (g_ptr->m_idx && display_autopick != 0)
3155         {
3156                 set_term_color(player_ptr, y, x, ap, cp);
3157                 return;
3158         }
3159
3160         monster_type *m_ptr = &floor_ptr->m_list[g_ptr->m_idx];
3161
3162         /* Visible monster */
3163         if (!m_ptr->ml)
3164         {
3165                 set_term_color(player_ptr, y, x, ap, cp);
3166                 return;
3167         }
3168
3169
3170         monster_race *r_ptr = &r_info[m_ptr->ap_r_idx];
3171
3172         feat_priority = 30;
3173
3174         /* Hallucination */
3175         if (player_ptr->image)
3176         {
3177                 /*
3178                  * Monsters with both CHAR_CLEAR and ATTR_CLEAR
3179                  * flags are always unseen.
3180                  */
3181                 if ((r_ptr->flags1 & (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR)) == (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR))
3182                 {
3183                         /* Do nothing */
3184                 }
3185                 else
3186                 {
3187                         image_monster(ap, cp);
3188                 }
3189
3190                 set_term_color(player_ptr, y, x, ap, cp);
3191                 return;
3192         }
3193
3194         /* Monster attr/char */
3195         a = r_ptr->x_attr;
3196         c = r_ptr->x_char;
3197
3198         if (!(r_ptr->flags1 & (RF1_CHAR_CLEAR | RF1_SHAPECHANGER | RF1_ATTR_CLEAR
3199                 | RF1_ATTR_MULTI | RF1_ATTR_SEMIRAND)))
3200         {
3201                 /* Desired monster attr/char */
3202                 *ap = a;
3203                 *cp = c;
3204                 set_term_color(player_ptr, y, x, ap, cp);
3205                 return;
3206         }
3207
3208         /*
3209          * Monsters with both CHAR_CLEAR and ATTR_CLEAR
3210          * flags are always unseen.
3211          */
3212         if ((r_ptr->flags1 & (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR)) == (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR))
3213         {
3214                 set_term_color(player_ptr, y, x, ap, cp);
3215                 return;
3216         }
3217
3218         /***  Monster's attr  ***/
3219         if ((r_ptr->flags1 & RF1_ATTR_CLEAR) && (*ap != TERM_DARK) && !use_graphics)
3220         {
3221                 /* Clear-attr */
3222                 /* Do nothing */
3223         }
3224         else if ((r_ptr->flags1 & RF1_ATTR_MULTI) && !use_graphics)
3225         {
3226                 /* Multi-hued attr */
3227                 if (r_ptr->flags2 & RF2_ATTR_ANY) *ap = randint1(15);
3228                 else switch (randint1(7))
3229                 {
3230                 case 1: *ap = TERM_RED;     break;
3231                 case 2: *ap = TERM_L_RED;   break;
3232                 case 3: *ap = TERM_WHITE;   break;
3233                 case 4: *ap = TERM_L_GREEN; break;
3234                 case 5: *ap = TERM_BLUE;    break;
3235                 case 6: *ap = TERM_L_DARK;  break;
3236                 case 7: *ap = TERM_GREEN;   break;
3237                 }
3238         }
3239         else if ((r_ptr->flags1 & RF1_ATTR_SEMIRAND) && !use_graphics)
3240         {
3241                 /* Use semi-random attr (usually mimics' colors vary) */
3242                 *ap = g_ptr->m_idx % 15 + 1;
3243         }
3244         else
3245         {
3246                 /* Normal case */
3247                 *ap = a;
3248         }
3249
3250         /***  Monster's char  ***/
3251         if ((r_ptr->flags1 & RF1_CHAR_CLEAR) && (*cp != ' ') && !use_graphics)
3252         {
3253                 set_term_color(player_ptr, y, x, ap, cp);
3254                 return;
3255         }
3256
3257         if (r_ptr->flags1 & RF1_SHAPECHANGER)
3258         {
3259                 if (use_graphics)
3260                 {
3261                         monster_race *tmp_r_ptr = &r_info[randint1(max_r_idx - 1)];
3262                         *cp = tmp_r_ptr->x_char;
3263                         *ap = tmp_r_ptr->x_attr;
3264                 }
3265                 else
3266                 {
3267                         *cp = (one_in_(25) ?
3268                                 image_object_hack[randint0(sizeof(image_object_hack) - 1)] :
3269                                 image_monster_hack[randint0(sizeof(image_monster_hack) - 1)]);
3270                 }
3271
3272                 set_term_color(player_ptr, y, x, ap, cp);
3273                 return;
3274         }
3275
3276         *cp = c;
3277         set_term_color(player_ptr, y, x, ap, cp);
3278 }
3279
3280
3281 void set_term_color(player_type *player_ptr, POSITION y, POSITION x, TERM_COLOR *ap, SYMBOL_CODE *cp)
3282 {
3283         if (!player_bold(player_ptr, y, x)) return;
3284
3285         monster_race *r_ptr = &r_info[0];
3286         *ap = r_ptr->x_attr;
3287         *cp = r_ptr->x_char;
3288         feat_priority = 31;
3289 }
3290
3291
3292 static concptr simplify_list[][2] =
3293 {
3294 #ifdef JP
3295         {"の魔法書", ""},
3296         {NULL, NULL}
3297 #else
3298         {"^Ring of ",   "="},
3299         {"^Amulet of ", "\""},
3300         {"^Scroll of ", "?"},
3301         {"^Scroll titled ", "?"},
3302         {"^Wand of "  , "-"},
3303         {"^Rod of "   , "-"},
3304         {"^Staff of " , "_"},
3305         {"^Potion of ", "!"},
3306         {" Spellbook ",""},
3307         {"^Book of ",   ""},
3308         {" Magic [",   "["},
3309         {" Book [",    "["},
3310         {" Arts [",    "["},
3311         {"^Set of ",    ""},
3312         {"^Pair of ",   ""},
3313         {NULL, NULL}
3314 #endif
3315 };
3316
3317
3318 static void display_shortened_item_name(player_type *player_ptr, object_type *o_ptr, int y)
3319 {
3320         char buf[MAX_NLEN];
3321         object_desc(player_ptr, buf, o_ptr, (OD_NO_FLAVOR | OD_OMIT_PREFIX | OD_NAME_ONLY));
3322         TERM_COLOR attr = tval_to_attr[o_ptr->tval % 128];
3323
3324         if (player_ptr->image)
3325         {
3326                 attr = TERM_WHITE;
3327                 strcpy(buf, _("何か奇妙な物", "something strange"));
3328         }
3329
3330         char *c = buf;
3331         for (c = buf; *c; c++)
3332         {
3333                 for (int i = 0; simplify_list[i][1]; i++)
3334                 {
3335                         concptr org_w = simplify_list[i][0];
3336
3337                         if (*org_w == '^')
3338                         {
3339                                 if (c == buf)
3340                                         org_w++;
3341                                 else
3342                                         continue;
3343                         }
3344
3345                         if (strncmp(c, org_w, strlen(org_w))) continue;
3346
3347                         char *s = c;
3348                         concptr tmp = simplify_list[i][1];
3349                         while (*tmp)
3350                                 *s++ = *tmp++;
3351                         tmp = c + strlen(org_w);
3352                         while (*tmp)
3353                                 *s++ = *tmp++;
3354                         *s = '\0';
3355                 }
3356         }
3357
3358         c = buf;
3359         int len = 0;
3360         /* 半角 12 文字分で切る */
3361         while (*c)
3362         {
3363 #ifdef JP
3364                 if (iskanji(*c))
3365                 {
3366                         if (len + 2 > 12) break;
3367                         c += 2;
3368                         len += 2;
3369                 }
3370                 else
3371 #endif
3372                 {
3373                         if (len + 1 > 12) break;
3374                         c++;
3375                         len++;
3376                 }
3377         }
3378
3379         *c = '\0';
3380         Term_putstr(0, y, 12, attr, buf);
3381 }
3382
3383
3384 /*
3385  * Display a "small-scale" map of the dungeon in the active Term
3386  */
3387 void display_map(player_type *player_ptr, int *cy, int *cx)
3388 {
3389         int i, j, x, y;
3390
3391         TERM_COLOR ta;
3392         SYMBOL_CODE tc;
3393
3394         byte tp;
3395
3396         TERM_COLOR **bigma;
3397         SYMBOL_CODE **bigmc;
3398         byte **bigmp;
3399
3400         TERM_COLOR **ma;
3401         SYMBOL_CODE **mc;
3402         byte **mp;
3403
3404         /* Save lighting effects */
3405         bool old_view_special_lite = view_special_lite;
3406         bool old_view_granite_lite = view_granite_lite;
3407
3408         TERM_LEN hgt, wid, yrat, xrat;
3409
3410         int **match_autopick_yx;
3411         object_type ***object_autopick_yx;
3412
3413         Term_get_size(&wid, &hgt);
3414         hgt -= 2;
3415         wid -= 14;
3416         if (use_bigtile) wid /= 2;
3417
3418         floor_type *floor_ptr = player_ptr->current_floor_ptr;
3419         yrat = (floor_ptr->height + hgt - 1) / hgt;
3420         xrat = (floor_ptr->width + wid - 1) / wid;
3421
3422         /* Disable lighting effects */
3423         view_special_lite = FALSE;
3424         view_granite_lite = FALSE;
3425
3426         /* Allocate the maps */
3427         C_MAKE(ma, (hgt + 2), TERM_COLOR *);
3428         C_MAKE(mc, (hgt + 2), char_ptr);
3429         C_MAKE(mp, (hgt + 2), byte_ptr);
3430         C_MAKE(match_autopick_yx, (hgt + 2), sint_ptr);
3431         C_MAKE(object_autopick_yx, (hgt + 2), object_type **);
3432
3433         /* Allocate and wipe each line map */
3434         for (y = 0; y < (hgt + 2); y++)
3435         {
3436                 /* Allocate one row each array */
3437                 C_MAKE(ma[y], (wid + 2), TERM_COLOR);
3438                 C_MAKE(mc[y], (wid + 2), char);
3439                 C_MAKE(mp[y], (wid + 2), byte);
3440                 C_MAKE(match_autopick_yx[y], (wid + 2), int);
3441                 C_MAKE(object_autopick_yx[y], (wid + 2), object_type *);
3442
3443                 for (x = 0; x < wid + 2; ++x)
3444                 {
3445                         match_autopick_yx[y][x] = -1;
3446                         object_autopick_yx[y][x] = NULL;
3447
3448                         /* Nothing here */
3449                         ma[y][x] = TERM_WHITE;
3450                         mc[y][x] = ' ';
3451
3452                         /* No priority */
3453                         mp[y][x] = 0;
3454                 }
3455         }
3456
3457         /* Allocate the maps */
3458         C_MAKE(bigma, (floor_ptr->height + 2), TERM_COLOR *);
3459         C_MAKE(bigmc, (floor_ptr->height + 2), char_ptr);
3460         C_MAKE(bigmp, (floor_ptr->height + 2), byte_ptr);
3461
3462         /* Allocate and wipe each line map */
3463         for (y = 0; y < (floor_ptr->height + 2); y++)
3464         {
3465                 /* Allocate one row each array */
3466                 C_MAKE(bigma[y], (floor_ptr->width + 2), TERM_COLOR);
3467                 C_MAKE(bigmc[y], (floor_ptr->width + 2), char);
3468                 C_MAKE(bigmp[y], (floor_ptr->width + 2), byte);
3469
3470                 for (x = 0; x < floor_ptr->width + 2; ++x)
3471                 {
3472                         /* Nothing here */
3473                         bigma[y][x] = TERM_WHITE;
3474                         bigmc[y][x] = ' ';
3475
3476                         /* No priority */
3477                         bigmp[y][x] = 0;
3478                 }
3479         }
3480
3481         /* Fill in the map */
3482         for (i = 0; i < floor_ptr->width; ++i)
3483         {
3484                 for (j = 0; j < floor_ptr->height; ++j)
3485                 {
3486                         x = i / xrat + 1;
3487                         y = j / yrat + 1;
3488
3489                         match_autopick = -1;
3490                         autopick_obj = NULL;
3491                         feat_priority = -1;
3492
3493                         /* Extract the current attr/char at that map location */
3494                         map_info(player_ptr, j, i, &ta, &tc, &ta, &tc);
3495
3496                         /* Extract the priority */
3497                         tp = (byte)feat_priority;
3498
3499                         if (match_autopick != -1
3500                                 && (match_autopick_yx[y][x] == -1
3501                                         || match_autopick_yx[y][x] > match_autopick))
3502                         {
3503                                 match_autopick_yx[y][x] = match_autopick;
3504                                 object_autopick_yx[y][x] = autopick_obj;
3505                                 tp = 0x7f;
3506                         }
3507
3508                         /* Save the char, attr and priority */
3509                         bigmc[j + 1][i + 1] = tc;
3510                         bigma[j + 1][i + 1] = ta;
3511                         bigmp[j + 1][i + 1] = tp;
3512                 }
3513         }
3514
3515         for (j = 0; j < floor_ptr->height; ++j)
3516         {
3517                 for (i = 0; i < floor_ptr->width; ++i)
3518                 {
3519                         x = i / xrat + 1;
3520                         y = j / yrat + 1;
3521
3522                         tc = bigmc[j + 1][i + 1];
3523                         ta = bigma[j + 1][i + 1];
3524                         tp = bigmp[j + 1][i + 1];
3525
3526                         /* rare feature has more priority */
3527                         if (mp[y][x] == tp)
3528                         {
3529                                 int t;
3530                                 int cnt = 0;
3531
3532                                 for (t = 0; t < 8; t++)
3533                                 {
3534                                         if (tc == bigmc[j + 1 + ddy_cdd[t]][i + 1 + ddx_cdd[t]] &&
3535                                                 ta == bigma[j + 1 + ddy_cdd[t]][i + 1 + ddx_cdd[t]])
3536                                                 cnt++;
3537                                 }
3538                                 if (cnt <= 4)
3539                                         tp++;
3540                         }
3541
3542                         /* Save "best" */
3543                         if (mp[y][x] < tp)
3544                         {
3545                                 /* Save the char, attr and priority */
3546                                 mc[y][x] = tc;
3547                                 ma[y][x] = ta;
3548                                 mp[y][x] = tp;
3549                         }
3550                 }
3551         }
3552
3553         /* Corners */
3554         x = wid + 1;
3555         y = hgt + 1;
3556
3557         /* Draw the corners */
3558         mc[0][0] = mc[0][x] = mc[y][0] = mc[y][x] = '+';
3559
3560         /* Draw the horizontal edges */
3561         for (x = 1; x <= wid; x++) mc[0][x] = mc[y][x] = '-';
3562
3563         /* Draw the vertical edges */
3564         for (y = 1; y <= hgt; y++) mc[y][0] = mc[y][x] = '|';
3565
3566         /* Display each map line in order */
3567         for (y = 0; y < hgt + 2; ++y)
3568         {
3569                 /* Start a new line */
3570                 Term_gotoxy(COL_MAP, y);
3571
3572                 /* Display the line */
3573                 for (x = 0; x < wid + 2; ++x)
3574                 {
3575                         ta = ma[y][x];
3576                         tc = mc[y][x];
3577
3578                         /* Hack -- fake monochrome */
3579                         if (!use_graphics)
3580                         {
3581                                 if (current_world_ptr->timewalk_m_idx) ta = TERM_DARK;
3582                                 else if (IS_INVULN(player_ptr) || player_ptr->timewalk) ta = TERM_WHITE;
3583                                 else if (player_ptr->wraith_form) ta = TERM_L_DARK;
3584                         }
3585
3586                         /* Add the character */
3587                         Term_add_bigch(ta, tc);
3588                 }
3589         }
3590
3591         for (y = 1; y < hgt + 1; ++y)
3592         {
3593                 match_autopick = -1;
3594                 for (x = 1; x <= wid; x++) {
3595                         if (match_autopick_yx[y][x] != -1 &&
3596                                 (match_autopick > match_autopick_yx[y][x] ||
3597                                         match_autopick == -1)) {
3598                                 match_autopick = match_autopick_yx[y][x];
3599                                 autopick_obj = object_autopick_yx[y][x];
3600                         }
3601                 }
3602
3603                 /* Clear old display */
3604                 Term_putstr(0, y, 12, 0, "            ");
3605
3606                 if (match_autopick != -1)
3607                         display_shortened_item_name(player_ptr, autopick_obj, y);
3608         }
3609
3610         /* Player location */
3611         (*cy) = player_ptr->y / yrat + 1 + ROW_MAP;
3612         if (!use_bigtile)
3613                 (*cx) = player_ptr->x / xrat + 1 + COL_MAP;
3614         else
3615                 (*cx) = (player_ptr->x / xrat + 1) * 2 + COL_MAP;
3616
3617         /* Restore lighting effects */
3618         view_special_lite = old_view_special_lite;
3619         view_granite_lite = old_view_granite_lite;
3620
3621         /* Free each line map */
3622         for (y = 0; y < (hgt + 2); y++)
3623         {
3624                 /* Free one row each array */
3625                 C_KILL(ma[y], (wid + 2), TERM_COLOR);
3626                 C_KILL(mc[y], (wid + 2), SYMBOL_CODE);
3627                 C_KILL(mp[y], (wid + 2), byte);
3628                 C_KILL(match_autopick_yx[y], (wid + 2), int);
3629                 C_KILL(object_autopick_yx[y], (wid + 2), object_type *);
3630         }
3631
3632         /* Free each line map */
3633         C_KILL(ma, (hgt + 2), TERM_COLOR *);
3634         C_KILL(mc, (hgt + 2), char_ptr);
3635         C_KILL(mp, (hgt + 2), byte_ptr);
3636         C_KILL(match_autopick_yx, (hgt + 2), sint_ptr);
3637         C_KILL(object_autopick_yx, (hgt + 2), object_type **);
3638
3639         /* Free each line map */
3640         for (y = 0; y < (floor_ptr->height + 2); y++)
3641         {
3642                 /* Free one row each array */
3643                 C_KILL(bigma[y], (floor_ptr->width + 2), TERM_COLOR);
3644                 C_KILL(bigmc[y], (floor_ptr->width + 2), SYMBOL_CODE);
3645                 C_KILL(bigmp[y], (floor_ptr->width + 2), byte);
3646         }
3647
3648         /* Free each line map */
3649         C_KILL(bigma, (floor_ptr->height + 2), TERM_COLOR *);
3650         C_KILL(bigmc, (floor_ptr->height + 2), char_ptr);
3651         C_KILL(bigmp, (floor_ptr->height + 2), byte_ptr);
3652 }
3653
3654
3655 /*
3656  * Display a "small-scale" map of the dungeon for the player
3657  *
3658  * Currently, the "player" is displayed on the map.
3659  */
3660 void do_cmd_view_map(player_type *player_ptr)
3661 {
3662         screen_save();
3663         prt(_("お待ち下さい...", "Please wait..."), 0, 0);
3664
3665         Term_fresh();
3666         Term_clear();
3667
3668         display_autopick = 0;
3669
3670         /* Display the map */
3671         int cy, cx;
3672         display_map(player_ptr, &cy, &cx);
3673
3674         if ((max_autopick == 0) || player_ptr->wild_mode)
3675         {
3676                 put_str(_("何かキーを押すとゲームに戻ります", "Hit any key to continue"), 23, 30);
3677                 /* Hilite the player */
3678                 move_cursor(cy, cx);
3679                 /* Get any key */
3680                 inkey();
3681                 screen_load();
3682                 return;
3683         }
3684
3685         display_autopick = ITEM_DISPLAY;
3686
3687         while (TRUE)
3688         {
3689                 int wid, hgt;
3690                 Term_get_size(&wid, &hgt);
3691                 int row_message = hgt - 1;
3692
3693                 put_str(_("何かキーを押してください('M':拾う 'N':放置 'D':M+N 'K':壊すアイテムを表示)",
3694                         " Hit M, N(for ~), K(for !), or D(same as M+N) to display auto-picker items."), row_message, 1);
3695
3696                 move_cursor(cy, cx);
3697
3698                 int i = inkey();
3699
3700                 byte flag;
3701                 if ('M' == i)
3702                         flag = (DO_AUTOPICK | DO_QUERY_AUTOPICK);
3703                 else if ('N' == i)
3704                         flag = DONT_AUTOPICK;
3705                 else if ('K' == i)
3706                         flag = DO_AUTODESTROY;
3707                 else if ('D' == i)
3708                         flag = (DO_AUTOPICK | DO_QUERY_AUTOPICK | DONT_AUTOPICK);
3709                 else
3710                         break;
3711
3712                 Term_fresh();
3713
3714                 if (~display_autopick & flag)
3715                         display_autopick |= flag;
3716                 else
3717                         display_autopick &= ~flag;
3718                 display_map(player_ptr, &cy, &cx);
3719         }
3720
3721         display_autopick = 0;
3722         screen_load();
3723 }
3724
3725
3726 /*
3727  * Track a new monster
3728  * @param player_ptr プレーヤーへの参照ポインタ
3729  * @param m_idx トラッキング対象のモンスターID。0の時キャンセル
3730  * @param なし
3731  */
3732 void health_track(player_type *player_ptr, MONSTER_IDX m_idx)
3733 {
3734         /* Mount monster is already tracked */
3735         if (m_idx && m_idx == player_ptr->riding) return;
3736
3737         /* Track a new guy */
3738         player_ptr->health_who = m_idx;
3739
3740         /* Redraw (later) */
3741         player_ptr->redraw |= (PR_HEALTH);
3742 }
3743
3744
3745 /*
3746  * Moves the cursor to a given MAP (y,x) location
3747  */
3748 void move_cursor_relative(int row, int col)
3749 {
3750         /* Real co-ords convert to screen positions */
3751         row -= panel_row_prt;
3752
3753         /* Go there */
3754         Term_gotoxy(panel_col_of(col), row);
3755 }
3756
3757
3758 /*
3759  * print project path
3760  */
3761 void print_path(player_type *player_ptr, POSITION y, POSITION x)
3762 {
3763         int path_n;
3764         u16b path_g[512];
3765         byte default_color = TERM_SLATE;
3766
3767         if (!display_path) return;
3768         if (project_length == -1) return;
3769
3770         /* Get projection path */
3771         floor_type *floor_ptr = player_ptr->current_floor_ptr;
3772         path_n = project_path(player_ptr, path_g, (project_length ? project_length : MAX_RANGE), player_ptr->y, player_ptr->x, y, x, PROJECT_PATH | PROJECT_THRU);
3773
3774         player_ptr->redraw |= (PR_MAP);
3775         handle_stuff(player_ptr);
3776
3777         /* Draw path */
3778         for (int i = 0; i < path_n; i++)
3779         {
3780                 POSITION ny = GRID_Y(path_g[i]);
3781                 POSITION nx = GRID_X(path_g[i]);
3782                 grid_type *g_ptr = &floor_ptr->grid_array[ny][nx];
3783
3784                 if (panel_contains(ny, nx))
3785                 {
3786                         TERM_COLOR a = default_color;
3787                         SYMBOL_CODE c;
3788
3789                         TERM_COLOR ta = default_color;
3790                         SYMBOL_CODE tc = '*';
3791
3792                         if (g_ptr->m_idx && floor_ptr->m_list[g_ptr->m_idx].ml)
3793                         {
3794                                 /* Determine what is there */
3795                                 map_info(player_ptr, ny, nx, &a, &c, &ta, &tc);
3796
3797                                 if (!IS_ASCII_GRAPHICS(a))
3798                                         a = default_color;
3799                                 else if (c == '.' && (a == TERM_WHITE || a == TERM_L_WHITE))
3800                                         a = default_color;
3801                                 else if (a == default_color)
3802                                         a = TERM_WHITE;
3803                         }
3804
3805                         if (!use_graphics)
3806                         {
3807                                 if (current_world_ptr->timewalk_m_idx) a = TERM_DARK;
3808                                 else if (IS_INVULN(player_ptr) || player_ptr->timewalk) a = TERM_WHITE;
3809                                 else if (player_ptr->wraith_form) a = TERM_L_DARK;
3810                         }
3811
3812                         c = '*';
3813
3814                         /* Hack -- Queue it */
3815                         Term_queue_bigchar(panel_col_of(nx), ny - panel_row_prt, a, c, ta, tc);
3816                 }
3817
3818                 /* Known Wall */
3819                 if ((g_ptr->info & CAVE_MARK) && !cave_have_flag_grid(g_ptr, FF_PROJECT)) break;
3820
3821                 /* Change color */
3822                 if (nx == x && ny == y) default_color = TERM_L_DARK;
3823         }
3824 }
3825
3826
3827 /*
3828  * Hack -- track the given monster race
3829  */
3830 void monster_race_track(player_type *player_ptr, MONRACE_IDX r_idx)
3831 {
3832         player_ptr->monster_race_idx = r_idx;
3833         player_ptr->window |= (PW_MONSTER);
3834 }
3835
3836
3837 /*
3838  * Hack -- track the given object kind
3839  */
3840 void object_kind_track(player_type *player_ptr, KIND_OBJECT_IDX k_idx)
3841 {
3842         player_ptr->object_kind_idx = k_idx;
3843         player_ptr->window |= (PW_OBJECT);
3844 }
3845
3846
3847 /*!
3848  * @brief 実ゲームプレイ時間を更新する
3849  */
3850 void update_playtime(void)
3851 {
3852         /* Check if the game has started */
3853         if (current_world_ptr->start_time != 0)
3854         {
3855                 u32b tmp = (u32b)time(NULL);
3856                 current_world_ptr->play_time += (tmp - current_world_ptr->start_time);
3857                 current_world_ptr->start_time = tmp;
3858         }
3859 }
3860
3861
3862 /*
3863  * Mega-Hack -- Delayed visual update
3864  * Only used if update_view(), update_lite() or update_mon_lite() was called
3865  */
3866 void delayed_visual_update(player_type *player_ptr)
3867 {
3868         /* Update needed grids */
3869         floor_type *floor_ptr = player_ptr->current_floor_ptr;
3870         for (int i = 0; i < floor_ptr->redraw_n; i++)
3871         {
3872                 POSITION y = floor_ptr->redraw_y[i];
3873                 POSITION x = floor_ptr->redraw_x[i];
3874                 grid_type *g_ptr;
3875                 g_ptr = &floor_ptr->grid_array[y][x];
3876
3877                 /* Update only needed grids (prevent multiple updating) */
3878                 if (!(g_ptr->info & CAVE_REDRAW)) continue;
3879
3880                 /* If required, note */
3881                 if (g_ptr->info & CAVE_NOTE) note_spot(player_ptr, y, x);
3882
3883                 lite_spot(player_ptr, y, x);
3884
3885                 /* Hack -- Visual update of monster on this grid */
3886                 if (g_ptr->m_idx) update_monster(player_ptr, g_ptr->m_idx, FALSE);
3887
3888                 /* No longer in the array */
3889                 g_ptr->info &= ~(CAVE_NOTE | CAVE_REDRAW);
3890         }
3891
3892         /* None left */
3893         floor_ptr->redraw_n = 0;
3894 }