-#include "angband.h"\r
-#include "grid.h"\r
-#include "generate.h"\r
-#include "rooms.h"\r
-#include "rooms-city.h"\r
-\r
-\r
-\r
-/*\r
-* Precalculate buildings' location of underground arcade\r
-*/\r
-static bool precalc_ugarcade(int town_hgt, int town_wid, int n)\r
-{\r
- int i, y, x, center_y, center_x, tmp, attempt = 10000;\r
- int max_bldg_hgt = 3 * town_hgt / MAX_TOWN_HGT;\r
- int max_bldg_wid = 5 * town_wid / MAX_TOWN_WID;\r
- ugbldg_type *cur_ugbldg;\r
- bool **ugarcade_used, abort;\r
-\r
- /* Allocate "ugarcade_used" array (2-dimension) */\r
- C_MAKE(ugarcade_used, town_hgt, bool *);\r
- C_MAKE(*ugarcade_used, town_hgt * town_wid, bool);\r
- for (y = 1; y < town_hgt; y++) ugarcade_used[y] = *ugarcade_used + y * town_wid;\r
-\r
- /* Calculate building locations */\r
- for (i = 0; i < n; i++)\r
- {\r
- cur_ugbldg = &ugbldg[i];\r
- (void)WIPE(cur_ugbldg, ugbldg_type);\r
-\r
- do\r
- {\r
- /* Find the "center" of the store */\r
- center_y = rand_range(2, town_hgt - 3);\r
- center_x = rand_range(2, town_wid - 3);\r
-\r
- /* Determine the store boundaries */\r
- tmp = center_y - randint1(max_bldg_hgt);\r
- cur_ugbldg->y0 = MAX(tmp, 1);\r
- tmp = center_x - randint1(max_bldg_wid);\r
- cur_ugbldg->x0 = MAX(tmp, 1);\r
- tmp = center_y + randint1(max_bldg_hgt);\r
- cur_ugbldg->y1 = MIN(tmp, town_hgt - 2);\r
- tmp = center_x + randint1(max_bldg_wid);\r
- cur_ugbldg->x1 = MIN(tmp, town_wid - 2);\r
-\r
- /* Scan this building's area */\r
- for (abort = FALSE, y = cur_ugbldg->y0; (y <= cur_ugbldg->y1) && !abort; y++)\r
- {\r
- for (x = cur_ugbldg->x0; x <= cur_ugbldg->x1; x++)\r
- {\r
- if (ugarcade_used[y][x])\r
- {\r
- abort = TRUE;\r
- break;\r
- }\r
- }\r
- }\r
-\r
- attempt--;\r
- } while (abort && attempt); /* Accept this building if no overlapping */\r
-\r
- /* Failed to generate underground arcade */\r
- if (!attempt) break;\r
-\r
- /*\r
- * Mark to ugarcade_used[][] as "used"\r
- * Note: Building-adjacent grids are included for preventing\r
- * connected bulidings.\r
- */\r
- for (y = cur_ugbldg->y0 - 1; y <= cur_ugbldg->y1 + 1; y++)\r
- {\r
- for (x = cur_ugbldg->x0 - 1; x <= cur_ugbldg->x1 + 1; x++)\r
- {\r
- ugarcade_used[y][x] = TRUE;\r
- }\r
- }\r
- }\r
-\r
- /* Free "ugarcade_used" array (2-dimension) */\r
- C_KILL(*ugarcade_used, town_hgt * town_wid, bool);\r
- C_KILL(ugarcade_used, town_hgt, bool *);\r
-\r
- /* If i < n, generation is not allowed */\r
- return i == n;\r
-}\r
-\r
-\r
-/*!\r
-* @brief タイプ16の部屋…地下都市生成のサブルーチン / Actually create buildings\r
-* @return なし\r
-* @param ltcy 生成基準Y座標\r
-* @param ltcx 生成基準X座標\r
-* @param stotes[] 生成する店舗のリスト\r
-* @param n 生成する店舗の数\r
-* @note\r
-* Note: ltcy and ltcx indicate "left top corner".\r
-*/\r
-static void build_stores(int ltcy, int ltcx, int stores[], int n)\r
-{\r
- int i, y, x;\r
- IDX j;\r
- ugbldg_type *cur_ugbldg;\r
-\r
- for (i = 0; i < n; i++)\r
- {\r
- cur_ugbldg = &ugbldg[i];\r
-\r
- /* Generate new room */\r
- generate_room_floor(\r
- ltcy + cur_ugbldg->y0 - 2, ltcx + cur_ugbldg->x0 - 2,\r
- ltcy + cur_ugbldg->y1 + 2, ltcx + cur_ugbldg->x1 + 2,\r
- FALSE);\r
- }\r
-\r
- for (i = 0; i < n; i++)\r
- {\r
- cur_ugbldg = &ugbldg[i];\r
-\r
- /* Build an invulnerable rectangular building */\r
- generate_fill_perm_bold(\r
- ltcy + cur_ugbldg->y0, ltcx + cur_ugbldg->x0,\r
- ltcy + cur_ugbldg->y1, ltcx + cur_ugbldg->x1);\r
-\r
- /* Pick a door direction (S,N,E,W) */\r
- switch (randint0(4))\r
- {\r
- /* Bottom side */\r
- case 0:\r
- y = cur_ugbldg->y1;\r
- x = rand_range(cur_ugbldg->x0, cur_ugbldg->x1);\r
- break;\r
-\r
- /* Top side */\r
- case 1:\r
- y = cur_ugbldg->y0;\r
- x = rand_range(cur_ugbldg->x0, cur_ugbldg->x1);\r
- break;\r
-\r
- /* Right side */\r
- case 2:\r
- y = rand_range(cur_ugbldg->y0, cur_ugbldg->y1);\r
- x = cur_ugbldg->x1;\r
- break;\r
-\r
- /* Left side */\r
- default:\r
- y = rand_range(cur_ugbldg->y0, cur_ugbldg->y1);\r
- x = cur_ugbldg->x0;\r
- break;\r
- }\r
-\r
- for (j = 0; j < max_f_idx; j++)\r
- {\r
- if (have_flag(f_info[j].flags, FF_STORE))\r
- {\r
- if (f_info[j].subtype == stores[i]) break;\r
- }\r
- }\r
-\r
- /* Clear previous contents, add a store door */\r
- if (j < max_f_idx)\r
- {\r
- cave_set_feat(ltcy + y, ltcx + x, j);\r
-\r
- /* Init store */\r
- store_init(NO_TOWN, stores[i]);\r
- }\r
- }\r
-}\r
-\r
-\r
-/*!\r
-* @brief タイプ16の部屋…地下都市の生成 / Type 16 -- Underground Arcade\r
-* @return なし\r
-* @details\r
-* Town logic flow for generation of new town\n\r
-* Originally from Vanilla 3.0.3\n\r
-*\n\r
-* We start with a fully wiped cave of normal floors.\n\r
-*\n\r
-* Note that town_gen_hack() plays games with the R.N.G.\n\r
-*\n\r
-* This function does NOT do anything about the owners of the stores,\n\r
-* nor the contents thereof. It only handles the physical layout.\n\r
-*/\r
-bool build_type16(void)\r
-{\r
- int stores[] =\r
- {\r
- STORE_GENERAL, STORE_ARMOURY, STORE_WEAPON, STORE_TEMPLE,\r
- STORE_ALCHEMIST, STORE_MAGIC, STORE_BLACK, STORE_BOOK,\r
- };\r
- int n = sizeof stores / sizeof(int);\r
- POSITION i, y, x, y1, x1, yval, xval;\r
- int town_hgt = rand_range(MIN_TOWN_HGT, MAX_TOWN_HGT);\r
- int town_wid = rand_range(MIN_TOWN_WID, MAX_TOWN_WID);\r
- bool prevent_bm = FALSE;\r
-\r
- /* Hack -- If already exist black market, prevent building */\r
- for (y = 0; (y < cur_hgt) && !prevent_bm; y++)\r
- {\r
- for (x = 0; x < cur_wid; x++)\r
- {\r
- if (cave[y][x].feat == FF_STORE)\r
- {\r
- prevent_bm = (f_info[cave[y][x].feat].subtype == STORE_BLACK);\r
- break;\r
- }\r
- }\r
- }\r
- for (i = 0; i < n; i++)\r
- {\r
- if ((stores[i] == STORE_BLACK) && prevent_bm) stores[i] = stores[--n];\r
- }\r
- if (!n) return FALSE;\r
-\r
- /* Allocate buildings array */\r
- C_MAKE(ugbldg, n, ugbldg_type);\r
-\r
- /* If cannot build stores, abort */\r
- if (!precalc_ugarcade(town_hgt, town_wid, n))\r
- {\r
- /* Free buildings array */\r
- C_KILL(ugbldg, n, ugbldg_type);\r
- return FALSE;\r
- }\r
-\r
- /* Find and reserve some space in the dungeon. Get center of room. */\r
- if (!find_space(&yval, &xval, town_hgt + 4, town_wid + 4))\r
- {\r
- /* Free buildings array */\r
- C_KILL(ugbldg, n, ugbldg_type);\r
- return FALSE;\r
- }\r
-\r
- /* Get top left corner */\r
- y1 = yval - (town_hgt / 2);\r
- x1 = xval - (town_wid / 2);\r
-\r
- /* Generate new room */\r
- generate_room_floor(\r
- y1 + town_hgt / 3, x1 + town_wid / 3,\r
- y1 + town_hgt * 2 / 3, x1 + town_wid * 2 / 3, FALSE);\r
-\r
- /* Build stores */\r
- build_stores(y1, x1, stores, n);\r
-\r
- msg_print_wizard(CHEAT_DUNGEON, _("地下街を生成しました", "Underground arcade was generated."));\r
-\r
- /* Free buildings array */\r
- C_KILL(ugbldg, n, ugbldg_type);\r
-\r
- return TRUE;\r
-}\r
-\r
+#include "angband.h"
+#include "util.h"
+
+#include "grid.h"
+#include "floor.h"
+#include "floor-generate.h"
+#include "rooms.h"
+#include "rooms-city.h"
+#include "store.h"
+#include "wild.h"
+
+
+
+/*
+* Precalculate buildings' location of underground arcade
+*/
+static bool precalc_ugarcade(int town_hgt, int town_wid, int n)
+{
+ POSITION i, y, x, center_y, center_x;
+ int tmp, attempt = 10000;
+ POSITION max_bldg_hgt = 3 * town_hgt / MAX_TOWN_HGT;
+ POSITION max_bldg_wid = 5 * town_wid / MAX_TOWN_WID;
+ ugbldg_type *cur_ugbldg;
+ bool **ugarcade_used, abort;
+
+ /* Allocate "ugarcade_used" array (2-dimension) */
+ C_MAKE(ugarcade_used, town_hgt, bool *);
+ C_MAKE(*ugarcade_used, town_hgt * town_wid, bool);
+ for (y = 1; y < town_hgt; y++) ugarcade_used[y] = *ugarcade_used + y * town_wid;
+
+ /* Calculate building locations */
+ for (i = 0; i < n; i++)
+ {
+ cur_ugbldg = &ugbldg[i];
+ (void)WIPE(cur_ugbldg, ugbldg_type);
+
+ do
+ {
+ /* Find the "center" of the store */
+ center_y = rand_range(2, town_hgt - 3);
+ center_x = rand_range(2, town_wid - 3);
+
+ /* Determine the store boundaries */
+ tmp = center_y - randint1(max_bldg_hgt);
+ cur_ugbldg->y0 = MAX(tmp, 1);
+ tmp = center_x - randint1(max_bldg_wid);
+ cur_ugbldg->x0 = MAX(tmp, 1);
+ tmp = center_y + randint1(max_bldg_hgt);
+ cur_ugbldg->y1 = MIN(tmp, town_hgt - 2);
+ tmp = center_x + randint1(max_bldg_wid);
+ cur_ugbldg->x1 = MIN(tmp, town_wid - 2);
+
+ /* Scan this building's area */
+ for (abort = FALSE, y = cur_ugbldg->y0; (y <= cur_ugbldg->y1) && !abort; y++)
+ {
+ for (x = cur_ugbldg->x0; x <= cur_ugbldg->x1; x++)
+ {
+ if (ugarcade_used[y][x])
+ {
+ abort = TRUE;
+ break;
+ }
+ }
+ }
+
+ attempt--;
+ } while (abort && attempt); /* Accept this building if no overlapping */
+
+ /* Failed to generate underground arcade */
+ if (!attempt) break;
+
+ /*
+ * Mark to ugarcade_used[][] as "used"
+ * Note: Building-adjacent grids are included for preventing
+ * connected bulidings.
+ */
+ for (y = cur_ugbldg->y0 - 1; y <= cur_ugbldg->y1 + 1; y++)
+ {
+ for (x = cur_ugbldg->x0 - 1; x <= cur_ugbldg->x1 + 1; x++)
+ {
+ ugarcade_used[y][x] = TRUE;
+ }
+ }
+ }
+
+ /* Free "ugarcade_used" array (2-dimension) */
+ C_KILL(*ugarcade_used, town_hgt * town_wid, bool);
+ C_KILL(ugarcade_used, town_hgt, bool *);
+
+ /* If i < n, generation is not allowed */
+ return i == n;
+}
+
+
+/*!
+* @brief タイプ16の部屋…地下都市生成のサブルーチン / Actually create buildings
+* @return なし
+* @param ltcy 生成基準Y座標
+* @param ltcx 生成基準X座標
+* @param stotes[] 生成する店舗のリスト
+* @param n 生成する店舗の数
+* @note
+* Note: ltcy and ltcx indicate "left top corner".
+*/
+static void build_stores(POSITION ltcy, POSITION ltcx, int stores[], int n)
+{
+ int i;
+ POSITION y, x;
+ FEAT_IDX j;
+ ugbldg_type *cur_ugbldg;
+
+ for (i = 0; i < n; i++)
+ {
+ cur_ugbldg = &ugbldg[i];
+
+ /* Generate new room */
+ generate_room_floor(
+ ltcy + cur_ugbldg->y0 - 2, ltcx + cur_ugbldg->x0 - 2,
+ ltcy + cur_ugbldg->y1 + 2, ltcx + cur_ugbldg->x1 + 2,
+ FALSE);
+ }
+
+ for (i = 0; i < n; i++)
+ {
+ cur_ugbldg = &ugbldg[i];
+
+ /* Build an invulnerable rectangular building */
+ generate_fill_perm_bold(
+ ltcy + cur_ugbldg->y0, ltcx + cur_ugbldg->x0,
+ ltcy + cur_ugbldg->y1, ltcx + cur_ugbldg->x1);
+
+ /* Pick a door direction (S,N,E,W) */
+ switch (randint0(4))
+ {
+ /* Bottom side */
+ case 0:
+ y = cur_ugbldg->y1;
+ x = rand_range(cur_ugbldg->x0, cur_ugbldg->x1);
+ break;
+
+ /* Top side */
+ case 1:
+ y = cur_ugbldg->y0;
+ x = rand_range(cur_ugbldg->x0, cur_ugbldg->x1);
+ break;
+
+ /* Right side */
+ case 2:
+ y = rand_range(cur_ugbldg->y0, cur_ugbldg->y1);
+ x = cur_ugbldg->x1;
+ break;
+
+ /* Left side */
+ default:
+ y = rand_range(cur_ugbldg->y0, cur_ugbldg->y1);
+ x = cur_ugbldg->x0;
+ break;
+ }
+
+ for (j = 0; j < max_f_idx; j++)
+ {
+ if (have_flag(f_info[j].flags, FF_STORE))
+ {
+ if (f_info[j].subtype == stores[i]) break;
+ }
+ }
+
+ /* Clear previous contents, add a store door */
+ if (j < max_f_idx)
+ {
+ cave_set_feat(ltcy + y, ltcx + x, j);
+
+ /* Init store */
+ store_init(NO_TOWN, stores[i]);
+ }
+ }
+}
+
+
+/*!
+* @brief タイプ16の部屋…地下都市の生成 / Type 16 -- Underground Arcade
+* @return なし
+* @details
+* Town logic flow for generation of new town\n
+* Originally from Vanilla 3.0.3\n
+*\n
+* We start with a fully wiped current_floor_ptr->grid_array of normal floors.\n
+*\n
+* Note that town_gen_hack() plays games with the R.N.G.\n
+*\n
+* This function does NOT do anything about the owners of the stores,\n
+* nor the contents thereof. It only handles the physical layout.\n
+*/
+bool build_type16(void)
+{
+ int stores[] =
+ {
+ STORE_GENERAL, STORE_ARMOURY, STORE_WEAPON, STORE_TEMPLE,
+ STORE_ALCHEMIST, STORE_MAGIC, STORE_BLACK, STORE_BOOK,
+ };
+ int n = sizeof stores / sizeof(int);
+ POSITION i, y, x, y1, x1, yval, xval;
+ int town_hgt = rand_range(MIN_TOWN_HGT, MAX_TOWN_HGT);
+ int town_wid = rand_range(MIN_TOWN_WID, MAX_TOWN_WID);
+ bool prevent_bm = FALSE;
+
+ /* Hack -- If already exist black market, prevent building */
+ for (y = 0; (y < current_floor_ptr->height) && !prevent_bm; y++)
+ {
+ for (x = 0; x < current_floor_ptr->width; x++)
+ {
+ if (current_floor_ptr->grid_array[y][x].feat == FF_STORE)
+ {
+ prevent_bm = (f_info[current_floor_ptr->grid_array[y][x].feat].subtype == STORE_BLACK);
+ break;
+ }
+ }
+ }
+ for (i = 0; i < n; i++)
+ {
+ if ((stores[i] == STORE_BLACK) && prevent_bm) stores[i] = stores[--n];
+ }
+ if (!n) return FALSE;
+
+ /* Allocate buildings array */
+ C_MAKE(ugbldg, n, ugbldg_type);
+
+ /* If cannot build stores, abort */
+ if (!precalc_ugarcade(town_hgt, town_wid, n))
+ {
+ /* Free buildings array */
+ C_KILL(ugbldg, n, ugbldg_type);
+ return FALSE;
+ }
+
+ /* Find and reserve some space in the dungeon. Get center of room. */
+ if (!find_space(&yval, &xval, town_hgt + 4, town_wid + 4))
+ {
+ /* Free buildings array */
+ C_KILL(ugbldg, n, ugbldg_type);
+ return FALSE;
+ }
+
+ /* Get top left corner */
+ y1 = yval - (town_hgt / 2);
+ x1 = xval - (town_wid / 2);
+
+ /* Generate new room */
+ generate_room_floor(
+ y1 + town_hgt / 3, x1 + town_wid / 3,
+ y1 + town_hgt * 2 / 3, x1 + town_wid * 2 / 3, FALSE);
+
+ /* Build stores */
+ build_stores(y1, x1, stores, n);
+
+ msg_print_wizard(CHEAT_DUNGEON, _("地下街を生成しました", "Underground arcade was generated."));
+
+ /* Free buildings array */
+ C_KILL(ugbldg, n, ugbldg_type);
+
+ return TRUE;
+}
+