OSDN Git Service

[Refactor] #40460 Separated fixed-map-generator.c/h from dungeon-file.c/h
[hengband/hengband.git] / src / floor / wild.c
1 /*!
2  * @file wild.c
3  * @brief 荒野マップの生成とルール管理 / Wilderness generation
4  * @date 2014/02/13
5  * @author
6  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke\n
7  * This software may be copied and distributed for educational, research, and\n
8  * not for profit purposes provided that this copyright and statement are\n
9  * included in all such copies.\n
10  * 2013 Deskull rearranged comment for Doxygen.
11  */
12
13 #include "floor/wild.h"
14 #include "dungeon/dungeon-file.h"
15 #include "dungeon/dungeon.h"
16 #include "dungeon/quest.h"
17 #include "floor/floor-town.h"
18 #include "grid/feature.h"
19 #include "grid/grid.h"
20 #include "info-reader/parse-error-types.h"
21 #include "io/files-util.h"
22 #include "io/tokenizer.h"
23 #include "main/init.h"
24 #include "monster/monster-status.h"
25 #include "monster/monster.h"
26 #include "player/player-effects.h"
27 #include "player/player-status.h"
28 #include "realm/realm-names-table.h"
29 #include "spell-realm/spells-hex.h"
30 #include "system/system-variables.h"
31 #include "util/util.h"
32 #include "view/display-main-window.h"
33 #include "world/world.h"
34
35 #define MAX_FEAT_IN_TERRAIN 18
36
37  /*
38   * Wilderness
39   */
40 wilderness_type **wilderness;
41
42 bool generate_encounter;
43
44 /*!
45  * @brief 地形生成確率を決める要素100の配列を確率テーブルから作成する
46  * @param feat_type 非一様確率を再現するための要素数100の配列
47  * @param prob 元の確率テーブル
48  * @return なし
49  */
50 static void set_floor_and_wall_aux(s16b feat_type[100], feat_prob prob[DUNGEON_FEAT_PROB_NUM])
51 {
52         int lim[DUNGEON_FEAT_PROB_NUM], cur = 0, i;
53
54         lim[0] = prob[0].percent;
55         for (i = 1; i < DUNGEON_FEAT_PROB_NUM; i++) lim[i] = lim[i - 1] + prob[i].percent;
56         if (lim[DUNGEON_FEAT_PROB_NUM - 1] < 100) lim[DUNGEON_FEAT_PROB_NUM - 1] = 100;
57
58         for (i = 0; i < 100; i++)
59         {
60                 while (i == lim[cur]) cur++;
61                 feat_type[i] = prob[cur].feat;
62         }
63 }
64
65
66 /*!
67  * @brief ダンジョンの地形を指定確率に応じて各マスへランダムに敷き詰める
68  * / Fill the arrays of floors and walls in the good proportions
69  * @param type ダンジョンID
70  * @return なし
71  */
72 void set_floor_and_wall(DUNGEON_IDX type)
73 {
74         DUNGEON_IDX cur_type = 255;
75         dungeon_type *d_ptr;
76
77         /* Already filled */
78         if (cur_type == type) return;
79
80         cur_type = type;
81         d_ptr = &d_info[type];
82
83         set_floor_and_wall_aux(feat_ground_type, d_ptr->floor);
84         set_floor_and_wall_aux(feat_wall_type, d_ptr->fill);
85
86         feat_wall_outer = d_ptr->outer_wall;
87         feat_wall_inner = d_ptr->inner_wall;
88         feat_wall_solid = d_ptr->outer_wall;
89 }
90
91
92 /*!
93  * @brief プラズマフラクタル的地形生成の再帰中間処理
94  * / Helper for plasma generation.
95  * @param x1 左上端の深み
96  * @param x2 右上端の深み
97  * @param x3 左下端の深み
98  * @param x4 右下端の深み
99  * @param xmid 中央座標X
100  * @param ymid 中央座標Y
101  * @param rough ランダム幅
102  * @param depth_max 深みの最大値
103  * @return なし
104  */
105 static void perturb_point_mid(floor_type *floor_ptr, FEAT_IDX x1, FEAT_IDX x2, FEAT_IDX x3, FEAT_IDX x4, POSITION xmid, POSITION ymid, FEAT_IDX rough, FEAT_IDX depth_max)
106 {
107         /*
108          * Average the four corners & perturb it a bit.
109          * tmp is a random int +/- rough
110          */
111         FEAT_IDX tmp2 = rough*2 + 1;
112         FEAT_IDX tmp = randint1(tmp2) - (rough + 1);
113
114         FEAT_IDX avg = ((x1 + x2 + x3 + x4) / 4) + tmp;
115
116         /* Division always rounds down, so we round up again */
117         if (((x1 + x2 + x3 + x4) % 4) > 1)
118                 avg++;
119
120         /* Normalize */
121         if (avg < 0) avg = 0;
122         if (avg > depth_max) avg = depth_max;
123
124         /* Set the new value. */
125         floor_ptr->grid_array[ymid][xmid].feat = (FEAT_IDX)avg;
126 }
127
128
129 /*!
130  * @brief プラズマフラクタル的地形生成の再帰末端処理
131  * / Helper for plasma generation.
132  * @param x1 中間末端部1の重み
133  * @param x2 中間末端部2の重み
134  * @param x3 中間末端部3の重み
135  * @param xmid 最終末端部座標X
136  * @param ymid 最終末端部座標Y
137  * @param rough ランダム幅
138  * @param depth_max 深みの最大値
139  * @return なし
140  */
141 static void perturb_point_end(floor_type *floor_ptr, FEAT_IDX x1, FEAT_IDX x2, FEAT_IDX x3, POSITION xmid, POSITION ymid, FEAT_IDX rough, FEAT_IDX depth_max)
142 {
143         /*
144          * Average the three corners & perturb it a bit.
145          * tmp is a random int +/- rough
146          */
147         FEAT_IDX tmp2 = rough * 2 + 1;
148         FEAT_IDX tmp = randint0(tmp2) - rough;
149
150         FEAT_IDX avg = ((x1 + x2 + x3) / 3) + tmp;
151
152         /* Division always rounds down, so we round up again */
153         if ((x1 + x2 + x3) % 3) avg++;
154
155         /* Normalize */
156         if (avg < 0) avg = 0;
157         if (avg > depth_max) avg = depth_max;
158
159         /* Set the new value. */
160         floor_ptr->grid_array[ymid][xmid].feat = (FEAT_IDX)avg;
161 }
162
163
164 /*!
165  * @brief プラズマフラクタル的地形生成の開始処理
166  * / Helper for plasma generation.
167  * @param x1 処理範囲の左上X座標
168  * @param y1 処理範囲の左上Y座標
169  * @param x2 処理範囲の右下X座標
170  * @param y2 処理範囲の右下Y座標
171  * @param depth_max 深みの最大値
172  * @param rough ランダム幅
173  * @return なし
174  * @details
175  * <pre>
176  * A generic function to generate the plasma fractal.
177  * Note that it uses ``cave_feat'' as temporary storage.
178  * The values in ``cave_feat'' after this function
179  * are NOT actual features; They are raw heights which
180  * need to be converted to features.
181  * </pre>
182  */
183 static void plasma_recursive(floor_type *floor_ptr, POSITION x1, POSITION y1, POSITION x2, POSITION y2, FEAT_IDX depth_max, FEAT_IDX rough)
184 {
185         /* Find middle */
186         POSITION xmid = (x2 - x1) / 2 + x1;
187         POSITION ymid = (y2 - y1) / 2 + y1;
188
189         /* Are we done? */
190         if (x1 + 1 == x2) return;
191
192         perturb_point_mid(floor_ptr, floor_ptr->grid_array[y1][x1].feat, floor_ptr->grid_array[y2][x1].feat, floor_ptr->grid_array[y1][x2].feat,
193                 floor_ptr->grid_array[y2][x2].feat, xmid, ymid, rough, depth_max);
194
195         perturb_point_end(floor_ptr, floor_ptr->grid_array[y1][x1].feat, floor_ptr->grid_array[y1][x2].feat, floor_ptr->grid_array[ymid][xmid].feat,
196                 xmid, y1, rough, depth_max);
197
198         perturb_point_end(floor_ptr, floor_ptr->grid_array[y1][x2].feat, floor_ptr->grid_array[y2][x2].feat, floor_ptr->grid_array[ymid][xmid].feat,
199                 x2, ymid, rough, depth_max);
200
201         perturb_point_end(floor_ptr, floor_ptr->grid_array[y2][x2].feat, floor_ptr->grid_array[y2][x1].feat, floor_ptr->grid_array[ymid][xmid].feat,
202                 xmid, y2, rough, depth_max);
203
204         perturb_point_end(floor_ptr, floor_ptr->grid_array[y2][x1].feat, floor_ptr->grid_array[y1][x1].feat, floor_ptr->grid_array[ymid][xmid].feat,
205                 x1, ymid, rough, depth_max);
206
207
208         /* Recurse the four quadrants */
209         plasma_recursive(floor_ptr, x1, y1, xmid, ymid, depth_max, rough);
210         plasma_recursive(floor_ptr, xmid, y1, x2, ymid, depth_max, rough);
211         plasma_recursive(floor_ptr, x1, ymid, xmid, y2, depth_max, rough);
212         plasma_recursive(floor_ptr, xmid, ymid, x2, y2, depth_max, rough);
213 }
214
215
216 /*
217  * The default table in terrain level generation.
218  */
219 static s16b terrain_table[MAX_WILDERNESS][MAX_FEAT_IN_TERRAIN];
220
221 /*!
222  * @brief 荒野フロア生成のサブルーチン
223  * @param terrain 荒野地形ID
224  * @param seed 乱数の固定シード
225  * @param border 未使用
226  * @param corner 広域マップの角部分としての生成ならばTRUE
227  * @return なし
228  */
229 static void generate_wilderness_area(floor_type *floor_ptr, int terrain, u32b seed, bool corner)
230 {
231         /* The outer wall is easy */
232         if (terrain == TERRAIN_EDGE)
233         {
234                 /* Create level background */
235                 for (POSITION y1 = 0; y1 < MAX_HGT; y1++)
236                 {
237                         for (POSITION x1 = 0; x1 < MAX_WID; x1++)
238                         {
239                                 floor_ptr->grid_array[y1][x1].feat = feat_permanent;
240                         }
241                 }
242
243                 return;
244         }
245
246         /* Hack -- Backup the RNG state */
247         u32b state_backup[4];
248         Rand_state_backup(state_backup);
249
250         /* Hack -- Induce consistant flavors */
251         Rand_state_set(seed);
252
253         int table_size = sizeof(terrain_table[0]) / sizeof(s16b);
254         if (!corner)
255         {
256                 /* Create level background */
257                 for (POSITION y1 = 0; y1 < MAX_HGT; y1++)
258                 {
259                         for (POSITION x1 = 0; x1 < MAX_WID; x1++)
260                         {
261                                 floor_ptr->grid_array[y1][x1].feat = table_size / 2;
262                         }
263                 }
264         }
265
266         /*
267          * Initialize the four corners
268          * ToDo: calculate the medium height of the adjacent
269          * terrains for every corner.
270          */
271         floor_ptr->grid_array[1][1].feat = (s16b)randint0(table_size);
272         floor_ptr->grid_array[MAX_HGT-2][1].feat = (s16b)randint0(table_size);
273         floor_ptr->grid_array[1][MAX_WID-2].feat = (s16b)randint0(table_size);
274         floor_ptr->grid_array[MAX_HGT-2][MAX_WID-2].feat = (s16b)randint0(table_size);
275
276         /* Hack -- only four corners */
277         if (corner)
278         {
279                 floor_ptr->grid_array[1][1].feat = terrain_table[terrain][floor_ptr->grid_array[1][1].feat];
280                 floor_ptr->grid_array[MAX_HGT - 2][1].feat = terrain_table[terrain][floor_ptr->grid_array[MAX_HGT - 2][1].feat];
281                 floor_ptr->grid_array[1][MAX_WID - 2].feat = terrain_table[terrain][floor_ptr->grid_array[1][MAX_WID - 2].feat];
282                 floor_ptr->grid_array[MAX_HGT - 2][MAX_WID - 2].feat = terrain_table[terrain][floor_ptr->grid_array[MAX_HGT - 2][MAX_WID - 2].feat];
283                 Rand_state_restore(state_backup);
284                 return;
285         }
286
287         /* Hack -- preserve four corners */
288         s16b north_west = floor_ptr->grid_array[1][1].feat;
289         s16b south_west = floor_ptr->grid_array[MAX_HGT - 2][1].feat;
290         s16b north_east = floor_ptr->grid_array[1][MAX_WID - 2].feat;
291         s16b south_east = floor_ptr->grid_array[MAX_HGT - 2][MAX_WID - 2].feat;
292
293         /* x1, y1, x2, y2, num_depths, roughness */
294         FEAT_IDX roughness = 1; /* The roughness of the level. */
295         plasma_recursive(floor_ptr, 1, 1, MAX_WID - 2, MAX_HGT - 2, table_size - 1, roughness);
296
297         /* Hack -- copyback four corners */
298         floor_ptr->grid_array[1][1].feat = north_west;
299         floor_ptr->grid_array[MAX_HGT - 2][1].feat = south_west;
300         floor_ptr->grid_array[1][MAX_WID - 2].feat = north_east;
301         floor_ptr->grid_array[MAX_HGT - 2][MAX_WID - 2].feat = south_east;
302
303         for (POSITION y1 = 1; y1 < MAX_HGT - 1; y1++)
304         {
305                 for (POSITION x1 = 1; x1 < MAX_WID - 1; x1++)
306                 {
307                         floor_ptr->grid_array[y1][x1].feat = terrain_table[terrain][floor_ptr->grid_array[y1][x1].feat];
308                 }
309         }
310
311         Rand_state_restore(state_backup);
312 }
313
314
315 /*!
316  * @brief 荒野フロア生成のメインルーチン /
317  * Load a town or generate a terrain level using "plasma" fractals.
318  * @param player_ptr プレーヤーへの参照ポインタ
319  * @param y 広域Y座標
320  * @param x 広域X座標
321  * @param border 広域マップの辺部分としての生成ならばTRUE
322  * @param corner 広域マップの角部分としての生成ならばTRUE
323  * @return なし
324  * @details
325  * <pre>
326  * x and y are the coordinates of the area in the wilderness.
327  * Border and corner are optimization flags to speed up the
328  * generation of the fractal terrain.
329  * If border is set then only the border of the terrain should
330  * be generated (for initializing the border structure).
331  * If corner is set then only the corners of the area are needed.
332  * </pre>
333  */
334 static void generate_area(player_type *player_ptr, POSITION y, POSITION x, bool border, bool corner)
335 {
336         /* Number of the town (if any) */
337         player_ptr->town_num = wilderness[y][x].town;
338
339         /* Set the base level */
340         floor_type *floor_ptr = player_ptr->current_floor_ptr;
341         floor_ptr->base_level = wilderness[y][x].level;
342
343         /* Set the dungeon level */
344         floor_ptr->dun_level = 0;
345
346         /* Set the monster generation level */
347         floor_ptr->monster_level = floor_ptr->base_level;
348
349         /* Set the object generation level */
350         floor_ptr->object_level = floor_ptr->base_level;
351
352
353         /* Create the town */
354         if (player_ptr->town_num)
355         {
356                 /* Reset the buildings */
357                 init_buildings();
358
359                 /* Initialize the town */
360                 if (border | corner)
361                         init_flags = INIT_CREATE_DUNGEON | INIT_ONLY_FEATURES;
362                 else
363                         init_flags = INIT_CREATE_DUNGEON;
364
365                 parse_fixed_map(player_ptr, "t_info.txt", 0, 0, MAX_HGT, MAX_WID);
366
367                 if (!corner && !border) player_ptr->visit |= (1L << (player_ptr->town_num - 1));
368         }
369         else
370         {
371                 int terrain = wilderness[y][x].terrain;
372                 u32b seed = wilderness[y][x].seed;
373
374                 generate_wilderness_area(floor_ptr, terrain, seed, corner);
375         }
376
377         if (!corner && !wilderness[y][x].town)
378         {
379                 /*
380                  * Place roads in the wilderness
381                  * ToDo: make the road a bit more interresting
382                  */
383                 if (wilderness[y][x].road)
384                 {
385                         floor_ptr->grid_array[MAX_HGT/2][MAX_WID/2].feat = feat_floor;
386
387                         POSITION x1, y1;
388                         if (wilderness[y-1][x].road)
389                         {
390                                 /* North road */
391                                 for (y1 = 1; y1 < MAX_HGT/2; y1++)
392                                 {
393                                         x1 = MAX_WID/2;
394                                         floor_ptr->grid_array[y1][x1].feat = feat_floor;
395                                 }
396                         }
397
398                         if (wilderness[y+1][x].road)
399                         {
400                                 /* North road */
401                                 for (y1 = MAX_HGT/2; y1 < MAX_HGT - 1; y1++)
402                                 {
403                                         x1 = MAX_WID/2;
404                                         floor_ptr->grid_array[y1][x1].feat = feat_floor;
405                                 }
406                         }
407
408                         if (wilderness[y][x+1].road)
409                         {
410                                 /* East road */
411                                 for (x1 = MAX_WID/2; x1 < MAX_WID - 1; x1++)
412                                 {
413                                         y1 = MAX_HGT/2;
414                                         floor_ptr->grid_array[y1][x1].feat = feat_floor;
415                                 }
416                         }
417
418                         if (wilderness[y][x-1].road)
419                         {
420                                 /* West road */
421                                 for (x1 = 1; x1 < MAX_WID/2; x1++)
422                                 {
423                                         y1 = MAX_HGT/2;
424                                         floor_ptr->grid_array[y1][x1].feat = feat_floor;
425                                 }
426                         }
427                 }
428         }
429
430         /*
431          * 本来は '> 0'で良いと思われるがエンバグするのも怖いので'!= 0'と記載する
432          * 問題なければ'> 0'へ置き換えること
433          */
434         bool is_winner = wilderness[y][x].entrance != 0;
435         is_winner &= !wilderness[y][x].town != 0;
436         bool is_wild_winner = (d_info[wilderness[y][x].entrance].flags1 & DF1_WINNER) == 0;
437         is_winner &= ((current_world_ptr->total_winner != 0) || is_wild_winner);
438         if (!is_winner) return;
439
440         /* Hack -- Backup the RNG state */
441         u32b state_backup[4];
442         Rand_state_backup(state_backup);
443
444         /* Hack -- Induce consistant flavors */
445         Rand_state_set(wilderness[y][x].seed);
446
447         int dy = rand_range(6, floor_ptr->height - 6);
448         int dx = rand_range(6, floor_ptr->width - 6);
449
450         floor_ptr->grid_array[dy][dx].feat = feat_entrance;
451         floor_ptr->grid_array[dy][dx].special = wilderness[y][x].entrance;
452
453         /* Hack -- Restore the RNG state */
454         Rand_state_restore(state_backup);
455 }
456
457
458 /*
459  * Border of the wilderness area
460  */
461 static border_type border;
462
463 /*!
464  * @brief 広域マップの生成 /
465  * Build the wilderness area outside of the town.
466  * @todo 広域マップは恒常生成にする予定、player_typeによる処理分岐は最終的に排除する。
467  * @param creature_ptr プレーヤーへの参照ポインタ
468  * @return なし
469  */
470 void wilderness_gen(player_type *creature_ptr)
471 {
472         /* Big town */
473         floor_type *floor_ptr = creature_ptr->current_floor_ptr;
474         floor_ptr->height = MAX_HGT;
475         floor_ptr->width = MAX_WID;
476
477         /* Assume illegal panel */
478         panel_row_min = floor_ptr->height;
479         panel_col_min = floor_ptr->width;
480
481         parse_fixed_map(creature_ptr, "w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
482         POSITION x = creature_ptr->wilderness_x;
483         POSITION y = creature_ptr->wilderness_y;
484         get_mon_num_prep(creature_ptr, get_monster_hook(creature_ptr), NULL);
485
486         /* North border */
487         generate_area(creature_ptr, y - 1, x, TRUE, FALSE);
488
489         for (int i = 1; i < MAX_WID - 1; i++)
490         {
491                 border.north[i] = floor_ptr->grid_array[MAX_HGT - 2][i].feat;
492         }
493
494         /* South border */
495         generate_area(creature_ptr, y + 1, x, TRUE, FALSE);
496
497         for (int i = 1; i < MAX_WID - 1; i++)
498         {
499                 border.south[i] = floor_ptr->grid_array[1][i].feat;
500         }
501
502         /* West border */
503         generate_area(creature_ptr, y, x - 1, TRUE, FALSE);
504
505         for (int i = 1; i < MAX_HGT - 1; i++)
506         {
507                 border.west[i] = floor_ptr->grid_array[i][MAX_WID - 2].feat;
508         }
509
510         /* East border */
511         generate_area(creature_ptr, y, x + 1, TRUE, FALSE);
512
513         for (int i = 1; i < MAX_HGT - 1; i++)
514         {
515                 border.east[i] = floor_ptr->grid_array[i][1].feat;
516         }
517
518         /* North west corner */
519         generate_area(creature_ptr, y - 1, x - 1, FALSE, TRUE);
520         border.north_west = floor_ptr->grid_array[MAX_HGT - 2][MAX_WID - 2].feat;
521
522         /* North east corner */
523         generate_area(creature_ptr, y - 1, x + 1, FALSE, TRUE);
524         border.north_east = floor_ptr->grid_array[MAX_HGT - 2][1].feat;
525
526         /* South west corner */
527         generate_area(creature_ptr, y + 1, x - 1, FALSE, TRUE);
528         border.south_west = floor_ptr->grid_array[1][MAX_WID - 2].feat;
529
530         /* South east corner */
531         generate_area(creature_ptr, y + 1, x + 1, FALSE, TRUE);
532         border.south_east = floor_ptr->grid_array[1][1].feat;
533
534         /* Create terrain of the current area */
535         generate_area(creature_ptr, y, x, FALSE, FALSE);
536
537         /* Special boundary walls -- North */
538         for (int i = 0; i < MAX_WID; i++)
539         {
540                 floor_ptr->grid_array[0][i].feat = feat_permanent;
541                 floor_ptr->grid_array[0][i].mimic = border.north[i];
542         }
543
544         /* Special boundary walls -- South */
545         for (int i = 0; i < MAX_WID; i++)
546         {
547                 floor_ptr->grid_array[MAX_HGT - 1][i].feat = feat_permanent;
548                 floor_ptr->grid_array[MAX_HGT - 1][i].mimic = border.south[i];
549         }
550
551         /* Special boundary walls -- West */
552         for (int i = 0; i < MAX_HGT; i++)
553         {
554                 floor_ptr->grid_array[i][0].feat = feat_permanent;
555                 floor_ptr->grid_array[i][0].mimic = border.west[i];
556         }
557
558         /* Special boundary walls -- East */
559         for (int i = 0; i < MAX_HGT; i++)
560         {
561                 floor_ptr->grid_array[i][MAX_WID - 1].feat = feat_permanent;
562                 floor_ptr->grid_array[i][MAX_WID - 1].mimic = border.east[i];
563         }
564
565         floor_ptr->grid_array[0][0].mimic = border.north_west;
566         floor_ptr->grid_array[0][MAX_WID - 1].mimic = border.north_east;
567         floor_ptr->grid_array[MAX_HGT - 1][0].mimic = border.south_west;
568         floor_ptr->grid_array[MAX_HGT - 1][MAX_WID - 1].mimic = border.south_east;
569
570         /* Light up or darken the area */
571         for (y = 0; y < floor_ptr->height; y++)
572         {
573                 for (x = 0; x < floor_ptr->width; x++)
574                 {
575                         grid_type *g_ptr;
576                         g_ptr = &floor_ptr->grid_array[y][x];
577
578                         if (is_daytime())
579                         {
580                                 /* Assume lit */
581                                 g_ptr->info |= CAVE_GLOW;
582
583                                 /* Hack -- Memorize lit grids if allowed */
584                                 if (view_perma_grids) g_ptr->info |= CAVE_MARK;
585                                 continue;
586                         }
587
588                         /* Feature code (applying "mimic" field) */
589                         feature_type *f_ptr;
590                         f_ptr = &f_info[get_feat_mimic(g_ptr)];
591
592                         if (!is_mirror_grid(g_ptr) && !have_flag(f_ptr->flags, FF_QUEST_ENTER) &&
593                                 !have_flag(f_ptr->flags, FF_ENTRANCE))
594                         {
595                                 /* Assume dark */
596                                 g_ptr->info &= ~(CAVE_GLOW);
597
598                                 /* Darken "boring" features */
599                                 if (!have_flag(f_ptr->flags, FF_REMEMBER))
600                                 {
601                                         /* Forget the grid */
602                                         g_ptr->info &= ~(CAVE_MARK);
603                                 }
604
605                                 continue;
606                         }
607                         
608                         if (!have_flag(f_ptr->flags, FF_ENTRANCE)) continue;
609
610                         g_ptr->info |= CAVE_GLOW;
611
612                         /* Hack -- Memorize lit grids if allowed */
613                         if (view_perma_grids) g_ptr->info |= CAVE_MARK;
614                 }
615         }
616
617         if (creature_ptr->teleport_town)
618         {
619                 for (y = 0; y < floor_ptr->height; y++)
620                 {
621                         for (x = 0; x < floor_ptr->width; x++)
622                         {
623                                 grid_type *g_ptr;
624                                 g_ptr = &floor_ptr->grid_array[y][x];
625
626                                 /* Seeing true feature code (ignore mimic) */
627                                 feature_type *f_ptr;
628                                 f_ptr = &f_info[g_ptr->feat];
629
630                                 if (!have_flag(f_ptr->flags, FF_BLDG)) continue;
631
632                                 if ((f_ptr->subtype != 4) && !((creature_ptr->town_num == 1) && (f_ptr->subtype == 0)))
633                                         continue;
634
635                                 if (g_ptr->m_idx)
636                                 {
637                                         delete_monster_idx(creature_ptr, g_ptr->m_idx);
638                                 }
639
640                                 creature_ptr->oldpy = y;
641                                 creature_ptr->oldpx = x;
642                         }
643                 }
644
645                 creature_ptr->teleport_town = FALSE;
646         }
647         else if (creature_ptr->leaving_dungeon)
648         {
649                 for (y = 0; y < floor_ptr->height; y++)
650                 {
651                         for (x = 0; x < floor_ptr->width; x++)
652                         {
653                                 grid_type *g_ptr;
654                                 g_ptr = &floor_ptr->grid_array[y][x];
655
656                                 if (!cave_have_flag_grid(g_ptr, FF_ENTRANCE)) continue;
657
658                                 if (g_ptr->m_idx)
659                                 {
660                                         delete_monster_idx(creature_ptr, g_ptr->m_idx);
661                                 }
662
663                                 creature_ptr->oldpy = y;
664                                 creature_ptr->oldpx = x;
665                         }
666                 }
667
668                 creature_ptr->teleport_town = FALSE;
669         }
670
671         player_place(creature_ptr, creature_ptr->oldpy, creature_ptr->oldpx);
672         int lim = (generate_encounter == TRUE) ? 40 : MIN_M_ALLOC_TN;
673
674         /* Make some residents */
675         for (int i = 0; i < lim; i++)
676         {
677                 BIT_FLAGS mode = 0;
678
679                 if (!(generate_encounter || (one_in_(2) && (!creature_ptr->town_num))))
680                         mode |= PM_ALLOW_SLEEP;
681
682                 /* Make a resident */
683                 (void)alloc_monster(creature_ptr, generate_encounter ? 0 : 3, mode);
684         }
685
686         if(generate_encounter) creature_ptr->ambush_flag = TRUE;
687         generate_encounter = FALSE;
688
689         /* Fill the arrays of floors and walls in the good proportions */
690         set_floor_and_wall(0);
691
692         /* Set rewarded quests to finished */
693         for (int i = 0; i < max_q_idx; i++)
694         {
695                 if (quest[i].status == QUEST_STATUS_REWARDED)
696                         quest[i].status = QUEST_STATUS_FINISHED;
697         }
698 }
699
700 static s16b conv_terrain2feat[MAX_WILDERNESS];
701
702 /*!
703  * @brief 広域マップの生成(簡易処理版) /
704  * Build the wilderness area. -DG-
705  * @return なし
706  */
707 void wilderness_gen_small(player_type *creature_ptr)
708 {
709         /* To prevent stupid things */
710         floor_type *floor_ptr = creature_ptr->current_floor_ptr;
711         for (int i = 0; i < MAX_WID; i++)
712         {
713                 for (int j = 0; j < MAX_HGT; j++)
714                 {
715                         floor_ptr->grid_array[j][i].feat = feat_permanent;
716                 }
717         }
718
719         parse_fixed_map(creature_ptr, "w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
720
721         /* Fill the map */
722         for (int i = 0; i < current_world_ptr->max_wild_x; i++)
723         {
724                 for (int j = 0; j < current_world_ptr->max_wild_y; j++)
725                 {
726                         if (wilderness[j][i].town && (wilderness[j][i].town != NO_TOWN))
727                         {
728                                 floor_ptr->grid_array[j][i].feat = (s16b)feat_town;
729                                 floor_ptr->grid_array[j][i].special = (s16b)wilderness[j][i].town;
730                                 floor_ptr->grid_array[j][i].info |= (CAVE_GLOW | CAVE_MARK);
731                                 continue;
732                         }
733                         
734                         if (wilderness[j][i].road)
735                         {
736                                 floor_ptr->grid_array[j][i].feat = feat_floor;
737                                 floor_ptr->grid_array[j][i].info |= (CAVE_GLOW | CAVE_MARK);
738                                 continue;
739                         }
740                         
741                         if (wilderness[j][i].entrance && (current_world_ptr->total_winner || !(d_info[wilderness[j][i].entrance].flags1 & DF1_WINNER)))
742                         {
743                                 floor_ptr->grid_array[j][i].feat = feat_entrance;
744                                 floor_ptr->grid_array[j][i].special = (byte)wilderness[j][i].entrance;
745                                 floor_ptr->grid_array[j][i].info |= (CAVE_GLOW | CAVE_MARK);
746                                 continue;
747                         }
748
749                         floor_ptr->grid_array[j][i].feat = conv_terrain2feat[wilderness[j][i].terrain];
750                         floor_ptr->grid_array[j][i].info |= (CAVE_GLOW | CAVE_MARK);
751                 }
752         }
753
754         floor_ptr->height = (s16b) current_world_ptr->max_wild_y;
755         floor_ptr->width = (s16b) current_world_ptr->max_wild_x;
756
757         if (floor_ptr->height > MAX_HGT) floor_ptr->height = MAX_HGT;
758         if (floor_ptr->width > MAX_WID) floor_ptr->width = MAX_WID;
759
760         /* Assume illegal panel */
761         panel_row_min = floor_ptr->height;
762         panel_col_min = floor_ptr->width;
763
764         creature_ptr->x = creature_ptr->wilderness_x;
765         creature_ptr->y = creature_ptr->wilderness_y;
766         creature_ptr->town_num = 0;
767 }
768
769
770 typedef struct wilderness_grid wilderness_grid;
771
772 struct wilderness_grid
773 {
774         int             terrain;    /* Terrain type */
775         TOWN_IDX town;   /* Town number */
776         DEPTH level;     /* Level of the wilderness */
777         byte    road;       /* Road */
778         char    name[32];       /* Name of the town/wilderness */
779 };
780
781
782 static wilderness_grid w_letter[255];
783
784 /*!
785  * @brief w_info.txtのデータ解析 /
786  * Parse a sub-file of the "extra info"
787  * @param buf 読み取ったデータ行のバッファ
788  * @param ymin 未使用
789  * @param xmin 広域地形マップを読み込みたいx座標の開始位置
790  * @param ymax 未使用
791  * @param xmax 広域地形マップを読み込みたいx座標の終了位置
792  * @param y 広域マップの高さを返す参照ポインタ
793  * @param x 広域マップの幅を返す参照ポインタ
794  * @return なし
795  */
796 errr parse_line_wilderness(player_type *creature_ptr, char *buf, int xmin, int xmax, int *y, int *x)
797 {
798         if (!(buf[0] == 'W')) return (PARSE_ERROR_GENERIC);
799
800         int num;
801         char *zz[33];
802         switch (buf[2])
803         {
804                 /* Process "W:F:<letter>:<terrain>:<town>:<road>:<name> */
805 #ifdef JP
806         case 'E':
807                 return 0;
808         case 'F':
809         case 'J':
810 #else
811         case 'J':
812                 return 0;
813         case 'F':
814         case 'E':
815 #endif
816         {
817                 if ((num = tokenize(buf+4, 6, zz, 0)) > 1)
818                 {
819                         int index = zz[0][0];
820                         
821                         if (num > 1)
822                                 w_letter[index].terrain = atoi(zz[1]);
823                         else
824                                 w_letter[index].terrain = 0;
825                         
826                         if (num > 2)
827                                 w_letter[index].level = (s16b)atoi(zz[2]);
828                         else
829                                 w_letter[index].level = 0;
830                         
831                         if (num > 3)
832                                 w_letter[index].town = (TOWN_IDX)atoi(zz[3]);
833                         else
834                                 w_letter[index].town = 0;
835                         
836                         if (num > 4)
837                                 w_letter[index].road = (byte)atoi(zz[4]);
838                         else
839                                 w_letter[index].road = 0;
840                         
841                         if (num > 5)
842                                 strcpy(w_letter[index].name, zz[5]);
843                         else
844                                 w_letter[index].name[0] = 0;
845                 }
846                 else
847                 {
848                                 /* Failure */
849                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
850                 }
851                 
852                 break;
853         }
854         
855         /* Process "W:D:<layout> */
856         /* Layout of the wilderness */
857         case 'D':
858         {
859                 char *s = buf+4;
860                 int len = strlen(s);
861                 int i;
862                 for (*x = xmin, i = 0; ((*x < xmax) && (i < len)); (*x)++, s++, i++)
863                 {
864                         int id = s[0];
865                         wilderness[*y][*x].terrain = w_letter[id].terrain;
866                         wilderness[*y][*x].level = w_letter[id].level;
867                         wilderness[*y][*x].town = w_letter[id].town;
868                         wilderness[*y][*x].road = w_letter[id].road;
869                         strcpy(town_info[w_letter[id].town].name, w_letter[id].name);
870                 }
871                 
872                 (*y)++;
873                 break;
874         }
875         
876         /* Process "W:P:<x>:<y> - starting position in the wilderness */
877         case 'P':
878         {
879                 bool is_corner = creature_ptr->wilderness_x == 0;
880                 is_corner = creature_ptr->wilderness_y == 0;
881                 if (!is_corner) break;
882
883                 if (tokenize(buf + 4, 2, zz, 0) != 2)
884                 {
885                         return PARSE_ERROR_TOO_FEW_ARGUMENTS;
886                 }
887
888                 creature_ptr->wilderness_y = atoi(zz[0]);
889                 creature_ptr->wilderness_x = atoi(zz[1]);
890
891                 if ((creature_ptr->wilderness_x < 1) ||
892                         (creature_ptr->wilderness_x > current_world_ptr->max_wild_x) ||
893                         (creature_ptr->wilderness_y < 1) ||
894                         (creature_ptr->wilderness_y > current_world_ptr->max_wild_y))
895                 {
896                         return PARSE_ERROR_OUT_OF_BOUNDS;
897                 }
898
899                 break;
900         }
901         
902         default:
903                 return PARSE_ERROR_UNDEFINED_DIRECTIVE;
904         }
905         
906         for (int i = 1; i < current_world_ptr->max_d_idx; i++)
907         {
908                 if (!d_info[i].maxdepth) continue;
909                 wilderness[d_info[i].dy][d_info[i].dx].entrance = (byte)i;
910                 if (!wilderness[d_info[i].dy][d_info[i].dx].town)
911                 {
912                         wilderness[d_info[i].dy][d_info[i].dx].level = d_info[i].mindepth;
913                 }
914         }
915
916         return 0;
917 }
918
919
920 /*!
921  * @brief ゲーム開始時に各荒野フロアの乱数シードを指定する /
922  * Generate the random seeds for the wilderness
923  * @return なし
924  */
925 void seed_wilderness(void)
926 {
927         for (POSITION x = 0; x < current_world_ptr->max_wild_x; x++)
928         {
929                 for (POSITION y = 0; y < current_world_ptr->max_wild_y; y++)
930                 {
931                         wilderness[y][x].seed = randint0(0x10000000);
932                         wilderness[y][x].entrance = 0;
933                 }
934         }
935 }
936
937
938 /*
939  * Pointer to wilderness_type
940  */
941 typedef wilderness_type *wilderness_type_ptr;
942
943 /*!
944  * @brief ゲーム開始時の荒野初期化メインルーチン /
945  * Initialize wilderness array
946  * @return エラーコード
947  */
948 errr init_wilderness(void)
949 {
950         /* Allocate the wilderness (two-dimension array) */
951         C_MAKE(wilderness, current_world_ptr->max_wild_y, wilderness_type_ptr);
952         C_MAKE(wilderness[0], current_world_ptr->max_wild_x * current_world_ptr->max_wild_y, wilderness_type);
953
954         /* Init the other pointers */
955         for (int i = 1; i < current_world_ptr->max_wild_y; i++)
956         {
957                 wilderness[i] = wilderness[0] + i * current_world_ptr->max_wild_x;
958         }
959
960         generate_encounter = FALSE;
961         return 0;
962 }
963
964
965 /*!
966  * @brief 荒野の地勢設定を初期化する /
967  * Initialize wilderness array
968  * @param terrain 初期化したい地勢ID
969  * @param feat_global 基本的な地形ID
970  * @param fmt 地勢内の地形数を参照するための独自フォーマット
971  * @return なし
972  */
973 static void init_terrain_table(int terrain, s16b feat_global, concptr fmt, ...)
974 {
975         /* Begin the varargs stuff */
976         va_list vp;
977         va_start(vp, fmt);
978
979         /* Wilderness terrains on global map */
980         conv_terrain2feat[terrain] = feat_global;
981
982         /* Wilderness terrains on local map */
983         int cur = 0;
984         char check = 'a';
985         for (concptr p = fmt; *p; p++)
986         {
987                 if (*p != check)
988                 {
989                         plog_fmt("Format error");
990                         continue;
991                 }
992
993                 FEAT_IDX feat = (s16b)va_arg(vp, int);
994                 int num = va_arg(vp, int);
995                 int lim = cur + num;
996
997                 for (; (cur < lim) && (cur < MAX_FEAT_IN_TERRAIN); cur++)
998                 {
999                         terrain_table[terrain][cur] = feat;
1000                 }
1001
1002                 if (cur >= MAX_FEAT_IN_TERRAIN) break;
1003
1004                 check++;
1005         }
1006
1007         if (cur < MAX_FEAT_IN_TERRAIN)
1008         {
1009                 plog_fmt("Too few parameters");
1010         }
1011
1012         va_end(vp);
1013 }
1014
1015
1016 /*!
1017  * @brief 荒野の地勢設定全体を初期化するメインルーチン /
1018  * Initialize arrays for wilderness terrains
1019  * @return なし
1020  */
1021 void init_wilderness_terrains(void)
1022 {
1023         init_terrain_table(TERRAIN_EDGE, feat_permanent, "a",
1024                 feat_permanent, MAX_FEAT_IN_TERRAIN);
1025
1026         init_terrain_table(TERRAIN_TOWN, feat_town, "a",
1027                 feat_floor, MAX_FEAT_IN_TERRAIN);
1028
1029         init_terrain_table(TERRAIN_DEEP_WATER, feat_deep_water, "ab",
1030                 feat_deep_water, 12,
1031                 feat_shallow_water, MAX_FEAT_IN_TERRAIN - 12);
1032
1033         init_terrain_table(TERRAIN_SHALLOW_WATER, feat_shallow_water, "abcde",
1034                 feat_deep_water, 3,
1035                 feat_shallow_water, 12,
1036                 feat_floor, 1,
1037                 feat_dirt, 1,
1038                 feat_grass, MAX_FEAT_IN_TERRAIN - 17);
1039
1040         init_terrain_table(TERRAIN_SWAMP, feat_swamp, "abcdef",
1041                 feat_dirt, 2,
1042                 feat_grass, 3,
1043                 feat_tree, 1,
1044                 feat_brake, 1,
1045                 feat_shallow_water, 4,
1046                 feat_swamp, MAX_FEAT_IN_TERRAIN - 11);
1047
1048         init_terrain_table(TERRAIN_DIRT, feat_dirt, "abcdef",
1049                 feat_floor, 3,
1050                 feat_dirt, 10,
1051                 feat_flower, 1,
1052                 feat_brake, 1,
1053                 feat_grass, 1,
1054                 feat_tree, MAX_FEAT_IN_TERRAIN - 16);
1055
1056         init_terrain_table(TERRAIN_GRASS, feat_grass, "abcdef",
1057                 feat_floor, 2,
1058                 feat_dirt, 2,
1059                 feat_grass, 9,
1060                 feat_flower, 1,
1061                 feat_brake, 2,
1062                 feat_tree, MAX_FEAT_IN_TERRAIN - 16);
1063
1064         init_terrain_table(TERRAIN_TREES, feat_tree, "abcde",
1065                 feat_floor, 2,
1066                 feat_dirt, 1,
1067                 feat_tree, 11,
1068                 feat_brake, 2,
1069                 feat_grass, MAX_FEAT_IN_TERRAIN - 16);
1070
1071         init_terrain_table(TERRAIN_DESERT, feat_dirt, "abc",
1072                 feat_floor, 2,
1073                 feat_dirt, 13,
1074                 feat_grass, MAX_FEAT_IN_TERRAIN - 15);
1075
1076         init_terrain_table(TERRAIN_SHALLOW_LAVA, feat_shallow_lava, "abc",
1077                 feat_shallow_lava, 14,
1078                 feat_deep_lava, 3,
1079                 feat_mountain, MAX_FEAT_IN_TERRAIN - 17);
1080
1081         init_terrain_table(TERRAIN_DEEP_LAVA, feat_deep_lava, "abcd",
1082                 feat_dirt, 3,
1083                 feat_shallow_lava, 3,
1084                 feat_deep_lava, 10,
1085                 feat_mountain, MAX_FEAT_IN_TERRAIN - 16);
1086
1087         init_terrain_table(TERRAIN_MOUNTAIN, feat_mountain, "abcdef",
1088                 feat_floor, 1,
1089                 feat_brake, 1,
1090                 feat_grass, 2,
1091                 feat_dirt, 2,
1092                 feat_tree, 2,
1093                 feat_mountain, MAX_FEAT_IN_TERRAIN - 8);
1094 }
1095
1096
1097 /*!
1098  * @brief 荒野から広域マップへの切り替え処理 /
1099  * Initialize arrays for wilderness terrains
1100  * @param encount 襲撃時TRUE
1101  * @return 切り替えが行われた場合はTRUEを返す。
1102  */
1103 bool change_wild_mode(player_type *creature_ptr, bool encount)
1104 {
1105         generate_encounter = encount;
1106
1107         /* It is in the middle of changing map */
1108         if (creature_ptr->leaving) return FALSE;
1109
1110         if (lite_town || vanilla_town)
1111         {
1112                 msg_print(_("荒野なんてない。", "No global map."));
1113                 return FALSE;
1114         }
1115
1116         if (creature_ptr->wild_mode)
1117         {
1118                 /* Save the location in the global map */
1119                 creature_ptr->wilderness_x = creature_ptr->x;
1120                 creature_ptr->wilderness_y = creature_ptr->y;
1121
1122                 /* Give first move to the player */
1123                 creature_ptr->energy_need = 0;
1124
1125                 /* Go back to the ordinary map */
1126                 creature_ptr->wild_mode = FALSE;
1127                 creature_ptr->leaving = TRUE;
1128                 return TRUE;
1129         }
1130
1131         bool have_pet = FALSE;
1132         for (int i = 1; i < creature_ptr->current_floor_ptr->m_max; i++)
1133         {
1134                 monster_type *m_ptr = &creature_ptr->current_floor_ptr->m_list[i];
1135
1136                 if (!monster_is_valid(m_ptr)) continue;
1137                 if (is_pet(m_ptr) && i != creature_ptr->riding) have_pet = TRUE;
1138                 if (MON_CSLEEP(m_ptr)) continue;
1139                 if (m_ptr->cdis > MAX_SIGHT) continue;
1140                 if (!is_hostile(m_ptr)) continue;
1141                 msg_print(_("敵がすぐ近くにいるときは広域マップに入れない!",
1142                         "You cannot enter global map, since there is some monsters nearby!"));
1143                 free_turn(creature_ptr);
1144                 return FALSE;
1145         }
1146
1147         if (have_pet)
1148         {
1149                 concptr msg = _("ペットを置いて広域マップに入りますか?",
1150                         "Do you leave your pets behind? ");
1151
1152                 if (!get_check_strict(msg, CHECK_OKAY_CANCEL))
1153                 {
1154                         free_turn(creature_ptr);
1155                         return FALSE;
1156                 }
1157         }
1158
1159         take_turn(creature_ptr, 1000);
1160
1161         /* Remember the position */
1162         creature_ptr->oldpx = creature_ptr->x;
1163         creature_ptr->oldpy = creature_ptr->y;
1164
1165         /* Cancel hex spelling */
1166         if (hex_spelling_any(creature_ptr)) stop_hex_spell_all(creature_ptr);
1167
1168         /* Cancel any special action */
1169         set_action(creature_ptr, ACTION_NONE);
1170
1171         /* Go into the global map */
1172         creature_ptr->wild_mode = TRUE;
1173         creature_ptr->leaving = TRUE;
1174         return TRUE;
1175 }