3 #include "generate.h"
\r
5 #include "rooms-city.h"
\r
10 * Precalculate buildings' location of underground arcade
\r
12 static bool precalc_ugarcade(int town_hgt, int town_wid, int n)
\r
14 int i, y, x, center_y, center_x, tmp, attempt = 10000;
\r
15 int max_bldg_hgt = 3 * town_hgt / MAX_TOWN_HGT;
\r
16 int max_bldg_wid = 5 * town_wid / MAX_TOWN_WID;
\r
17 ugbldg_type *cur_ugbldg;
\r
18 bool **ugarcade_used, abort;
\r
20 /* Allocate "ugarcade_used" array (2-dimension) */
\r
21 C_MAKE(ugarcade_used, town_hgt, bool *);
\r
22 C_MAKE(*ugarcade_used, town_hgt * town_wid, bool);
\r
23 for (y = 1; y < town_hgt; y++) ugarcade_used[y] = *ugarcade_used + y * town_wid;
\r
25 /* Calculate building locations */
\r
26 for (i = 0; i < n; i++)
\r
28 cur_ugbldg = &ugbldg[i];
\r
29 (void)WIPE(cur_ugbldg, ugbldg_type);
\r
33 /* Find the "center" of the store */
\r
34 center_y = rand_range(2, town_hgt - 3);
\r
35 center_x = rand_range(2, town_wid - 3);
\r
37 /* Determine the store boundaries */
\r
38 tmp = center_y - randint1(max_bldg_hgt);
\r
39 cur_ugbldg->y0 = MAX(tmp, 1);
\r
40 tmp = center_x - randint1(max_bldg_wid);
\r
41 cur_ugbldg->x0 = MAX(tmp, 1);
\r
42 tmp = center_y + randint1(max_bldg_hgt);
\r
43 cur_ugbldg->y1 = MIN(tmp, town_hgt - 2);
\r
44 tmp = center_x + randint1(max_bldg_wid);
\r
45 cur_ugbldg->x1 = MIN(tmp, town_wid - 2);
\r
47 /* Scan this building's area */
\r
48 for (abort = FALSE, y = cur_ugbldg->y0; (y <= cur_ugbldg->y1) && !abort; y++)
\r
50 for (x = cur_ugbldg->x0; x <= cur_ugbldg->x1; x++)
\r
52 if (ugarcade_used[y][x])
\r
61 } while (abort && attempt); /* Accept this building if no overlapping */
\r
63 /* Failed to generate underground arcade */
\r
64 if (!attempt) break;
\r
67 * Mark to ugarcade_used[][] as "used"
\r
68 * Note: Building-adjacent grids are included for preventing
\r
69 * connected bulidings.
\r
71 for (y = cur_ugbldg->y0 - 1; y <= cur_ugbldg->y1 + 1; y++)
\r
73 for (x = cur_ugbldg->x0 - 1; x <= cur_ugbldg->x1 + 1; x++)
\r
75 ugarcade_used[y][x] = TRUE;
\r
80 /* Free "ugarcade_used" array (2-dimension) */
\r
81 C_KILL(*ugarcade_used, town_hgt * town_wid, bool);
\r
82 C_KILL(ugarcade_used, town_hgt, bool *);
\r
84 /* If i < n, generation is not allowed */
\r
90 * @brief
\83^
\83C
\83v16
\82Ì
\95\94\89®
\81c
\92n
\89º
\93s
\8es
\90¶
\90¬
\82Ì
\83T
\83u
\83\8b\81[
\83`
\83\93 / Actually create buildings
\r
92 * @param ltcy
\90¶
\90¬
\8aî
\8f\80Y
\8dÀ
\95W
\r
93 * @param ltcx
\90¶
\90¬
\8aî
\8f\80X
\8dÀ
\95W
\r
94 * @param stotes[]
\90¶
\90¬
\82·
\82é
\93X
\95Ü
\82Ì
\83\8a\83X
\83g
\r
95 * @param n
\90¶
\90¬
\82·
\82é
\93X
\95Ü
\82Ì
\90\94\r
97 * Note: ltcy and ltcx indicate "left top corner".
\r
99 static void build_stores(int ltcy, int ltcx, int stores[], int n)
\r
103 ugbldg_type *cur_ugbldg;
\r
105 for (i = 0; i < n; i++)
\r
107 cur_ugbldg = &ugbldg[i];
\r
109 /* Generate new room */
\r
110 generate_room_floor(
\r
111 ltcy + cur_ugbldg->y0 - 2, ltcx + cur_ugbldg->x0 - 2,
\r
112 ltcy + cur_ugbldg->y1 + 2, ltcx + cur_ugbldg->x1 + 2,
\r
116 for (i = 0; i < n; i++)
\r
118 cur_ugbldg = &ugbldg[i];
\r
120 /* Build an invulnerable rectangular building */
\r
121 generate_fill_perm_bold(
\r
122 ltcy + cur_ugbldg->y0, ltcx + cur_ugbldg->x0,
\r
123 ltcy + cur_ugbldg->y1, ltcx + cur_ugbldg->x1);
\r
125 /* Pick a door direction (S,N,E,W) */
\r
126 switch (randint0(4))
\r
130 y = cur_ugbldg->y1;
\r
131 x = rand_range(cur_ugbldg->x0, cur_ugbldg->x1);
\r
136 y = cur_ugbldg->y0;
\r
137 x = rand_range(cur_ugbldg->x0, cur_ugbldg->x1);
\r
142 y = rand_range(cur_ugbldg->y0, cur_ugbldg->y1);
\r
143 x = cur_ugbldg->x1;
\r
148 y = rand_range(cur_ugbldg->y0, cur_ugbldg->y1);
\r
149 x = cur_ugbldg->x0;
\r
153 for (j = 0; j < max_f_idx; j++)
\r
155 if (have_flag(f_info[j].flags, FF_STORE))
\r
157 if (f_info[j].subtype == stores[i]) break;
\r
161 /* Clear previous contents, add a store door */
\r
164 cave_set_feat(ltcy + y, ltcx + x, j);
\r
167 store_init(NO_TOWN, stores[i]);
\r
174 * @brief
\83^
\83C
\83v16
\82Ì
\95\94\89®
\81c
\92n
\89º
\93s
\8es
\82Ì
\90¶
\90¬ / Type 16 -- Underground Arcade
\r
177 * Town logic flow for generation of new town\n
\r
178 * Originally from Vanilla 3.0.3\n
\r
180 * We start with a fully wiped cave of normal floors.\n
\r
182 * Note that town_gen_hack() plays games with the R.N.G.\n
\r
184 * This function does NOT do anything about the owners of the stores,\n
\r
185 * nor the contents thereof. It only handles the physical layout.\n
\r
187 bool build_type16(void)
\r
191 STORE_GENERAL, STORE_ARMOURY, STORE_WEAPON, STORE_TEMPLE,
\r
192 STORE_ALCHEMIST, STORE_MAGIC, STORE_BLACK, STORE_BOOK,
\r
194 int n = sizeof stores / sizeof(int);
\r
195 POSITION i, y, x, y1, x1, yval, xval;
\r
196 int town_hgt = rand_range(MIN_TOWN_HGT, MAX_TOWN_HGT);
\r
197 int town_wid = rand_range(MIN_TOWN_WID, MAX_TOWN_WID);
\r
198 bool prevent_bm = FALSE;
\r
200 /* Hack -- If already exist black market, prevent building */
\r
201 for (y = 0; (y < cur_hgt) && !prevent_bm; y++)
\r
203 for (x = 0; x < cur_wid; x++)
\r
205 if (cave[y][x].feat == FF_STORE)
\r
207 prevent_bm = (f_info[cave[y][x].feat].subtype == STORE_BLACK);
\r
212 for (i = 0; i < n; i++)
\r
214 if ((stores[i] == STORE_BLACK) && prevent_bm) stores[i] = stores[--n];
\r
216 if (!n) return FALSE;
\r
218 /* Allocate buildings array */
\r
219 C_MAKE(ugbldg, n, ugbldg_type);
\r
221 /* If cannot build stores, abort */
\r
222 if (!precalc_ugarcade(town_hgt, town_wid, n))
\r
224 /* Free buildings array */
\r
225 C_KILL(ugbldg, n, ugbldg_type);
\r
229 /* Find and reserve some space in the dungeon. Get center of room. */
\r
230 if (!find_space(&yval, &xval, town_hgt + 4, town_wid + 4))
\r
232 /* Free buildings array */
\r
233 C_KILL(ugbldg, n, ugbldg_type);
\r
237 /* Get top left corner */
\r
238 y1 = yval - (town_hgt / 2);
\r
239 x1 = xval - (town_wid / 2);
\r
241 /* Generate new room */
\r
242 generate_room_floor(
\r
243 y1 + town_hgt / 3, x1 + town_wid / 3,
\r
244 y1 + town_hgt * 2 / 3, x1 + town_wid * 2 / 3, FALSE);
\r
247 build_stores(y1, x1, stores, n);
\r
249 msg_print_wizard(CHEAT_DUNGEON, _("
\92n
\89º
\8aX
\82ð
\90¶
\90¬
\82µ
\82Ü
\82µ
\82½", "Underground arcade was generated."));
\r
251 /* Free buildings array */
\r
252 C_KILL(ugbldg, n, ugbldg_type);
\r