OSDN Git Service

[fix] #41503 超能力者でゲームを開始しようとするとクラッシュ
[hengband/hengband.git] / src / view / display-map.c
1 #include "view/display-map.h"
2 #include "autopick/autopick-finder.h"
3 #include "autopick/autopick-methods-table.h"
4 #include "game-option/map-screen-options.h"
5 #include "game-option/special-options.h"
6 #include "grid/feature.h"
7 #include "grid/grid.h"
8 #include "monster-race/monster-race.h"
9 #include "monster-race/race-flags1.h"
10 #include "monster-race/race-flags2.h"
11 #include "object/object-info.h"
12 #include "object/object-kind.h"
13 #include "object/object-mark-types.h"
14 #include "system/floor-type-definition.h"
15 #include "term/term-color-types.h"
16 #include "util/bit-flags-calculator.h"
17 #include "window/main-window-util.h"
18 #include "world/world.h"
19
20 byte display_autopick; /*!< 自動拾い状態の設定フラグ */
21
22 /* 一般的にオブジェクトシンボルとして扱われる記号を定義する(幻覚処理向け) /  Hack -- Legal object codes */
23 char image_object_hack[MAX_IMAGE_OBJECT_HACK] = "?/|\\\"!$()_-=[]{},~";
24
25 /* 一般的にモンスターシンボルとして扱われる記号を定義する(幻覚処理向け) / Hack -- Legal monster codes */
26 char image_monster_hack[MAX_IMAGE_MONSTER_HACK] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
27
28 /*!
29  * @brief オブジェクトの表示を幻覚状態に差し替える / Hallucinatory object
30  * @param ap 本来の色
31  * @param cp 本来のシンボル
32  * @return なし
33  */
34 static void image_object(TERM_COLOR *ap, SYMBOL_CODE *cp)
35 {
36     if (use_graphics) {
37         object_kind *k_ptr = &k_info[randint1(max_k_idx - 1)];
38         *cp = k_ptr->x_char;
39         *ap = k_ptr->x_attr;
40         return;
41     }
42
43     size_t n = sizeof(image_object_hack) - 1;
44     *cp = image_object_hack[randint0(n)];
45     *ap = randint1(15);
46 }
47
48 /*!
49  * @brief モンスターの表示を幻覚状態に差し替える / Mega-Hack -- Hallucinatory monster
50  * @param ap 本来の色
51  * @param cp 本来のシンボル
52  * @return なし
53  */
54 static void image_monster(TERM_COLOR *ap, SYMBOL_CODE *cp)
55 {
56     if (use_graphics) {
57         monster_race *r_ptr = &r_info[randint1(max_r_idx - 1)];
58         *cp = r_ptr->x_char;
59         *ap = r_ptr->x_attr;
60         return;
61     }
62
63     *cp = (one_in_(25) ? image_object_hack[randint0(sizeof(image_object_hack) - 1)] : image_monster_hack[randint0(sizeof(image_monster_hack) - 1)]);
64     *ap = randint1(15);
65 }
66
67 /*!
68  * @brief オブジェクト&モンスターの表示を幻覚状態に差し替える / Hack -- Random hallucination
69  * @param ap 本来の色
70  * @param cp 本来のシンボル
71  * @return なし
72  */
73 static void image_random(TERM_COLOR *ap, SYMBOL_CODE *cp)
74 {
75     if (randint0(100) < 75) {
76         image_monster(ap, cp);
77     } else {
78         image_object(ap, cp);
79     }
80 }
81
82 /*!
83  * @brief Mコマンドによる縮小マップの表示を行う / Extract the attr/char to display at the given (legal) map location
84  */
85 void map_info(player_type *player_ptr, POSITION y, POSITION x, TERM_COLOR *ap, SYMBOL_CODE *cp, TERM_COLOR *tap, SYMBOL_CODE *tcp)
86 {
87     floor_type *floor_ptr = player_ptr->current_floor_ptr;
88     grid_type *g_ptr = &floor_ptr->grid_array[y][x];
89     OBJECT_IDX this_o_idx, next_o_idx = 0;
90     FEAT_IDX feat = get_feat_mimic(g_ptr);
91     feature_type *f_ptr = &f_info[feat];
92     TERM_COLOR a;
93     SYMBOL_CODE c;
94     if (!has_flag(f_ptr->flags, FF_REMEMBER)) {
95         if (!player_ptr->blind
96             && ((g_ptr->info & (CAVE_MARK | CAVE_LITE | CAVE_MNLT))
97                 || ((g_ptr->info & CAVE_VIEW) && (((g_ptr->info & (CAVE_GLOW | CAVE_MNDK)) == CAVE_GLOW) || player_ptr->see_nocto)))) {
98             a = f_ptr->x_attr[F_LIT_STANDARD];
99             c = f_ptr->x_char[F_LIT_STANDARD];
100             if (player_ptr->wild_mode) {
101                 if (view_special_lite && !is_daytime()) {
102                     a = f_ptr->x_attr[F_LIT_DARK];
103                     c = f_ptr->x_char[F_LIT_DARK];
104                 }
105             } else if (darkened_grid(player_ptr, g_ptr)) {
106                 feat = (view_unsafe_grids && (g_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
107                 f_ptr = &f_info[feat];
108                 a = f_ptr->x_attr[F_LIT_STANDARD];
109                 c = f_ptr->x_char[F_LIT_STANDARD];
110             } else if (view_special_lite) {
111                 if (g_ptr->info & (CAVE_LITE | CAVE_MNLT)) {
112                     if (view_yellow_lite) {
113                         a = f_ptr->x_attr[F_LIT_LITE];
114                         c = f_ptr->x_char[F_LIT_LITE];
115                     }
116                 } else if ((g_ptr->info & (CAVE_GLOW | CAVE_MNDK)) != CAVE_GLOW) {
117                     a = f_ptr->x_attr[F_LIT_DARK];
118                     c = f_ptr->x_char[F_LIT_DARK];
119                 } else if (!(g_ptr->info & CAVE_VIEW)) {
120                     if (view_bright_lite) {
121                         a = f_ptr->x_attr[F_LIT_DARK];
122                         c = f_ptr->x_char[F_LIT_DARK];
123                     }
124                 }
125             }
126         } else {
127             feat = (view_unsafe_grids && (g_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
128             f_ptr = &f_info[feat];
129             a = f_ptr->x_attr[F_LIT_STANDARD];
130             c = f_ptr->x_char[F_LIT_STANDARD];
131         }
132     } else {
133         if (g_ptr->info & CAVE_MARK) {
134             a = f_ptr->x_attr[F_LIT_STANDARD];
135             c = f_ptr->x_char[F_LIT_STANDARD];
136             if (player_ptr->wild_mode) {
137                 if (view_granite_lite && (player_ptr->blind || !is_daytime())) {
138                     a = f_ptr->x_attr[F_LIT_DARK];
139                     c = f_ptr->x_char[F_LIT_DARK];
140                 }
141             } else if (darkened_grid(player_ptr, g_ptr) && !player_ptr->blind) {
142                 if (has_flag(f_ptr->flags, FF_LOS) && has_flag(f_ptr->flags, FF_PROJECT)) {
143                     feat = (view_unsafe_grids && (g_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
144                     f_ptr = &f_info[feat];
145                     a = f_ptr->x_attr[F_LIT_STANDARD];
146                     c = f_ptr->x_char[F_LIT_STANDARD];
147                 } else if (view_granite_lite && view_bright_lite) {
148                     a = f_ptr->x_attr[F_LIT_DARK];
149                     c = f_ptr->x_char[F_LIT_DARK];
150                 }
151             } else if (view_granite_lite) {
152                 if (player_ptr->blind) {
153                     a = f_ptr->x_attr[F_LIT_DARK];
154                     c = f_ptr->x_char[F_LIT_DARK];
155                 } else if (g_ptr->info & (CAVE_LITE | CAVE_MNLT)) {
156                     if (view_yellow_lite) {
157                         a = f_ptr->x_attr[F_LIT_LITE];
158                         c = f_ptr->x_char[F_LIT_LITE];
159                     }
160                 } else if (view_bright_lite) {
161                     if (!(g_ptr->info & CAVE_VIEW)) {
162                         a = f_ptr->x_attr[F_LIT_DARK];
163                         c = f_ptr->x_char[F_LIT_DARK];
164                     } else if ((g_ptr->info & (CAVE_GLOW | CAVE_MNDK)) != CAVE_GLOW) {
165                         a = f_ptr->x_attr[F_LIT_DARK];
166                         c = f_ptr->x_char[F_LIT_DARK];
167                     } else if (!has_flag(f_ptr->flags, FF_LOS) && !check_local_illumination(player_ptr, y, x)) {
168                         a = f_ptr->x_attr[F_LIT_DARK];
169                         c = f_ptr->x_char[F_LIT_DARK];
170                     }
171                 }
172             }
173         } else {
174             feat = (view_unsafe_grids && (g_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
175             f_ptr = &f_info[feat];
176             a = f_ptr->x_attr[F_LIT_STANDARD];
177             c = f_ptr->x_char[F_LIT_STANDARD];
178         }
179     }
180
181     if (feat_priority == -1)
182         feat_priority = f_ptr->priority;
183
184     (*tap) = a;
185     (*tcp) = c;
186     (*ap) = a;
187     (*cp) = c;
188
189     if (player_ptr->image && one_in_(256))
190         image_random(ap, cp);
191
192     for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) {
193         object_type *o_ptr;
194         o_ptr = &floor_ptr->o_list[this_o_idx];
195         next_o_idx = o_ptr->next_o_idx;
196         if (!(o_ptr->marked & OM_FOUND))
197             continue;
198
199         if (display_autopick) {
200             byte act;
201
202             match_autopick = find_autopick_list(player_ptr, o_ptr);
203             if (match_autopick == -1)
204                 continue;
205
206             act = autopick_list[match_autopick].action;
207
208             if ((act & DO_DISPLAY) && (act & display_autopick)) {
209                 autopick_obj = o_ptr;
210             } else {
211                 match_autopick = -1;
212                 continue;
213             }
214         }
215
216         (*cp) = object_char(o_ptr);
217         (*ap) = object_attr(o_ptr);
218         feat_priority = 20;
219         if (player_ptr->image)
220             image_object(ap, cp);
221
222         break;
223     }
224
225     if (g_ptr->m_idx && display_autopick != 0) {
226         set_term_color(player_ptr, y, x, ap, cp);
227         return;
228     }
229
230     monster_type *m_ptr = &floor_ptr->m_list[g_ptr->m_idx];
231     if (!m_ptr->ml) {
232         set_term_color(player_ptr, y, x, ap, cp);
233         return;
234     }
235
236     monster_race *r_ptr = &r_info[m_ptr->ap_r_idx];
237     feat_priority = 30;
238     if (player_ptr->image) {
239         if ((r_ptr->flags1 & (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR)) == (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR)) {
240             /* Do nothing */
241         } else {
242             image_monster(ap, cp);
243         }
244
245         set_term_color(player_ptr, y, x, ap, cp);
246         return;
247     }
248
249     a = r_ptr->x_attr;
250     c = r_ptr->x_char;
251     if (!(r_ptr->flags1 & (RF1_CHAR_CLEAR | RF1_SHAPECHANGER | RF1_ATTR_CLEAR | RF1_ATTR_MULTI | RF1_ATTR_SEMIRAND))) {
252         *ap = a;
253         *cp = c;
254         set_term_color(player_ptr, y, x, ap, cp);
255         return;
256     }
257
258     if ((r_ptr->flags1 & (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR)) == (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR)) {
259         set_term_color(player_ptr, y, x, ap, cp);
260         return;
261     }
262
263     if ((r_ptr->flags1 & RF1_ATTR_CLEAR) && (*ap != TERM_DARK) && !use_graphics) {
264         /* Do nothing */
265     } else if ((r_ptr->flags1 & RF1_ATTR_MULTI) && !use_graphics) {
266         if (r_ptr->flags2 & RF2_ATTR_ANY)
267             *ap = randint1(15);
268         else
269             switch (randint1(7)) {
270             case 1:
271                 *ap = TERM_RED;
272                 break;
273             case 2:
274                 *ap = TERM_L_RED;
275                 break;
276             case 3:
277                 *ap = TERM_WHITE;
278                 break;
279             case 4:
280                 *ap = TERM_L_GREEN;
281                 break;
282             case 5:
283                 *ap = TERM_BLUE;
284                 break;
285             case 6:
286                 *ap = TERM_L_DARK;
287                 break;
288             case 7:
289                 *ap = TERM_GREEN;
290                 break;
291             }
292     } else if ((r_ptr->flags1 & RF1_ATTR_SEMIRAND) && !use_graphics) {
293         *ap = g_ptr->m_idx % 15 + 1;
294     } else {
295         *ap = a;
296     }
297
298     if ((r_ptr->flags1 & RF1_CHAR_CLEAR) && (*cp != ' ') && !use_graphics) {
299         set_term_color(player_ptr, y, x, ap, cp);
300         return;
301     }
302
303     if (r_ptr->flags1 & RF1_SHAPECHANGER) {
304         if (use_graphics) {
305             monster_race *tmp_r_ptr = &r_info[randint1(max_r_idx - 1)];
306             *cp = tmp_r_ptr->x_char;
307             *ap = tmp_r_ptr->x_attr;
308         } else {
309             *cp = (one_in_(25) ? image_object_hack[randint0(sizeof(image_object_hack) - 1)] : image_monster_hack[randint0(sizeof(image_monster_hack) - 1)]);
310         }
311
312         set_term_color(player_ptr, y, x, ap, cp);
313         return;
314     }
315
316     *cp = c;
317     set_term_color(player_ptr, y, x, ap, cp);
318 }