OSDN Git Service

Merge remote-tracking branch 'remotes/origin/feature/Fix-Compile-on-Linux' into develop
[hengband/hengband.git] / src / window / main-window-util.c
1 #include "window/main-window-util.h"
2 #include "flavor/flavor-describer.h"
3 #include "flavor/object-flavor-types.h"
4 #include "floor/cave.h"
5 #include "floor/geometry.h"
6 #include "game-option/map-screen-options.h"
7 #include "game-option/special-options.h"
8 #include "grid/grid.h"
9 #include "monster-race/monster-race.h"
10 #include "system/floor-type-definition.h"
11 #include "system/monster-race-definition.h"
12 #include "system/object-type-definition.h"
13 #include "term/gameterm.h"
14 #include "term/screen-processor.h"
15 #include "term/term-color-types.h"
16 #include "view/display-map.h"
17 #include "world/world.h"
18
19 /*
20  * Dungeon size info
21  */
22 POSITION panel_row_min;
23 POSITION panel_row_max;
24 POSITION panel_col_min;
25 POSITION panel_col_max;
26 POSITION panel_col_prt;
27 POSITION panel_row_prt;
28
29 int match_autopick;
30 object_type *autopick_obj; /*!< 各種自動拾い処理時に使うオブジェクトポインタ */
31 int feat_priority; /*!< マップ縮小表示時に表示すべき地形の優先度を保管する */
32
33 static concptr simplify_list[][2] = {
34 #ifdef JP
35     { "の魔法書", "" }, { NULL, NULL }
36 #else
37     { "^Ring of ", "=" }, { "^Amulet of ", "\"" }, { "^Scroll of ", "?" }, { "^Scroll titled ", "?" }, { "^Wand of ", "-" }, { "^Rod of ", "-" },
38     { "^Staff of ", "_" }, { "^Potion of ", "!" }, { " Spellbook ", "" }, { "^Book of ", "" }, { " Magic [", "[" }, { " Book [", "[" }, { " Arts [", "[" },
39     { "^Set of ", "" }, { "^Pair of ", "" }, { NULL, NULL }
40 #endif
41 };
42
43 /*!
44  * @brief 画面左の能力値表示を行うために指定位置から13キャラ分を空白消去後指定のメッセージを明るい青で描画する /
45  * Print character info at given row, column in a 13 char field
46  * @param info 表示文字列
47  * @param row 描画列
48  * @param col 描画行
49  * @return なし
50  */
51 void print_field(concptr info, TERM_LEN row, TERM_LEN col)
52 {
53     c_put_str(TERM_WHITE, "             ", row, col);
54     c_put_str(TERM_L_BLUE, info, row, col);
55 }
56
57 /*
58  * Prints the map of the dungeon
59  *
60  * Note that, for efficiency, we contain an "optimized" version
61  * of both "lite_spot()" and "print_rel()", and that we use the
62  * "lite_spot()" function to display the player grid, if needed.
63  */
64 void print_map(player_type *player_ptr)
65 {
66     TERM_LEN wid, hgt;
67     term_get_size(&wid, &hgt);
68
69     wid -= COL_MAP + 2;
70     hgt -= ROW_MAP + 2;
71
72     int v;
73     (void)term_get_cursor(&v);
74
75     (void)term_set_cursor(0);
76
77     floor_type *floor_ptr = player_ptr->current_floor_ptr;
78     POSITION xmin = (0 < panel_col_min) ? panel_col_min : 0;
79     POSITION xmax = (floor_ptr->width - 1 > panel_col_max) ? panel_col_max : floor_ptr->width - 1;
80     POSITION ymin = (0 < panel_row_min) ? panel_row_min : 0;
81     POSITION ymax = (floor_ptr->height - 1 > panel_row_max) ? panel_row_max : floor_ptr->height - 1;
82
83     for (POSITION y = 1; y <= ymin - panel_row_prt; y++) {
84         term_erase(COL_MAP, y, wid);
85     }
86
87     for (POSITION y = ymax - panel_row_prt; y <= hgt; y++) {
88         term_erase(COL_MAP, y, wid);
89     }
90
91     for (POSITION y = ymin; y <= ymax; y++) {
92         for (POSITION x = xmin; x <= xmax; x++) {
93             TERM_COLOR a;
94             SYMBOL_CODE c;
95             TERM_COLOR ta;
96             SYMBOL_CODE tc;
97             map_info(player_ptr, y, x, &a, &c, &ta, &tc);
98             if (!use_graphics) {
99                 if (current_world_ptr->timewalk_m_idx)
100                     a = TERM_DARK;
101                 else if (is_invuln(player_ptr) || player_ptr->timewalk)
102                     a = TERM_WHITE;
103                 else if (player_ptr->wraith_form)
104                     a = TERM_L_DARK;
105             }
106
107             term_queue_bigchar(panel_col_of(x), y - panel_row_prt, a, c, ta, tc);
108         }
109     }
110
111     lite_spot(player_ptr, player_ptr->y, player_ptr->x);
112     (void)term_set_cursor(v);
113 }
114
115 static void display_shortened_item_name(player_type *player_ptr, object_type *o_ptr, int y)
116 {
117     char buf[MAX_NLEN];
118     describe_flavor(player_ptr, buf, o_ptr, (OD_NO_FLAVOR | OD_OMIT_PREFIX | OD_NAME_ONLY));
119     TERM_COLOR attr = tval_to_attr[o_ptr->tval % 128];
120
121     if (player_ptr->image) {
122         attr = TERM_WHITE;
123         strcpy(buf, _("何か奇妙な物", "something strange"));
124     }
125
126     char *c = buf;
127     for (c = buf; *c; c++) {
128         for (int i = 0; simplify_list[i][1]; i++) {
129             concptr org_w = simplify_list[i][0];
130
131             if (*org_w == '^') {
132                 if (c == buf)
133                     org_w++;
134                 else
135                     continue;
136             }
137
138             if (strncmp(c, org_w, strlen(org_w)))
139                 continue;
140
141             char *s = c;
142             concptr tmp = simplify_list[i][1];
143             while (*tmp)
144                 *s++ = *tmp++;
145             tmp = c + strlen(org_w);
146             while (*tmp)
147                 *s++ = *tmp++;
148             *s = '\0';
149         }
150     }
151
152     c = buf;
153     int len = 0;
154     /* 半角 12 文字分で切る */
155     while (*c) {
156 #ifdef JP
157         if (iskanji(*c)) {
158             if (len + 2 > 12)
159                 break;
160             c += 2;
161             len += 2;
162         } else
163 #endif
164         {
165             if (len + 1 > 12)
166                 break;
167             c++;
168             len++;
169         }
170     }
171
172     *c = '\0';
173     term_putstr(0, y, 12, attr, buf);
174 }
175
176 /*
177  * Display a "small-scale" map of the dungeon in the active Term
178  */
179 void display_map(player_type *player_ptr, int *cy, int *cx)
180 {
181     int i, j, x, y;
182
183     TERM_COLOR ta;
184     SYMBOL_CODE tc;
185
186     byte tp;
187
188     TERM_COLOR **bigma;
189     SYMBOL_CODE **bigmc;
190     byte **bigmp;
191
192     TERM_COLOR **ma;
193     SYMBOL_CODE **mc;
194     byte **mp;
195
196     bool old_view_special_lite = view_special_lite;
197     bool old_view_granite_lite = view_granite_lite;
198     TERM_LEN hgt, wid, yrat, xrat;
199     int **match_autopick_yx;
200     object_type ***object_autopick_yx;
201     term_get_size(&wid, &hgt);
202     hgt -= 2;
203     wid -= 14;
204     if (use_bigtile)
205         wid /= 2;
206
207     floor_type *floor_ptr = player_ptr->current_floor_ptr;
208     yrat = (floor_ptr->height + hgt - 1) / hgt;
209     xrat = (floor_ptr->width + wid - 1) / wid;
210     view_special_lite = FALSE;
211     view_granite_lite = FALSE;
212
213     C_MAKE(ma, (hgt + 2), TERM_COLOR *);
214     C_MAKE(mc, (hgt + 2), char_ptr);
215     C_MAKE(mp, (hgt + 2), byte_ptr);
216     C_MAKE(match_autopick_yx, (hgt + 2), int *);
217     C_MAKE(object_autopick_yx, (hgt + 2), object_type **);
218     for (y = 0; y < (hgt + 2); y++) {
219         C_MAKE(ma[y], (wid + 2), TERM_COLOR);
220         C_MAKE(mc[y], (wid + 2), char);
221         C_MAKE(mp[y], (wid + 2), byte);
222         C_MAKE(match_autopick_yx[y], (wid + 2), int);
223         C_MAKE(object_autopick_yx[y], (wid + 2), object_type *);
224         for (x = 0; x < wid + 2; ++x) {
225             match_autopick_yx[y][x] = -1;
226             object_autopick_yx[y][x] = NULL;
227             ma[y][x] = TERM_WHITE;
228             mc[y][x] = ' ';
229             mp[y][x] = 0;
230         }
231     }
232
233     C_MAKE(bigma, (floor_ptr->height + 2), TERM_COLOR *);
234     C_MAKE(bigmc, (floor_ptr->height + 2), char_ptr);
235     C_MAKE(bigmp, (floor_ptr->height + 2), byte_ptr);
236     for (y = 0; y < (floor_ptr->height + 2); y++) {
237         C_MAKE(bigma[y], (floor_ptr->width + 2), TERM_COLOR);
238         C_MAKE(bigmc[y], (floor_ptr->width + 2), char);
239         C_MAKE(bigmp[y], (floor_ptr->width + 2), byte);
240         for (x = 0; x < floor_ptr->width + 2; ++x) {
241             bigma[y][x] = TERM_WHITE;
242             bigmc[y][x] = ' ';
243             bigmp[y][x] = 0;
244         }
245     }
246
247     for (i = 0; i < floor_ptr->width; ++i) {
248         for (j = 0; j < floor_ptr->height; ++j) {
249             x = i / xrat + 1;
250             y = j / yrat + 1;
251
252             match_autopick = -1;
253             autopick_obj = NULL;
254             feat_priority = -1;
255             map_info(player_ptr, j, i, &ta, &tc, &ta, &tc);
256             tp = (byte)feat_priority;
257             if (match_autopick != -1 && (match_autopick_yx[y][x] == -1 || match_autopick_yx[y][x] > match_autopick)) {
258                 match_autopick_yx[y][x] = match_autopick;
259                 object_autopick_yx[y][x] = autopick_obj;
260                 tp = 0x7f;
261             }
262
263             bigmc[j + 1][i + 1] = tc;
264             bigma[j + 1][i + 1] = ta;
265             bigmp[j + 1][i + 1] = tp;
266         }
267     }
268
269     for (j = 0; j < floor_ptr->height; ++j) {
270         for (i = 0; i < floor_ptr->width; ++i) {
271             x = i / xrat + 1;
272             y = j / yrat + 1;
273
274             tc = bigmc[j + 1][i + 1];
275             ta = bigma[j + 1][i + 1];
276             tp = bigmp[j + 1][i + 1];
277             if (mp[y][x] == tp) {
278                 int t;
279                 int cnt = 0;
280
281                 for (t = 0; t < 8; t++) {
282                     if (tc == bigmc[j + 1 + ddy_cdd[t]][i + 1 + ddx_cdd[t]] && ta == bigma[j + 1 + ddy_cdd[t]][i + 1 + ddx_cdd[t]])
283                         cnt++;
284                 }
285                 if (cnt <= 4)
286                     tp++;
287             }
288
289             if (mp[y][x] < tp) {
290                 mc[y][x] = tc;
291                 ma[y][x] = ta;
292                 mp[y][x] = tp;
293             }
294         }
295     }
296
297     x = wid + 1;
298     y = hgt + 1;
299
300     mc[0][0] = mc[0][x] = mc[y][0] = mc[y][x] = '+';
301     for (x = 1; x <= wid; x++)
302         mc[0][x] = mc[y][x] = '-';
303
304     for (y = 1; y <= hgt; y++)
305         mc[y][0] = mc[y][x] = '|';
306
307     for (y = 0; y < hgt + 2; ++y) {
308         term_gotoxy(COL_MAP, y);
309         for (x = 0; x < wid + 2; ++x) {
310             ta = ma[y][x];
311             tc = mc[y][x];
312             if (!use_graphics) {
313                 if (current_world_ptr->timewalk_m_idx)
314                     ta = TERM_DARK;
315                 else if (is_invuln(player_ptr) || player_ptr->timewalk)
316                     ta = TERM_WHITE;
317                 else if (player_ptr->wraith_form)
318                     ta = TERM_L_DARK;
319             }
320
321             term_add_bigch(ta, tc);
322         }
323     }
324
325     for (y = 1; y < hgt + 1; ++y) {
326         match_autopick = -1;
327         for (x = 1; x <= wid; x++) {
328             if (match_autopick_yx[y][x] != -1 && (match_autopick > match_autopick_yx[y][x] || match_autopick == -1)) {
329                 match_autopick = match_autopick_yx[y][x];
330                 autopick_obj = object_autopick_yx[y][x];
331             }
332         }
333
334         term_putstr(0, y, 12, 0, "            ");
335         if (match_autopick != -1)
336             display_shortened_item_name(player_ptr, autopick_obj, y);
337     }
338
339     (*cy) = player_ptr->y / yrat + 1 + ROW_MAP;
340     if (!use_bigtile)
341         (*cx) = player_ptr->x / xrat + 1 + COL_MAP;
342     else
343         (*cx) = (player_ptr->x / xrat + 1) * 2 + COL_MAP;
344
345     view_special_lite = old_view_special_lite;
346     view_granite_lite = old_view_granite_lite;
347
348     for (y = 0; y < (hgt + 2); y++) {
349         C_KILL(ma[y], (wid + 2), TERM_COLOR);
350         C_KILL(mc[y], (wid + 2), SYMBOL_CODE);
351         C_KILL(mp[y], (wid + 2), byte);
352         C_KILL(match_autopick_yx[y], (wid + 2), int);
353         C_KILL(object_autopick_yx[y], (wid + 2), object_type *);
354     }
355
356     C_KILL(ma, (hgt + 2), TERM_COLOR *);
357     C_KILL(mc, (hgt + 2), char_ptr);
358     C_KILL(mp, (hgt + 2), byte_ptr);
359     C_KILL(match_autopick_yx, (hgt + 2), int *);
360     C_KILL(object_autopick_yx, (hgt + 2), object_type **);
361     for (y = 0; y < (floor_ptr->height + 2); y++) {
362         C_KILL(bigma[y], (floor_ptr->width + 2), TERM_COLOR);
363         C_KILL(bigmc[y], (floor_ptr->width + 2), SYMBOL_CODE);
364         C_KILL(bigmp[y], (floor_ptr->width + 2), byte);
365     }
366
367     C_KILL(bigma, (floor_ptr->height + 2), TERM_COLOR *);
368     C_KILL(bigmc, (floor_ptr->height + 2), char_ptr);
369     C_KILL(bigmp, (floor_ptr->height + 2), byte_ptr);
370 }
371
372 void set_term_color(player_type *player_ptr, POSITION y, POSITION x, TERM_COLOR *ap, SYMBOL_CODE *cp)
373 {
374     if (!player_bold(player_ptr, y, x))
375         return;
376
377     monster_race *r_ptr = &r_info[0];
378     *ap = r_ptr->x_attr;
379     *cp = r_ptr->x_char;
380     feat_priority = 31;
381 }
382
383 /*
384  * Calculate panel colum of a location in the map
385  */
386 int panel_col_of(int col)
387 {
388     col -= panel_col_min;
389     if (use_bigtile)
390         col *= 2;
391     return col + 13;
392 }