OSDN Git Service

Merge branch 'master' of git.osdn.net:/gitroot/hengband/hengband
[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 \89B\82µ\83h\83A\82ð\94z\92u\82·\82é
56  * @param player_ptr \83v\83\8c\81[\83\84\81[\82Ö\82Ì\8eQ\8fÆ\83|\83C\83\93\83^
57  * @param y \94z\92u\82µ\82½\82¢\83t\83\8d\83A\82ÌY\8dÀ\95W
58  * @param x \94z\92u\82µ\82½\82¢\83t\83\8d\83A\82ÌX\8dÀ\95W
59  * @param type DOOR_DEFAULT / DOOR_DOOR / DOOR_GLASS_DOOR / DOOR_CURTAIN \82Ì\82¢\82¸\82ê\82©
60  * @return \82È\82µ
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 (have_flag(f_info[g_ptr->mimic].flags, FF_MOVE) || have_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 \8c®\82Ì\82©\82©\82Á\82½\83h\83A\82ð\94z\92u\82·\82é
95  * @param player_ptr \83v\83\8c\81[\83\84\81[\82Ö\82Ì\8eQ\8fÆ\83|\83C\83\93\83^
96  * @param y \94z\92u\82µ\82½\82¢\83t\83\8d\83A\82ÌY\8dÀ\95W
97  * @param x \94z\92u\82µ\82½\82¢\83t\83\8d\83A\82ÌX\8dÀ\95W
98  * @return \82È\82µ
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 \8f\8a\92è\82Ì\88Ê\92u\82É\82³\82Ü\82´\82Ü\82È\8fó\91Ô\82â\8eí\97Þ\82Ì\83h\83A\82ð\94z\92u\82·\82é / Place a random type of door at the given location
115  * @param player_ptr \83v\83\8c\81[\83\84\81[\82Ö\82Ì\8eQ\8fÆ\83|\83C\83\93\83^
116  * @param y \83h\83A\82Ì\94z\92u\82ð\8e\8e\82Ý\82½\82¢\83}\83X\82ÌY\8dÀ\95W
117  * @param x \83h\83A\82Ì\94z\92u\82ð\8e\8e\82Ý\82½\82¢\83}\83X\82ÌX\8dÀ\95W
118  * @param room \95\94\89®\82É\90Ú\82µ\82Ä\82¢\82é\8fê\8d\87\8cü\82¯\82Ì\83h\83A\90\90¬\82©\94Û\82©
119  * @return \82È\82µ
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 (have_flag(f_info[g_ptr->mimic].flags, FF_MOVE) || have_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 \8f\8a\92è\82Ì\88Ê\92u\82É\8ae\8eí\82Ì\95Â\82\82½\83h\83A\82ð\94z\92u\82·\82é / Place a random type of normal door at the given location.
174  * @param player_ptr \83v\83\8c\81[\83\84\81[\82Ö\82Ì\8eQ\8fÆ\83|\83C\83\93\83^
175  * @param y \83h\83A\82Ì\94z\92u\82ð\8e\8e\82Ý\82½\82¢\83}\83X\82ÌY\8dÀ\95W
176  * @param x \83h\83A\82Ì\94z\92u\82ð\8e\8e\82Ý\82½\82¢\83}\83X\82ÌX\8dÀ\95W
177  * @param type \83h\83A\82Ì\92n\8c`ID
178  * @return \82È\82µ
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 }