OSDN Git Service

[Refactor] #37353 生命領域処理を cmd-spell.c から realm-life.c/h へ分離。
[hengband/hengband.git] / src / rooms-vault.c
1 #include "angband.h"\r
2 #include "grid.h"\r
3 #include "rooms.h"\r
4 #include "generate.h"\r
5 \r
6 \r
7 \r
8 /*!\r
9 * @brief Vault\92n\8c`\82ð\89ñ\93]\81A\8fã\89º\8d\89E\94½\93]\82·\82é\82½\82ß\82Ì\8dÀ\95W\95Ï\8a·\82ð\95Ô\82· / coordinate translation code\r
10 * @param x \95Ï\8a·\82µ\82½\82¢\93_\82ÌX\8dÀ\95W\8eQ\8fÆ\83|\83C\83\93\83^\r
11 * @param y \95Ï\8a·\82µ\82½\82¢\93_\82ÌY\8dÀ\95W\8eQ\8fÆ\83|\83C\83\93\83^\r
12 * @param xoffset Vault\90\90¬\8e\9e\82Ì\8aî\8f\80X\8dÀ\95W\r
13 * @param yoffset Vault\90\90¬\8e\9e\82Ì\8aî\8f\80Y\8dÀ\95W\r
14 * @param transno \8f\88\97\9dID\r
15 * @return \82È\82µ\r
16 */\r
17 static void coord_trans(POSITION *x, POSITION *y, POSITION xoffset, POSITION yoffset, int transno)\r
18 {\r
19         int i;\r
20         int temp;\r
21 \r
22         /*\r
23         * transno specifies what transformation is required. (0-7)\r
24         * The lower two bits indicate by how much the vault is rotated,\r
25         * and the upper bit indicates a reflection.\r
26         * This is done by using rotation matrices... however since\r
27         * these are mostly zeros for rotations by 90 degrees this can\r
28         * be expressed simply in terms of swapping and inverting the\r
29         * x and y coordinates.\r
30         */\r
31         for (i = 0; i < transno % 4; i++)\r
32         {\r
33                 /* rotate by 90 degrees */\r
34                 temp = *x;\r
35                 *x = -(*y);\r
36                 *y = temp;\r
37         }\r
38 \r
39         if (transno / 4)\r
40         {\r
41                 /* Reflect depending on status of 3rd bit. */\r
42                 *x = -(*x);\r
43         }\r
44 \r
45         /* Add offsets so vault stays in the first quadrant */\r
46         *x += xoffset;\r
47         *y += yoffset;\r
48 }\r
49 \r
50 \r
51 /*!\r
52 * @brief Vault\82ð\83t\83\8d\83A\82É\94z\92u\82·\82é / Hack -- fill in "vault" rooms\r
53 * @param yval \90\90¬\8aî\8f\80Y\8dÀ\95W\r
54 * @param xval \90\90¬\8aî\8f\80X\8dÀ\95W\r
55 * @param ymax Vault\82ÌY\83T\83C\83Y\r
56 * @param xmax Vault\82ÌX\83T\83C\83Y\r
57 * @param data Vault\82Ì\83f\81[\83^\95\8e\9a\97ñ\r
58 * @param xoffset \95Ï\8a·\8aî\8f\80X\8dÀ\95W\r
59 * @param yoffset \95Ï\8a·\8aî\8f\80Y\8dÀ\95W\r
60 * @param transno \95Ï\8a·ID\r
61 * @return \82È\82µ\r
62 */\r
63 static void build_vault(POSITION yval, POSITION xval, POSITION ymax, POSITION xmax, cptr data,\r
64         POSITION xoffset, POSITION yoffset, int transno)\r
65 {\r
66         POSITION dx, dy, x, y, i, j;\r
67         cptr t;\r
68         cave_type *c_ptr;\r
69 \r
70         /* Place dungeon features and objects */\r
71         for (t = data, dy = 0; dy < ymax; dy++)\r
72         {\r
73                 for (dx = 0; dx < xmax; dx++, t++)\r
74                 {\r
75                         /* prevent loop counter from being overwritten */\r
76                         i = dx;\r
77                         j = dy;\r
78 \r
79                         /* Flip / rotate */\r
80                         coord_trans(&i, &j, xoffset, yoffset, transno);\r
81 \r
82                         /* Extract the location */\r
83                         if (transno % 2 == 0)\r
84                         {\r
85                                 /* no swap of x/y */\r
86                                 x = xval - (xmax / 2) + i;\r
87                                 y = yval - (ymax / 2) + j;\r
88                         }\r
89                         else\r
90                         {\r
91                                 /* swap of x/y */\r
92                                 x = xval - (ymax / 2) + i;\r
93                                 y = yval - (xmax / 2) + j;\r
94                         }\r
95 \r
96                         /* Hack -- skip "non-grids" */\r
97                         if (*t == ' ') continue;\r
98 \r
99                         /* Access the grid */\r
100                         c_ptr = &cave[y][x];\r
101 \r
102                         /* Lay down a floor */\r
103                         place_floor_grid(c_ptr);\r
104 \r
105                         /* Remove any mimic */\r
106                         c_ptr->mimic = 0;\r
107 \r
108                         /* Part of a vault */\r
109                         c_ptr->info |= (CAVE_ROOM | CAVE_ICKY);\r
110 \r
111                         /* Analyze the grid */\r
112                         switch (*t)\r
113                         {\r
114                                 /* Granite wall (outer) */\r
115                         case '%':\r
116                                 place_outer_noperm_grid(c_ptr);\r
117                                 break;\r
118 \r
119                                 /* Granite wall (inner) */\r
120                         case '#':\r
121                                 place_inner_grid(c_ptr);\r
122                                 break;\r
123 \r
124                                 /* Glass wall (inner) */\r
125                         case '$':\r
126                                 place_inner_grid(c_ptr);\r
127                                 c_ptr->feat = feat_glass_wall;\r
128                                 break;\r
129 \r
130                                 /* Permanent wall (inner) */\r
131                         case 'X':\r
132                                 place_inner_perm_grid(c_ptr);\r
133                                 break;\r
134 \r
135                                 /* Permanent glass wall (inner) */\r
136                         case 'Y':\r
137                                 place_inner_perm_grid(c_ptr);\r
138                                 c_ptr->feat = feat_permanent_glass_wall;\r
139                                 break;\r
140 \r
141                                 /* Treasure/trap */\r
142                         case '*':\r
143                                 if (randint0(100) < 75)\r
144                                 {\r
145                                         place_object(y, x, 0L);\r
146                                 }\r
147                                 else\r
148                                 {\r
149                                         place_trap(y, x);\r
150                                 }\r
151                                 break;\r
152 \r
153                                 /* Secret doors */\r
154                         case '+':\r
155                                 place_secret_door(y, x, DOOR_DEFAULT);\r
156                                 break;\r
157 \r
158                                 /* Secret glass doors */\r
159                         case '-':\r
160                                 place_secret_door(y, x, DOOR_GLASS_DOOR);\r
161                                 if (is_closed_door(c_ptr->feat)) c_ptr->mimic = feat_glass_wall;\r
162                                 break;\r
163 \r
164                                 /* Curtains */\r
165                         case '\'':\r
166                                 place_secret_door(y, x, DOOR_CURTAIN);\r
167                                 break;\r
168 \r
169                                 /* Trap */\r
170                         case '^':\r
171                                 place_trap(y, x);\r
172                                 break;\r
173 \r
174                                 /* Black market in a dungeon */\r
175                         case 'S':\r
176                                 set_cave_feat(y, x, feat_black_market);\r
177                                 store_init(NO_TOWN, STORE_BLACK);\r
178                                 break;\r
179 \r
180                                 /* The Pattern */\r
181                         case 'p':\r
182                                 set_cave_feat(y, x, feat_pattern_start);\r
183                                 break;\r
184 \r
185                         case 'a':\r
186                                 set_cave_feat(y, x, feat_pattern_1);\r
187                                 break;\r
188 \r
189                         case 'b':\r
190                                 set_cave_feat(y, x, feat_pattern_2);\r
191                                 break;\r
192 \r
193                         case 'c':\r
194                                 set_cave_feat(y, x, feat_pattern_3);\r
195                                 break;\r
196 \r
197                         case 'd':\r
198                                 set_cave_feat(y, x, feat_pattern_4);\r
199                                 break;\r
200 \r
201                         case 'P':\r
202                                 set_cave_feat(y, x, feat_pattern_end);\r
203                                 break;\r
204 \r
205                         case 'B':\r
206                                 set_cave_feat(y, x, feat_pattern_exit);\r
207                                 break;\r
208 \r
209                         case 'A':\r
210                                 /* Reward for Pattern walk */\r
211                                 object_level = base_level + 12;\r
212                                 place_object(y, x, AM_GOOD | AM_GREAT);\r
213                                 object_level = base_level;\r
214                                 break;\r
215                         }\r
216                 }\r
217         }\r
218 \r
219 \r
220         /* Place dungeon monsters and objects */\r
221         for (t = data, dy = 0; dy < ymax; dy++)\r
222         {\r
223                 for (dx = 0; dx < xmax; dx++, t++)\r
224                 {\r
225                         /* prevent loop counter from being overwritten */\r
226                         i = dx;\r
227                         j = dy;\r
228 \r
229                         /* Flip / rotate */\r
230                         coord_trans(&i, &j, xoffset, yoffset, transno);\r
231 \r
232                         /* Extract the location */\r
233                         if (transno % 2 == 0)\r
234                         {\r
235                                 /* no swap of x/y */\r
236                                 x = xval - (xmax / 2) + i;\r
237                                 y = yval - (ymax / 2) + j;\r
238                         }\r
239                         else\r
240                         {\r
241                                 /* swap of x/y */\r
242                                 x = xval - (ymax / 2) + i;\r
243                                 y = yval - (xmax / 2) + j;\r
244                         }\r
245 \r
246                         /* Hack -- skip "non-grids" */\r
247                         if (*t == ' ') continue;\r
248 \r
249                         /* Analyze the symbol */\r
250                         switch (*t)\r
251                         {\r
252                                 /* Monster */\r
253                         case '&':\r
254                         {\r
255                                 monster_level = base_level + 5;\r
256                                 place_monster(y, x, (PM_ALLOW_SLEEP | PM_ALLOW_GROUP));\r
257                                 monster_level = base_level;\r
258                                 break;\r
259                         }\r
260 \r
261                         /* Meaner monster */\r
262                         case '@':\r
263                         {\r
264                                 monster_level = base_level + 11;\r
265                                 place_monster(y, x, (PM_ALLOW_SLEEP | PM_ALLOW_GROUP));\r
266                                 monster_level = base_level;\r
267                                 break;\r
268                         }\r
269 \r
270                         /* Meaner monster, plus treasure */\r
271                         case '9':\r
272                         {\r
273                                 monster_level = base_level + 9;\r
274                                 place_monster(y, x, PM_ALLOW_SLEEP);\r
275                                 monster_level = base_level;\r
276                                 object_level = base_level + 7;\r
277                                 place_object(y, x, AM_GOOD);\r
278                                 object_level = base_level;\r
279                                 break;\r
280                         }\r
281 \r
282                         /* Nasty monster and treasure */\r
283                         case '8':\r
284                         {\r
285                                 monster_level = base_level + 40;\r
286                                 place_monster(y, x, PM_ALLOW_SLEEP);\r
287                                 monster_level = base_level;\r
288                                 object_level = base_level + 20;\r
289                                 place_object(y, x, AM_GOOD | AM_GREAT);\r
290                                 object_level = base_level;\r
291                                 break;\r
292                         }\r
293 \r
294                         /* Monster and/or object */\r
295                         case ',':\r
296                         {\r
297                                 if (randint0(100) < 50)\r
298                                 {\r
299                                         monster_level = base_level + 3;\r
300                                         place_monster(y, x, (PM_ALLOW_SLEEP | PM_ALLOW_GROUP));\r
301                                         monster_level = base_level;\r
302                                 }\r
303                                 if (randint0(100) < 50)\r
304                                 {\r
305                                         object_level = base_level + 7;\r
306                                         place_object(y, x, 0L);\r
307                                         object_level = base_level;\r
308                                 }\r
309                                 break;\r
310                         }\r
311 \r
312                         }\r
313                 }\r
314         }\r
315 }\r
316 \r
317 \r
318 \r
319 /*!\r
320 * @brief \83^\83C\83v7\82Ì\95\94\89®\81cv_info.txt\82æ\82è\8f¬\8c^vault\82ð\90\90¬\82·\82é / Type 7 -- simple vaults (see "v_info.txt")\r
321 * @return \82È\82µ\r
322 */\r
323 bool build_type7(void)\r
324 {\r
325         vault_type *v_ptr = NULL;\r
326         int dummy;\r
327         POSITION x, y;\r
328         POSITION xval, yval;\r
329         POSITION xoffset, yoffset;\r
330         int transno;\r
331 \r
332         /* Pick a lesser vault */\r
333         for (dummy = 0; dummy < SAFE_MAX_ATTEMPTS; dummy++)\r
334         {\r
335                 /* Access a random vault record */\r
336                 v_ptr = &v_info[randint0(max_v_idx)];\r
337 \r
338                 /* Accept the first lesser vault */\r
339                 if (v_ptr->typ == 7) break;\r
340         }\r
341 \r
342         /* No lesser vault found */\r
343         if (dummy >= SAFE_MAX_ATTEMPTS)\r
344         {\r
345                 msg_print_wizard(CHEAT_DUNGEON, _("\8f¬\8c^\8cÅ\92èVault\82ð\94z\92u\82Å\82«\82Ü\82¹\82ñ\82Å\82µ\82½\81B", "Could not place lesser vault."));\r
346                 return FALSE;\r
347         }\r
348 \r
349         /* pick type of transformation (0-7) */\r
350         transno = randint0(8);\r
351 \r
352         /* calculate offsets */\r
353         x = v_ptr->wid;\r
354         y = v_ptr->hgt;\r
355 \r
356         /* Some huge vault cannot be ratated to fit in the dungeon */\r
357         if (x + 2 > cur_hgt - 2)\r
358         {\r
359                 /* Forbid 90 or 270 degree ratation */\r
360                 transno &= ~1;\r
361         }\r
362 \r
363         coord_trans(&x, &y, 0, 0, transno);\r
364 \r
365         if (x < 0)\r
366         {\r
367                 xoffset = -x - 1;\r
368         }\r
369         else\r
370         {\r
371                 xoffset = 0;\r
372         }\r
373 \r
374         if (y < 0)\r
375         {\r
376                 yoffset = -y - 1;\r
377         }\r
378         else\r
379         {\r
380                 yoffset = 0;\r
381         }\r
382 \r
383         /* Find and reserve some space in the dungeon.  Get center of room. */\r
384         if (!find_space(&yval, &xval, abs(y), abs(x))) return FALSE;\r
385 \r
386 #ifdef FORCE_V_IDX\r
387         v_ptr = &v_info[2];\r
388 #endif\r
389 \r
390         /* Message */\r
391         msg_format_wizard(CHEAT_DUNGEON, _("\8f¬\8c^Vault(%s)\82ð\90\90¬\82µ\82Ü\82µ\82½\81B", "Lesser vault (%s)."), v_name + v_ptr->name);\r
392 \r
393         /* Hack -- Build the vault */\r
394         build_vault(yval, xval, v_ptr->hgt, v_ptr->wid,\r
395                 v_text + v_ptr->text, xoffset, yoffset, transno);\r
396 \r
397         return TRUE;\r
398 }\r
399 \r
400 /*!\r
401 * @brief \83^\83C\83v8\82Ì\95\94\89®\81cv_info.txt\82æ\82è\91å\8c^vault\82ð\90\90¬\82·\82é / Type 8 -- greater vaults (see "v_info.txt")\r
402 * @return \82È\82µ\r
403 */\r
404 bool build_type8(void)\r
405 {\r
406         vault_type *v_ptr;\r
407         int dummy;\r
408         POSITION xval, yval;\r
409         POSITION x, y;\r
410         int transno;\r
411         int xoffset, yoffset;\r
412 \r
413         /* Pick a greater vault */\r
414         for (dummy = 0; dummy < SAFE_MAX_ATTEMPTS; dummy++)\r
415         {\r
416                 /* Access a random vault record */\r
417                 v_ptr = &v_info[randint0(max_v_idx)];\r
418 \r
419                 /* Accept the first greater vault */\r
420                 if (v_ptr->typ == 8) break;\r
421         }\r
422 \r
423         /* No greater vault found */\r
424         if (dummy >= SAFE_MAX_ATTEMPTS)\r
425         {\r
426                 msg_print_wizard(CHEAT_DUNGEON, _("\91å\8c^\8cÅ\92èVault\82ð\94z\92u\82Å\82«\82Ü\82¹\82ñ\82Å\82µ\82½\81B", "Could not place greater vault."));\r
427                 return FALSE;\r
428         }\r
429 \r
430         /* pick type of transformation (0-7) */\r
431         transno = randint0(8);\r
432 \r
433         /* calculate offsets */\r
434         x = v_ptr->wid;\r
435         y = v_ptr->hgt;\r
436 \r
437         /* Some huge vault cannot be ratated to fit in the dungeon */\r
438         if (x + 2 > cur_hgt - 2)\r
439         {\r
440                 /* Forbid 90 or 270 degree ratation */\r
441                 transno &= ~1;\r
442         }\r
443 \r
444         coord_trans(&x, &y, 0, 0, transno);\r
445 \r
446         if (x < 0)\r
447         {\r
448                 xoffset = -x - 1;\r
449         }\r
450         else\r
451         {\r
452                 xoffset = 0;\r
453         }\r
454 \r
455         if (y < 0)\r
456         {\r
457                 yoffset = -y - 1;\r
458         }\r
459         else\r
460         {\r
461                 yoffset = 0;\r
462         }\r
463 \r
464         /*\r
465         * Try to allocate space for room.  If fails, exit\r
466         *\r
467         * Hack -- Prepare a bit larger space (+2, +2) to\r
468         * prevent generation of vaults with no-entrance.\r
469         */\r
470         /* Find and reserve some space in the dungeon.  Get center of room. */\r
471         if (!find_space(&yval, &xval, (POSITION)(abs(y) + 2), (POSITION)(abs(x) + 2))) return FALSE;\r
472 \r
473 #ifdef FORCE_V_IDX\r
474         v_ptr = &v_info[76 + randint1(3)];\r
475 #endif\r
476 \r
477         msg_format_wizard(CHEAT_DUNGEON, _("\91å\8c^\8cÅ\92èVault(%s)\82ð\90\90¬\82µ\82Ü\82µ\82½\81B", "Greater vault (%s)."), v_name + v_ptr->name);\r
478 \r
479         /* Hack -- Build the vault */\r
480         build_vault(yval, xval, v_ptr->hgt, v_ptr->wid,\r
481                 v_text + v_ptr->text, xoffset, yoffset, transno);\r
482 \r
483         return TRUE;\r
484 }\r