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 "timed-effect/player-blindness.h"
25 #include "timed-effect/player-hallucination.h"
26 #include "timed-effect/timed-effects.h"
27 #include "util/bit-flags-calculator.h"
28 #include "window/main-window-util.h"
29 #include "world/world.h"
31 byte display_autopick; /*!< 自動拾い状態の設定フラグ */
33 /* 一般的にオブジェクトシンボルとして扱われる記号を定義する(幻覚処理向け) / Hack -- Legal object codes */
34 char image_object_hack[MAX_IMAGE_OBJECT_HACK] = "?/|\\\"!$()_-=[]{},~";
36 /* 一般的にモンスターシンボルとして扱われる記号を定義する(幻覚処理向け) / Hack -- Legal monster codes */
37 char image_monster_hack[MAX_IMAGE_MONSTER_HACK] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
40 * @brief オブジェクトの表示を幻覚状態に差し替える / Hallucinatory object
44 static void image_object(TERM_COLOR *ap, char *cp)
47 auto *k_ptr = &k_info[randint1(k_info.size() - 1)];
53 size_t n = sizeof(image_object_hack) - 1;
54 *cp = image_object_hack[randint0(n)];
59 * @brief モンスターの表示を幻覚状態に差し替える / Mega-Hack -- Hallucinatory monster
63 static void image_monster(TERM_COLOR *ap, char *cp)
66 auto r_idx = MonsterRace::pick_one_at_random();
67 auto *r_ptr = &r_info[r_idx];
73 *cp = (one_in_(25) ? image_object_hack[randint0(sizeof(image_object_hack) - 1)] : image_monster_hack[randint0(sizeof(image_monster_hack) - 1)]);
78 * @brief オブジェクト&モンスターの表示を幻覚状態に差し替える / Hack -- Random hallucination
82 static void image_random(TERM_COLOR *ap, char *cp)
84 if (randint0(100) < 75) {
85 image_monster(ap, cp);
92 * @brief マップに表示されるべき地形(壁)かどうかを判定する
93 * @param floor_ptr 階の情報への参照ポインタ
94 * @param f_ptr 地形の情報への参照ポインタ
97 * @return 表示されるべきならtrue、そうでないならfalse
99 * 周り全てが壁に囲まれている壁についてはオプション状態による。
100 * 1か所でも空きがあるか、壁ではない地形、金を含む地形、永久岩は表示。
102 static bool is_revealed_wall(floor_type *floor_ptr, feature_type *f_ptr, POSITION y, POSITION x)
104 if (view_hidden_walls) {
105 if (view_unsafe_walls) {
108 if (none_bits(floor_ptr->grid_array[y][x].info, CAVE_UNSAFE)) {
113 if (f_ptr->flags.has_not(FloorFeatureType::WALL) || f_ptr->flags.has(FloorFeatureType::HAS_GOLD)) {
117 if (in_bounds(floor_ptr, y, x) && f_ptr->flags.has(FloorFeatureType::PERMANENT)) {
122 for (int i = 0; i < 8; i++) {
123 int dy = y + ddy_cdd[i];
124 int dx = x + ddx_cdd[i];
125 if (!in_bounds(floor_ptr, dy, dx)) {
130 FEAT_IDX f_idx = floor_ptr->grid_array[dy][dx].feat;
131 feature_type *n_ptr = &f_info[f_idx];
132 if (n_ptr->flags.has(FloorFeatureType::WALL)) {
141 * @brief 指定した座標の地形の表示属性を取得する / Extract the attr/char to display at the given (legal) map location
142 * @param player_ptr プレイヤー情報への参照ポインタ
147 * @param tap 文字色属性(タイル)
148 * @param tcp 文字種属性(タイル)
150 void map_info(PlayerType *player_ptr, POSITION y, POSITION x, TERM_COLOR *ap, char *cp, TERM_COLOR *tap, char *tcp)
152 auto *floor_ptr = player_ptr->current_floor_ptr;
153 auto *g_ptr = &floor_ptr->grid_array[y][x];
154 FEAT_IDX feat = g_ptr->get_feat_mimic();
155 auto *f_ptr = &f_info[feat];
158 if (f_ptr->flags.has_not(FloorFeatureType::REMEMBER)) {
159 auto is_visible = any_bits(g_ptr->info, (CAVE_MARK | CAVE_LITE | CAVE_MNLT));
160 auto is_glowing = match_bits(g_ptr->info, CAVE_GLOW | CAVE_MNDK, CAVE_GLOW);
161 auto can_view = g_ptr->is_view() && (is_glowing || player_ptr->see_nocto);
162 const auto is_blind = player_ptr->effects()->blindness()->is_blind();
163 if (!is_blind && (is_visible || can_view)) {
164 a = f_ptr->x_attr[F_LIT_STANDARD];
165 c = f_ptr->x_char[F_LIT_STANDARD];
166 if (player_ptr->wild_mode) {
167 if (view_special_lite && !is_daytime()) {
168 a = f_ptr->x_attr[F_LIT_DARK];
169 c = f_ptr->x_char[F_LIT_DARK];
171 } else if (darkened_grid(player_ptr, g_ptr)) {
172 feat = (view_unsafe_grids && (g_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
173 f_ptr = &f_info[feat];
174 a = f_ptr->x_attr[F_LIT_STANDARD];
175 c = f_ptr->x_char[F_LIT_STANDARD];
176 } else if (view_special_lite) {
177 if (g_ptr->info & (CAVE_LITE | CAVE_MNLT)) {
178 if (view_yellow_lite) {
179 a = f_ptr->x_attr[F_LIT_LITE];
180 c = f_ptr->x_char[F_LIT_LITE];
182 } else if ((g_ptr->info & (CAVE_GLOW | CAVE_MNDK)) != CAVE_GLOW) {
183 a = f_ptr->x_attr[F_LIT_DARK];
184 c = f_ptr->x_char[F_LIT_DARK];
185 } else if (!(g_ptr->info & CAVE_VIEW)) {
186 if (view_bright_lite) {
187 a = f_ptr->x_attr[F_LIT_DARK];
188 c = f_ptr->x_char[F_LIT_DARK];
193 feat = (view_unsafe_grids && (g_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
194 f_ptr = &f_info[feat];
195 a = f_ptr->x_attr[F_LIT_STANDARD];
196 c = f_ptr->x_char[F_LIT_STANDARD];
199 if (g_ptr->is_mark() && is_revealed_wall(floor_ptr, f_ptr, y, x)) {
200 a = f_ptr->x_attr[F_LIT_STANDARD];
201 c = f_ptr->x_char[F_LIT_STANDARD];
202 const auto is_blind = player_ptr->effects()->blindness()->is_blind();
203 if (player_ptr->wild_mode) {
204 if (view_granite_lite && (is_blind || !is_daytime())) {
205 a = f_ptr->x_attr[F_LIT_DARK];
206 c = f_ptr->x_char[F_LIT_DARK];
208 } else if (darkened_grid(player_ptr, g_ptr) && !is_blind) {
209 if (f_ptr->flags.has_all_of({ FloorFeatureType::LOS, FloorFeatureType::PROJECT })) {
210 feat = (view_unsafe_grids && (g_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
211 f_ptr = &f_info[feat];
212 a = f_ptr->x_attr[F_LIT_STANDARD];
213 c = f_ptr->x_char[F_LIT_STANDARD];
214 } else if (view_granite_lite && view_bright_lite) {
215 a = f_ptr->x_attr[F_LIT_DARK];
216 c = f_ptr->x_char[F_LIT_DARK];
218 } else if (view_granite_lite) {
220 a = f_ptr->x_attr[F_LIT_DARK];
221 c = f_ptr->x_char[F_LIT_DARK];
222 } else if (g_ptr->info & (CAVE_LITE | CAVE_MNLT)) {
223 if (view_yellow_lite) {
224 a = f_ptr->x_attr[F_LIT_LITE];
225 c = f_ptr->x_char[F_LIT_LITE];
227 } else if (view_bright_lite) {
228 if (!(g_ptr->info & CAVE_VIEW)) {
229 a = f_ptr->x_attr[F_LIT_DARK];
230 c = f_ptr->x_char[F_LIT_DARK];
231 } else if ((g_ptr->info & (CAVE_GLOW | CAVE_MNDK)) != CAVE_GLOW) {
232 a = f_ptr->x_attr[F_LIT_DARK];
233 c = f_ptr->x_char[F_LIT_DARK];
234 } else if (f_ptr->flags.has_not(FloorFeatureType::LOS) && !check_local_illumination(player_ptr, y, x)) {
235 a = f_ptr->x_attr[F_LIT_DARK];
236 c = f_ptr->x_char[F_LIT_DARK];
241 feat = (view_unsafe_grids && (g_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
242 f_ptr = &f_info[feat];
243 a = f_ptr->x_attr[F_LIT_STANDARD];
244 c = f_ptr->x_char[F_LIT_STANDARD];
248 if (feat_priority == -1) {
249 feat_priority = f_ptr->priority;
257 auto is_hallucinated = player_ptr->effects()->hallucination()->is_hallucinated();
258 if (is_hallucinated && one_in_(256)) {
259 image_random(ap, cp);
262 for (const auto this_o_idx : g_ptr->o_idx_list) {
264 o_ptr = &floor_ptr->o_list[this_o_idx];
265 if (!(o_ptr->marked & OM_FOUND)) {
269 if (display_autopick) {
272 match_autopick = find_autopick_list(player_ptr, o_ptr);
273 if (match_autopick == -1) {
277 act = autopick_list[match_autopick].action;
279 if ((act & DO_DISPLAY) && (act & display_autopick)) {
280 autopick_obj = o_ptr;
287 (*cp) = object_char(o_ptr);
288 (*ap) = object_attr(o_ptr);
290 if (is_hallucinated) {
291 image_object(ap, cp);
297 if (g_ptr->m_idx && display_autopick != 0) {
298 set_term_color(player_ptr, y, x, ap, cp);
302 auto *m_ptr = &floor_ptr->m_list[g_ptr->m_idx];
304 set_term_color(player_ptr, y, x, ap, cp);
308 auto *r_ptr = &r_info[m_ptr->ap_r_idx];
310 if (is_hallucinated) {
311 if (r_ptr->visual_flags.has_all_of({ MonsterVisualType::CLEAR, MonsterVisualType::CLEAR_COLOR })) {
314 image_monster(ap, cp);
317 set_term_color(player_ptr, y, x, ap, cp);
323 if (r_ptr->visual_flags.has_none_of({ MonsterVisualType::CLEAR, MonsterVisualType::SHAPECHANGER, MonsterVisualType::CLEAR_COLOR, MonsterVisualType::MULTI_COLOR, MonsterVisualType::RANDOM_COLOR })) {
326 set_term_color(player_ptr, y, x, ap, cp);
330 if (r_ptr->visual_flags.has_all_of({ MonsterVisualType::CLEAR, MonsterVisualType::CLEAR_COLOR })) {
331 set_term_color(player_ptr, y, x, ap, cp);
335 if (r_ptr->visual_flags.has(MonsterVisualType::CLEAR_COLOR) && (*ap != TERM_DARK) && !use_graphics) {
337 } else if (r_ptr->visual_flags.has(MonsterVisualType::MULTI_COLOR) && !use_graphics) {
338 if (r_ptr->visual_flags.has(MonsterVisualType::ANY_COLOR)) {
341 switch (randint1(7)) {
365 } else if (r_ptr->visual_flags.has(MonsterVisualType::RANDOM_COLOR) && !use_graphics) {
366 *ap = g_ptr->m_idx % 15 + 1;
371 if (r_ptr->visual_flags.has(MonsterVisualType::CLEAR) && (*cp != ' ') && !use_graphics) {
372 set_term_color(player_ptr, y, x, ap, cp);
376 if (r_ptr->visual_flags.has(MonsterVisualType::SHAPECHANGER)) {
378 auto r_idx = MonsterRace::pick_one_at_random();
379 monster_race *tmp_r_ptr = &r_info[r_idx];
380 *cp = tmp_r_ptr->x_char;
381 *ap = tmp_r_ptr->x_attr;
383 *cp = (one_in_(25) ? image_object_hack[randint0(sizeof(image_object_hack) - 1)] : image_monster_hack[randint0(sizeof(image_monster_hack) - 1)]);
386 set_term_color(player_ptr, y, x, ap, cp);
391 set_term_color(player_ptr, y, x, ap, cp);