Separate generation of underground city from rooms.c to rooms-city.c/h.
<ClCompile Include="..\..\src\realm-life.c" />\r
<ClCompile Include="..\..\src\realm-trump.c" />\r
<ClCompile Include="..\..\src\report.c" />\r
+ <ClCompile Include="..\..\src\rooms-city.c" />\r
<ClCompile Include="..\..\src\rooms-normal.c" />\r
<ClCompile Include="..\..\src\rooms-pitnest.c" />\r
<ClCompile Include="..\..\src\rooms-vault.c" />\r
<ClInclude Include="..\..\src\realm-song.h" />\r
<ClInclude Include="..\..\src\realm-sorcery.h" />\r
<ClInclude Include="..\..\src\realm-trump.h" />\r
+ <ClInclude Include="..\..\src\rooms-city.h" />\r
<ClInclude Include="..\..\src\rooms-normal.h" />\r
<ClInclude Include="..\..\src\rooms-pitnest.h" />\r
<ClInclude Include="..\..\src\rooms-vault.h" />\r
<ClCompile Include="..\..\src\realm-hissatsu.c">\r
<Filter>Source</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\..\src\rooms-city.c">\r
+ <Filter>Source</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<ClInclude Include="..\..\src\angband.h">\r
<ClInclude Include="..\..\src\realm-hex.h">\r
<Filter>Header</Filter>\r
</ClInclude>\r
+ <ClInclude Include="..\..\src\rooms-city.h">\r
+ <Filter>Header</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
<ItemGroup>\r
<ResourceCompile Include="..\..\src\angband.rc" />\r
--- /dev/null
+#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 \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
+* @return \82È\82µ\r
+* @param ltcy \90¶\90¬\8aî\8f\80Y\8dÀ\95W\r
+* @param ltcx \90¶\90¬\8aî\8f\80X\8dÀ\95W\r
+* @param stotes[] \90¶\90¬\82·\82é\93X\95Ü\82Ì\83\8a\83X\83g\r
+* @param n \90¶\90¬\82·\82é\93X\95Ü\82Ì\90\94\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 \83^\83C\83v16\82Ì\95\94\89®\81c\92n\89º\93s\8es\82Ì\90¶\90¬ / Type 16 -- Underground Arcade\r
+* @return \82È\82µ\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, _("\92n\89º\8aX\82ð\90¶\90¬\82µ\82Ü\82µ\82½", "Underground arcade was generated."));\r
+\r
+ /* Free buildings array */\r
+ C_KILL(ugbldg, n, ugbldg_type);\r
+\r
+ return TRUE;\r
+}\r
+\r
--- /dev/null
+extern bool build_type16(void);\r
+\r
+/* Minimum & maximum town size */\r
+#define MIN_TOWN_WID ((MAX_WID / 3) / 2)\r
+#define MIN_TOWN_HGT ((MAX_HGT / 3) / 2)\r
+#define MAX_TOWN_WID ((MAX_WID / 3) * 2 / 3)\r
+#define MAX_TOWN_HGT ((MAX_HGT / 3) * 2 / 3)\r
+\r
+/* Struct for build underground buildings */\r
+typedef struct\r
+{\r
+ int y0, x0; /* North-west corner (relative) */\r
+ int y1, x1; /* South-east corner (relative) */\r
+}\r
+ugbldg_type;\r
+\r
+ugbldg_type *ugbldg;\r
#include "rooms-normal.h"
#include "rooms-pitnest.h"
#include "rooms-vault.h"
+#include "rooms-city.h"
/*!
}
}
-/* Minimum & maximum town size */
-#define MIN_TOWN_WID ((MAX_WID / 3) / 2)
-#define MIN_TOWN_HGT ((MAX_HGT / 3) / 2)
-#define MAX_TOWN_WID ((MAX_WID / 3) * 2 / 3)
-#define MAX_TOWN_HGT ((MAX_HGT / 3) * 2 / 3)
-
-/* Struct for build underground buildings */
-typedef struct
-{
- int y0, x0; /* North-west corner (relative) */
- int y1, x1; /* South-east corner (relative) */
-}
-ugbldg_type;
-
-ugbldg_type *ugbldg;
-
-/*
- * Precalculate buildings' location of underground arcade
- */
-static bool precalc_ugarcade(int town_hgt, int town_wid, int n)
-{
- int i, y, x, center_y, center_x, tmp, attempt = 10000;
- int max_bldg_hgt = 3 * town_hgt / MAX_TOWN_HGT;
- int 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(int ltcy, int ltcx, int stores[], int n)
-{
- int i, y, x;
- 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 cave 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
- */
-static 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 < cur_hgt) && !prevent_bm; y++)
- {
- for (x = 0; x < cur_wid; x++)
- {
- if (cave[y][x].feat == FF_STORE)
- {
- prevent_bm = (f_info[cave[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;
-}
-
/*!
* @brief 与えられた部屋型IDに応じて部屋の生成処理分岐を行い結果を返す / Attempt to build a room of the given type at the given block
extern void build_small_room(int x0, int y0);
extern void add_outer_wall(int x, int y, int light, int x1, int y1, int x2, int y2);
extern int dist2(int x1, int y1, int x2, int y2, int h1, int h2, int h3, int h4);
+extern void generate_room_floor(int y1, int x1, int y2, int x2, int light);
+extern void generate_fill_perm_bold(int y1, int x1, int y2, int x2);