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"
7 #include "room/door-definition.h"
8 #include "system/floor-type-definition.h"
9 #include "util/bit-flags-calculator.h"
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.
15 * The doors must be INSIDE the allocated region.
17 void add_door(player_type *player_ptr, POSITION x, POSITION y)
19 floor_type *floor_ptr = player_ptr->current_floor_ptr;
20 if (!is_outer_bold(floor_ptr, y, x))
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);
44 * where x = don't care
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);
56 * @param player_ptr プレーヤーへの参照ポインタ
57 * @param y 配置したいフロアのY座標
58 * @param x 配置したいフロアのX座標
59 * @param type DOOR_DEFAULT / DOOR_DOOR / DOOR_GLASS_DOOR / DOOR_CURTAIN のいずれか
62 void place_secret_door(player_type *player_ptr, POSITION y, POSITION x, int type)
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);
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))
73 : ((d_info[floor_ptr->dungeon_idx].flags1 & DF1_GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR);
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)];
89 g_ptr->info &= ~(CAVE_FLOOR);
90 delete_monster(player_ptr, y, x);
94 * @brief 鍵のかかったドアを配置する
95 * @param player_ptr プレーヤーへの参照ポインタ
96 * @param y 配置したいフロアのY座標
97 * @param x 配置したいフロアのX座標
100 void place_locked_door(player_type *player_ptr, POSITION y, POSITION x)
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);
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);
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 部屋に接している場合向けのドア生成か否か
121 void place_random_door(player_type *player_ptr, POSITION y, POSITION x, bool room)
123 floor_type *floor_ptr = player_ptr->current_floor_ptr;
124 grid_type *g_ptr = &floor_ptr->grid_array[y][x];
127 if (d_info[floor_ptr->dungeon_idx].flags1 & DF1_NO_DOORS) {
128 place_bold(player_ptr, y, x, GB_FLOOR);
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))
134 : ((d_info[floor_ptr->dungeon_idx].flags1 & DF1_GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR);
136 int tmp = randint0(1000);
137 FEAT_IDX feat = feat_none;
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);
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)];
155 place_closed_door(player_ptr, y, x, type);
159 delete_monster(player_ptr, y, x);
163 if (feat == feat_none) {
164 place_bold(player_ptr, y, x, GB_FLOOR);
166 set_cave_feat(floor_ptr, y, x, feat);
169 delete_monster(player_ptr, y, x);
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
180 void place_closed_door(player_type *player_ptr, POSITION y, POSITION x, int type)
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);
188 int tmp = randint0(400);
189 FEAT_IDX feat = feat_none;
191 feat = feat_door[type].closed;
192 } else if (tmp < 399) {
193 feat = feat_locked_door_random(type);
195 feat = feat_jammed_door_random(type);
198 if (feat == feat_none) {
199 place_bold(player_ptr, y, x, GB_FLOOR);
203 cave_set_feat(player_ptr, y, x, feat);
204 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);