• R/O
  • HTTP
  • SSH
  • HTTPS

hengband: Commit

変愚蛮怒のメインリポジトリです


Commit MetaInfo

Revision173d1efd3c6eb41a0e5456e12306850c731f61a4 (tree)
Time2003-08-27 00:49:44
Authormogami <mogami@0568...>
Commitermogami

Log Message

ダンジョンの部屋生成コードを変更。SAngから大幅に変更しつつ移植。
大きい部屋から先に生成するので Greater Vault の生成失敗が少なくなる。
深層のフロアが特殊な部屋ばっかりになる傾向があるので、
各部屋の出現率 room_info_normal を今後調整する必要あり。
今後、ダンジョン毎に異なる room_info を用意する事で特徴を出す事もできる。

Change Summary

Incremental Difference

--- a/src/defines.h
+++ b/src/defines.h
@@ -2437,33 +2437,6 @@
24372437 #define CAVE_IN_DETECT 0x4000 /* trap detected area (inner circle only) */
24382438
24392439
2440-/* Room types for generate_lake() */
2441-#define GEN_LAKE_TYPE_LAVA 1
2442-#define GEN_LAKE_TYPE_WATER 2
2443-#define GEN_LAKE_TYPE_CAVE 3
2444-#define GEN_LAKE_TYPE_EARTH_VAULT 4
2445-#define GEN_LAKE_TYPE_AIR_VAULT 5
2446-#define GEN_LAKE_TYPE_WATER_VAULT 6
2447-#define GEN_LAKE_TYPE_FIRE_VAULT 7
2448-
2449-
2450-/* Room types for room_build() */
2451-#define ROOM_BUILD_TYPE_NORMAL 1
2452-#define ROOM_BUILD_TYPE_OVERLAP 2
2453-#define ROOM_BUILD_TYPE_CROSS 3
2454-#define ROOM_BUILD_TYPE_INNER_FEAT 4
2455-#define ROOM_BUILD_TYPE_NEST 5
2456-#define ROOM_BUILD_TYPE_PIT 6
2457-#define ROOM_BUILD_TYPE_LESSER_VAULT 7
2458-#define ROOM_BUILD_TYPE_GREATER_VAULT 8
2459-#define ROOM_BUILD_TYPE_FRACAVE 9
2460-#define ROOM_BUILD_TYPE_RANDOM_VAULT 10
2461-#define ROOM_BUILD_TYPE_OVAL 11
2462-#define ROOM_BUILD_TYPE_CRYPT 12
2463-#define ROOM_BUILD_TYPE_TRAP_PIT 13
2464-#define ROOM_BUILD_TYPE_TRAP 14
2465-
2466-
24672440 /*
24682441 * Bit flags for the "project()" function
24692442 *
--- a/src/generate.c
+++ b/src/generate.c
@@ -104,8 +104,6 @@
104104 #include "rooms.h"
105105 #include "streams.h"
106106
107-int dun_rooms;
108-
109107 int dun_tun_rnd;
110108 int dun_tun_chg;
111109 int dun_tun_con;
@@ -118,6 +116,7 @@ int dun_tun_jct;
118116 */
119117 dun_data *dun;
120118
119+
121120 /*
122121 * Places some staircases near walls
123122 */
@@ -491,28 +490,125 @@ static void set_bound_perm_wall(cave_type *c_ptr)
491490
492491
493492 /*
494- * Generate a new dungeon level
493+ * Generate various caverns and lakes
495494 *
496- * Note that "dun_body" adds about 4000 bytes of memory to the stack.
495+ * There were moved from cave_gen().
497496 */
498-static bool cave_gen(void)
497+static void gen_caverns_and_lakes(void)
499498 {
500- int i, j, k, y, x, y1, x1;
499+#ifdef ALLOW_CAVERNS_AND_LAKES
500+ /* Possible "destroyed" level */
501+ if ((dun_level > 30) && one_in_(DUN_DEST*2) && (small_levels) && (d_info[dungeon_type].flags1 & DF1_DESTROY))
502+ {
503+ dun->destroyed = TRUE;
501504
502- int max_vault_ok = 2;
505+ /* extra rubble around the place looks cool */
506+ build_lake(one_in_(2) ? LAKE_T_CAVE : LAKE_T_EARTH_VAULT);
507+ }
503508
504- int feat1 = 0, feat2 = 0;
509+ /* Make a lake some of the time */
510+ if (one_in_(LAKE_LEVEL) && !dun->empty_level && !dun->destroyed &&
511+ (d_info[dungeon_type].flags1 & DF1_LAKE_MASK))
512+ {
513+ int count = 0;
514+ if (d_info[dungeon_type].flags1 & DF1_LAKE_WATER) count += 3;
515+ if (d_info[dungeon_type].flags1 & DF1_LAKE_LAVA) count += 3;
516+ if (d_info[dungeon_type].flags1 & DF1_LAKE_RUBBLE) count += 3;
517+ if (d_info[dungeon_type].flags1 & DF1_LAKE_TREE) count += 3;
505518
506- cave_type *c_ptr;
519+ if (d_info[dungeon_type].flags1 & DF1_LAKE_LAVA)
520+ {
521+ /* Lake of Lava */
522+ if ((dun_level > 80) && (randint0(count) < 2)) dun->laketype = LAKE_T_LAVA;
523+ count -= 2;
524+
525+ /* Lake of Lava2 */
526+ if (!dun->laketype && (dun_level > 80) && one_in_(count)) dun->laketype = LAKE_T_FIRE_VAULT;
527+ count--;
528+ }
529+
530+ if ((d_info[dungeon_type].flags1 & DF1_LAKE_WATER) && !dun->laketype)
531+ {
532+ /* Lake of Water */
533+ if ((dun_level > 50) && randint0(count) < 2) dun->laketype = LAKE_T_WATER;
534+ count -= 2;
535+
536+ /* Lake of Water2 */
537+ if (!dun->laketype && (dun_level > 50) && one_in_(count)) dun->laketype = LAKE_T_WATER_VAULT;
538+ count--;
539+ }
540+
541+ if ((d_info[dungeon_type].flags1 & DF1_LAKE_RUBBLE) && !dun->laketype)
542+ {
543+ /* Lake of rubble */
544+ if ((dun_level > 35) && (randint0(count) < 2)) dun->laketype = LAKE_T_CAVE;
545+ count -= 2;
546+
547+ /* Lake of rubble2 */
548+ if (!dun->laketype && (dun_level > 35) && one_in_(count)) dun->laketype = LAKE_T_EARTH_VAULT;
549+ count--;
550+ }
551+
552+ /* Lake of tree */
553+ if ((dun_level > 5) && (d_info[dungeon_type].flags1 & DF1_LAKE_TREE) && !dun->laketype) dun->laketype = LAKE_T_AIR_VAULT;
554+
555+ if (dun->laketype)
556+ {
557+ if (cheat_room)
558+#ifdef JP
559+ msg_print("湖を生成。");
560+#else
561+ msg_print("Lake on the level.");
562+#endif
507563
508- bool destroyed = FALSE;
509- bool empty_level = FALSE;
510- bool cavern = FALSE;
511- int laketype = 0;
564+ build_lake(dun->laketype);
565+ }
566+ }
567+
568+ if ((dun_level > DUN_CAVERN) && !dun->empty_level &&
569+ (d_info[dungeon_type].flags1 & DF1_CAVERN) &&
570+ !dun->laketype && !dun->destroyed && (randint1(1000) < dun_level))
571+ {
572+ dun->cavern = TRUE;
573+
574+ /* make a large fractal cave in the middle of the dungeon */
575+
576+ if (cheat_room)
577+#ifdef JP
578+ msg_print("洞窟を生成。");
579+#else
580+ msg_print("Cavern on level.");
581+#endif
512582
583+ build_cavern();
584+ }
585+#endif /* ALLOW_CAVERNS_AND_LAKES */
586+
587+ /* Hack -- No destroyed "quest" levels */
588+ if (quest_number(dun_level)) dun->destroyed = FALSE;
589+}
590+
591+
592+
593+/*
594+ * Generate a new dungeon level
595+ *
596+ * Note that "dun_body" adds about 4000 bytes of memory to the stack.
597+ */
598+static bool cave_gen(void)
599+{
600+ int i, k, y, x;
513601
514602 dun_data dun_body;
515603
604+ /* Global data */
605+ dun = &dun_body;
606+
607+ dun->destroyed = FALSE;
608+ dun->empty_level = FALSE;
609+ dun->cavern = FALSE;
610+ dun->laketype = 0;
611+
516612 /* Fill the arrays of floors and walls in the good proportions */
517613 set_floor_and_wall(dungeon_type);
518614
@@ -524,14 +620,7 @@ static bool cave_gen(void)
524620 feat_wall_inner = d_info[dungeon_type].inner_wall;
525621 feat_wall_solid = d_info[dungeon_type].outer_wall;
526622
527- /* Global data */
528- dun = &dun_body;
529-
530- if (cur_hgt <= SCREEN_HGT / 2 - 2) max_vault_ok--;
531- if (cur_wid <= SCREEN_WID / 2 - 2) max_vault_ok--;
532-
533623 /* Randomize the dungeon creation values */
534- dun_rooms = rand_range(DUN_ROOMS_MIN, DUN_ROOMS_MAX);
535624 dun_tun_rnd = rand_range(DUN_TUN_RND_MIN, DUN_TUN_RND_MAX);
536625 dun_tun_chg = rand_range(DUN_TUN_CHG_MIN, DUN_TUN_CHG_MAX);
537626 dun_tun_con = rand_range(DUN_TUN_CON_MIN, DUN_TUN_CON_MAX);
@@ -551,16 +640,13 @@ static bool cave_gen(void)
551640 }
552641 }
553642
554- /* No "crowded" rooms yet */
555- dun->crowded = 0;
556-
557643 /* No rooms yet */
558644 dun->cent_n = 0;
559645
560646 /* Empty arena levels */
561647 if (ironman_empty_levels || ((d_info[dungeon_type].flags1 & DF1_ARENA) && (empty_levels && one_in_(EMPTY_LEVEL))))
562648 {
563- empty_level = TRUE;
649+ dun->empty_level = TRUE;
564650
565651 if (cheat_room)
566652 #ifdef JP
@@ -570,7 +656,7 @@ static bool cave_gen(void)
570656 #endif
571657 }
572658
573- if (empty_level)
659+ if (dun->empty_level)
574660 {
575661 /* Start with floors */
576662 for (y = 0; y < cur_hgt; y++)
@@ -607,96 +693,10 @@ static bool cave_gen(void)
607693 }
608694 }
609695
610-#ifdef ALLOW_CAVERNS_AND_LAKES
611- /* Possible "destroyed" level */
612- if ((dun_level > 30) && one_in_(DUN_DEST*2) && (small_levels) && (d_info[dungeon_type].flags1 & DF1_DESTROY))
613- {
614- destroyed = TRUE;
615696
616- /* extra rubble around the place looks cool */
617- build_lake(one_in_(2) ? GEN_LAKE_TYPE_CAVE : GEN_LAKE_TYPE_EARTH_VAULT);
618- }
697+ /* Generate various caverns and lakes */
698+ gen_caverns_and_lakes();
619699
620- /* Make a lake some of the time */
621- if (one_in_(LAKE_LEVEL) && !empty_level && !destroyed &&
622- (d_info[dungeon_type].flags1 & DF1_LAKE_MASK))
623- {
624- int count = 0;
625- if (d_info[dungeon_type].flags1 & DF1_LAKE_WATER) count += 3;
626- if (d_info[dungeon_type].flags1 & DF1_LAKE_LAVA) count += 3;
627- if (d_info[dungeon_type].flags1 & DF1_LAKE_RUBBLE) count += 3;
628- if (d_info[dungeon_type].flags1 & DF1_LAKE_TREE) count += 3;
629-
630- if (d_info[dungeon_type].flags1 & DF1_LAKE_LAVA)
631- {
632- /* Lake of Lava */
633- if ((dun_level > 80) && (randint0(count) < 2)) laketype = GEN_LAKE_TYPE_LAVA;
634- count -= 2;
635-
636- /* Lake of Lava2 */
637- if (!laketype && (dun_level > 80) && one_in_(count)) laketype = GEN_LAKE_TYPE_FIRE_VAULT;
638- count--;
639- }
640-
641- if ((d_info[dungeon_type].flags1 & DF1_LAKE_WATER) && !laketype)
642- {
643- /* Lake of Water */
644- if ((dun_level > 50) && randint0(count) < 2) laketype = GEN_LAKE_TYPE_WATER;
645- count -= 2;
646-
647- /* Lake of Water2 */
648- if (!laketype && (dun_level > 50) && one_in_(count)) laketype = GEN_LAKE_TYPE_WATER_VAULT;
649- count--;
650- }
651-
652- if ((d_info[dungeon_type].flags1 & DF1_LAKE_RUBBLE) && !laketype)
653- {
654- /* Lake of rubble */
655- if ((dun_level > 35) && (randint0(count) < 2)) laketype = GEN_LAKE_TYPE_CAVE;
656- count -= 2;
657-
658- /* Lake of rubble2 */
659- if (!laketype && (dun_level > 35) && one_in_(count)) laketype = GEN_LAKE_TYPE_EARTH_VAULT;
660- count--;
661- }
662-
663- /* Lake of tree */
664- if ((dun_level > 5) && (d_info[dungeon_type].flags1 & DF1_LAKE_TREE) && !laketype) laketype = GEN_LAKE_TYPE_AIR_VAULT;
665-
666- if (laketype)
667- {
668- if (cheat_room)
669-#ifdef JP
670- msg_print("湖を生成。");
671-#else
672- msg_print("Lake on the level.");
673-#endif
674-
675- build_lake(laketype);
676- }
677- }
678-
679- if ((dun_level > DUN_CAVERN) && !empty_level &&
680- (d_info[dungeon_type].flags1 & DF1_CAVERN) &&
681- !laketype && !destroyed && (randint1(1000) < dun_level))
682- {
683- cavern = TRUE;
684-
685- /* make a large fractal cave in the middle of the dungeon */
686-
687- if (cheat_room)
688-#ifdef JP
689- msg_print("洞窟を生成。");
690-#else
691- msg_print("Cavern on level.");
692-#endif
693-
694- build_cavern();
695- }
696-#endif /* ALLOW_CAVERNS_AND_LAKES */
697-
698- /* Hack -- No destroyed "quest" levels */
699- if (quest_number(dun_level)) destroyed = FALSE;
700700
701701 /* Build maze */
702702 if (d_info[dungeon_type].flags1 & DF1_MAZE)
@@ -713,136 +713,11 @@ static bool cave_gen(void)
713713 /* Build some rooms */
714714 else
715715 {
716- for (i = 0; i < dun_rooms; i++)
717- {
718- bool force_rooms = (ironman_rooms && !((d_info[dungeon_type].flags1 & DF1_BEGINNER) || (d_info[dungeon_type].flags1 & DF1_CHAMELEON)));
719-
720- /* Pick a block for the room */
721- y = randint0(dun->row_rooms);
722- x = randint0(dun->col_rooms);
723-
724- /* Align dungeon rooms */
725- if (d_info[dungeon_type].flags1 & DF1_NO_CAVE)
726- {
727- /* Slide some rooms right */
728- if ((x % 3) == 0) x++;
729-
730- /* Slide some rooms left */
731- if ((x % 3) == 2) x--;
732- }
716+ /*
717+ * Build each type of room in turn until we cannot build any more.
718+ */
719+ generate_rooms();
733720
734- /* Attempt an "unusual" room */
735- if (force_rooms || (randint0(DUN_UNUSUAL) < dun_level))
736- {
737- /* Roll for room type */
738- while (1)
739- {
740- k = (force_rooms ? 0 : randint0(100));
741- if (force_rooms) break;
742- if ((d_info[dungeon_type].flags1 & DF1_NO_VAULT) && (k < 14)) continue;
743- break;
744- }
745-
746- /* Attempt a very unusual room */
747- if (force_rooms || (randint0(DUN_UNUSUAL) < dun_level))
748- {
749-#ifdef FORCE_V_IDX
750- if (room_build(y, x, ROOM_BUILD_TYPE_GREATER_VAULT)) continue;
751-#else
752- /* Type 8 -- Greater vault (4%) */
753- if (k < 4)
754- {
755- if (max_vault_ok > 1)
756- {
757- if (room_build(y, x, ROOM_BUILD_TYPE_GREATER_VAULT)) continue;
758- }
759- else
760- {
761-#ifdef JP
762- if (cheat_room) msg_print("巨大な地下室を却下します。");
763-#else
764- if (cheat_room) msg_print("Refusing a greater vault.");
765-#endif
766- }
767- }
768-
769- /* Type 7 -- Lesser vault (6%) */
770- if (k < 10)
771- {
772- if (max_vault_ok > 0)
773- {
774- if (room_build(y, x, ROOM_BUILD_TYPE_LESSER_VAULT)) continue;
775- }
776- else
777- {
778-#ifdef JP
779- if (cheat_room) msg_print("小さな地下室を却下します。");
780-#else
781- if (cheat_room) msg_print("Refusing a lesser vault.");
782-#endif
783- }
784- }
785-
786-
787- /* Type 10 -- Random vault (4%) */
788- if ((k < 14) && room_build(y, x, ROOM_BUILD_TYPE_RANDOM_VAULT)) continue;
789-
790- /* Type 5 -- Monster nest (8%) */
791- if ((k < 22) && room_build(y, x, ROOM_BUILD_TYPE_NEST)) continue;
792-
793- /* Type 6 -- Monster pit (10%) */
794- if ((k < 32) && room_build(y, x, ROOM_BUILD_TYPE_PIT)) continue;
795-
796- /* Type 13 -- Trapped monster pit (5%) */
797- if ((k < 37) && room_build(y, x, ROOM_BUILD_TYPE_TRAP_PIT)) continue;
798-
799- /* Type 14 -- Trapped room (5%) */
800- if ((k < 42) && room_build(y, x, ROOM_BUILD_TYPE_TRAP)) continue;
801-#endif
802- }
803-
804- /* Type 2 -- Overlapping (25%) */
805- if ((k < 25) && room_build(y, x, ROOM_BUILD_TYPE_OVERLAP)) continue;
806-
807- /* Type 3 -- Cross room (25%) */
808- if ((k < 50) && room_build(y, x, ROOM_BUILD_TYPE_CROSS)) continue;
809-
810- if (d_info[dungeon_type].flags1 & DF1_NO_CAVE)
811- {
812- if (room_build(y, x, ROOM_BUILD_TYPE_INNER_FEAT)) continue;
813- }
814- else
815- {
816- /* Type 4 -- Large room (25%) */
817- if ((k < 75) && room_build(y, x, ROOM_BUILD_TYPE_INNER_FEAT)) continue;
818-
819- /* Type 11 -- Circular (10%) */
820- if ((k < 85) && room_build(y, x, ROOM_BUILD_TYPE_OVAL)) continue;
821-
822- /* Type 12 -- Crypt (15%) */
823- if ((k < 100) && room_build(y, x, ROOM_BUILD_TYPE_CRYPT)) continue;
824- }
825- }
826-
827- /* The deeper you are, the more cavelike the rooms are */
828- k = randint1(100);
829-
830- /* No caves when a cavern exists: they look bad */
831- if (((k < dun_level) || (d_info[dungeon_type].flags1 & DF1_CAVE))
832- && !cavern && !empty_level && !laketype
833- && !(d_info[dungeon_type].flags1 & DF1_NO_CAVE))
834- {
835- /* Type 9 -- Fractal cave */
836- if (room_build(y, x, ROOM_BUILD_TYPE_FRACAVE)) continue;
837- }
838- else
839- {
840- /* Attempt a "trivial" room */
841- if (room_build(y, x, ROOM_BUILD_TYPE_NORMAL)) continue;
842- }
843-
844- continue;
845- }
846721
847722 /* Make a hole in the dungeon roof sometimes at level 1 */
848723 if (dun_level == 1)
@@ -854,11 +729,13 @@ static bool cave_gen(void)
854729 }
855730
856731 /* Destroy the level if necessary */
857- if (destroyed) destroy_level();
732+ if (dun->destroyed) destroy_level();
858733
859734 /* Hack -- Add some rivers */
860735 if (one_in_(3) && (randint1(dun_level) > 5))
861736 {
737+ int feat1 = 0, feat2 = 0;
738+
862739 /* Choose water or lava */
863740 if ((randint1(MAX_DEPTH * 2) - 1 > dun_level) && (d_info[dungeon_type].flags1 & DF1_WATER_RIVER))
864741 {
@@ -874,9 +751,9 @@ static bool cave_gen(void)
874751
875752
876753 /* Only add river if matches lake type or if have no lake at all */
877- if ((((laketype == GEN_LAKE_TYPE_LAVA) && (feat1 == FEAT_DEEP_LAVA)) ||
878- ((laketype == GEN_LAKE_TYPE_WATER) && (feat1 == FEAT_DEEP_WATER)) ||
879- !laketype) && feat1)
754+ if ((((dun->laketype == LAKE_T_LAVA) && (feat1 == FEAT_DEEP_LAVA)) ||
755+ ((dun->laketype == LAKE_T_WATER) && (feat1 == FEAT_DEEP_WATER)) ||
756+ !dun->laketype) && feat1)
880757 {
881758 add_river(feat1, feat2);
882759 }
@@ -885,14 +762,15 @@ static bool cave_gen(void)
885762 /* Hack -- Scramble the room order */
886763 for (i = 0; i < dun->cent_n; i++)
887764 {
888- int pick1 = randint0(dun->cent_n);
889- int pick2 = randint0(dun->cent_n);
890- y1 = dun->cent[pick1].y;
891- x1 = dun->cent[pick1].x;
892- dun->cent[pick1].y = dun->cent[pick2].y;
893- dun->cent[pick1].x = dun->cent[pick2].x;
894- dun->cent[pick2].y = y1;
895- dun->cent[pick2].x = x1;
765+ int ty, tx;
766+ int pick = rand_range(0, i);
767+
768+ ty = dun->cent[i].y;
769+ tx = dun->cent[i].x;
770+ dun->cent[i].y = dun->cent[pick].y;
771+ dun->cent[i].x = dun->cent[pick].x;
772+ dun->cent[pick].y = ty;
773+ dun->cent[pick].x = tx;
896774 }
897775
898776 /* Start with no tunnel doors */
@@ -905,6 +783,8 @@ static bool cave_gen(void)
905783 /* Connect all the rooms together */
906784 for (i = 0; i < dun->cent_n; i++)
907785 {
786+ int j;
787+
908788 /* Reset the arrays */
909789 dun->tunn_n = 0;
910790 dun->wall_n = 0;
@@ -924,6 +804,8 @@ static bool cave_gen(void)
924804 /* Turn the tunnel into corridor */
925805 for (j = 0; j < dun->tunn_n; j++)
926806 {
807+ cave_type *c_ptr;
808+
927809 /* Access the grid */
928810 y = dun->tunn[j].y;
929811 x = dun->tunn[j].x;
@@ -945,6 +827,8 @@ static bool cave_gen(void)
945827 /* Apply the piercings that we found */
946828 for (j = 0; j < dun->wall_n; j++)
947829 {
830+ cave_type *c_ptr;
831+
948832 /* Access the grid */
949833 y = dun->wall[j].y;
950834 x = dun->wall[j].x;
@@ -992,7 +876,7 @@ static bool cave_gen(void)
992876 if (!alloc_stairs(FEAT_LESS, rand_range(1, 2), 3)) return FALSE;
993877 }
994878
995- if (!laketype)
879+ if (!dun->laketype)
996880 {
997881 if (d_info[dungeon_type].stream2)
998882 {
@@ -1093,7 +977,7 @@ msg_format("
1093977 /* Put the Guardian */
1094978 (void)alloc_guardian();
1095979
1096- if (empty_level && (!one_in_(DARK_EMPTY) || (randint1(100) > dun_level)) && !(d_info[dungeon_type].flags1 & DF1_DARKNESS))
980+ if (dun->empty_level && (!one_in_(DARK_EMPTY) || (randint1(100) > dun_level)) && !(d_info[dungeon_type].flags1 & DF1_DARKNESS))
1097981 {
1098982 /* Lite the cave */
1099983 for (y = 0; y < cur_hgt; y++)
--- a/src/generate.h
+++ b/src/generate.h
@@ -13,10 +13,6 @@
1313 #define DARK_EMPTY 5 /* 1/chance of arena level NOT being lit (2) */
1414 #define DUN_CAVERN 20 /* 1/chance of having a cavern level */
1515
16-/* Number of rooms to attempt (was 50) */
17-#define DUN_ROOMS_MIN 10
18-#define DUN_ROOMS_MAX 100
19-
2016 /*
2117 * Dungeon tunnel generation values
2218 */
@@ -139,8 +135,11 @@ struct dun_data
139135 /* Array of which blocks are used */
140136 bool room_map[MAX_ROOMS_ROW][MAX_ROOMS_COL];
141137
142- /* Hack -- there is a pit/nest on this level */
143- int crowded;
138+ /* Various type of dungeon floors */
139+ bool destroyed;
140+ bool empty_level;
141+ bool cavern;
142+ int laketype;
144143 };
145144
146145 extern dun_data *dun;
--- a/src/grid.c
+++ b/src/grid.c
@@ -446,7 +446,6 @@ void correct_dir(int *rdir, int *cdir, int y1, int x1, int y2, int x2)
446446 }
447447
448448
449-
450449 /*
451450 * Pick a random direction
452451 */
@@ -1147,3 +1146,4 @@ bool build_tunnel2(int x1, int y1, int x2, int y2, int type, int cutoff)
11471146 return TRUE;
11481147 }
11491148 }
1149+
--- a/src/rooms.c
+++ b/src/rooms.c
@@ -18,25 +18,58 @@
1818
1919
2020 /*
21- * Array of minimum room depths
21+ * [from SAngband (originally from OAngband)]
22+ *
23+ * Table of values that control how many times each type of room will
24+ * appear. Each type of room has its own row, and each column
25+ * corresponds to dungeon levels 0, 10, 20, and so on. The final
26+ * value is the minimum depth the room can appear at. -LM-
27+ *
28+ * Level 101 and below use the values for level 100.
29+ *
30+ * Rooms with lots of monsters or loot may not be generated if the
31+ * object or monster lists are already nearly full. Rooms will not
32+ * appear above their minimum depth. Tiny levels will not have space
33+ * for all the rooms you ask for.
2234 */
23-static s16b roomdep[] =
35+static room_info_type room_info_normal[ROOM_T_MAX] =
2436 {
25- 0, /* 0 = Nothing */
26- 1, /* 1 = Simple (33x11) */
27- 1, /* 2 = Overlapping (33x11) */
28- 3, /* 3 = Crossed (33x11) */
29- 3, /* 4 = Large (33x11) */
30- 10, /* 5 = Monster nest (33x11) */
31- 10, /* 6 = Monster pit (33x11) */
32- 10, /* 7 = Lesser vault (33x22) */
33- 20, /* 8 = Greater vault (66x44) */
34- 5, /* 9 = Fractal cave (42x24) */
35- 10, /* 10 = Random vault (44x22) */
36- 3, /* 11 = Circular rooms (22x22) */
37- 10, /* 12 = Crypts (22x22) */
38- 20, /* 13 = Trapped monster pit */
39- 20, /* 14 = Piranha/Armageddon trap room */
37+ /* Depth */
38+ /* 0 10 20 30 40 50 60 70 80 90 100 min limit */
39+
40+ {{999,900,800,700,600,500,400,300,200,100, 0}, 0}, /*NORMAL */
41+ {{ 1, 10, 20, 30, 40, 50, 60, 70, 80, 90,100}, 1}, /*OVERLAP */
42+ {{ 1, 10, 20, 30, 40, 50, 60, 70, 80, 90,100}, 3}, /*CROSS */
43+ {{ 1, 10, 20, 30, 40, 50, 60, 70, 80, 90,100}, 3}, /*INNER_F */
44+ {{ 0, 1, 1, 1, 2, 3, 5, 6, 8, 10, 13}, 10}, /*NEST */
45+ {{ 0, 1, 1, 2, 3, 4, 6, 8, 10, 13, 16}, 10}, /*PIT */
46+ {{ 0, 1, 1, 1, 2, 2, 3, 5, 6, 8, 10}, 10}, /*LESSER_V */
47+ {{ 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 6}, 20}, /*GREATER_V*/
48+ {{ 0,100,200,300,400,500,600,700,800,900,999}, 10}, /*FRACAVE */
49+ {{ 0, 1, 1, 1, 1, 2, 2, 3, 4, 5, 6}, 10}, /*RANDOM_V */
50+ {{ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40}, 3}, /*OVAL */
51+ {{ 1, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60}, 10}, /*CRYPT */
52+ {{ 0, 0, 1, 1, 1, 2, 3, 4, 5, 6, 8}, 20}, /*TRAP_PIT */
53+ {{ 0, 0, 1, 1, 1, 2, 3, 4, 5, 6, 8}, 20}, /*TRAP */
54+};
55+
56+
57+/* Build rooms in descending order of difficulty. */
58+static byte room_build_order[ROOM_T_MAX] = {
59+ ROOM_T_GREATER_VAULT,
60+ ROOM_T_RANDOM_VAULT,
61+ ROOM_T_LESSER_VAULT,
62+ ROOM_T_TRAP_PIT,
63+ ROOM_T_PIT,
64+ ROOM_T_NEST,
65+ ROOM_T_TRAP,
66+ ROOM_T_INNER_FEAT,
67+ ROOM_T_OVAL,
68+ ROOM_T_CRYPT,
69+ ROOM_T_OVERLAP,
70+ ROOM_T_CROSS,
71+ ROOM_T_FRACAVE,
72+ ROOM_T_NORMAL,
4073 };
4174
4275
@@ -201,92 +234,171 @@ static void check_room_boundary(int x1, int y1, int x2, int y2)
201234
202235
203236 /*
204- * This function is used to allocate the space needed by a room in the room_map
205- * array.
206- * x, y represent the size of the room (0...x-1) by (0...y-1).
207- * crowded is used to denote a monset nest.
208- * by0, bx0 are the positions in the room_map array given to the build_type'x'
209- * function.
210- * xx, yy are the returned center of the allocated room in coordinates for
211- * cave.feat and cave.info etc.
237+ * Find a good spot for the next room. -LM-
238+ *
239+ * Find and allocate a free space in the dungeon large enough to hold
240+ * the room calling this function.
241+ *
242+ * We allocate space in 11x11 blocks, but want to make sure that rooms
243+ * align neatly on the standard screen. Therefore, we make them use
244+ * blocks in few 11x33 rectangles as possible.
245+ *
246+ * Be careful to include the edges of the room in height and width!
247+ *
248+ * Return TRUE and values for the center of the room if all went well.
249+ * Otherwise, return FALSE.
212250 */
213-static bool room_alloc(int x, int y, bool crowded, int by0, int bx0, int *xx, int *yy)
251+static bool find_space(int *y, int *x, int height, int width)
214252 {
215- int temp, bx1, bx2, by1, by2, by, bx;
253+ int i;
254+ int by, bx, by1, bx1, by2, bx2;
255+ int block_y, block_x;
216256
217- /* Calculate number of room_map squares to allocate */
257+ bool filled;
218258
219- /* temp is total number along width */
220- temp = ((x - 1) / BLOCK_WID) + 1;
221259
222- /* bx2 = ending block */
223- bx2 = temp / 2 + bx0;
260+ /* Find out how many blocks we need. */
261+ int blocks_high = 1 + ((height - 1) / BLOCK_HGT);
262+ int blocks_wide = 1 + ((width - 1) / BLOCK_WID);
224263
225- /* bx1 = starting block (Note: rounding taken care of here.) */
226- bx1 = bx2 + 1 - temp;
264+ /* There are no way to allocate such huge space */
265+ if (dun->row_rooms < blocks_high) return FALSE;
266+ if (dun->col_rooms < blocks_wide) return FALSE;
227267
228- /* temp is total number along height */
229- temp = ((y - 1) / BLOCK_HGT) + 1;
268+ /* Sometimes, little rooms like to have more space. */
269+ if (blocks_wide == 2)
270+ {
271+ if (one_in_(3)) blocks_wide = 3;
272+ }
273+ else if (blocks_wide == 1)
274+ {
275+ if (one_in_(2)) blocks_wide = rand_range(2, 3);
276+ }
230277
231- /* by2 = ending block */
232- by2 = temp / 2 + by0;
233278
234- /* by1 = starting block */
235- by1 = by2 + 1 - temp;
279+ /* We'll allow twenty-five guesses. */
280+ for (i = 0; i < 25; i++)
281+ {
282+ filled = FALSE;
236283
284+ /* Pick a top left block at random */
285+ block_y = randint0(dun->row_rooms - blocks_high);
286+ block_x = randint0(dun->col_rooms - blocks_wide);
237287
238- /* Never run off the screen */
239- if ((by1 < 0) || (by2 >= dun->row_rooms)) return (FALSE);
240- if ((bx1 < 0) || (bx2 >= dun->col_rooms)) return (FALSE);
241288
242- /* Verify open space */
243- for (by = by1; by <= by2; by++)
244- {
245- for (bx = bx1; bx <= bx2; bx++)
289+ /* Itty-bitty rooms can shift about within their rectangle */
290+ if (blocks_wide < 3)
246291 {
247- if (dun->room_map[by][bx]) return (FALSE);
292+ /* Rooms that straddle a border must shift. */
293+ if ((blocks_wide == 2) && ((block_x % 3) == 2))
294+ {
295+ if (one_in_(2)) block_x--;
296+ else block_x++;
297+ }
248298 }
249- }
250299
251- /* It is *extremely* important that the following calculation */
252- /* be *exactly* correct to prevent memory errors XXX XXX XXX */
300+ /* Rooms with width divisible by 3 get fitted to a rectangle. */
301+ else if ((blocks_wide % 3) == 0)
302+ {
303+ /* Align to the left edge of a 11x33 rectangle. */
304+ if ((block_x % 3) == 2) block_x++;
305+ if ((block_x % 3) == 1) block_x--;
306+ }
307+
308+ /*
309+ * Big rooms that do not have a width divisible by 3 get
310+ * aligned towards the edge of the dungeon closest to them.
311+ */
312+ else
313+ {
314+ /* Shift towards left edge of dungeon. */
315+ if (block_x + (blocks_wide / 2) <= dun->col_rooms / 2)
316+ {
317+ if (((block_x % 3) == 2) && ((blocks_wide % 3) == 2))
318+ block_x--;
319+ if ((block_x % 3) == 1) block_x--;
320+ }
321+
322+ /* Shift toward right edge of dungeon. */
323+ else
324+ {
325+ if (((block_x % 3) == 2) && ((blocks_wide % 3) == 2))
326+ block_x++;
327+ if ((block_x % 3) == 1) block_x++;
328+ }
329+ }
253330
254- /* Acquire the location of the room */
255- *yy = ((by1 + by2 + 1) * BLOCK_HGT) / 2;
256- *xx = ((bx1 + bx2 + 1) * BLOCK_WID) / 2;
331+ /* Extract blocks */
332+ by1 = block_y + 0;
333+ bx1 = block_x + 0;
334+ by2 = block_y + blocks_high;
335+ bx2 = block_x + blocks_wide;
257336
337+ /* Never run off the screen */
338+ if ((by1 < 0) || (by2 > dun->row_rooms)) continue;
339+ if ((bx1 < 0) || (bx2 > dun->col_rooms)) continue;
258340
259- /* Save the room location */
260- if (dun->cent_n < CENT_MAX)
261- {
262- dun->cent[dun->cent_n].y = *yy;
263- dun->cent[dun->cent_n].x = *xx;
264- dun->cent_n++;
265- }
341+ /* Verify available space */
342+ for (by = by1; by < by2; by++)
343+ {
344+ for (bx = bx1; bx < bx2; bx++)
345+ {
346+ if (dun->room_map[by][bx])
347+ {
348+ filled = TRUE;
349+ }
350+ }
351+ }
266352
267- /* Reserve some blocks */
268- for (by = by1; by <= by2; by++)
269- {
270- for (bx = bx1; bx <= bx2; bx++)
353+ /* If space filled, try again. */
354+ if (filled) continue;
355+
356+
357+ /* It is *extremely* important that the following calculation */
358+ /* be *exactly* correct to prevent memory errors XXX XXX XXX */
359+
360+ /* Acquire the location of the room */
361+ (*y) = ((by1 + by2) * BLOCK_HGT) / 2;
362+ (*x) = ((bx1 + bx2) * BLOCK_WID) / 2;
363+
364+ /* Save the room location */
365+ if (dun->cent_n < CENT_MAX)
271366 {
272- dun->room_map[by][bx] = TRUE;
367+ dun->cent[dun->cent_n].y = *y;
368+ dun->cent[dun->cent_n].x = *x;
369+ dun->cent_n++;
273370 }
274- }
275371
276- /* Count "crowded" rooms */
277- if (crowded) dun->crowded++;
372+ /* Reserve some blocks. */
373+ for (by = by1; by < by2; by++)
374+ {
375+ for (bx = bx1; bx < bx2; bx++)
376+ {
377+ dun->room_map[by][bx] = TRUE;
378+ }
379+ }
278380
279- /*
280- * Hack- See if room will cut off a cavern.
281- * If so, fix by tunneling outside the room in such a way as to connect the caves.
282- */
283- check_room_boundary(*xx - x / 2 - 1, *yy - y / 2 - 1,
284- *xx + (x - 1) / 2 + 1, *yy + (y - 1) / 2 + 1);
285381
286- /* Success */
287- return (TRUE);
382+ /*
383+ * Hack- See if room will cut off a cavern.
384+ *
385+ * If so, fix by tunneling outside the room in such a
386+ * way as to connect the caves.
387+ */
388+ check_room_boundary(*x - width / 2 - 1, *y - height / 2 - 1, *x + (width - 1) / 2 + 1, *y + (height - 1) / 2 + 1);
389+
390+
391+ /* Success. */
392+ return (TRUE);
393+ }
394+
395+ /* Failure. */
396+ return (FALSE);
288397 }
289398
399+
400+
401+
290402 /*
291403 * Room building routines.
292404 *
@@ -311,7 +423,7 @@ static bool room_alloc(int x, int y, bool crowded, int by0, int bx0, int *xx, in
311423 /*
312424 * Type 1 -- normal rectangular rooms
313425 */
314-static void build_type1(int by0, int bx0)
426+static bool build_type1(void)
315427 {
316428 int y, x, y2, x2, yval, xval;
317429 int y1, x1, xsize, ysize;
@@ -329,8 +441,8 @@ static void build_type1(int by0, int bx0)
329441 xsize = x1 + x2 + 1;
330442 ysize = y1 + y2 + 1;
331443
332- /* Try to allocate space for room. If fails, exit */
333- if (!room_alloc(xsize + 2, ysize + 2, FALSE, by0, bx0, &xval, &yval)) return;
444+ /* Find and reserve some space in the dungeon. Get center of room. */
445+ if (!find_space(&yval, &xval, ysize + 2, xsize + 2)) return FALSE;
334446
335447 /* Choose lite or dark */
336448 light = ((dun_level <= randint1(25)) && !(d_info[dungeon_type].flags1 & DF1_DARKNESS));
@@ -452,13 +564,15 @@ static void build_type1(int by0, int bx0)
452564
453565 place_random_door(yval, xval, TRUE);
454566 }
567+
568+ return TRUE;
455569 }
456570
457571
458572 /*
459573 * Type 2 -- Overlapping rectangular rooms
460574 */
461-static void build_type2(int by0, int bx0)
575+static bool build_type2(void)
462576 {
463577 int y, x, xval, yval;
464578 int y1a, x1a, y2a, x2a;
@@ -466,9 +580,8 @@ static void build_type2(int by0, int bx0)
466580 bool light;
467581 cave_type *c_ptr;
468582
469-
470- /* Try to allocate space for room. If fails, exit */
471- if (!room_alloc(25, 11, FALSE, by0, bx0, &xval, &yval)) return;
583+ /* Find and reserve some space in the dungeon. Get center of room. */
584+ if (!find_space(&yval, &xval, 11, 25)) return FALSE;
472585
473586 /* Choose lite or dark */
474587 light = ((dun_level <= randint1(25)) && !(d_info[dungeon_type].flags1 & DF1_DARKNESS));
@@ -564,6 +677,8 @@ static void build_type2(int by0, int bx0)
564677 place_floor_grid(c_ptr);
565678 }
566679 }
680+
681+ return TRUE;
567682 }
568683
569684
@@ -580,7 +695,7 @@ static void build_type2(int by0, int bx0)
580695 * the code below will work (with "bounds checking") for 5x5, or even
581696 * for unsymetric values like 4x3 or 5x3 or 3x4 or 3x5, or even larger.
582697 */
583-static void build_type3(int by0, int bx0)
698+static bool build_type3(void)
584699 {
585700 int y, x, dy, dx, wy, wx;
586701 int y1a, x1a, y2a, x2a;
@@ -590,8 +705,9 @@ static void build_type3(int by0, int bx0)
590705 cave_type *c_ptr;
591706
592707
593- /* Try to allocate space for room. */
594- if (!room_alloc(25, 11, FALSE, by0, bx0, &xval, &yval)) return;
708+ /* Find and reserve some space in the dungeon. Get center of room. */
709+ if (!find_space(&yval, &xval, 11, 25)) return FALSE;
710+
595711
596712 /* Choose lite or dark */
597713 light = ((dun_level <= randint1(25)) && !(d_info[dungeon_type].flags1 & DF1_DARKNESS));
@@ -817,6 +933,8 @@ static void build_type3(int by0, int bx0)
817933 break;
818934 }
819935 }
936+
937+ return TRUE;
820938 }
821939
822940
@@ -830,7 +948,7 @@ static void build_type3(int by0, int bx0)
830948 * 4 - Inner room has a maze
831949 * 5 - A set of four inner rooms
832950 */
833-static void build_type4(int by0, int bx0)
951+static bool build_type4(void)
834952 {
835953 int y, x, y1, x1;
836954 int y2, x2, tmp, yval, xval;
@@ -838,8 +956,8 @@ static void build_type4(int by0, int bx0)
838956 cave_type *c_ptr;
839957
840958
841- /* Try to allocate space for room. */
842- if (!room_alloc(25, 11, FALSE, by0, bx0, &xval, &yval)) return;
959+ /* Find and reserve some space in the dungeon. Get center of room. */
960+ if (!find_space(&yval, &xval, 11, 25)) return FALSE;
843961
844962 /* Choose lite or dark */
845963 light = ((dun_level <= randint1(25)) && !(d_info[dungeon_type].flags1 & DF1_DARKNESS));
@@ -1135,6 +1253,8 @@ static void build_type4(int by0, int bx0)
11351253 break;
11361254 }
11371255 }
1256+
1257+ return TRUE;
11381258 }
11391259
11401260
@@ -1688,9 +1808,6 @@ static int pick_vault_type(vault_aux_type *l_ptr, s16b allow_flag_mask)
16881808 return n_ptr->name ? count : -1;
16891809 }
16901810
1691-static void build_type6(int by0, int bx0, bool nest);
1692-static void build_type5(int by0, int bx0, bool nest);
1693-
16941811 static vault_aux_type nest_types[] =
16951812 {
16961813 #ifdef JP
@@ -1921,7 +2038,7 @@ static void ang_sort_swap_nest_mon_info(vptr u, vptr v, int a, int b)
19212038 *
19222039 * Note that "monster nests" will never contain "unique" monsters.
19232040 */
1924-static void build_type5(int by0, int bx0, bool pit)
2041+static bool build_type5(void)
19252042 {
19262043 int y, x, y1, x1, y2, x2, xval, yval;
19272044 int i;
@@ -1934,18 +2051,13 @@ static void build_type5(int by0, int bx0, bool pit)
19342051 int cur_nest_type = pick_vault_type(nest_types, d_info[dungeon_type].nest);
19352052 vault_aux_type *n_ptr;
19362053
1937- /* Try to allocate space for room. */
1938- if (!room_alloc(25, 11, TRUE, by0, bx0, &xval, &yval)) return;
2054+ /* Find and reserve some space in the dungeon. Get center of room. */
2055+ if (!find_space(&yval, &xval, 11, 25)) return FALSE;
19392056
19402057 /* No type available */
19412058 if (cur_nest_type < 0)
19422059 {
1943- if (pit) return;
1944- else
1945- {
1946- build_type6(by0, bx0, TRUE);
1947- return;
1948- }
2060+ return FALSE;
19492061 }
19502062
19512063 n_ptr = &nest_types[cur_nest_type];
@@ -2053,7 +2165,7 @@ static void build_type5(int by0, int bx0, bool pit)
20532165 }
20542166
20552167 /* Notice failure */
2056- if (!r_idx || !attempts) return;
2168+ if (!r_idx || !attempts) return FALSE;
20572169
20582170 /* Note the alignment */
20592171 if (r_ptr->flags3 & RF3_EVIL) align.sub_align |= SUB_ALIGN_EVIL;
@@ -2118,6 +2230,8 @@ static void build_type5(int by0, int bx0, bool pit)
21182230 msg_print(r_name + r_info[nest_mon_info[i].r_idx].name);
21192231 }
21202232 }
2233+
2234+ return TRUE;
21212235 }
21222236
21232237
@@ -2157,7 +2271,7 @@ static void build_type5(int by0, int bx0, bool pit)
21572271 *
21582272 * Note that "monster pits" will never contain "unique" monsters.
21592273 */
2160-static void build_type6(int by0, int bx0, bool nest)
2274+static bool build_type6(void)
21612275 {
21622276 int y, x, y1, x1, y2, x2, xval, yval;
21632277 int i, j;
@@ -2171,18 +2285,13 @@ static void build_type6(int by0, int bx0, bool nest)
21712285 int cur_pit_type = pick_vault_type(pit_types, d_info[dungeon_type].pit);
21722286 vault_aux_type *n_ptr;
21732287
2174- /* Try to allocate space for room. */
2175- if (!room_alloc(25, 11, TRUE, by0, bx0, &xval, &yval)) return;
2288+ /* Find and reserve some space in the dungeon. Get center of room. */
2289+ if (!find_space(&yval, &xval, 11, 25)) return FALSE;
21762290
21772291 /* No type available */
21782292 if (cur_pit_type < 0)
21792293 {
2180- if (nest) return;
2181- else
2182- {
2183- build_type5(by0, bx0, TRUE);
2184- return;
2185- }
2294+ return FALSE;
21862295 }
21872296
21882297 n_ptr = &pit_types[cur_pit_type];
@@ -2287,7 +2396,7 @@ static void build_type6(int by0, int bx0, bool nest)
22872396 }
22882397
22892398 /* Notice failure */
2290- if (!r_idx || !attempts) return;
2399+ if (!r_idx || !attempts) return FALSE;
22912400
22922401 /* Note the alignment */
22932402 if (r_ptr->flags3 & RF3_EVIL) align.sub_align |= SUB_ALIGN_EVIL;
@@ -2399,6 +2508,8 @@ static void build_type6(int by0, int bx0, bool nest)
23992508
24002509 /* Center monster */
24012510 place_monster_aux(0, yval, xval, what[7], PM_NO_KAGE);
2511+
2512+ return TRUE;
24022513 }
24032514
24042515
@@ -2417,7 +2528,7 @@ static void coord_trans(int *x, int *y, int xoffset, int yoffset, int transno)
24172528 * be expressed simply in terms of swapping and inverting the
24182529 * x and y coordinates.
24192530 */
2420- for (i = 0; i <= transno % 4; i++)
2531+ for (i = 0; i < transno % 4; i++)
24212532 {
24222533 /* rotate by 90 degrees */
24232534 temp = *x;
@@ -2463,7 +2574,7 @@ static void build_vault(int yval, int xval, int ymax, int xmax, cptr data,
24632574 coord_trans(&i, &j, xoffset, yoffset, transno);
24642575
24652576 /* Extract the location */
2466- if (transno%2)
2577+ if (transno % 2 == 0)
24672578 {
24682579 /* no swap of x/y */
24692580 x = xval - (xmax / 2) + i;
@@ -2592,7 +2703,7 @@ static void build_vault(int yval, int xval, int ymax, int xmax, cptr data,
25922703 coord_trans(&i, &j, xoffset, yoffset, transno);
25932704
25942705 /* Extract the location */
2595- if (transno % 2)
2706+ if (transno % 2 == 0)
25962707 {
25972708 /* no swap of x/y */
25982709 x = xval - (xmax / 2) + i;
@@ -2680,7 +2791,7 @@ static void build_vault(int yval, int xval, int ymax, int xmax, cptr data,
26802791 /*
26812792 * Type 7 -- simple vaults (see "v_info.txt")
26822793 */
2683-static void build_type7(int by0, int bx0)
2794+static bool build_type7(void)
26842795 {
26852796 vault_type *v_ptr = NULL;
26862797 int dummy = 0;
@@ -2702,7 +2813,7 @@ static void build_type7(int by0, int bx0)
27022813 }
27032814
27042815 /* No lesser vault found */
2705- if (!v_ptr) return;
2816+ if (!v_ptr) return FALSE;
27062817
27072818 /* pick type of transformation (0-7) */
27082819 transno = randint0(8);
@@ -2711,6 +2822,13 @@ static void build_type7(int by0, int bx0)
27112822 x = v_ptr->wid;
27122823 y = v_ptr->hgt;
27132824
2825+ /* Some huge vault cannot be ratated to fit in the dungeon */
2826+ if (x+2 > cur_hgt-2)
2827+ {
2828+ /* Forbid 90 or 270 degree ratation */
2829+ transno &= ~1;
2830+ }
2831+
27142832 coord_trans(&x, &y, 0, 0, transno);
27152833
27162834 if (x < 0)
@@ -2731,8 +2849,10 @@ static void build_type7(int by0, int bx0)
27312849 yoffset = 0;
27322850 }
27332851
2734- /* Try to allocate space for room. */
2735- if (!room_alloc(abs(x), abs(y), FALSE, by0, bx0, &xval, &yval)) return;
2852+
2853+ /* Find and reserve some space in the dungeon. Get center of room. */
2854+ if (!find_space(&yval, &xval, abs(y), abs(x))) return FALSE;
2855+
27362856
27372857 if (dummy >= SAFE_MAX_ATTEMPTS)
27382858 {
@@ -2745,7 +2865,7 @@ msg_print("
27452865 #endif
27462866
27472867 }
2748- return;
2868+ return FALSE;
27492869 }
27502870
27512871
@@ -2769,13 +2889,15 @@ msg_print("
27692889 /* Hack -- Build the vault */
27702890 build_vault(yval, xval, v_ptr->hgt, v_ptr->wid,
27712891 v_text + v_ptr->text, xoffset, yoffset, transno);
2892+
2893+ return TRUE;
27722894 }
27732895
27742896
27752897 /*
27762898 * Type 8 -- greater vaults (see "v_info.txt")
27772899 */
2778-static void build_type8(int by0, int bx0)
2900+static bool build_type8(void)
27792901 {
27802902 vault_type *v_ptr = NULL;
27812903 int dummy = 0;
@@ -2797,7 +2919,7 @@ static void build_type8(int by0, int bx0)
27972919 }
27982920
27992921 /* No greater vault found */
2800- if (!v_ptr) return;
2922+ if (!v_ptr) return FALSE;
28012923
28022924 /* pick type of transformation (0-7) */
28032925 transno = randint0(8);
@@ -2806,6 +2928,13 @@ static void build_type8(int by0, int bx0)
28062928 x = v_ptr->wid;
28072929 y = v_ptr->hgt;
28082930
2931+ /* Some huge vault cannot be ratated to fit in the dungeon */
2932+ if (x+2 > cur_hgt-2)
2933+ {
2934+ /* Forbid 90 or 270 degree ratation */
2935+ transno &= ~1;
2936+ }
2937+
28092938 coord_trans(&x, &y, 0, 0, transno);
28102939
28112940 if (x < 0)
@@ -2832,7 +2961,9 @@ static void build_type8(int by0, int bx0)
28322961 * Hack -- Prepare a bit larger space (+2, +2) to
28332962 * prevent generation of vaults with no-entrance.
28342963 */
2835- if (!room_alloc(abs(x) + 2, abs(y) + 2, FALSE, by0, bx0, &xval, &yval)) return;
2964+ /* Find and reserve some space in the dungeon. Get center of room. */
2965+ if (!find_space(&yval, &xval, abs(y) + 2, abs(x) + 2)) return FALSE;
2966+
28362967
28372968 if (dummy >= SAFE_MAX_ATTEMPTS)
28382969 {
@@ -2845,7 +2976,7 @@ msg_print("
28452976 #endif
28462977
28472978 }
2848- return;
2979+ return FALSE;
28492980 }
28502981
28512982
@@ -2869,6 +3000,8 @@ msg_print("
28693000 /* Hack -- Build the vault */
28703001 build_vault(yval, xval, v_ptr->hgt, v_ptr->wid,
28713002 v_text + v_ptr->text, xoffset, yoffset, transno);
3003+
3004+ return TRUE;
28723005 }
28733006
28743007 /*
@@ -3519,7 +3652,7 @@ static bool generate_fracave(int y0, int x0, int xsize, int ysize, int cutoff, b
35193652 /*
35203653 * Driver routine to create fractal cave system
35213654 */
3522-static void build_type9(int by0, int bx0)
3655+static bool build_type9(void)
35233656 {
35243657 int grd, roug, cutoff, xsize, ysize, y0, x0;
35253658
@@ -3529,8 +3662,8 @@ static void build_type9(int by0, int bx0)
35293662 xsize = randint1(22) * 2 + 6;
35303663 ysize = randint1(15) * 2 + 6;
35313664
3532- /* Try to allocate space for room. If fails, exit */
3533- if (!room_alloc(xsize + 1, ysize + 1, FALSE, by0, bx0, &x0, &y0)) return;
3665+ /* Find and reserve some space in the dungeon. Get center of room. */
3666+ if (!find_space(&y0, &x0, ysize + 1, xsize + 1)) return FALSE;
35343667
35353668 light = done = FALSE;
35363669 room = TRUE;
@@ -3558,6 +3691,8 @@ static void build_type9(int by0, int bx0)
35583691 /* Convert to normal format + clean up */
35593692 done = generate_fracave(y0, x0, xsize, ysize, cutoff, light, room);
35603693 }
3694+
3695+ return TRUE;
35613696 }
35623697
35633698 #ifdef ALLOW_CAVERNS_AND_LAKES
@@ -3613,37 +3748,37 @@ static bool generate_lake(int y0, int x0, int xsize, int ysize, int c1, int c2,
36133748 /* Get features based on type */
36143749 switch (type)
36153750 {
3616- case GEN_LAKE_TYPE_LAVA: /* Lava */
3751+ case LAKE_T_LAVA: /* Lava */
36173752 feat1 = FEAT_DEEP_LAVA;
36183753 feat2 = FEAT_SHAL_LAVA;
36193754 feat3 = floor_type[randint0(100)];
36203755 break;
3621- case GEN_LAKE_TYPE_WATER: /* Water */
3756+ case LAKE_T_WATER: /* Water */
36223757 feat1 = FEAT_DEEP_WATER;
36233758 feat2 = FEAT_SHAL_WATER;
36243759 feat3 = floor_type[randint0(100)];
36253760 break;
3626- case GEN_LAKE_TYPE_CAVE: /* Collapsed cave */
3761+ case LAKE_T_CAVE: /* Collapsed cave */
36273762 feat1 = floor_type[randint0(100)];
36283763 feat2 = floor_type[randint0(100)];
36293764 feat3 = FEAT_RUBBLE;
36303765 break;
3631- case GEN_LAKE_TYPE_EARTH_VAULT: /* Earth vault */
3766+ case LAKE_T_EARTH_VAULT: /* Earth vault */
36323767 feat1 = FEAT_RUBBLE;
36333768 feat2 = floor_type[randint0(100)];
36343769 feat3 = FEAT_RUBBLE;
36353770 break;
3636- case GEN_LAKE_TYPE_AIR_VAULT: /* Air vault */
3771+ case LAKE_T_AIR_VAULT: /* Air vault */
36373772 feat1 = FEAT_GRASS;
36383773 feat2 = FEAT_TREES;
36393774 feat3 = FEAT_GRASS;
36403775 break;
3641- case GEN_LAKE_TYPE_WATER_VAULT: /* Water vault */
3776+ case LAKE_T_WATER_VAULT: /* Water vault */
36423777 feat1 = FEAT_SHAL_WATER;
36433778 feat2 = FEAT_DEEP_WATER;
36443779 feat3 = FEAT_SHAL_WATER;
36453780 break;
3646- case GEN_LAKE_TYPE_FIRE_VAULT: /* Fire Vault */
3781+ case LAKE_T_FIRE_VAULT: /* Fire Vault */
36473782 feat1 = FEAT_SHAL_LAVA;
36483783 feat2 = FEAT_DEEP_LAVA;
36493784 feat3 = FEAT_SHAL_LAVA;
@@ -3756,7 +3891,7 @@ void build_lake(int type)
37563891 int c1, c2, c3;
37573892
37583893 /* paranoia - exit if lake type out of range. */
3759- if ((type < GEN_LAKE_TYPE_LAVA) || (type > GEN_LAKE_TYPE_FIRE_VAULT))
3894+ if ((type < LAKE_T_LAVA) || (type > LAKE_T_FIRE_VAULT))
37603895 {
37613896 msg_format("Invalid lake type (%d)", type);
37623897 return;
@@ -4481,7 +4616,7 @@ void build_maze_vault(int x0, int y0, int xsize, int ysize, bool is_vault)
44814616 * a way to get in even if the vault abuts a side of the dungeon.
44824617 */
44834618 static void build_mini_c_vault(int x0, int y0, int xsize, int ysize)
4484- {
4619+{
44854620 int dy, dx;
44864621 int y1, x1, y2, x2, y, x, total;
44874622 int m, n, num_vertices;
@@ -4506,7 +4641,7 @@ static void build_mini_c_vault(int x0, int y0, int xsize, int ysize)
45064641
45074642 cave[y1-2][x].info |= (CAVE_ROOM | CAVE_ICKY);
45084643
4509- place_extra_noperm_bold(y1-2, x);
4644+ place_outer_noperm_bold(y1-2, x);
45104645 }
45114646
45124647 for (x = x1 - 2; x <= x2 + 2; x++)
@@ -4515,7 +4650,7 @@ static void build_mini_c_vault(int x0, int y0, int xsize, int ysize)
45154650
45164651 cave[y2+2][x].info |= (CAVE_ROOM | CAVE_ICKY);
45174652
4518- place_extra_noperm_bold(y2+2, x);
4653+ place_outer_noperm_bold(y2+2, x);
45194654 }
45204655
45214656 for (y = y1 - 2; y <= y2 + 2; y++)
@@ -4524,7 +4659,7 @@ static void build_mini_c_vault(int x0, int y0, int xsize, int ysize)
45244659
45254660 cave[y][x1-2].info |= (CAVE_ROOM | CAVE_ICKY);
45264661
4527- place_extra_noperm_bold(y, x1-2);
4662+ place_outer_noperm_bold(y, x1-2);
45284663 }
45294664
45304665 for (y = y1 - 2; y <= y2 + 2; y++)
@@ -4533,17 +4668,21 @@ static void build_mini_c_vault(int x0, int y0, int xsize, int ysize)
45334668
45344669 cave[y][x2+2].info |= (CAVE_ROOM | CAVE_ICKY);
45354670
4536- place_extra_noperm_bold(y, x2+2);
4671+ place_outer_noperm_bold(y, x2+2);
45374672 }
45384673
45394674 for (y = y1 - 1; y <= y2 + 1; y++)
45404675 {
45414676 for (x = x1 - 1; x <= x2 + 1; x++)
45424677 {
4543- cave[y][x].info |= (CAVE_ROOM | CAVE_ICKY);
4678+ cave_type *c_ptr = &cave[y][x];
4679+
4680+ c_ptr->info |= (CAVE_ROOM | CAVE_ICKY);
45444681
45454682 /* Permanent walls */
4546- cave[y][x].feat = FEAT_PERM_INNER;
4683+ c_ptr->feat = FEAT_PERM_INNER;
4684+ c_ptr->info &= ~(CAVE_MASK);
4685+ c_ptr->info |= CAVE_INNER;
45474686 }
45484687 }
45494688
@@ -4578,15 +4717,15 @@ static void build_mini_c_vault(int x0, int y0, int xsize, int ysize)
45784717 {
45794718 /* left and right */
45804719 y = randint1(dy) + dy / 2;
4581- place_outer_noperm_bold(y1 + y, x1 - 1);
4582- place_outer_noperm_bold(y1 + y, x2 + 1);
4720+ place_inner_bold(y1 + y, x1 - 1);
4721+ place_inner_bold(y1 + y, x2 + 1);
45834722 }
45844723 else
45854724 {
45864725 /* top and bottom */
45874726 x = randint1(dx) + dx / 2;
4588- place_outer_noperm_bold(y1 - 1, x1 + x);
4589- place_outer_noperm_bold(y2 + 1, x1 + x);
4727+ place_inner_bold(y1 - 1, x1 + x);
4728+ place_inner_bold(y2 + 1, x1 + x);
45904729 }
45914730
45924731 /* Fill with monsters and treasure, highest difficulty */
@@ -5069,22 +5208,22 @@ static void build_elemental_vault(int x0, int y0, int xsiz, int ysiz)
50695208 if (dun_level < 25)
50705209 {
50715210 /* Earth vault (Rubble) */
5072- type = GEN_LAKE_TYPE_EARTH_VAULT;
5211+ type = LAKE_T_EARTH_VAULT;
50735212 }
50745213 else if (dun_level < 50)
50755214 {
50765215 /* Air vault (Trees) */
5077- type = GEN_LAKE_TYPE_AIR_VAULT;
5216+ type = LAKE_T_AIR_VAULT;
50785217 }
50795218 else if (dun_level < 75)
50805219 {
50815220 /* Water vault (shallow water) */
5082- type = GEN_LAKE_TYPE_WATER_VAULT;
5221+ type = LAKE_T_WATER_VAULT;
50835222 }
50845223 else
50855224 {
50865225 /* Fire vault (shallow lava) */
5087- type = GEN_LAKE_TYPE_FIRE_VAULT;
5226+ type = LAKE_T_FIRE_VAULT;
50885227 }
50895228
50905229 while (!done)
@@ -5138,7 +5277,7 @@ static void build_elemental_vault(int x0, int y0, int xsiz, int ysiz)
51385277 /*
51395278 * Random vaults
51405279 */
5141-static void build_type10(int by0, int bx0)
5280+static bool build_type10(void)
51425281 {
51435282 int y0, x0, xsize, ysize, vtype;
51445283
@@ -5147,8 +5286,8 @@ static void build_type10(int by0, int bx0)
51475286 xsize = randint1(22) + 22;
51485287 ysize = randint1(11) + 11;
51495288
5150- /* Allocate in room_map. If will not fit, exit */
5151- if (!room_alloc(xsize + 1, ysize + 1, FALSE, by0, bx0, &x0, &y0)) return;
5289+ /* Find and reserve some space in the dungeon. Get center of room. */
5290+ if (!find_space(&y0, &x0, ysize + 1, xsize + 1)) return FALSE;
51525291
51535292 /* Boost the rating- higher than lesser vaults and lower than greater vaults */
51545293 rating += 10;
@@ -5183,8 +5322,10 @@ static void build_type10(int by0, int bx0)
51835322 /* I know how to add a few more... give me some time. */
51845323
51855324 /* Paranoia */
5186- default: return;
5325+ default: return FALSE;
51875326 }
5327+
5328+ return TRUE;
51885329 }
51895330
51905331
@@ -5195,7 +5336,7 @@ static void build_type10(int by0, int bx0)
51955336 *
51965337 * When done fill from the inside to find the walls,
51975338 */
5198-static void build_type11(int by0, int bx0)
5339+static bool build_type11(void)
51995340 {
52005341 int rad, x, y, x0, y0;
52015342 int light = FALSE;
@@ -5205,8 +5346,8 @@ static void build_type11(int by0, int bx0)
52055346
52065347 rad = randint0(9);
52075348
5208- /* Allocate in room_map. If will not fit, exit */
5209- if (!room_alloc(rad * 2 + 1, rad * 2 + 1, FALSE, by0, bx0, &x0, &y0)) return;
5349+ /* Find and reserve some space in the dungeon. Get center of room. */
5350+ if (!find_space(&y0, &x0, rad * 2 + 1, rad * 2 + 1)) return FALSE;
52105351
52115352 /* Make circular floor */
52125353 for (x = x0 - rad; x <= x0 + rad; x++)
@@ -5228,6 +5369,8 @@ static void build_type11(int by0, int bx0)
52285369
52295370 /* Find visible outer walls and set to be FEAT_OUTER */
52305371 add_outer_wall(x0, y0, light, x0 - rad, y0 - rad, x0 + rad, y0 + rad);
5372+
5373+ return TRUE;
52315374 }
52325375
52335376
@@ -5238,8 +5381,8 @@ static void build_type11(int by0, int bx0)
52385381 *
52395382 * When done fill from the inside to find the walls,
52405383 */
5241-static void build_type12(int by0, int bx0)
5242- {
5384+static bool build_type12(void)
5385+{
52435386 int rad, x, y, x0, y0;
52445387 int light = FALSE;
52455388 bool emptyflag = TRUE;
@@ -5256,8 +5399,8 @@ static void build_type12(int by0, int bx0)
52565399
52575400 rad = randint1(9);
52585401
5259- /* Allocate in room_map. If will not fit, exit */
5260- if (!room_alloc(rad * 2 + 3, rad * 2 + 3, FALSE, by0, bx0, &x0, &y0)) return;
5402+ /* Find and reserve some space in the dungeon. Get center of room. */
5403+ if (!find_space(&y0, &x0, rad * 2 + 3, rad * 2 + 3)) return FALSE;
52615404
52625405 /* Make floor */
52635406 for (x = x0 - rad; x <= x0 + rad; x++)
@@ -5322,6 +5465,8 @@ static void build_type12(int by0, int bx0)
53225465 /* Traps naturally */
53235466 vault_traps(y0, x0, 4, 4, randint0(3) + 2);
53245467 }
5468+
5469+ return TRUE;
53255470 }
53265471
53275472
@@ -5387,7 +5532,7 @@ static bool vault_aux_trapped_pit(int r_idx)
53875532 *
53885533 * Note that "monster pits" will never contain "unique" monsters.
53895534 */
5390-static void build_type13(int by0, int bx0)
5535+static bool build_type13(void)
53915536 {
53925537 static int placing[][3] = {
53935538 {-2, -9, 0}, {-2, -8, 0}, {-3, -7, 0}, {-3, -6, 0},
@@ -5431,13 +5576,13 @@ static void build_type13(int by0, int bx0)
54315576 vault_aux_type *n_ptr;
54325577
54335578 /* Only in Angband */
5434- if (dungeon_type != 1) return;
5579+ if (dungeon_type != 1) return FALSE;
54355580
5436- /* Try to allocate space for room. */
5437- if (!room_alloc(25, 13, TRUE, by0, bx0, &xval, &yval)) return;
5581+ /* Find and reserve some space in the dungeon. Get center of room. */
5582+ if (!find_space(&yval, &xval, 13, 25)) return FALSE;
54385583
54395584 /* No type available */
5440- if (cur_pit_type < 0) return;
5585+ if (cur_pit_type < 0) return FALSE;
54415586
54425587 n_ptr = &pit_types[cur_pit_type];
54435588
@@ -5569,7 +5714,7 @@ static void build_type13(int by0, int bx0)
55695714 }
55705715
55715716 /* Notice failure */
5572- if (!r_idx || !attempts) return;
5717+ if (!r_idx || !attempts) return FALSE;
55735718
55745719 /* Note the alignment */
55755720 if (r_ptr->flags3 & RF3_EVIL) align.sub_align |= SUB_ALIGN_EVIL;
@@ -5640,6 +5785,8 @@ static void build_type13(int by0, int bx0)
56405785 x = xval + placing[i][1];
56415786 place_monster_aux(0, y, x, what[placing[i][2]], PM_NO_KAGE);
56425787 }
5788+
5789+ return TRUE;
56435790 }
56445791
56455792
@@ -5648,7 +5795,7 @@ static void build_type13(int by0, int bx0)
56485795 *
56495796 * A special trap is placed at center of the room
56505797 */
5651-static void build_type14(int by0, int bx0)
5798+static bool build_type14(void)
56525799 {
56535800 int y, x, y2, x2, yval, xval;
56545801 int y1, x1, xsize, ysize;
@@ -5667,8 +5814,8 @@ static void build_type14(int by0, int bx0)
56675814 xsize = x1 + x2 + 1;
56685815 ysize = y1 + y2 + 1;
56695816
5670- /* Try to allocate space for room. If fails, exit */
5671- if (!room_alloc(xsize + 2, ysize + 2, FALSE, by0, bx0, &xval, &yval)) return;
5817+ /* Find and reserve some space in the dungeon. Get center of room. */
5818+ if (!find_space(&yval, &xval, ysize + 2, xsize + 2)) return FALSE;
56725819
56735820 /* Choose lite or dark */
56745821 light = ((dun_level <= randint1(25)) && !(d_info[dungeon_type].flags1 & DF1_DARKNESS));
@@ -5728,6 +5875,8 @@ static void build_type14(int by0, int bx0)
57285875 msg_format("Room of %s", f_name + f_info[trap].name);
57295876 #endif
57305877 }
5878+
5879+ return TRUE;
57315880 }
57325881
57335882
@@ -5737,33 +5886,26 @@ static void build_type14(int by0, int bx0)
57375886 * Note that we restrict the number of "crowded" rooms to reduce
57385887 * the chance of overflowing the monster list during level creation.
57395888 */
5740-bool room_build(int by0, int bx0, int typ)
5889+bool room_build(int typ)
57415890 {
5742- /* Restrict level */
5743- if ((dun_level < roomdep[typ]) && !ironman_rooms) return FALSE;
5744-
5745- /* Restrict "crowded" rooms */
5746- if ((dun->crowded >= 2) && ((typ == ROOM_BUILD_TYPE_NEST) ||
5747- (typ == ROOM_BUILD_TYPE_PIT) || (typ == ROOM_BUILD_TYPE_TRAP_PIT))) return FALSE;
5748-
57495891 /* Build a room */
57505892 switch (typ)
57515893 {
57525894 /* Build an appropriate room */
5753- case ROOM_BUILD_TYPE_NORMAL: build_type1(by0, bx0); break;
5754- case ROOM_BUILD_TYPE_OVERLAP: build_type2(by0, bx0); break;
5755- case ROOM_BUILD_TYPE_CROSS: build_type3(by0, bx0); break;
5756- case ROOM_BUILD_TYPE_INNER_FEAT: build_type4(by0, bx0); break;
5757- case ROOM_BUILD_TYPE_NEST: build_type5(by0, bx0, FALSE); break;
5758- case ROOM_BUILD_TYPE_PIT: build_type6(by0, bx0, FALSE); break;
5759- case ROOM_BUILD_TYPE_LESSER_VAULT: build_type7(by0, bx0); break;
5760- case ROOM_BUILD_TYPE_GREATER_VAULT: build_type8(by0, bx0); break;
5761- case ROOM_BUILD_TYPE_FRACAVE: build_type9(by0, bx0); break;
5762- case ROOM_BUILD_TYPE_RANDOM_VAULT: build_type10(by0, bx0); break;
5763- case ROOM_BUILD_TYPE_OVAL: build_type11(by0, bx0); break;
5764- case ROOM_BUILD_TYPE_CRYPT: build_type12(by0, bx0); break;
5765- case ROOM_BUILD_TYPE_TRAP_PIT: build_type13(by0, bx0); break;
5766- case ROOM_BUILD_TYPE_TRAP: build_type14(by0, bx0); break;
5895+ case ROOM_T_NORMAL: build_type1(); break;
5896+ case ROOM_T_OVERLAP: build_type2(); break;
5897+ case ROOM_T_CROSS: build_type3(); break;
5898+ case ROOM_T_INNER_FEAT: build_type4(); break;
5899+ case ROOM_T_NEST: build_type5(); break;
5900+ case ROOM_T_PIT: build_type6(); break;
5901+ case ROOM_T_LESSER_VAULT: build_type7(); break;
5902+ case ROOM_T_GREATER_VAULT: build_type8(); break;
5903+ case ROOM_T_FRACAVE: build_type9(); break;
5904+ case ROOM_T_RANDOM_VAULT: build_type10(); break;
5905+ case ROOM_T_OVAL: build_type11(); break;
5906+ case ROOM_T_CRYPT: build_type12(); break;
5907+ case ROOM_T_TRAP_PIT: build_type13(); break;
5908+ case ROOM_T_TRAP: build_type14(); break;
57675909
57685910 /* Paranoia */
57695911 default: return FALSE;
@@ -5771,3 +5913,193 @@ bool room_build(int by0, int bx0, int typ)
57715913
57725914 return TRUE;
57735915 }
5916+
5917+
5918+#define MOVE_PLIST(dst, src) (prob_list[dst] += prob_list[src], prob_list[src] = 0)
5919+
5920+/*
5921+ * [from SAngband (originally from OAngband)]
5922+ *
5923+ * Generate rooms in dungeon. Build bigger rooms at first.
5924+ */
5925+void generate_rooms(void)
5926+{
5927+ int i;
5928+ bool remain;
5929+ int crowded = 0;
5930+ int total_prob;
5931+ int prob_list[ROOM_T_MAX];
5932+ int rooms_built = 0;
5933+ int area_size = 100 * (cur_hgt*cur_wid) / (MAX_HGT*MAX_WID);
5934+ int level_index = MIN(10, div_round(dun_level, 10));
5935+
5936+ /* Number of each type of room on this level */
5937+ s16b room_num[ROOM_T_MAX];
5938+
5939+ /* Limit number of rooms */
5940+ int dun_rooms = rand_range(DUN_ROOMS_MIN, DUN_ROOMS_MAX * area_size / 100);
5941+
5942+ /* Assume normal cave */
5943+ room_info_type *room_info_ptr = room_info_normal;
5944+
5945+
5946+ /*
5947+ * Initialize probability list.
5948+ */
5949+ for (i = 0; i < ROOM_T_MAX; i++)
5950+ {
5951+ /* No rooms allowed above their minimum depth. */
5952+ if (dun_level < room_info_ptr[i].min_level)
5953+ {
5954+ prob_list[i] = 0;
5955+ }
5956+ else
5957+ {
5958+ prob_list[i] = room_info_ptr[i].prob[level_index];
5959+ }
5960+ }
5961+
5962+ /*
5963+ * XXX -- Various dungeon types and options.
5964+ */
5965+
5966+ /* Ironman sees only Greater Vaults */
5967+ if (ironman_rooms && !((d_info[dungeon_type].flags1 & (DF1_BEGINNER | DF1_CHAMELEON))))
5968+ {
5969+ for (i = 0; i < ROOM_T_MAX; i++)
5970+ {
5971+ if (i == ROOM_T_GREATER_VAULT) prob_list[i] = 1;
5972+ else prob_list[i] = 0;
5973+ }
5974+ }
5975+
5976+ /* Forbidden vaults */
5977+ else if (d_info[dungeon_type].flags1 & DF1_NO_VAULT)
5978+ {
5979+ prob_list[ROOM_T_LESSER_VAULT] = 0;
5980+ prob_list[ROOM_T_GREATER_VAULT] = 0;
5981+ prob_list[ROOM_T_RANDOM_VAULT] = 0;
5982+ }
5983+
5984+
5985+ /* NO_CAVE dungeon (Castle)*/
5986+ if (d_info[dungeon_type].flags1 & DF1_NO_CAVE)
5987+ {
5988+ MOVE_PLIST(ROOM_T_NORMAL, ROOM_T_FRACAVE);
5989+ MOVE_PLIST(ROOM_T_INNER_FEAT, ROOM_T_CRYPT);
5990+ MOVE_PLIST(ROOM_T_INNER_FEAT, ROOM_T_OVAL);
5991+ }
5992+
5993+ /* CAVE dungeon (Orc cave etc.) */
5994+ else if (d_info[dungeon_type].flags1 & DF1_CAVE)
5995+ {
5996+ MOVE_PLIST(ROOM_T_FRACAVE, ROOM_T_NORMAL);
5997+ }
5998+
5999+ /* No caves when a (random) cavern exists: they look bad */
6000+ else if (dun->cavern || dun->empty_level)
6001+ {
6002+ prob_list[ROOM_T_FRACAVE] = 0;
6003+ }
6004+
6005+
6006+ /*
6007+ * Initialize number of rooms,
6008+ * And calcurate total probability.
6009+ */
6010+ for (total_prob = 0, i = 0; i < ROOM_T_MAX; i++)
6011+ {
6012+ room_num[i] = 0;
6013+ total_prob += prob_list[i];
6014+ }
6015+
6016+ /*
6017+ * Prepare the number of rooms, of all types, we should build
6018+ * on this level.
6019+ */
6020+ for (i = 0; i < dun_rooms; i++)
6021+ {
6022+ int room_type;
6023+ int rand = randint0(total_prob);
6024+
6025+ /* Get room_type randomly */
6026+ for (room_type = 0; room_type < ROOM_T_MAX; room_type++)
6027+ {
6028+ if (rand < prob_list[room_type]) break;
6029+ else rand -= prob_list[room_type];
6030+ }
6031+
6032+ /* Paranoia */
6033+ if (room_type >= ROOM_T_MAX) room_type = ROOM_T_NORMAL;
6034+
6035+ /* Increase the number of rooms of that type we should build. */
6036+ room_num[room_type]++;
6037+ }
6038+
6039+
6040+ /*
6041+ * Build each type of room one by one until we cannot build any more.
6042+ * [from SAngband (originally from OAngband)]
6043+ */
6044+ while (TRUE)
6045+ {
6046+ /* Assume no remaining rooms */
6047+ remain = FALSE;
6048+
6049+ for (i = 0; i < ROOM_T_MAX; i++)
6050+ {
6051+ /* What type of room are we building now? */
6052+ int room_type = room_build_order[i];
6053+
6054+ /* Stop building rooms when we hit the maximum. */
6055+ if (rooms_built >= dun_rooms)
6056+ {
6057+ remain = FALSE;
6058+ break;
6059+ }
6060+
6061+ /* Go next if none available */
6062+ if (!room_num[room_type]) continue;
6063+
6064+ /* Use up one unit */
6065+ room_num[room_type]--;
6066+
6067+ /* Build the room. */
6068+ if (room_build(room_type))
6069+ {
6070+ /* Increase the room built count. */
6071+ rooms_built++;
6072+
6073+ /* Mark as there was some remaining rooms */
6074+ remain = TRUE;
6075+
6076+ switch (room_type)
6077+ {
6078+ case ROOM_T_PIT:
6079+ case ROOM_T_NEST:
6080+ case ROOM_T_TRAP_PIT:
6081+
6082+ /* Avoid too many monsters */
6083+ if (++crowded >= 2)
6084+ {
6085+ room_num[ROOM_T_PIT] = 0;
6086+ room_num[ROOM_T_NEST] = 0;
6087+ room_num[ROOM_T_TRAP_PIT] = 0;
6088+ }
6089+ }
6090+ }
6091+
6092+ /* Stop building this type on failure. */
6093+ else
6094+ {
6095+ room_num[room_type] = 0;
6096+ }
6097+ }
6098+
6099+ /* End loop if no room remain */
6100+ if (!remain) break;
6101+ }
6102+
6103+}
6104+
6105+
--- a/src/rooms.h
+++ b/src/rooms.h
@@ -12,11 +12,62 @@
1212 */
1313
1414
15+/* Number of rooms to attempt (was 50) */
16+#define DUN_ROOMS_MIN 10
17+#define DUN_ROOMS_MAX 100
18+
19+
20+/* Room types for generate_lake() */
21+#define LAKE_T_LAVA 1
22+#define LAKE_T_WATER 2
23+#define LAKE_T_CAVE 3
24+#define LAKE_T_EARTH_VAULT 4
25+#define LAKE_T_AIR_VAULT 5
26+#define LAKE_T_WATER_VAULT 6
27+#define LAKE_T_FIRE_VAULT 7
28+
29+
30+/* Room types for room_build() */
31+#define ROOM_T_NORMAL 0 /* Simple (33x11) */
32+#define ROOM_T_OVERLAP 1 /* Overlapping (33x11) */
33+#define ROOM_T_CROSS 2 /* Crossed (33x11) */
34+#define ROOM_T_INNER_FEAT 3 /* Large (33x11) */
35+#define ROOM_T_NEST 4 /* Monster nest (33x11) */
36+#define ROOM_T_PIT 5 /* Monster pit (33x11) */
37+#define ROOM_T_LESSER_VAULT 6 /* Lesser vault (33x22) */
38+#define ROOM_T_GREATER_VAULT 7 /* Greater vault (66x44) */
39+#define ROOM_T_FRACAVE 8 /* Fractal cave (42x24) */
40+#define ROOM_T_RANDOM_VAULT 9 /* Random vault (44x22) */
41+#define ROOM_T_OVAL 10 /* Circular rooms (22x22) */
42+#define ROOM_T_CRYPT 11 /* Crypts (22x22) */
43+#define ROOM_T_TRAP_PIT 12 /* Trapped monster pit */
44+#define ROOM_T_TRAP 13 /* Piranha/Armageddon trap room */
45+
46+#define ROOM_T_MAX 14
47+
48+
49+/*
50+ * Room type information
51+ */
52+typedef struct room_info_type room_info_type;
53+
54+struct room_info_type
55+{
56+ /* Allocation information. */
57+ s16b prob[ROOM_T_MAX];
58+
59+ /* Minimum level on which room can appear. */
60+ byte min_level;
61+};
62+
63+
1564 /* Externs */
1665 #ifdef ALLOW_CAVERNS_AND_LAKES
1766 extern void build_lake(int type);
1867 extern void build_cavern(void);
1968 #endif /* ALLOW_CAVERNS_AND_LAKES */
2069
21-extern bool room_build(int y0, int x0, int typ);
70+extern bool room_build(int typ);
71+extern void generate_rooms(void);
2272 extern void build_maze_vault(int x0, int y0, int xsize, int ysize, bool is_vault);
73+
--- a/src/z-rand.c
+++ b/src/z-rand.c
@@ -313,4 +313,33 @@ s16b maxroll(int num, int sides)
313313 }
314314
315315
316+/*
317+ * Given a numerator and a denominator, supply a properly rounded result,
318+ * using the RNG to smooth out remainders. -LM-
319+ */
320+s32b div_round(s32b n, s32b d)
321+{
322+ s32b tmp;
323+
324+ /* Refuse to divide by zero */
325+ if (!d) return (n);
326+
327+ /* Division */
328+ tmp = n / d;
329+
330+ /* Rounding */
331+ if ((ABS(n) % ABS(d)) > randint0(ABS(d)))
332+ {
333+ /* Increase the absolute value */
334+ if (n * d > 0L) tmp += 1L;
335+ else tmp -= 1L;
336+ }
337+
338+ /* Return */
339+ return (tmp);
340+}
341+
342+
343+
344+
316345
--- a/src/z-rand.h
+++ b/src/z-rand.h
@@ -96,6 +96,7 @@ extern s32b Rand_div(u32b m);
9696 extern s16b randnor(int mean, int stand);
9797 extern s16b damroll(int num, int sides);
9898 extern s16b maxroll(int num, int sides);
99+extern s32b div_round(s32b n, s32b d);
99100
100101
101102 #endif
Show on old repository browser