OSDN Git Service

[Fix] display-sub-windows.c 内のDoxygenコメントエラー修正 / Fix Doxygen comment error in display...
[hengbandforosx/hengbandosx.git] / src / window / display-sub-windows.c
1 #include "window/display-sub-windows.h"
2 #include "core/window-redrawer.h"
3 #include "flavor/flavor-describer.h"
4 #include "floor/cave.h"
5 #include "game-option/option-flags.h"
6 #include "game-option/special-options.h"
7 #include "game-option/text-display-options.h"
8 #include "grid/feature.h"
9 #include "grid/grid.h"
10 #include "inventory/inventory-describer.h"
11 #include "inventory/inventory-slot-types.h"
12 #include "inventory/inventory-util.h"
13 #include "monster-race/monster-race.h"
14 #include "monster-race/race-flags1.h"
15 #include "monster/monster-flag-types.h"
16 #include "monster/monster-info.h"
17 #include "object/item-tester-hooker.h"
18 #include "object/object-info.h"
19 #include "spell-kind/magic-item-recharger.h"
20 #include "system/floor-type-definition.h"
21 #include "system/monster-type-definition.h"
22 #include "target/target-preparation.h"
23 #include "target/target-types.h"
24 #include "term/gameterm.h"
25 #include "term/screen-processor.h"
26 #include "term/term-color-types.h"
27 #include "view/display-lore.h"
28 #include "view/display-map.h"
29 #include "view/display-messages.h"
30 #include "view/display-player.h"
31 #include "view/object-describer.h"
32 #include "window/main-window-equipments.h"
33 #include "window/main-window-util.h"
34 #include "world/world.h"
35
36 /*!
37  * @brief サブウィンドウに所持品一覧を表示する / Hack -- display inventory in sub-windows
38  * @param player_ptr プレーヤーへの参照ポインタ
39  * @return なし
40  */
41 void fix_inventory(player_type *player_ptr, tval_type item_tester_tval)
42 {
43     for (int j = 0; j < 8; j++) {
44         term_type *old = Term;
45         if (!angband_term[j])
46             continue;
47
48         if (!(window_flag[j] & (PW_INVEN)))
49             continue;
50
51         term_activate(angband_term[j]);
52         display_inventory(player_ptr, item_tester_tval);
53         term_fresh();
54         term_activate(old);
55     }
56 }
57
58 /*!
59  * @brief モンスターの現在数を一行で表現する / Print monster info in line
60  * @param x 表示列
61  * @param y 表示行
62  * @param m_ptr 思い出を表示するモンスター情報の参照ポインタ
63  * @param n_same モンスターの数の現在数
64  * @details
65  * <pre>
66  * nnn X LV name
67  *  nnn : number or unique(U) or wanted unique(W)
68  *  X   : symbol of monster
69  *  LV  : monster lv if known
70  *  name: name of monster
71  * </pre>
72  * @return なし
73  */
74 static void print_monster_line(TERM_LEN x, TERM_LEN y, monster_type *m_ptr, int n_same)
75 {
76     char buf[256];
77     MONRACE_IDX r_idx = m_ptr->ap_r_idx;
78     monster_race *r_ptr = &r_info[r_idx];
79
80     term_gotoxy(x, y);
81     if (!r_ptr)
82         return;
83     if (r_ptr->flags1 & RF1_UNIQUE) {
84         bool is_bounty = FALSE;
85         for (int i = 0; i < MAX_BOUNTY; i++) {
86             if (current_world_ptr->bounty_r_idx[i] == r_idx) {
87                 is_bounty = TRUE;
88                 break;
89             }
90         }
91
92         term_addstr(-1, TERM_WHITE, is_bounty ? "  W" : "  U");
93     } else {
94         sprintf(buf, "%3d", n_same);
95         term_addstr(-1, TERM_WHITE, buf);
96     }
97
98     term_addstr(-1, TERM_WHITE, " ");
99     term_add_bigch(r_ptr->x_attr, r_ptr->x_char);
100
101     if (r_ptr->r_tkills && !(m_ptr->mflag2 & MFLAG2_KAGE)) {
102         sprintf(buf, " %2d", (int)r_ptr->level);
103     } else {
104         strcpy(buf, " ??");
105     }
106
107     term_addstr(-1, TERM_WHITE, buf);
108
109     sprintf(buf, " %s ", r_name + r_ptr->name);
110     term_addstr(-1, TERM_WHITE, buf);
111 }
112
113 /*!
114  * @brief モンスターの出現リストを表示する / Print monster info in line
115  * @param x 表示列
116  * @param y 表示行
117  * @param max_lines 最大何行描画するか
118  */
119 void print_monster_list(floor_type *floor_ptr, TERM_LEN x, TERM_LEN y, TERM_LEN max_lines)
120 {
121     TERM_LEN line = y;
122     monster_type *last_mons = NULL;
123     monster_type *m_ptr = NULL;
124     int n_same = 0;
125     int i;
126     for (i = 0; i < tmp_pos.n; i++) {
127         grid_type *g_ptr = &floor_ptr->grid_array[tmp_pos.y[i]][tmp_pos.x[i]];
128         if (!g_ptr->m_idx || !floor_ptr->m_list[g_ptr->m_idx].ml)
129             continue;
130         m_ptr = &floor_ptr->m_list[g_ptr->m_idx];
131         if (is_pet(m_ptr))
132             continue; // pet
133         if (!m_ptr->r_idx)
134             continue; // dead?
135
136         //ソート済みなので同じモンスターは連続する.これを利用して同じモンスターをカウント,まとめて表示する.
137         //先頭モンスター
138         if (!last_mons) {
139             last_mons = m_ptr;
140             n_same = 1;
141             continue;
142         }
143
144         // same race?
145         if (last_mons->ap_r_idx == m_ptr->ap_r_idx) {
146             n_same++;
147             continue; //表示処理を次に回す
148         }
149
150         // print last mons info
151         print_monster_line(x, line++, last_mons, n_same);
152         n_same = 1;
153         last_mons = m_ptr;
154         if (line - y - 1 == max_lines)
155             break;
156     }
157
158     if (line - y - 1 == max_lines && i != tmp_pos.n) {
159         term_gotoxy(x, line);
160         term_addstr(-1, TERM_WHITE, "-- and more --");
161     } else {
162         if (last_mons)
163             print_monster_line(x, line++, last_mons, n_same);
164     }
165 }
166
167 /*!
168  * @brief 出現中モンスターのリストをサブウィンドウに表示する / Hack -- display monster list in sub-windows
169  * @param player_ptr プレーヤーへの参照ポインタ
170  * @return なし
171  */
172 void fix_monster_list(player_type *player_ptr)
173 {
174     for (int j = 0; j < 8; j++) {
175         term_type *old = Term;
176         if (!angband_term[j])
177             continue;
178         if (!(window_flag[j] & PW_MONSTER_LIST))
179             continue;
180
181         term_activate(angband_term[j]);
182         int w, h;
183         term_get_size(&w, &h);
184         term_clear();
185         target_set_prepare(player_ptr, TARGET_LOOK);
186         print_monster_list(player_ptr->current_floor_ptr, 0, 0, h);
187         term_fresh();
188         term_activate(old);
189     }
190 }
191
192 /*!
193  * @brief 装備アイテム一覧を表示する /
194  * Choice window "shadow" of the "show_equip()" function
195  * @return なし
196  */
197 static void display_equipment(player_type *owner_ptr, tval_type tval)
198 {
199     if (!owner_ptr || !owner_ptr->inventory_list)
200         return;
201
202     TERM_LEN wid, hgt;
203     term_get_size(&wid, &hgt);
204
205     TERM_COLOR attr = TERM_WHITE;
206     char tmp_val[80];
207     GAME_TEXT o_name[MAX_NLEN];
208     for (int i = INVEN_RARM; i < INVEN_TOTAL; i++) {
209         object_type *o_ptr;
210         o_ptr = &owner_ptr->inventory_list[i];
211         tmp_val[0] = tmp_val[1] = tmp_val[2] = ' ';
212         if (select_ring_slot ? is_ring_slot(i) : item_tester_okay(owner_ptr, o_ptr, tval)) {
213             tmp_val[0] = index_to_label(i);
214             tmp_val[1] = ')';
215         }
216
217         term_putstr(0, i - INVEN_RARM, 3, TERM_WHITE, tmp_val);
218         if ((((i == INVEN_RARM) && owner_ptr->left_hand_weapon) || ((i == INVEN_LARM) && owner_ptr->right_hand_weapon)) && owner_ptr->two_handed_weapon) {
219             strcpy(o_name, _("(武器を両手持ち)", "(wielding with two-hands)"));
220             attr = TERM_WHITE;
221         } else {
222             describe_flavor(owner_ptr, o_name, o_ptr, 0);
223             attr = tval_to_attr[o_ptr->tval % 128];
224         }
225
226         int n = strlen(o_name);
227         if (o_ptr->timeout)
228             attr = TERM_L_DARK;
229
230         term_putstr(3, i - INVEN_RARM, n, attr, o_name);
231         term_erase(3 + n, i - INVEN_RARM, 255);
232         if (show_weights) {
233             int wgt = o_ptr->weight * o_ptr->number;
234             sprintf(tmp_val, _("%3d.%1d kg", "%3d.%1d lb"), _(lbtokg1(wgt), wgt / 10), _(lbtokg2(wgt), wgt % 10));
235             prt(tmp_val, i - INVEN_RARM, wid - (show_labels ? 28 : 9));
236         }
237
238         if (show_labels) {
239             term_putstr(wid - 20, i - INVEN_RARM, -1, TERM_WHITE, " <-- ");
240             prt(mention_use(owner_ptr, i), i - INVEN_RARM, wid - 15);
241         }
242     }
243
244     for (int i = INVEN_TOTAL - INVEN_RARM; i < hgt; i++)
245         term_erase(0, i, 255);
246 }
247
248 /*!
249  * @brief 現在の装備品をサブウィンドウに表示する /
250  * Hack -- display equipment in sub-windows
251  * @param player_ptr プレーヤーへの参照ポインタ
252  * @return なし
253  */
254 void fix_equip(player_type *player_ptr, tval_type item_tester_tval)
255 {
256     for (int j = 0; j < 8; j++) {
257         term_type *old = Term;
258         if (!angband_term[j])
259             continue;
260         if (!(window_flag[j] & (PW_EQUIP)))
261             continue;
262
263         term_activate(angband_term[j]);
264         display_equipment(player_ptr, item_tester_tval);
265         term_fresh();
266         term_activate(old);
267     }
268 }
269
270 /*!
271  * @brief 現在のプレイヤーステータスをサブウィンドウに表示する /
272  * @param player_ptr プレーヤーへの参照ポインタ
273  * Hack -- display character in sub-windows
274  * @return なし
275  */
276 void fix_player(player_type *player_ptr)
277 {
278     for (int j = 0; j < 8; j++) {
279         term_type *old = Term;
280         if (!angband_term[j])
281             continue;
282
283         if (!(window_flag[j] & (PW_PLAYER)))
284             continue;
285
286         term_activate(angband_term[j]);
287         update_playtime();
288         display_player(player_ptr, 0);
289         term_fresh();
290         term_activate(old);
291     }
292 }
293
294 /*!
295  * @brief ゲームメッセージ履歴をサブウィンドウに表示する /
296  * Hack -- display recent messages in sub-windows
297  * Adjust for width and split messages
298  * @return なし
299  */
300 void fix_message(void)
301 {
302     for (int j = 0; j < 8; j++) {
303         term_type *old = Term;
304         if (!angband_term[j])
305             continue;
306
307         if (!(window_flag[j] & (PW_MESSAGE)))
308             continue;
309
310         term_activate(angband_term[j]);
311         TERM_LEN w, h;
312         term_get_size(&w, &h);
313         for (int i = 0; i < h; i++) {
314             term_putstr(0, (h - 1) - i, -1, (byte)((i < now_message) ? TERM_WHITE : TERM_SLATE), message_str((s16b)i));
315             TERM_LEN x, y;
316             term_locate(&x, &y);
317             term_erase(x, y, 255);
318         }
319
320         term_fresh();
321         term_activate(old);
322     }
323 }
324
325 /*!
326  * @brief 簡易マップをサブウィンドウに表示する /
327  * Hack -- display overhead view in sub-windows
328  * Adjust for width and split messages
329  * @param player_ptr プレーヤーへの参照ポインタ
330  * @return なし
331  * @details
332  * Note that the "player" symbol does NOT appear on the map.
333  */
334 void fix_overhead(player_type *player_ptr)
335 {
336     for (int j = 0; j < 8; j++) {
337         term_type *old = Term;
338         TERM_LEN wid, hgt;
339         if (!angband_term[j])
340             continue;
341
342         if (!(window_flag[j] & (PW_OVERHEAD)))
343             continue;
344
345         term_activate(angband_term[j]);
346         term_get_size(&wid, &hgt);
347         if (wid > COL_MAP + 2 && hgt > ROW_MAP + 2) {
348             int cy, cx;
349             display_map(player_ptr, &cy, &cx);
350             term_fresh();
351         }
352
353         term_activate(old);
354     }
355 }
356
357 static void display_dungeon(player_type *player_ptr)
358 {
359     TERM_COLOR ta = 0;
360     SYMBOL_CODE tc = '\0';
361
362     for (TERM_LEN x = player_ptr->x - Term->wid / 2 + 1; x <= player_ptr->x + Term->wid / 2; x++) {
363         for (TERM_LEN y = player_ptr->y - Term->hgt / 2 + 1; y <= player_ptr->y + Term->hgt / 2; y++) {
364             TERM_COLOR a;
365             SYMBOL_CODE c;
366             if (!in_bounds2(player_ptr->current_floor_ptr, y, x)) {
367                 feature_type *f_ptr = &f_info[feat_none];
368                 a = f_ptr->x_attr[F_LIT_STANDARD];
369                 c = f_ptr->x_char[F_LIT_STANDARD];
370                 term_queue_char(x - player_ptr->x + Term->wid / 2 - 1, y - player_ptr->y + Term->hgt / 2 - 1, a, c, ta, tc);
371                 continue;
372             }
373
374             map_info(player_ptr, y, x, &a, &c, &ta, &tc);
375
376             if (!use_graphics) {
377                 if (current_world_ptr->timewalk_m_idx)
378                     a = TERM_DARK;
379                 else if (is_invuln(player_ptr) || player_ptr->timewalk)
380                     a = TERM_WHITE;
381                 else if (player_ptr->wraith_form)
382                     a = TERM_L_DARK;
383             }
384
385             term_queue_char(x - player_ptr->x + Term->wid / 2 - 1, y - player_ptr->y + Term->hgt / 2 - 1, a, c, ta, tc);
386         }
387     }
388 }
389
390 /*!
391  * @brief ダンジョンの地形をサブウィンドウに表示する /
392  * Hack -- display dungeon view in sub-windows
393  * @param player_ptr プレーヤーへの参照ポインタ
394  * @return なし
395  */
396 void fix_dungeon(player_type *player_ptr)
397 {
398     for (int j = 0; j < 8; j++) {
399         term_type *old = Term;
400         if (!angband_term[j])
401             continue;
402
403         if (!(window_flag[j] & (PW_DUNGEON)))
404             continue;
405
406         term_activate(angband_term[j]);
407         display_dungeon(player_ptr);
408         term_fresh();
409         term_activate(old);
410     }
411 }
412
413 /*!
414  * @brief モンスターの思い出をサブウィンドウに表示する /
415  * Hack -- display dungeon view in sub-windows
416  * @param player_ptr プレーヤーへの参照ポインタ
417  * @return なし
418  */
419 void fix_monster(player_type *player_ptr)
420 {
421     for (int j = 0; j < 8; j++) {
422         term_type *old = Term;
423         if (!angband_term[j])
424             continue;
425
426         if (!(window_flag[j] & (PW_MONSTER)))
427             continue;
428
429         term_activate(angband_term[j]);
430         if (player_ptr->monster_race_idx)
431             display_roff(player_ptr);
432
433         term_fresh();
434         term_activate(old);
435     }
436 }
437
438 /*!
439  * @brief ベースアイテム情報をサブウィンドウに表示する /
440  * Hack -- display object recall in sub-windows
441  * @param player_ptr プレーヤーへの参照ポインタ
442  * @return なし
443  */
444 void fix_object(player_type *player_ptr)
445 {
446     for (int j = 0; j < 8; j++) {
447         term_type *old = Term;
448         if (!angband_term[j])
449             continue;
450
451         if (!(window_flag[j] & (PW_OBJECT)))
452             continue;
453
454         term_activate(angband_term[j]);
455         if (player_ptr->object_kind_idx)
456             display_koff(player_ptr, player_ptr->object_kind_idx);
457
458         term_fresh();
459         term_activate(old);
460     }
461 }
462
463 /*!
464  * @brief サブウィンドウに所持品、装備品リストの表示を行う /
465  * Flip "inven" and "equip" in any sub-windows
466  * @return なし
467  */
468 void toggle_inventory_equipment(player_type *owner_ptr)
469 {
470     for (int j = 0; j < 8; j++) {
471         if (!angband_term[j])
472             continue;
473
474         if (window_flag[j] & (PW_INVEN)) {
475             window_flag[j] &= ~(PW_INVEN);
476             window_flag[j] |= (PW_EQUIP);
477             owner_ptr->window |= (PW_EQUIP);
478             continue;
479         }
480
481         if (window_flag[j] & PW_EQUIP) {
482             window_flag[j] &= ~(PW_EQUIP);
483             window_flag[j] |= PW_INVEN;
484             owner_ptr->window |= PW_INVEN;
485         }
486     }
487 }