OSDN Git Service

Merge branch 'master' of git.osdn.net:/gitroot/hengband/hengband
[hengband/hengband.git] / src / room / rooms-special.c
1 #include "room/rooms-special.h"
2 #include "dungeon/dungeon-flag-types.h"
3 #include "dungeon/dungeon.h"
4 #include "floor/floor-generator.h"
5 #include "game-option/cheat-types.h"
6 #include "grid/door.h"
7 #include "grid/feature.h"
8 #include "grid/grid.h"
9 #include "grid/object-placer.h"
10 #include "monster-race/monster-race-hook.h"
11 #include "monster-floor/monster-generator.h"
12 #include "monster/monster-list.h"
13 #include "monster/monster-util.h"
14 #include "monster-floor/place-monster-types.h"
15 #include "object-enchant/item-apply-magic.h"
16 #include "object/object-kind-hook.h"
17 #include "room/space-finder.h"
18 #include "system/floor-type-definition.h"
19 #include "system/system-variables.h"
20 #include "wizard/wizard-messages.h"
21
22 /*!
23 * @brief タイプ15の部屋…ガラス部屋の生成 / Type 15 -- glass rooms
24 * @param player_ptr プレーヤーへの参照ポインタ
25 * @return なし
26 */
27 bool build_type15(player_type *player_ptr, dun_data_type *dd_ptr)
28 {
29         POSITION y, x, y2, x2, yval, xval;
30         POSITION y1, x1, xsize, ysize;
31         bool light;
32
33         grid_type *g_ptr;
34
35         /* Pick a room size */
36         xsize = rand_range(9, 13);
37         ysize = rand_range(9, 13);
38
39         /* Find and reserve some space in the dungeon.  Get center of room. */
40         floor_type *floor_ptr = player_ptr->current_floor_ptr;
41         if (!find_space(player_ptr, dd_ptr, &yval, &xval, ysize + 2, xsize + 2)) return FALSE;
42
43         /* Choose lite or dark */
44         light = ((floor_ptr->dun_level <= randint1(25)) && !(d_info[floor_ptr->dungeon_idx].flags1 & DF1_DARKNESS));
45
46         /* Get corner values */
47         y1 = yval - ysize / 2;
48         x1 = xval - xsize / 2;
49         y2 = yval + (ysize - 1) / 2;
50         x2 = xval + (xsize - 1) / 2;
51
52         /* Place a full floor under the room */
53         for (y = y1 - 1; y <= y2 + 1; y++)
54         {
55                 for (x = x1 - 1; x <= x2 + 1; x++)
56                 {
57                         g_ptr = &floor_ptr->grid_array[y][x];
58                         place_grid(player_ptr, g_ptr, GB_FLOOR);
59                         g_ptr->feat = feat_glass_floor;
60                         g_ptr->info |= (CAVE_ROOM);
61                         if (light) g_ptr->info |= (CAVE_GLOW);
62                 }
63         }
64
65         /* Walls around the room */
66         for (y = y1 - 1; y <= y2 + 1; y++)
67         {
68                 g_ptr = &floor_ptr->grid_array[y][x1 - 1];
69                 place_grid(player_ptr, g_ptr, GB_OUTER);
70                 g_ptr->feat = feat_glass_wall;
71                 g_ptr = &floor_ptr->grid_array[y][x2 + 1];
72                 place_grid(player_ptr, g_ptr, GB_OUTER);
73                 g_ptr->feat = feat_glass_wall;
74         }
75
76         for (x = x1 - 1; x <= x2 + 1; x++)
77         {
78                 g_ptr = &floor_ptr->grid_array[y1 - 1][x];
79                 place_grid(player_ptr, g_ptr, GB_OUTER);
80                 g_ptr->feat = feat_glass_wall;
81                 g_ptr = &floor_ptr->grid_array[y2 + 1][x];
82                 place_grid(player_ptr, g_ptr, GB_OUTER);
83                 g_ptr->feat = feat_glass_wall;
84         }
85
86         switch (randint1(3))
87         {
88         case 1: /* 4 lite breathers + potion */
89         {
90                 DIRECTION dir1, dir2;
91                 get_mon_num_prep(player_ptr, vault_aux_lite, NULL);
92
93                 /* Place fixed lite berathers */
94                 for (dir1 = 4; dir1 < 8; dir1++)
95                 {
96                         MONRACE_IDX r_idx = get_mon_num(player_ptr, floor_ptr->dun_level, 0);
97
98                         y = yval + 2 * ddy_ddd[dir1];
99                         x = xval + 2 * ddx_ddd[dir1];
100                         if (r_idx) place_monster_aux(player_ptr, 0, y, x, r_idx, PM_ALLOW_SLEEP);
101
102                         /* Walls around the breather */
103                         for (dir2 = 0; dir2 < 8; dir2++)
104                         {
105                                 g_ptr = &floor_ptr->grid_array[y + ddy_ddd[dir2]][x + ddx_ddd[dir2]];
106                                 place_grid(player_ptr, g_ptr, GB_INNER);
107                                 g_ptr->feat = feat_glass_wall;
108                         }
109                 }
110
111                 /* Walls around the potion */
112                 for (dir1 = 0; dir1 < 4; dir1++)
113                 {
114                         y = yval + 2 * ddy_ddd[dir1];
115                         x = xval + 2 * ddx_ddd[dir1];
116                         g_ptr = &floor_ptr->grid_array[y][x];
117                         place_grid(player_ptr, g_ptr, GB_INNER_PERM);
118                         g_ptr->feat = feat_permanent_glass_wall;
119                         floor_ptr->grid_array[yval + ddy_ddd[dir1]][xval + ddx_ddd[dir1]].info |= (CAVE_ICKY);
120                 }
121
122                 /* Glass door */
123                 dir1 = randint0(4);
124                 y = yval + 2 * ddy_ddd[dir1];
125                 x = xval + 2 * ddx_ddd[dir1];
126                 place_secret_door(player_ptr, y, x, DOOR_GLASS_DOOR);
127                 g_ptr = &floor_ptr->grid_array[y][x];
128                 if (is_closed_door(player_ptr, g_ptr->feat)) g_ptr->mimic = feat_glass_wall;
129
130                 /* Place a potion */
131                 get_obj_num_hook = kind_is_potion;
132                 place_object(player_ptr, yval, xval, AM_NO_FIXED_ART);
133                 floor_ptr->grid_array[yval][xval].info |= (CAVE_ICKY);
134         }
135         break;
136
137         case 2: /* 1 lite breather + random object */
138         {
139                 MONRACE_IDX r_idx;
140                 DIRECTION dir1;
141
142                 /* Pillars */
143                 g_ptr = &floor_ptr->grid_array[y1 + 1][x1 + 1];
144                 place_grid(player_ptr, g_ptr, GB_INNER);
145                 g_ptr->feat = feat_glass_wall;
146
147                 g_ptr = &floor_ptr->grid_array[y1 + 1][x2 - 1];
148                 place_grid(player_ptr, g_ptr, GB_INNER);
149                 g_ptr->feat = feat_glass_wall;
150
151                 g_ptr = &floor_ptr->grid_array[y2 - 1][x1 + 1];
152                 place_grid(player_ptr, g_ptr, GB_INNER);
153                 g_ptr->feat = feat_glass_wall;
154
155                 g_ptr = &floor_ptr->grid_array[y2 - 1][x2 - 1];
156                 place_grid(player_ptr, g_ptr, GB_INNER);
157                 g_ptr->feat = feat_glass_wall;
158                 get_mon_num_prep(player_ptr, vault_aux_lite, NULL);
159
160                 r_idx = get_mon_num(player_ptr, floor_ptr->dun_level, 0);
161                 if (r_idx) place_monster_aux(player_ptr, 0, yval, xval, r_idx, 0L);
162
163                 /* Walls around the breather */
164                 for (dir1 = 0; dir1 < 8; dir1++)
165                 {
166                         g_ptr = &floor_ptr->grid_array[yval + ddy_ddd[dir1]][xval + ddx_ddd[dir1]];
167                         place_grid(player_ptr, g_ptr, GB_INNER);
168                         g_ptr->feat = feat_glass_wall;
169                 }
170
171                 /* Curtains around the breather */
172                 for (y = yval - 1; y <= yval + 1; y++)
173                 {
174                         place_secret_door(player_ptr, y, xval - 2, DOOR_CURTAIN);
175                         place_secret_door(player_ptr, y, xval + 2, DOOR_CURTAIN);
176                 }
177
178                 for (x = xval - 1; x <= xval + 1; x++)
179                 {
180                         place_secret_door(player_ptr, yval - 2, x, DOOR_CURTAIN);
181                         place_secret_door(player_ptr, yval + 2, x, DOOR_CURTAIN);
182                 }
183
184                 /* Place an object */
185                 place_object(player_ptr, yval, xval, AM_NO_FIXED_ART);
186                 floor_ptr->grid_array[yval][xval].info |= (CAVE_ICKY);
187         }
188         break;
189
190         case 3: /* 4 shards breathers + 2 potions */
191         {
192                 DIRECTION dir1;
193
194                 /* Walls around the potion */
195                 for (y = yval - 2; y <= yval + 2; y++)
196                 {
197                         g_ptr = &floor_ptr->grid_array[y][xval - 3];
198                         place_grid(player_ptr, g_ptr, GB_INNER);
199                         g_ptr->feat = feat_glass_wall;
200                         g_ptr = &floor_ptr->grid_array[y][xval + 3];
201                         place_grid(player_ptr, g_ptr, GB_INNER);
202                         g_ptr->feat = feat_glass_wall;
203                 }
204
205                 for (x = xval - 2; x <= xval + 2; x++)
206                 {
207                         g_ptr = &floor_ptr->grid_array[yval - 3][x];
208                         place_grid(player_ptr, g_ptr, GB_INNER);
209                         g_ptr->feat = feat_glass_wall;
210                         g_ptr = &floor_ptr->grid_array[yval + 3][x];
211                         place_grid(player_ptr, g_ptr, GB_INNER);
212                         g_ptr->feat = feat_glass_wall;
213                 }
214
215                 for (dir1 = 4; dir1 < 8; dir1++)
216                 {
217                         g_ptr = &floor_ptr->grid_array[yval + 2 * ddy_ddd[dir1]][xval + 2 * ddx_ddd[dir1]];
218                         place_grid(player_ptr, g_ptr, GB_INNER);
219                         g_ptr->feat = feat_glass_wall;
220                 }
221
222                 get_mon_num_prep(player_ptr, vault_aux_shards, NULL);
223
224                 /* Place shard berathers */
225                 for (dir1 = 4; dir1 < 8; dir1++)
226                 {
227                         MONRACE_IDX r_idx = get_mon_num(player_ptr, floor_ptr->dun_level, 0);
228
229                         y = yval + ddy_ddd[dir1];
230                         x = xval + ddx_ddd[dir1];
231                         if (r_idx) place_monster_aux(player_ptr, 0, y, x, r_idx, 0L);
232                 }
233
234                 /* Place two potions */
235                 if (one_in_(2))
236                 {
237                         get_obj_num_hook = kind_is_potion;
238                         place_object(player_ptr, yval, xval - 1, AM_NO_FIXED_ART);
239                         get_obj_num_hook = kind_is_potion;
240                         place_object(player_ptr, yval, xval + 1, AM_NO_FIXED_ART);
241                 }
242                 else
243                 {
244                         get_obj_num_hook = kind_is_potion;
245                         place_object(player_ptr, yval - 1, xval, AM_NO_FIXED_ART);
246                         get_obj_num_hook = kind_is_potion;
247                         place_object(player_ptr, yval + 1, xval, AM_NO_FIXED_ART);
248                 }
249
250                 for (y = yval - 2; y <= yval + 2; y++)
251                         for (x = xval - 2; x <= xval + 2; x++)
252                                 floor_ptr->grid_array[y][x].info |= (CAVE_ICKY);
253
254         }
255         break;
256         }
257
258         msg_print_wizard(player_ptr, CHEAT_DUNGEON, _("ガラスの部屋が生成されました。", "Glass room was generated."));
259         return TRUE;
260 }