1 #include "view/display-map.h"
2 #include "autopick/autopick-finder.h"
3 #include "autopick/autopick-methods-table.h"
4 #include "autopick/autopick-util.h"
5 #include "floor/cave.h"
6 #include "floor/geometry.h"
7 #include "game-option/map-screen-options.h"
8 #include "game-option/special-options.h"
9 #include "grid/feature.h"
10 #include "grid/grid.h"
11 #include "monster-race/monster-race.h"
12 #include "monster-race/race-flags1.h"
13 #include "monster-race/race-flags2.h"
14 #include "object/object-info.h"
15 #include "object/object-kind.h"
16 #include "object/object-mark-types.h"
17 #include "system/floor-type-definition.h"
18 #include "system/grid-type-definition.h"
19 #include "system/monster-race-definition.h"
20 #include "system/monster-type-definition.h"
21 #include "system/object-type-definition.h"
22 #include "system/player-type-definition.h"
23 #include "term/term-color-types.h"
24 #include "util/bit-flags-calculator.h"
25 #include "window/main-window-util.h"
26 #include "world/world.h"
28 byte display_autopick; /*!< 自動拾い状態の設定フラグ */
30 /* 一般的にオブジェクトシンボルとして扱われる記号を定義する(幻覚処理向け) / Hack -- Legal object codes */
31 char image_object_hack[MAX_IMAGE_OBJECT_HACK] = "?/|\\\"!$()_-=[]{},~";
33 /* 一般的にモンスターシンボルとして扱われる記号を定義する(幻覚処理向け) / Hack -- Legal monster codes */
34 char image_monster_hack[MAX_IMAGE_MONSTER_HACK] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
37 * @brief オブジェクトの表示を幻覚状態に差し替える / Hallucinatory object
41 static void image_object(TERM_COLOR *ap, SYMBOL_CODE *cp)
44 object_kind *k_ptr = &k_info[randint1(k_info.size() - 1)];
50 size_t n = sizeof(image_object_hack) - 1;
51 *cp = image_object_hack[randint0(n)];
56 * @brief モンスターの表示を幻覚状態に差し替える / Mega-Hack -- Hallucinatory monster
60 static void image_monster(TERM_COLOR *ap, SYMBOL_CODE *cp)
63 monster_race *r_ptr = &r_info[randint1(r_info.size() - 1)];
69 *cp = (one_in_(25) ? image_object_hack[randint0(sizeof(image_object_hack) - 1)] : image_monster_hack[randint0(sizeof(image_monster_hack) - 1)]);
74 * @brief オブジェクト&モンスターの表示を幻覚状態に差し替える / Hack -- Random hallucination
78 static void image_random(TERM_COLOR *ap, SYMBOL_CODE *cp)
80 if (randint0(100) < 75) {
81 image_monster(ap, cp);
88 * @brief マップに表示されるべき地形(壁)かどうかを判定する
89 * @param floor_ptr 階の情報への参照ポインタ
90 * @param f_ptr 地形の情報への参照ポインタ
93 * @return 表示されるべきならtrue、そうでないならfalse
95 * 周り全てが壁に囲まれている壁についてはオプション状態による。
96 * 1か所でも空きがあるか、壁ではない地形、金を含む地形、永久岩は表示。
98 static bool is_revealed_wall(floor_type *floor_ptr, feature_type *f_ptr, POSITION y, POSITION x)
100 if (view_hidden_walls) {
101 if (view_unsafe_walls)
103 if (none_bits(floor_ptr->grid_array[y][x].info, CAVE_UNSAFE))
107 if (f_ptr->flags.has_not(FF::WALL) || f_ptr->flags.has(FF::HAS_GOLD))
110 if (in_bounds(floor_ptr, y, x) && f_ptr->flags.has(FF::PERMANENT))
114 for (int i = 0; i < 8; i++) {
115 int dy = y + ddy_cdd[i];
116 int dx = x + ddx_cdd[i];
117 if (!in_bounds(floor_ptr, dy, dx)) {
122 FEAT_IDX f_idx = floor_ptr->grid_array[dy][dx].feat;
123 feature_type *n_ptr = &f_info[f_idx];
124 if (n_ptr->flags.has(FF::WALL))
132 * @brief 指定した座標の地形の表示属性を取得する / Extract the attr/char to display at the given (legal) map location
133 * @param player_ptr プレイヤー情報への参照ポインタ
138 * @param tap 文字色属性(タイル)
139 * @param tcp 文字種属性(タイル)
141 void map_info(player_type *player_ptr, POSITION y, POSITION x, TERM_COLOR *ap, SYMBOL_CODE *cp, TERM_COLOR *tap, SYMBOL_CODE *tcp)
143 floor_type *floor_ptr = player_ptr->current_floor_ptr;
144 grid_type *g_ptr = &floor_ptr->grid_array[y][x];
145 FEAT_IDX feat = g_ptr->get_feat_mimic();
146 feature_type *f_ptr = &f_info[feat];
149 if (f_ptr->flags.has_not(FF::REMEMBER)) {
150 auto is_visible = any_bits(g_ptr->info, (CAVE_MARK | CAVE_LITE | CAVE_MNLT));
151 auto is_glowing = match_bits(g_ptr->info, CAVE_GLOW | CAVE_MNDK, CAVE_GLOW);
152 auto can_view = g_ptr->is_view() && (is_glowing || player_ptr->see_nocto);
153 if ((player_ptr->blind == 0) && (is_visible || can_view)) {
154 a = f_ptr->x_attr[F_LIT_STANDARD];
155 c = f_ptr->x_char[F_LIT_STANDARD];
156 if (player_ptr->wild_mode) {
157 if (view_special_lite && !is_daytime()) {
158 a = f_ptr->x_attr[F_LIT_DARK];
159 c = f_ptr->x_char[F_LIT_DARK];
161 } else if (darkened_grid(player_ptr, g_ptr)) {
162 feat = (view_unsafe_grids && (g_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
163 f_ptr = &f_info[feat];
164 a = f_ptr->x_attr[F_LIT_STANDARD];
165 c = f_ptr->x_char[F_LIT_STANDARD];
166 } else if (view_special_lite) {
167 if (g_ptr->info & (CAVE_LITE | CAVE_MNLT)) {
168 if (view_yellow_lite) {
169 a = f_ptr->x_attr[F_LIT_LITE];
170 c = f_ptr->x_char[F_LIT_LITE];
172 } else if ((g_ptr->info & (CAVE_GLOW | CAVE_MNDK)) != CAVE_GLOW) {
173 a = f_ptr->x_attr[F_LIT_DARK];
174 c = f_ptr->x_char[F_LIT_DARK];
175 } else if (!(g_ptr->info & CAVE_VIEW)) {
176 if (view_bright_lite) {
177 a = f_ptr->x_attr[F_LIT_DARK];
178 c = f_ptr->x_char[F_LIT_DARK];
183 feat = (view_unsafe_grids && (g_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
184 f_ptr = &f_info[feat];
185 a = f_ptr->x_attr[F_LIT_STANDARD];
186 c = f_ptr->x_char[F_LIT_STANDARD];
189 if (g_ptr->is_mark() && is_revealed_wall(floor_ptr, f_ptr, y, x)) {
190 a = f_ptr->x_attr[F_LIT_STANDARD];
191 c = f_ptr->x_char[F_LIT_STANDARD];
192 if (player_ptr->wild_mode) {
193 if (view_granite_lite && (player_ptr->blind || !is_daytime())) {
194 a = f_ptr->x_attr[F_LIT_DARK];
195 c = f_ptr->x_char[F_LIT_DARK];
197 } else if (darkened_grid(player_ptr, g_ptr) && !player_ptr->blind) {
198 if (f_ptr->flags.has_all_of({FF::LOS, FF::PROJECT})) {
199 feat = (view_unsafe_grids && (g_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
200 f_ptr = &f_info[feat];
201 a = f_ptr->x_attr[F_LIT_STANDARD];
202 c = f_ptr->x_char[F_LIT_STANDARD];
203 } else if (view_granite_lite && view_bright_lite) {
204 a = f_ptr->x_attr[F_LIT_DARK];
205 c = f_ptr->x_char[F_LIT_DARK];
207 } else if (view_granite_lite) {
208 if (player_ptr->blind) {
209 a = f_ptr->x_attr[F_LIT_DARK];
210 c = f_ptr->x_char[F_LIT_DARK];
211 } else if (g_ptr->info & (CAVE_LITE | CAVE_MNLT)) {
212 if (view_yellow_lite) {
213 a = f_ptr->x_attr[F_LIT_LITE];
214 c = f_ptr->x_char[F_LIT_LITE];
216 } else if (view_bright_lite) {
217 if (!(g_ptr->info & CAVE_VIEW)) {
218 a = f_ptr->x_attr[F_LIT_DARK];
219 c = f_ptr->x_char[F_LIT_DARK];
220 } else if ((g_ptr->info & (CAVE_GLOW | CAVE_MNDK)) != CAVE_GLOW) {
221 a = f_ptr->x_attr[F_LIT_DARK];
222 c = f_ptr->x_char[F_LIT_DARK];
223 } else if (f_ptr->flags.has_not(FF::LOS) && !check_local_illumination(player_ptr, y, x)) {
224 a = f_ptr->x_attr[F_LIT_DARK];
225 c = f_ptr->x_char[F_LIT_DARK];
230 feat = (view_unsafe_grids && (g_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
231 f_ptr = &f_info[feat];
232 a = f_ptr->x_attr[F_LIT_STANDARD];
233 c = f_ptr->x_char[F_LIT_STANDARD];
237 if (feat_priority == -1)
238 feat_priority = f_ptr->priority;
245 if (player_ptr->hallucinated && one_in_(256))
246 image_random(ap, cp);
248 for (const auto this_o_idx : g_ptr->o_idx_list) {
250 o_ptr = &floor_ptr->o_list[this_o_idx];
251 if (!(o_ptr->marked & OM_FOUND))
254 if (display_autopick) {
257 match_autopick = find_autopick_list(player_ptr, o_ptr);
258 if (match_autopick == -1)
261 act = autopick_list[match_autopick].action;
263 if ((act & DO_DISPLAY) && (act & display_autopick)) {
264 autopick_obj = o_ptr;
271 (*cp) = object_char(o_ptr);
272 (*ap) = object_attr(o_ptr);
274 if (player_ptr->hallucinated)
275 image_object(ap, cp);
280 if (g_ptr->m_idx && display_autopick != 0) {
281 set_term_color(player_ptr, y, x, ap, cp);
285 monster_type *m_ptr = &floor_ptr->m_list[g_ptr->m_idx];
287 set_term_color(player_ptr, y, x, ap, cp);
291 monster_race *r_ptr = &r_info[m_ptr->ap_r_idx];
293 if (player_ptr->hallucinated) {
294 if ((r_ptr->flags1 & (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR)) == (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR)) {
297 image_monster(ap, cp);
300 set_term_color(player_ptr, y, x, ap, cp);
306 if (!(r_ptr->flags1 & (RF1_CHAR_CLEAR | RF1_SHAPECHANGER | RF1_ATTR_CLEAR | RF1_ATTR_MULTI | RF1_ATTR_SEMIRAND))) {
309 set_term_color(player_ptr, y, x, ap, cp);
313 if ((r_ptr->flags1 & (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR)) == (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR)) {
314 set_term_color(player_ptr, y, x, ap, cp);
318 if ((r_ptr->flags1 & RF1_ATTR_CLEAR) && (*ap != TERM_DARK) && !use_graphics) {
320 } else if ((r_ptr->flags1 & RF1_ATTR_MULTI) && !use_graphics) {
321 if (r_ptr->flags2 & RF2_ATTR_ANY)
324 switch (randint1(7)) {
347 } else if ((r_ptr->flags1 & RF1_ATTR_SEMIRAND) && !use_graphics) {
348 *ap = g_ptr->m_idx % 15 + 1;
353 if ((r_ptr->flags1 & RF1_CHAR_CLEAR) && (*cp != ' ') && !use_graphics) {
354 set_term_color(player_ptr, y, x, ap, cp);
358 if (r_ptr->flags1 & RF1_SHAPECHANGER) {
360 monster_race *tmp_r_ptr = &r_info[randint1(r_info.size() - 1)];
361 *cp = tmp_r_ptr->x_char;
362 *ap = tmp_r_ptr->x_attr;
364 *cp = (one_in_(25) ? image_object_hack[randint0(sizeof(image_object_hack) - 1)] : image_monster_hack[randint0(sizeof(image_monster_hack) - 1)]);
367 set_term_color(player_ptr, y, x, ap, cp);
372 set_term_color(player_ptr, y, x, ap, cp);