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"
9 #include "monster-race/monster-race.h"
10 #include "monster-race/race-indice-types.h"
11 #include "player/player-status.h"
12 #include "system/floor-type-definition.h"
13 #include "system/item-entity.h"
14 #include "system/monster-race-info.h"
15 #include "system/player-type-definition.h"
16 #include "term/gameterm.h"
17 #include "term/screen-processor.h"
18 #include "term/term-color-types.h"
19 #include "timed-effect/player-hallucination.h"
20 #include "timed-effect/timed-effects.h"
21 #include "view/display-map.h"
22 #include "world/world.h"
28 POSITION panel_row_min;
29 POSITION panel_row_max;
30 POSITION panel_col_min;
31 POSITION panel_col_max;
32 POSITION panel_col_prt;
33 POSITION panel_row_prt;
36 ItemEntity *autopick_obj; /*!< 各種自動拾い処理時に使うオブジェクトポインタ */
37 int feat_priority; /*!< マップ縮小表示時に表示すべき地形の優先度を保管する */
39 static concptr simplify_list[][2] = {
41 { "の魔法書", "" }, { nullptr, nullptr }
43 { "^Ring of ", "=" }, { "^Amulet of ", "\"" }, { "^Scroll of ", "?" }, { "^Scroll titled ", "?" }, { "^Wand of ", "-" }, { "^Rod of ", "-" },
44 { "^Staff of ", "_" }, { "^Potion of ", "!" }, { " Spellbook ", "" }, { "^Book of ", "" }, { " Magic [", "[" }, { " Book [", "[" }, { " Arts [", "[" },
45 { "^Set of ", "" }, { "^Pair of ", "" }, { nullptr, nullptr }
50 * @brief 画面左の能力値表示を行うために指定位置から13キャラ分を空白消去後指定のメッセージを明るい青で描画する /
51 * Print character info at given row, column in a 13 char field
56 void print_field(concptr info, TERM_LEN row, TERM_LEN col)
58 c_put_str(TERM_WHITE, " ", row, col);
59 c_put_str(TERM_L_BLUE, info, row, col);
63 * Prints the map of the dungeon
65 * Note that, for efficiency, we contain an "optimized" version
66 * of both "lite_spot()" and "print_rel()", and that we use the
67 * "lite_spot()" function to display the player grid, if needed.
69 void print_map(PlayerType *player_ptr)
72 term_get_size(&wid, &hgt);
78 (void)term_get_cursor(&v);
80 (void)term_set_cursor(0);
82 auto *floor_ptr = player_ptr->current_floor_ptr;
83 POSITION xmin = (0 < panel_col_min) ? panel_col_min : 0;
84 POSITION xmax = (floor_ptr->width - 1 > panel_col_max) ? panel_col_max : floor_ptr->width - 1;
85 POSITION ymin = (0 < panel_row_min) ? panel_row_min : 0;
86 POSITION ymax = (floor_ptr->height - 1 > panel_row_max) ? panel_row_max : floor_ptr->height - 1;
88 for (POSITION y = 1; y <= ymin - panel_row_prt; y++) {
89 term_erase(COL_MAP, y, wid);
92 for (POSITION y = ymax - panel_row_prt; y <= hgt; y++) {
93 term_erase(COL_MAP, y, wid);
96 for (POSITION y = ymin; y <= ymax; y++) {
97 for (POSITION x = xmin; x <= xmax; x++) {
102 map_info(player_ptr, y, x, &a, &c, &ta, &tc);
104 if (w_ptr->timewalk_m_idx) {
106 } else if (is_invuln(player_ptr) || player_ptr->timewalk) {
108 } else if (player_ptr->wraith_form) {
113 term_queue_bigchar(panel_col_of(x), y - panel_row_prt, a, c, ta, tc);
117 lite_spot(player_ptr, player_ptr->y, player_ptr->x);
118 (void)term_set_cursor(v);
121 static void display_shortened_item_name(PlayerType *player_ptr, ItemEntity *o_ptr, int y)
124 describe_flavor(player_ptr, buf, o_ptr, (OD_NO_FLAVOR | OD_OMIT_PREFIX | OD_NAME_ONLY));
125 TERM_COLOR attr = tval_to_attr[enum2i(o_ptr->tval) % 128];
127 if (player_ptr->effects()->hallucination()->is_hallucinated()) {
129 strcpy(buf, _("何か奇妙な物", "something strange"));
133 for (c = buf; *c; c++) {
134 for (int i = 0; simplify_list[i][1]; i++) {
135 concptr org_w = simplify_list[i][0];
145 if (strncmp(c, org_w, strlen(org_w))) {
150 concptr tmp = simplify_list[i][1];
154 tmp = c + strlen(org_w);
185 term_putstr(0, y, 12, attr, buf);
189 * @brief 縮小マップ表示 / Display a "small-scale" map of the dungeon in the active Term
190 * @param player_ptr プレイヤー情報への参照ポインタ
191 * @param cy 縮小マップ上のプレイヤーのy座標
192 * @param cx 縮小マップ上のプレイヤーのx座標
194 * メインウィンドウ('M'コマンド)、サブウィンドウ兼(縮小図)用。
195 * use_bigtile時に横の描画列数は1/2になる。
197 void display_map(PlayerType *player_ptr, int *cy, int *cx)
206 bool old_view_special_lite = view_special_lite;
207 bool old_view_granite_lite = view_granite_lite;
209 TERM_LEN border_width = use_bigtile ? 2 : 1; //!< @note 枠線幅
210 TERM_LEN hgt, wid, yrat, xrat;
211 term_get_size(&wid, &hgt);
213 wid -= 12 + border_width * 2; //!< @note 描画桁数(枠線抜)
218 auto *floor_ptr = player_ptr->current_floor_ptr;
219 yrat = (floor_ptr->height + hgt - 1) / hgt;
220 xrat = (floor_ptr->width + wid - 1) / wid;
221 view_special_lite = false;
222 view_granite_lite = false;
225 vector<vector<TERM_COLOR>> ma(hgt + 2, vector<TERM_COLOR>(wid + 2, TERM_WHITE));
226 vector<vector<char>> mc(hgt + 2, vector<char>(wid + 2, ' '));
227 vector<vector<byte>> mp(hgt + 2, vector<byte>(wid + 2, 0));
228 vector<vector<int>> match_autopick_yx(hgt + 2, vector<int>(wid + 2, -1));
229 vector<vector<ItemEntity *>> object_autopick_yx(hgt + 2, vector<ItemEntity *>(wid + 2, nullptr));
231 vector<vector<TERM_COLOR>> bigma(floor_ptr->height + 2, vector<TERM_COLOR>(floor_ptr->width + 2, TERM_WHITE));
232 vector<vector<char>> bigmc(floor_ptr->height + 2, vector<char>(floor_ptr->width + 2, ' '));
233 vector<vector<byte>> bigmp(floor_ptr->height + 2, vector<byte>(floor_ptr->width + 2, 0));
235 for (i = 0; i < floor_ptr->width; ++i) {
236 for (j = 0; j < floor_ptr->height; ++j) {
241 autopick_obj = nullptr;
243 map_info(player_ptr, j, i, &ta, &tc, &ta, &tc);
244 tp = (byte)feat_priority;
245 if (match_autopick != -1 && (match_autopick_yx[y][x] == -1 || match_autopick_yx[y][x] > match_autopick)) {
246 match_autopick_yx[y][x] = match_autopick;
247 object_autopick_yx[y][x] = autopick_obj;
251 bigmc[j + 1][i + 1] = tc;
252 bigma[j + 1][i + 1] = ta;
253 bigmp[j + 1][i + 1] = tp;
257 for (j = 0; j < floor_ptr->height; ++j) {
258 for (i = 0; i < floor_ptr->width; ++i) {
262 tc = bigmc[j + 1][i + 1];
263 ta = bigma[j + 1][i + 1];
264 tp = bigmp[j + 1][i + 1];
265 if (mp[y][x] == tp) {
269 for (t = 0; t < 8; t++) {
270 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]]) {
290 mc[0][0] = mc[0][x] = mc[y][0] = mc[y][x] = '+';
291 for (x = 1; x <= wid; x++) {
292 mc[0][x] = mc[y][x] = '-';
295 for (y = 1; y <= hgt; y++) {
296 mc[y][0] = mc[y][x] = '|';
299 for (y = 0; y < hgt + 2; ++y) {
300 term_gotoxy(COL_MAP, y);
301 for (x = 0; x < wid + 2; ++x) {
305 if (w_ptr->timewalk_m_idx) {
307 } else if (is_invuln(player_ptr) || player_ptr->timewalk) {
309 } else if (player_ptr->wraith_form) {
314 term_add_bigch(ta, tc);
318 for (y = 1; y < hgt + 1; ++y) {
320 for (x = 1; x <= wid; x++) {
321 if (match_autopick_yx[y][x] != -1 && (match_autopick > match_autopick_yx[y][x] || match_autopick == -1)) {
322 match_autopick = match_autopick_yx[y][x];
323 autopick_obj = object_autopick_yx[y][x];
327 term_putstr(0, y, 12, 0, " ");
328 if (match_autopick != -1) {
329 display_shortened_item_name(player_ptr, autopick_obj, y);
333 (*cy) = player_ptr->y / yrat + 1 + ROW_MAP;
335 (*cx) = player_ptr->x / xrat + 1 + COL_MAP;
337 (*cx) = (player_ptr->x / xrat + 1) * 2 + COL_MAP;
340 view_special_lite = old_view_special_lite;
341 view_granite_lite = old_view_granite_lite;
344 void set_term_color(PlayerType *player_ptr, POSITION y, POSITION x, TERM_COLOR *ap, char *cp)
346 if (!player_bold(player_ptr, y, x)) {
350 auto *r_ptr = &monraces_info[MonsterRaceId::PLAYER];
357 * Calculate panel colum of a location in the map
359 int panel_col_of(int col)
361 col -= panel_col_min;