summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/dungeon.cc
diff options
context:
space:
mode:
authorharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2007-04-07 11:10:16 +0000
committerharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2007-04-07 11:10:16 +0000
commit361c9481bd37fc56fbbaac0d34c9e5c82af0b931 (patch)
tree211da3dcd514f8901eb654365e4fb51d8309431a /crawl-ref/source/dungeon.cc
parent14c66301ea2ed5a18dbcf15c314781acd5d9e985 (diff)
downloadcrawl-ref-361c9481bd37fc56fbbaac0d34c9e5c82af0b931.tar.gz
crawl-ref-361c9481bd37fc56fbbaac0d34c9e5c82af0b931.zip
Preliminary refactoring in dungeon creation code.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1255 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/dungeon.cc')
-rw-r--r--crawl-ref/source/dungeon.cc289
1 files changed, 137 insertions, 152 deletions
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index e45c2b5686..c1ac43d334 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -86,10 +86,10 @@ static bool make_box(int room_x1, int room_y1, int room_x2, int room_y2,
unsigned char floor=0, unsigned char wall=0, unsigned char avoid=0);
static void replace_area(int sx, int sy, int ex, int ey, unsigned char replace,
unsigned char feature);
-static int builder_by_type(int level_number, char level_type);
-static int builder_by_branch(int level_number);
-static int builder_normal(int level_number, char level_type, spec_room &s);
-static int builder_basic(int level_number);
+static builder_rc_type builder_by_type(int level_number, char level_type);
+static builder_rc_type builder_by_branch(int level_number);
+static builder_rc_type builder_normal(int level_number, char level_type, spec_room &s);
+static builder_rc_type builder_basic(int level_number);
static void builder_extras(int level_number, int level_type);
static void builder_items(int level_number, char level_type, int items_wanted);
static void builder_monsters(int level_number, char level_type, int mon_wanted);
@@ -387,121 +387,59 @@ static void reset_level()
static void build_layout_skeleton(int level_number, int level_type,
spec_room &sr)
{
- int skip_build = builder_by_type(level_number, level_type);
- if (skip_build < 0)
+ builder_rc_type skip_build = builder_by_type(level_number, level_type);
+
+ if (skip_build == BUILD_QUIT) // quit immediately
return;
- if (skip_build == 0)
+ if (skip_build == BUILD_CONTINUE)
{
skip_build = builder_by_branch(level_number);
- if (skip_build < 0)
+ if (skip_build == BUILD_QUIT)
return;
}
- if (skip_build == 0)
+ if (skip_build == BUILD_CONTINUE)
{
// do 'normal' building. Well, except for the swamp.
if (!player_in_branch( BRANCH_SWAMP ))
skip_build = builder_normal(level_number, level_type, sr);
- if (skip_build == 0)
+ if (skip_build == BUILD_CONTINUE)
{
skip_build = builder_basic(level_number);
- if (skip_build == 0)
+ if (skip_build == BUILD_CONTINUE)
builder_extras(level_number, level_type);
}
}
}
-static void build_dungeon_level(int level_number, int level_type)
+static int num_mons_wanted(int level_type)
{
- spec_room sr;
+ if (level_type == LEVEL_ABYSS ||
+ player_in_branch( BRANCH_ECUMENICAL_TEMPLE ))
+ return 0;
- reset_level();
- build_layout_skeleton(level_number, level_type, sr);
+ int mon_wanted = roll_dice( 3, 10 );
- if (you.level_type == LEVEL_LABYRINTH)
- return;
+ if (player_in_hell())
+ mon_wanted += roll_dice( 3, 8 );
+ else if (player_in_branch( BRANCH_HALL_OF_BLADES ))
+ mon_wanted += roll_dice( 6, 8 );
- // Try to place minivaults that really badly want to be placed. Still
- // no guarantees, seeing this is a minivault.
- place_special_minivaults(level_number, level_type);
-
- // hook up the special room (if there is one, and it hasn't
- // been hooked up already in roguey_level()
- if (sr.created && !sr.hooked_up)
- specr_2(sr);
-
- // now place items, monster, gates, etc.
- // stairs must exist by this point. Some items and monsters
- // already exist.
-
- // time to make the swamp {dlb}:
- if (player_in_branch( BRANCH_SWAMP ))
- prepare_swamp();
+ if (mon_wanted > 60)
+ mon_wanted = 60;
- // figure out how many 'normal' monsters we should place
- int mon_wanted = 0;
- if (level_type == LEVEL_ABYSS
- || player_in_branch( BRANCH_ECUMENICAL_TEMPLE ))
- {
- mon_wanted = 0;
- }
- else
- {
- mon_wanted = roll_dice( 3, 10 );
-
- if (player_in_hell())
- mon_wanted += roll_dice( 3, 8 );
- else if (player_in_branch( BRANCH_HALL_OF_BLADES ))
- mon_wanted += roll_dice( 6, 8 );
-
- // unlikely - now only possible in HoB {dlb} 10mar2000
- if (mon_wanted > 60)
- mon_wanted = 60;
- }
-
- place_branch_entrances( level_number, level_type );
-
- check_doors();
-
- if (!player_in_branch( BRANCH_DIS ) && !player_in_branch( BRANCH_VAULTS ))
- hide_doors();
-
- if (!player_in_branch( BRANCH_ECUMENICAL_TEMPLE ))
- place_traps(level_number);
-
- int items_wanted = 3 + roll_dice( 3, 11 );
-
- if (level_number > 5 && one_chance_in(500 - 5 * level_number))
- items_wanted = 10 + random2avg( 90, 2 ); // rich level!
-
- // change pre-rock (105) to rock, and pre-floor (106) to floor
- replace_area( 0,0,GXM-1,GYM-1, DNGN_BUILDER_SPECIAL_WALL, DNGN_ROCK_WALL );
- replace_area( 0,0,GXM-1,GYM-1, DNGN_BUILDER_SPECIAL_FLOOR, DNGN_FLOOR );
-
- // place items
- builder_items(level_number, level_type, items_wanted);
-
- // place monsters
- builder_monsters(level_number, level_type, mon_wanted);
-
- // place shops, if appropriate
- if (player_in_branch( BRANCH_MAIN_DUNGEON )
- || player_in_branch( BRANCH_ORCISH_MINES )
- || player_in_branch( BRANCH_ELVEN_HALLS )
- || player_in_branch( BRANCH_LAIR )
- || player_in_branch( BRANCH_VAULTS )
- || player_in_branch( BRANCH_SNAKE_PIT )
- || player_in_branch( BRANCH_SWAMP ))
- {
- place_shops(level_number);
- }
+ return mon_wanted;
+}
+static void fixup_walls()
+{
// If level part of Dis -> all walls metal;
// If part of vaults -> walls depend on level;
// If part of crypt -> all walls stone:
+
if (player_in_branch( BRANCH_DIS )
|| player_in_branch( BRANCH_VAULTS )
|| player_in_branch( BRANCH_CRYPT ))
@@ -530,7 +468,10 @@ static void build_dungeon_level(int level_number, int level_type)
replace_area(0,0,GXM-1,GYM-1,DNGN_ROCK_WALL,vault_wall);
}
+}
+static void fixup_branch_stairs()
+{
// Top level of branch levels - replaces up stairs
// with stairs back to dungeon or wherever:
if ( branches[(int)you.where_are_you].exit_stairs != NUM_FEATURES &&
@@ -555,18 +496,8 @@ static void build_dungeon_level(int level_number, int level_type)
grd[x][y] = DNGN_ROCK_STAIRS_UP;
}
- if (player_in_branch( BRANCH_CRYPT ))
- {
- if (one_chance_in(3))
- mons_place( MONS_CURSE_SKULL, BEH_SLEEP, MHITNOT, false, 0, 0 );
-
- if (one_chance_in(7))
- mons_place( MONS_CURSE_SKULL, BEH_SLEEP, MHITNOT, false, 0, 0 );
- }
-
- place_altars();
-
// hall of blades (1 level deal) - no down staircases, thanks!
+ // XXX XXX why the special-casing?
if (player_in_branch( BRANCH_HALL_OF_BLADES ))
{
for (int x = 1; x < GXM; x++)
@@ -581,6 +512,77 @@ static void build_dungeon_level(int level_number, int level_type)
}
}
}
+}
+
+static void build_dungeon_level(int level_number, int level_type)
+{
+ spec_room sr;
+
+ reset_level();
+ build_layout_skeleton(level_number, level_type, sr);
+
+ if (you.level_type == LEVEL_LABYRINTH)
+ return;
+
+ // Try to place minivaults that really badly want to be placed. Still
+ // no guarantees, seeing this is a minivault.
+ place_special_minivaults(level_number, level_type);
+
+ // hook up the special room (if there is one, and it hasn't
+ // been hooked up already in roguey_level()
+ if (sr.created && !sr.hooked_up)
+ specr_2(sr);
+
+ // now place items, monster, gates, etc.
+ // stairs must exist by this point. Some items and monsters
+ // already exist.
+
+ // time to make the swamp {dlb}:
+ if (player_in_branch( BRANCH_SWAMP ))
+ prepare_swamp();
+
+ place_branch_entrances( level_number, level_type );
+
+ check_doors();
+
+ if (!player_in_branch( BRANCH_DIS ) && !player_in_branch( BRANCH_VAULTS ))
+ hide_doors();
+
+ if (!player_in_branch( BRANCH_ECUMENICAL_TEMPLE ))
+ place_traps(level_number);
+
+ int items_wanted = 3 + roll_dice( 3, 11 );
+
+ if (level_number > 5 && one_chance_in(500 - 5 * level_number))
+ items_wanted = 10 + random2avg( 90, 2 ); // rich level!
+
+ // change pre-rock (105) to rock, and pre-floor (106) to floor
+ replace_area( 0,0,GXM-1,GYM-1, DNGN_BUILDER_SPECIAL_WALL, DNGN_ROCK_WALL );
+ replace_area( 0,0,GXM-1,GYM-1, DNGN_BUILDER_SPECIAL_FLOOR, DNGN_FLOOR );
+
+ // place items
+ builder_items(level_number, level_type, items_wanted);
+
+ // place monsters
+ builder_monsters(level_number, level_type, num_mons_wanted(level_type));
+
+ // place shops, if appropriate
+ if ( branches[(int)you.where_are_you].has_shops )
+ place_shops(level_number);
+
+ fixup_walls();
+ fixup_branch_stairs();
+
+ if (player_in_branch( BRANCH_CRYPT ))
+ {
+ if (one_chance_in(3))
+ mons_place( MONS_CURSE_SKULL, BEH_SLEEP, MHITNOT, false, 0, 0 );
+
+ if (one_chance_in(7))
+ mons_place( MONS_CURSE_SKULL, BEH_SLEEP, MHITNOT, false, 0, 0 );
+ }
+
+ place_altars();
link_items();
@@ -3673,22 +3675,15 @@ static void set_weapon_special(int the_weapon, int spwpn)
static void check_doors(void)
{
- unsigned char ig;
- unsigned char solid_count = 0; // clarifies innermost loop {dlb}
- int x,y;
-
- for (x = 1; x < GXM-1; x++)
+ for (int x = 1; x < GXM-1; x++)
{
- for (y = 1; y < GYM-1; y++)
+ for (int y = 1; y < GYM-1; y++)
{
- ig = grd[x][y];
-
- if (ig != DNGN_CLOSED_DOOR)
+ if (grd[x][y] != DNGN_CLOSED_DOOR)
continue;
- solid_count = 0;
+ int solid_count = 0;
- // first half of each conditional represents bounds checking {dlb}:
if (grid_is_solid( grd[x - 1][y] ))
solid_count++;
@@ -3878,23 +3873,23 @@ static bool make_box(int room_x1, int room_y1, int room_x2, int room_y2,
// take care of labyrinth, abyss, pandemonium
// returns 1 if we should skip further generation,
// -1 if we should immediately quit, and 0 otherwise.
-static int builder_by_type(int level_number, char level_type)
+static builder_rc_type builder_by_type(int level_number, char level_type)
{
if (level_type == LEVEL_LABYRINTH)
{
labyrinth_level(level_number);
- return -1;
+ return BUILD_QUIT;
}
if (level_type == LEVEL_ABYSS)
{
generate_abyss();
- return 1;
+ return BUILD_SKIP;
}
if (level_type == LEVEL_PANDEMONIUM)
{
- char which_demon = -1;
+ int which_demon = -1;
// Could do spotty_level, but that doesn't always put all paired
// stairs reachable from each other which isn't a problem in normal
// dungeon but could be in Pandemonium
@@ -3923,14 +3918,12 @@ static int builder_by_type(int level_number, char level_type)
you.unique_creatures[MONS_MNOLEG + which_demon] = true;
const int vault =
- random_map_for_tag(
- pandemon_level_names[(int) which_demon],
- false);
+ random_map_for_tag(pandemon_level_names[which_demon], false);
ASSERT(vault != -1);
if (vault == -1)
end(1, false, "Failed to find Pandemonium level %s!\n",
- pandemon_level_names[(int) which_demon]);
+ pandemon_level_names[which_demon]);
build_vaults(level_number, vault);
}
@@ -3945,11 +3938,11 @@ static int builder_by_type(int level_number, char level_type)
build_minivaults(level_number, vault);
}
- return 1;
+ return BUILD_SKIP;
}
// must be normal dungeon
- return 0;
+ return BUILD_CONTINUE;
}
static int random_portal_vault(const std::string &tag)
@@ -3995,42 +3988,42 @@ static int random_map_for_dlevel(int level_number, bool wantmini = false)
// returns 1 if we should skip further generation,
// -1 if we should immediately quit, and 0 otherwise.
-static int builder_by_branch(int level_number)
+static builder_rc_type builder_by_branch(int level_number)
{
const int vault = random_map_for_dlevel(level_number);
if (vault != -1)
{
build_vaults(level_number, vault);
- return 1;
+ return BUILD_SKIP;
}
switch (you.where_are_you)
{
case BRANCH_HIVE:
spotty_level(false, 100 + random2(500), false);
- return 1;
+ return BUILD_SKIP;
case BRANCH_SLIME_PITS:
spotty_level(false, 100 + random2(500), false);
- return 1;
+ return BUILD_SKIP;
case BRANCH_ORCISH_MINES:
spotty_level(false, 100 + random2(500), false);
- return 1;
+ return BUILD_SKIP;
case BRANCH_LAIR:
if (!one_chance_in(3))
{
spotty_level(false, 100 + random2(500), false);
- return 1;
+ return BUILD_SKIP;
}
break;
default:
break;
}
- return 0;
+ return BUILD_CONTINUE;
}
static void place_special_minivaults(int level_number, int level_type)
@@ -4064,8 +4057,8 @@ static void place_special_minivaults(int level_number, int level_type)
// returns 1 if we should dispense with city building,
// 0 otherwise. Also sets special_room if one is generated
// so that we can link it up later.
-
-static int builder_normal(int level_number, char level_type, spec_room &sr)
+static builder_rc_type builder_normal(int level_number, char level_type,
+ spec_room &sr)
{
UNUSED( level_type );
@@ -4083,13 +4076,13 @@ static int builder_normal(int level_number, char level_type, spec_room &sr)
if (vault != -1)
{
build_vaults(level_number, vault);
- return 1;
+ return BUILD_SKIP;
}
if (player_in_branch( BRANCH_DIS ))
{
city_level(level_number);
- return 1;
+ return BUILD_SKIP;
}
if (player_in_branch( BRANCH_VAULTS ))
@@ -4098,7 +4091,7 @@ static int builder_normal(int level_number, char level_type, spec_room &sr)
city_level(level_number);
else
plan_main(level_number, 4);
- return 1;
+ return BUILD_SKIP;
}
if (level_number > 7 && level_number < 23)
@@ -4106,13 +4099,13 @@ static int builder_normal(int level_number, char level_type, spec_room &sr)
if (one_chance_in(16))
{
spotty_level(false, 0, coinflip());
- return 1;
+ return BUILD_SKIP;
}
if (one_chance_in(16))
{
bigger_room();
- return 1;
+ return BUILD_SKIP;
}
}
@@ -4127,7 +4120,7 @@ static int builder_normal(int level_number, char level_type, spec_room &sr)
build_minivaults(level_number, mvault);
}
- return 1;
+ return BUILD_SKIP;
}
if (one_chance_in(3))
@@ -4146,7 +4139,7 @@ static int builder_normal(int level_number, char level_type, spec_room &sr)
if (mvault != -1)
{
build_minivaults(level_number, mvault);
- return 1;
+ return BUILD_SKIP;
}
}
}
@@ -4167,11 +4160,11 @@ static int builder_normal(int level_number, char level_type, spec_room &sr)
if (!sr.created && level_number > 5 && !done_city && one_chance_in(5))
special_room(level_number, sr);
- return 0;
+ return BUILD_CONTINUE;
}
// returns 1 if we should skip extras(), otherwise 0
-static int builder_basic(int level_number)
+static builder_rc_type builder_basic(int level_number)
{
int temp_rand;
int doorlevel = random2(11);
@@ -4265,7 +4258,7 @@ static int builder_basic(int level_number)
}
}
- return 0;
+ return BUILD_CONTINUE;
}
static void builder_extras( int level_number, int level_type )
@@ -4323,7 +4316,6 @@ static void builder_extras( int level_number, int level_type )
build_lake( river_type );
}
-
if (level_number > 8 && one_chance_in(16))
build_river( river_type );
else if (level_number > 8 && one_chance_in(12))
@@ -4784,20 +4776,13 @@ static void builder_monsters(int level_number, char level_type, int mon_wanted)
}
// Unique beasties:
- int which_unique;
-
if (level_number > 0
&& you.level_type == LEVEL_DUNGEON // avoid generating on temp levels
- && !player_in_hell()
- && !player_in_branch( BRANCH_ORCISH_MINES )
- && !player_in_branch( BRANCH_HIVE )
- && !player_in_branch( BRANCH_LAIR )
- && !player_in_branch( BRANCH_SLIME_PITS )
- && !player_in_branch( BRANCH_ECUMENICAL_TEMPLE ))
+ && branches[(int)you.where_are_you].has_uniques)
{
while(one_chance_in(3))
{
- which_unique = -1; // 30 in total
+ int which_unique = -1; // 30 in total
while(which_unique < 0 || you.unique_creatures[which_unique])
{
@@ -4813,7 +4798,7 @@ static void builder_monsters(int level_number, char level_type, int mon_wanted)
// usually, we'll have quit after a few tries. Make sure we don't
// create unique[-1] by accident.
- if (which_unique < 0)
+ if (which_unique == -1)
break;
// note: unique_creatures 40 + used by unique demons