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-mark-types.h"
16 #include "system/baseitem-info.h"
17 #include "system/floor-type-definition.h"
18 #include "system/grid-type-definition.h"
19 #include "system/item-entity.h"
20 #include "system/monster-entity.h"
21 #include "system/monster-race-info.h"
22 #include "system/player-type-definition.h"
23 #include "system/terrain-type-definition.h"
24 #include "term/term-color-types.h"
25 #include "timed-effect/player-blindness.h"
26 #include "timed-effect/player-hallucination.h"
27 #include "timed-effect/timed-effects.h"
28 #include "util/bit-flags-calculator.h"
29 #include "window/main-window-util.h"
30 #include "world/world.h"
33 byte display_autopick; /*!< 自動拾い状態の設定フラグ */
36 /* 一般的にオブジェクトシンボルとして扱われる記号を定義する(幻覚処理向け) / Hack -- Legal object codes */
37 const std::string image_objects = R"(?/|\"!$()_-=[]{},~)";
39 /* 一般的にモンスターシンボルとして扱われる記号を定義する(幻覚処理向け) / Hack -- Legal monster codes */
40 const std::string image_monsters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
44 * @brief オブジェクトの表示を幻覚状態に差し替える / Hallucinatory object
48 static void image_object(TERM_COLOR *ap, char *cp)
51 const auto &baseitem = baseitems_info[randint1(baseitems_info.size() - 1)];
52 *cp = baseitem.x_char;
53 *ap = baseitem.x_attr;
57 *cp = rand_choice(image_objects);
62 * @brief モンスターの表示を幻覚状態に差し替える / Mega-Hack -- Hallucinatory monster
66 static void image_monster(TERM_COLOR *ap, char *cp)
69 auto r_idx = MonsterRace::pick_one_at_random();
70 auto *r_ptr = &monraces_info[r_idx];
76 *cp = one_in_(25) ? rand_choice(image_objects) : rand_choice(image_monsters);
81 * @brief オブジェクト&モンスターの表示を幻覚状態に差し替える / Hack -- Random hallucination
85 static void image_random(TERM_COLOR *ap, char *cp)
87 if (randint0(100) < 75) {
88 image_monster(ap, cp);
95 * @brief マップに表示されるべき地形(壁)かどうかを判定する
96 * @param floor_ptr 階の情報への参照ポインタ
99 * @return 表示されるべきならtrue、そうでないならfalse
101 * 周り全てが壁に囲まれている壁についてはオプション状態による。
102 * 1か所でも空きがあるか、壁ではない地形、金を含む地形、永久岩は表示。
104 static bool is_revealed_wall(FloorType *floor_ptr, int y, int x)
106 const auto &grid = floor_ptr->grid_array[y][x];
107 if (view_hidden_walls) {
108 if (view_unsafe_walls) {
111 if (none_bits(grid.info, CAVE_UNSAFE)) {
116 const auto &terrain = grid.get_terrain_mimic();
117 if (terrain.flags.has_not(TerrainCharacteristics::WALL) || terrain.flags.has(TerrainCharacteristics::HAS_GOLD)) {
121 if (in_bounds(floor_ptr, y, x) && terrain.flags.has(TerrainCharacteristics::PERMANENT)) {
125 constexpr auto neighbors = 8;
126 const auto &terrains = TerrainList::get_instance();
128 for (auto i = 0; i < neighbors; i++) {
129 const auto dy = y + ddy_cdd[i];
130 const auto dx = x + ddx_cdd[i];
131 if (!in_bounds(floor_ptr, dy, dx)) {
136 const auto terrain_id = floor_ptr->grid_array[dy][dx].feat;
137 const auto &terrain_neighbor = terrains[terrain_id];
138 if (terrain_neighbor.flags.has(TerrainCharacteristics::WALL)) {
143 return n != neighbors;
147 * @brief 指定した座標の地形の表示属性を取得する
148 * @param player_ptr プレイヤー情報への参照ポインタ
153 * @param tap 文字色属性(タイル)
154 * @param tcp 文字種属性(タイル)
155 * @todo 強力発動コピペの嵐…ポインタ引数の嵐……Fuuu^h^hck!!
157 void map_info(PlayerType *player_ptr, POSITION y, POSITION x, TERM_COLOR *ap, char *cp, TERM_COLOR *tap, char *tcp)
159 auto &floor = *player_ptr->current_floor_ptr;
160 const Pos2D pos(y, x);
161 auto &grid = floor.get_grid(pos);
162 auto &terrains = TerrainList::get_instance();
163 auto *terrain_mimic_ptr = &grid.get_terrain_mimic();
166 if (terrain_mimic_ptr->flags.has_not(TerrainCharacteristics::REMEMBER)) {
167 auto is_visible = any_bits(grid.info, (CAVE_MARK | CAVE_LITE | CAVE_MNLT));
168 auto is_glowing = match_bits(grid.info, CAVE_GLOW | CAVE_MNDK, CAVE_GLOW);
169 auto can_view = grid.is_view() && (is_glowing || player_ptr->see_nocto);
170 const auto is_blind = player_ptr->effects()->blindness()->is_blind();
171 if (!is_blind && (is_visible || can_view)) {
172 a = terrain_mimic_ptr->x_attr[F_LIT_STANDARD];
173 c = terrain_mimic_ptr->x_char[F_LIT_STANDARD];
174 if (player_ptr->wild_mode) {
175 if (view_special_lite && !is_daytime()) {
176 a = terrain_mimic_ptr->x_attr[F_LIT_DARK];
177 c = terrain_mimic_ptr->x_char[F_LIT_DARK];
179 } else if (darkened_grid(player_ptr, &grid)) {
180 const auto unsafe_terrain_id = (view_unsafe_grids && (grid.info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
181 terrain_mimic_ptr = &terrains[unsafe_terrain_id];
182 a = terrain_mimic_ptr->x_attr[F_LIT_STANDARD];
183 c = terrain_mimic_ptr->x_char[F_LIT_STANDARD];
184 } else if (view_special_lite) {
185 if (grid.info & (CAVE_LITE | CAVE_MNLT)) {
186 if (view_yellow_lite) {
187 a = terrain_mimic_ptr->x_attr[F_LIT_LITE];
188 c = terrain_mimic_ptr->x_char[F_LIT_LITE];
190 } else if ((grid.info & (CAVE_GLOW | CAVE_MNDK)) != CAVE_GLOW) {
191 a = terrain_mimic_ptr->x_attr[F_LIT_DARK];
192 c = terrain_mimic_ptr->x_char[F_LIT_DARK];
193 } else if (!(grid.info & CAVE_VIEW)) {
194 if (view_bright_lite) {
195 a = terrain_mimic_ptr->x_attr[F_LIT_DARK];
196 c = terrain_mimic_ptr->x_char[F_LIT_DARK];
201 const auto unsafe_terrain_id = (view_unsafe_grids && (grid.info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
202 terrain_mimic_ptr = &terrains[unsafe_terrain_id];
203 a = terrain_mimic_ptr->x_attr[F_LIT_STANDARD];
204 c = terrain_mimic_ptr->x_char[F_LIT_STANDARD];
207 if (grid.is_mark() && is_revealed_wall(&floor, y, x)) {
208 a = terrain_mimic_ptr->x_attr[F_LIT_STANDARD];
209 c = terrain_mimic_ptr->x_char[F_LIT_STANDARD];
210 const auto is_blind = player_ptr->effects()->blindness()->is_blind();
211 if (player_ptr->wild_mode) {
212 if (view_granite_lite && (is_blind || !is_daytime())) {
213 a = terrain_mimic_ptr->x_attr[F_LIT_DARK];
214 c = terrain_mimic_ptr->x_char[F_LIT_DARK];
216 } else if (darkened_grid(player_ptr, &grid) && !is_blind) {
217 if (terrain_mimic_ptr->flags.has_all_of({ TerrainCharacteristics::LOS, TerrainCharacteristics::PROJECT })) {
218 const auto unsafe_terrain_id = (view_unsafe_grids && (grid.info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
219 terrain_mimic_ptr = &terrains[unsafe_terrain_id];
220 a = terrain_mimic_ptr->x_attr[F_LIT_STANDARD];
221 c = terrain_mimic_ptr->x_char[F_LIT_STANDARD];
222 } else if (view_granite_lite && view_bright_lite) {
223 a = terrain_mimic_ptr->x_attr[F_LIT_DARK];
224 c = terrain_mimic_ptr->x_char[F_LIT_DARK];
226 } else if (view_granite_lite) {
228 a = terrain_mimic_ptr->x_attr[F_LIT_DARK];
229 c = terrain_mimic_ptr->x_char[F_LIT_DARK];
230 } else if (grid.info & (CAVE_LITE | CAVE_MNLT)) {
231 if (view_yellow_lite) {
232 a = terrain_mimic_ptr->x_attr[F_LIT_LITE];
233 c = terrain_mimic_ptr->x_char[F_LIT_LITE];
235 } else if (view_bright_lite) {
236 if (!(grid.info & CAVE_VIEW)) {
237 a = terrain_mimic_ptr->x_attr[F_LIT_DARK];
238 c = terrain_mimic_ptr->x_char[F_LIT_DARK];
239 } else if ((grid.info & (CAVE_GLOW | CAVE_MNDK)) != CAVE_GLOW) {
240 a = terrain_mimic_ptr->x_attr[F_LIT_DARK];
241 c = terrain_mimic_ptr->x_char[F_LIT_DARK];
242 } else if (terrain_mimic_ptr->flags.has_not(TerrainCharacteristics::LOS) && !check_local_illumination(player_ptr, y, x)) {
243 a = terrain_mimic_ptr->x_attr[F_LIT_DARK];
244 c = terrain_mimic_ptr->x_char[F_LIT_DARK];
249 const auto unsafe_terrain_id = (view_unsafe_grids && (grid.info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
250 terrain_mimic_ptr = &terrains[unsafe_terrain_id];
251 a = terrain_mimic_ptr->x_attr[F_LIT_STANDARD];
252 c = terrain_mimic_ptr->x_char[F_LIT_STANDARD];
256 if (feat_priority == -1) {
257 feat_priority = terrain_mimic_ptr->priority;
265 auto is_hallucinated = player_ptr->effects()->hallucination()->is_hallucinated();
266 if (is_hallucinated && one_in_(256)) {
267 image_random(ap, cp);
270 for (const auto this_o_idx : grid.o_idx_list) {
272 o_ptr = &floor.o_list[this_o_idx];
273 if (o_ptr->marked.has_not(OmType::FOUND)) {
277 if (display_autopick) {
280 match_autopick = find_autopick_list(player_ptr, o_ptr);
281 if (match_autopick == -1) {
285 act = autopick_list[match_autopick].action;
287 if ((act & DO_DISPLAY) && (act & display_autopick)) {
288 autopick_obj = o_ptr;
295 *cp = o_ptr->get_symbol();
296 *ap = o_ptr->get_color();
298 if (is_hallucinated) {
299 image_object(ap, cp);
305 if (grid.m_idx && display_autopick != 0) {
306 set_term_color(player_ptr, y, x, ap, cp);
310 auto *m_ptr = &floor.m_list[grid.m_idx];
312 set_term_color(player_ptr, y, x, ap, cp);
316 auto *r_ptr = &m_ptr->get_appearance_monrace();
318 if (is_hallucinated) {
319 if (r_ptr->visual_flags.has_all_of({ MonsterVisualType::CLEAR, MonsterVisualType::CLEAR_COLOR })) {
322 image_monster(ap, cp);
325 set_term_color(player_ptr, y, x, ap, cp);
331 if (r_ptr->visual_flags.has_none_of({ MonsterVisualType::CLEAR, MonsterVisualType::SHAPECHANGER, MonsterVisualType::CLEAR_COLOR, MonsterVisualType::MULTI_COLOR, MonsterVisualType::RANDOM_COLOR })) {
334 set_term_color(player_ptr, y, x, ap, cp);
338 if (r_ptr->visual_flags.has_all_of({ MonsterVisualType::CLEAR, MonsterVisualType::CLEAR_COLOR })) {
339 set_term_color(player_ptr, y, x, ap, cp);
343 if (r_ptr->visual_flags.has(MonsterVisualType::CLEAR_COLOR) && (*ap != TERM_DARK) && !use_graphics) {
345 } else if (r_ptr->visual_flags.has(MonsterVisualType::MULTI_COLOR) && !use_graphics) {
346 if (r_ptr->visual_flags.has(MonsterVisualType::ANY_COLOR)) {
349 constexpr static auto colors = {
359 *ap = rand_choice(colors);
361 } else if (r_ptr->visual_flags.has(MonsterVisualType::RANDOM_COLOR) && !use_graphics) {
362 *ap = grid.m_idx % 15 + 1;
367 if (r_ptr->visual_flags.has(MonsterVisualType::CLEAR) && (*cp != ' ') && !use_graphics) {
368 set_term_color(player_ptr, y, x, ap, cp);
372 if (r_ptr->visual_flags.has(MonsterVisualType::SHAPECHANGER)) {
374 auto r_idx = MonsterRace::pick_one_at_random();
375 MonsterRaceInfo *tmp_r_ptr = &monraces_info[r_idx];
376 *cp = tmp_r_ptr->x_char;
377 *ap = tmp_r_ptr->x_attr;
379 *cp = one_in_(25) ? rand_choice(image_objects) : rand_choice(image_monsters);
382 set_term_color(player_ptr, y, x, ap, cp);
387 set_term_color(player_ptr, y, x, ap, cp);