OSDN Git Service

[Refactor] 無駄な空白、改行の削除、includeのソート
[hengband/hengband.git] / src / grid / door.c
1 #include "grid/door.h"
2 #include "dungeon/dungeon-flag-types.h"
3 #include "dungeon/dungeon.h"
4 #include "floor/cave.h"
5 #include "grid/feature.h"
6 #include "grid/grid.h"
7 #include "room/door-definition.h"
8 #include "system/floor-type-definition.h"
9 #include "util/bit-flags-calculator.h"
10
11 /*
12  * Routine used by the random vault creators to add a door to a location
13  * Note that range checking has to be done in the calling routine.
14  *
15  * The doors must be INSIDE the allocated region.
16  */
17 void add_door(player_type *player_ptr, POSITION x, POSITION y)
18 {
19     floor_type *floor_ptr = player_ptr->current_floor_ptr;
20     if (!is_outer_bold(floor_ptr, y, x))
21         return;
22
23     /* look at:
24      *  x#x
25      *  .#.
26      *  x#x
27      *
28      *  where x=don't care
29      *  .=floor, #=wall
30      */
31
32     if (is_floor_bold(floor_ptr, y - 1, x) && is_floor_bold(floor_ptr, y + 1, x)
33         && (is_outer_bold(floor_ptr, y, x - 1) && is_outer_bold(floor_ptr, y, x + 1))) {
34         place_secret_door(player_ptr, y, x, DOOR_DEFAULT);
35         place_bold(player_ptr, y, x - 1, GB_SOLID);
36         place_bold(player_ptr, y, x + 1, GB_SOLID);
37     }
38
39     /* look at:
40      *  x#x
41      *  .#.
42      *  x#x
43      *
44      *  where x = don't care
45      *  .=floor, #=wall
46      */
47     if (is_outer_bold(floor_ptr, y - 1, x) && is_outer_bold(floor_ptr, y + 1, x) && is_floor_bold(floor_ptr, y, x - 1) && is_floor_bold(floor_ptr, y, x + 1)) {
48         place_secret_door(player_ptr, y, x, DOOR_DEFAULT);
49         place_bold(player_ptr, y - 1, x, GB_SOLID);
50         place_bold(player_ptr, y + 1, x, GB_SOLID);
51     }
52 }
53
54 /*!
55  * @brief 隠しドアを配置する
56  * @param player_ptr プレーヤーへの参照ポインタ
57  * @param y 配置したいフロアのY座標
58  * @param x 配置したいフロアのX座標
59  * @param type DOOR_DEFAULT / DOOR_DOOR / DOOR_GLASS_DOOR / DOOR_CURTAIN のいずれか
60  * @return なし
61  */
62 void place_secret_door(player_type *player_ptr, POSITION y, POSITION x, int type)
63 {
64     floor_type *floor_ptr = player_ptr->current_floor_ptr;
65     if (d_info[floor_ptr->dungeon_idx].flags1 & DF1_NO_DOORS) {
66         place_bold(player_ptr, y, x, GB_FLOOR);
67         return;
68     }
69
70     if (type == DOOR_DEFAULT) {
71         type = ((d_info[floor_ptr->dungeon_idx].flags1 & DF1_CURTAIN) && one_in_((d_info[floor_ptr->dungeon_idx].flags1 & DF1_NO_CAVE) ? 16 : 256))
72             ? DOOR_CURTAIN
73             : ((d_info[floor_ptr->dungeon_idx].flags1 & DF1_GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR);
74     }
75
76     place_closed_door(player_ptr, y, x, type);
77     grid_type *g_ptr = &floor_ptr->grid_array[y][x];
78     if (type != DOOR_CURTAIN) {
79         g_ptr->mimic = feat_wall_inner;
80         if (feat_supports_los(g_ptr->mimic) && !feat_supports_los(g_ptr->feat)) {
81             if (has_flag(f_info[g_ptr->mimic].flags, FF_MOVE) || has_flag(f_info[g_ptr->mimic].flags, FF_CAN_FLY)) {
82                 g_ptr->feat = one_in_(2) ? g_ptr->mimic : feat_ground_type[randint0(100)];
83             }
84
85             g_ptr->mimic = 0;
86         }
87     }
88
89     g_ptr->info &= ~(CAVE_FLOOR);
90     delete_monster(player_ptr, y, x);
91 }
92
93 /*!
94  * @brief 鍵のかかったドアを配置する
95  * @param player_ptr プレーヤーへの参照ポインタ
96  * @param y 配置したいフロアのY座標
97  * @param x 配置したいフロアのX座標
98  * @return なし
99  */
100 void place_locked_door(player_type *player_ptr, POSITION y, POSITION x)
101 {
102     floor_type *floor_ptr = player_ptr->current_floor_ptr;
103     if (d_info[floor_ptr->dungeon_idx].flags1 & DF1_NO_DOORS) {
104         place_bold(player_ptr, y, x, GB_FLOOR);
105         return;
106     }
107
108     set_cave_feat(floor_ptr, y, x, feat_locked_door_random((d_info[player_ptr->dungeon_idx].flags1 & DF1_GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR));
109     floor_ptr->grid_array[y][x].info &= ~(CAVE_FLOOR);
110     delete_monster(player_ptr, y, x);
111 }
112
113 /*!
114  * @brief 所定の位置にさまざまな状態や種類のドアを配置する / Place a random type of door at the given location
115  * @param player_ptr プレーヤーへの参照ポインタ
116  * @param y ドアの配置を試みたいマスのY座標
117  * @param x ドアの配置を試みたいマスのX座標
118  * @param room 部屋に接している場合向けのドア生成か否か
119  * @return なし
120  */
121 void place_random_door(player_type *player_ptr, POSITION y, POSITION x, bool room)
122 {
123     floor_type *floor_ptr = player_ptr->current_floor_ptr;
124     grid_type *g_ptr = &floor_ptr->grid_array[y][x];
125     g_ptr->mimic = 0;
126
127     if (d_info[floor_ptr->dungeon_idx].flags1 & DF1_NO_DOORS) {
128         place_bold(player_ptr, y, x, GB_FLOOR);
129         return;
130     }
131
132     int type = ((d_info[floor_ptr->dungeon_idx].flags1 & DF1_CURTAIN) && one_in_((d_info[floor_ptr->dungeon_idx].flags1 & DF1_NO_CAVE) ? 16 : 256))
133         ? DOOR_CURTAIN
134         : ((d_info[floor_ptr->dungeon_idx].flags1 & DF1_GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR);
135
136     int tmp = randint0(1000);
137     FEAT_IDX feat = feat_none;
138     if (tmp < 300) {
139         feat = feat_door[type].open;
140     } else if (tmp < 400) {
141         feat = feat_door[type].broken;
142     } else if (tmp < 600) {
143         place_closed_door(player_ptr, y, x, type);
144
145         if (type != DOOR_CURTAIN) {
146             g_ptr->mimic = room ? feat_wall_outer : feat_wall_type[randint0(100)];
147             if (feat_supports_los(g_ptr->mimic) && !feat_supports_los(g_ptr->feat)) {
148                 if (has_flag(f_info[g_ptr->mimic].flags, FF_MOVE) || has_flag(f_info[g_ptr->mimic].flags, FF_CAN_FLY)) {
149                     g_ptr->feat = one_in_(2) ? g_ptr->mimic : feat_ground_type[randint0(100)];
150                 }
151                 g_ptr->mimic = 0;
152             }
153         }
154     } else {
155         place_closed_door(player_ptr, y, x, type);
156     }
157
158     if (tmp >= 400) {
159         delete_monster(player_ptr, y, x);
160         return;
161     }
162
163     if (feat == feat_none) {
164         place_bold(player_ptr, y, x, GB_FLOOR);
165     } else {
166         set_cave_feat(floor_ptr, y, x, feat);
167     }
168
169     delete_monster(player_ptr, y, x);
170 }
171
172 /*!
173  * @brief 所定の位置に各種の閉じたドアを配置する / Place a random type of normal door at the given location.
174  * @param player_ptr プレーヤーへの参照ポインタ
175  * @param y ドアの配置を試みたいマスのY座標
176  * @param x ドアの配置を試みたいマスのX座標
177  * @param type ドアの地形ID
178  * @return なし
179  */
180 void place_closed_door(player_type *player_ptr, POSITION y, POSITION x, int type)
181 {
182     floor_type *floor_ptr = player_ptr->current_floor_ptr;
183     if (d_info[floor_ptr->dungeon_idx].flags1 & DF1_NO_DOORS) {
184         place_bold(player_ptr, y, x, GB_FLOOR);
185         return;
186     }
187
188     int tmp = randint0(400);
189     FEAT_IDX feat = feat_none;
190     if (tmp < 300) {
191         feat = feat_door[type].closed;
192     } else if (tmp < 399) {
193         feat = feat_locked_door_random(type);
194     } else {
195         feat = feat_jammed_door_random(type);
196     }
197
198     if (feat == feat_none) {
199         place_bold(player_ptr, y, x, GB_FLOOR);
200         return;
201     }
202
203     cave_set_feat(player_ptr, y, x, feat);
204     floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
205 }