1 #include "grid/feature.h"
2 #include "core/player-update-types.h"
3 #include "dungeon/dungeon-flag-types.h"
4 #include "dungeon/dungeon.h"
5 #include "floor/cave.h"
6 #include "game-option/map-screen-options.h"
8 #include "grid/lighting-colors-table.h"
9 #include "mind/mind-ninja.h"
10 #include "monster/monster-update.h"
11 #include "player/special-defense-types.h"
12 #include "room/door-definition.h"
13 #include "system/floor-type-definition.h"
14 #include "util/bit-flags-calculator.h"
15 #include "world/world.h"
17 /*** Terrain feature variables ***/
19 /* The terrain feature arrays */
32 FEAT_IDX feat_explosive_rune;
36 FEAT_IDX feat_up_stair;
37 FEAT_IDX feat_down_stair;
38 FEAT_IDX feat_entrance;
41 FEAT_IDX feat_trap_open;
42 FEAT_IDX feat_trap_armageddon;
43 FEAT_IDX feat_trap_piranha;
49 FEAT_IDX feat_magma_vein;
50 FEAT_IDX feat_quartz_vein;
53 FEAT_IDX feat_granite;
54 FEAT_IDX feat_permanent;
57 FEAT_IDX feat_glass_floor;
60 FEAT_IDX feat_glass_wall;
61 FEAT_IDX feat_permanent_glass_wall;
64 FEAT_IDX feat_pattern_start;
65 FEAT_IDX feat_pattern_1;
66 FEAT_IDX feat_pattern_2;
67 FEAT_IDX feat_pattern_3;
68 FEAT_IDX feat_pattern_4;
69 FEAT_IDX feat_pattern_end;
70 FEAT_IDX feat_pattern_old;
71 FEAT_IDX feat_pattern_exit;
72 FEAT_IDX feat_pattern_corrupted;
75 FEAT_IDX feat_black_market;
79 FEAT_IDX feat_deep_water;
80 FEAT_IDX feat_shallow_water;
81 FEAT_IDX feat_deep_lava;
82 FEAT_IDX feat_shallow_lava;
83 FEAT_IDX feat_heavy_cold_zone;
84 FEAT_IDX feat_cold_zone;
85 FEAT_IDX feat_heavy_electrical_zone;
86 FEAT_IDX feat_electrical_zone;
87 FEAT_IDX feat_deep_acid_puddle;
88 FEAT_IDX feat_shallow_acid_puddle;
89 FEAT_IDX feat_deep_poisonous_puddle;
90 FEAT_IDX feat_shallow_poisonous_puddle;
96 FEAT_IDX feat_mountain;
99 /* Unknown grid (not detected) */
100 FEAT_IDX feat_undetected;
102 FEAT_IDX feat_wall_outer;
103 FEAT_IDX feat_wall_inner;
104 FEAT_IDX feat_wall_solid;
105 FEAT_IDX feat_ground_type[100], feat_wall_type[100];
108 * Maximum number of terrain features in f_info.txt
113 * @brief 地形が罠持ちであるかの判定を行う。 / Return TRUE if the given feature is a trap
114 * @param feat 地形情報のID
115 * @return 罠持ちの地形ならばTRUEを返す。
117 bool is_trap(player_type *player_ptr, FEAT_IDX feat)
121 return has_flag(f_info[feat].flags, FF_TRAP);
125 * @brief 地形が閉じたドアであるかの判定を行う。 / Return TRUE if the given grid is a closed door
126 * @param feat 地形情報のID
127 * @return 閉じたドアのある地形ならばTRUEを返す。
129 bool is_closed_door(player_type *player_ptr, FEAT_IDX feat)
133 feature_type *f_ptr = &f_info[feat];
135 return (has_flag(f_ptr->flags, FF_OPEN) || has_flag(f_ptr->flags, FF_BASH)) &&
136 !has_flag(f_ptr->flags, FF_MOVE);
143 void apply_default_feat_lighting(TERM_COLOR *f_attr, SYMBOL_CODE *f_char)
145 TERM_COLOR s_attr = f_attr[F_LIT_STANDARD];
146 SYMBOL_CODE s_char = f_char[F_LIT_STANDARD];
148 if (is_ascii_graphics(s_attr)) /* For ASCII */
150 f_attr[F_LIT_LITE] = lighting_colours[s_attr & 0x0f][0];
151 f_attr[F_LIT_DARK] = lighting_colours[s_attr & 0x0f][1];
152 for (int i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
154 } else /* For tile graphics */
156 for (int i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
158 f_char[F_LIT_LITE] = s_char + 2;
159 f_char[F_LIT_DARK] = s_char + 1;
164 * Not using graphical tiles for this feature?
166 bool is_ascii_graphics(char x) { return (x & 0x80) == 0; }
169 * Determine if a "feature" is "permanent wall"
171 bool permanent_wall(feature_type *f_ptr) { return has_flag(f_ptr->flags, FF_WALL) && has_flag(f_ptr->flags, FF_PERMANENT); }
173 FEAT_IDX feat_locked_door_random(int door_type)
175 return feat_door[door_type].num_locked ? feat_door[door_type].locked[randint0(feat_door[door_type].num_locked)] : feat_none;
178 FEAT_IDX feat_jammed_door_random(int door_type)
180 return feat_door[door_type].num_jammed ? feat_door[door_type].jammed[randint0(feat_door[door_type].num_jammed)] : feat_none;
184 * Determine if a "legal" grid is within "los" of the player *
185 * Note the use of comparison to zero to force a "boolean" result
187 static bool player_has_los_grid(grid_type *g_ptr) { return (g_ptr->info & CAVE_VIEW) != 0; }
190 * Change the "feat" flag for a grid, and notice/redraw the grid
192 void cave_set_feat(player_type *player_ptr, POSITION y, POSITION x, FEAT_IDX feat)
194 floor_type *floor_ptr = player_ptr->current_floor_ptr;
195 grid_type *g_ptr = &floor_ptr->grid_array[y][x];
196 feature_type *f_ptr = &f_info[feat];
197 if (!current_world_ptr->character_dungeon) {
200 if (has_flag(f_ptr->flags, FF_GLOW) && !(d_info[floor_ptr->dungeon_idx].flags1 & DF1_DARKNESS)) {
201 for (DIRECTION i = 0; i < 9; i++) {
202 POSITION yy = y + ddy_ddd[i];
203 POSITION xx = x + ddx_ddd[i];
204 if (!in_bounds2(floor_ptr, yy, xx))
207 floor_ptr->grid_array[yy][xx].info |= CAVE_GLOW;
214 bool old_los = cave_has_flag_bold(floor_ptr, y, x, FF_LOS);
215 bool old_mirror = is_mirror_grid(g_ptr);
219 g_ptr->info &= ~(CAVE_OBJECT);
220 if (old_mirror && (d_info[floor_ptr->dungeon_idx].flags1 & DF1_DARKNESS)) {
221 g_ptr->info &= ~(CAVE_GLOW);
222 if (!view_torch_grids)
223 g_ptr->info &= ~(CAVE_MARK);
225 update_local_illumination(player_ptr, y, x);
228 if (!has_flag(f_ptr->flags, FF_REMEMBER))
229 g_ptr->info &= ~(CAVE_MARK);
231 update_monster(player_ptr, g_ptr->m_idx, FALSE);
233 note_spot(player_ptr, y, x);
234 lite_spot(player_ptr, y, x);
235 if (old_los ^ has_flag(f_ptr->flags, FF_LOS))
236 player_ptr->update |= PU_VIEW | PU_LITE | PU_MON_LITE | PU_MONSTERS;
238 if (!has_flag(f_ptr->flags, FF_GLOW) || (d_info[player_ptr->dungeon_idx].flags1 & DF1_DARKNESS))
241 for (DIRECTION i = 0; i < 9; i++) {
242 POSITION yy = y + ddy_ddd[i];
243 POSITION xx = x + ddx_ddd[i];
244 if (!in_bounds2(floor_ptr, yy, xx))
248 cc_ptr = &floor_ptr->grid_array[yy][xx];
249 cc_ptr->info |= CAVE_GLOW;
251 if (player_has_los_grid(cc_ptr)) {
253 update_monster(player_ptr, cc_ptr->m_idx, FALSE);
254 note_spot(player_ptr, yy, xx);
255 lite_spot(player_ptr, yy, xx);
258 update_local_illumination(player_ptr, yy, xx);
261 if (player_ptr->special_defense & NINJA_S_STEALTH) {
262 if (floor_ptr->grid_array[player_ptr->y][player_ptr->x].info & CAVE_GLOW)
263 set_superstealth(player_ptr, FALSE);
267 FEAT_IDX conv_dungeon_feat(floor_type *floor_ptr, FEAT_IDX newfeat)
269 feature_type *f_ptr = &f_info[newfeat];
270 if (!has_flag(f_ptr->flags, FF_CONVERT))
273 switch (f_ptr->subtype) {
274 case CONVERT_TYPE_FLOOR:
275 return feat_ground_type[randint0(100)];
276 case CONVERT_TYPE_WALL:
277 return feat_wall_type[randint0(100)];
278 case CONVERT_TYPE_INNER:
279 return feat_wall_inner;
280 case CONVERT_TYPE_OUTER:
281 return feat_wall_outer;
282 case CONVERT_TYPE_SOLID:
283 return feat_wall_solid;
284 case CONVERT_TYPE_STREAM1:
285 return d_info[floor_ptr->dungeon_idx].stream1;
286 case CONVERT_TYPE_STREAM2:
287 return d_info[floor_ptr->dungeon_idx].stream2;