summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/branch.cc6
-rw-r--r--crawl-ref/source/branch.h2
-rw-r--r--crawl-ref/source/dungeon.cc239
-rw-r--r--crawl-ref/source/mon-pick.cc4
-rw-r--r--crawl-ref/source/notes.cc2
5 files changed, 116 insertions, 137 deletions
diff --git a/crawl-ref/source/branch.cc b/crawl-ref/source/branch.cc
index b0fcfe9c0e..ff56d2fe1b 100644
--- a/crawl-ref/source/branch.cc
+++ b/crawl-ref/source/branch.cc
@@ -4,8 +4,14 @@
#include "AppHdr.h"
#include "branch.h"
+#include "externs.h"
#include "mon-pick.h"
+Branch& your_branch()
+{
+ return branches[static_cast<int>(you.where_are_you)];
+}
+
Branch branches[] = {
{ BRANCH_MAIN_DUNGEON, BRANCH_MAIN_DUNGEON, 27, -1,
diff --git a/crawl-ref/source/branch.h b/crawl-ref/source/branch.h
index e98e288e55..8246f7128c 100644
--- a/crawl-ref/source/branch.h
+++ b/crawl-ref/source/branch.h
@@ -38,4 +38,6 @@ struct Branch
extern Branch branches[];
+Branch& your_branch();
+
#endif
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index c1ac43d334..5b39faa997 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -207,7 +207,7 @@ static void place_altars()
if ( you.level_type == LEVEL_DUNGEON )
{
- int prob = branches[(int)you.where_are_you].altar_chance;
+ int prob = your_branch().altar_chance;
while (prob)
{
if (random2(100) >= prob)
@@ -474,7 +474,7 @@ 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 &&
+ if ( your_branch().exit_stairs != NUM_FEATURES &&
player_branch_depth() == 1 &&
you.level_type == LEVEL_DUNGEON )
{
@@ -482,11 +482,11 @@ static void fixup_branch_stairs()
for (int y = 1; y < GYM; y++)
if (grd[x][y] >= DNGN_STONE_STAIRS_UP_I
&& grd[x][y] <= DNGN_ROCK_STAIRS_UP)
- grd[x][y] = branches[(int)you.where_are_you].exit_stairs;
+ grd[x][y] = your_branch().exit_stairs;
}
// bottom level of branch - replaces down stairs with up ladders:
- if ( player_branch_depth() == branches[(int)you.where_are_you].depth &&
+ if ( player_branch_depth() == your_branch().depth &&
you.level_type == LEVEL_DUNGEON)
{
for (int x = 1; x < GXM; x++)
@@ -529,7 +529,7 @@ static void build_dungeon_level(int level_number, int level_type)
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()
+ // been hooked up already in roguey_level())
if (sr.created && !sr.hooked_up)
specr_2(sr);
@@ -567,21 +567,12 @@ static void build_dungeon_level(int level_number, int level_type)
builder_monsters(level_number, level_type, num_mons_wanted(level_type));
// place shops, if appropriate
- if ( branches[(int)you.where_are_you].has_shops )
+ if ( your_branch().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();
@@ -3967,7 +3958,7 @@ static int random_map_for_dlevel(int level_number, bool wantmini = false)
// This dodge allows designers to specify PLACE: as Elf:$ or Slime:$ or
// whatever:$ to say "last level in branch 'whatever'".
- if (subdepth == branches[(int)you.where_are_you].depth)
+ if (subdepth == your_branch().depth)
altname = level_name(0);
int vault = random_map_for_place(name, wantmini);
@@ -3986,8 +3977,9 @@ static int random_map_for_dlevel(int level_number, bool wantmini = false)
return (vault);
}
-// returns 1 if we should skip further generation,
-// -1 if we should immediately quit, and 0 otherwise.
+// returns BUILD_SKIP if we should skip further generation,
+// BUILD_QUIT if we should immediately quit, and BUILD_CONTINUE
+// otherwise.
static builder_rc_type builder_by_branch(int level_number)
{
const int vault = random_map_for_dlevel(level_number);
@@ -4000,26 +3992,15 @@ static builder_rc_type builder_by_branch(int level_number)
switch (you.where_are_you)
{
+ case BRANCH_LAIR:
+ if (!one_chance_in(3))
+ break;
case BRANCH_HIVE:
- spotty_level(false, 100 + random2(500), false);
- return BUILD_SKIP;
-
case BRANCH_SLIME_PITS:
- spotty_level(false, 100 + random2(500), false);
- return BUILD_SKIP;
-
case BRANCH_ORCISH_MINES:
spotty_level(false, 100 + random2(500), false);
return BUILD_SKIP;
- case BRANCH_LAIR:
- if (!one_chance_in(3))
- {
- spotty_level(false, 100 + random2(500), false);
- return BUILD_SKIP;
- }
- break;
-
default:
break;
}
@@ -4751,129 +4732,107 @@ static int pick_unique(int lev)
return (which_unique);
}
-static void builder_monsters(int level_number, char level_type, int mon_wanted)
+// Place uniques on the level.
+// There is a hidden dependency on the player's actual
+// location (through your_branch().)
+// Return the number of uniques placed.
+static int place_uniques(int level_number, char level_type)
{
- int i = 0;
- int totalplaced = 0;
int not_used = 0;
- int x,y;
- int lava_spaces, water_spaces;
- int aq_creatures;
- int swimming_things[4];
+ // Unique beasties:
+ if (level_number <= 0 || level_type != LEVEL_DUNGEON ||
+ !your_branch().has_uniques)
+ return 0;
- if (level_type == LEVEL_PANDEMONIUM
- || player_in_branch(BRANCH_ECUMENICAL_TEMPLE))
- return;
+ int num_placed = 0;
- for (i = 0; i < mon_wanted; i++)
+ while(one_chance_in(3))
{
- if (place_monster( not_used, RANDOM_MONSTER, level_number, BEH_SLEEP,
- MHITNOT, false, 1, 1, true, PROX_ANYWHERE, 250, 0,
- no_monster_zones ))
- {
- totalplaced++;
- }
- }
+ int which_unique = -1; // 30 in total
- // Unique beasties:
- if (level_number > 0
- && you.level_type == LEVEL_DUNGEON // avoid generating on temp levels
- && branches[(int)you.where_are_you].has_uniques)
- {
- while(one_chance_in(3))
+ while(which_unique < 0 || you.unique_creatures[which_unique])
{
- int which_unique = -1; // 30 in total
-
- while(which_unique < 0 || you.unique_creatures[which_unique])
+ // sometimes, we just quit if a unique is already placed.
+ if (which_unique >= 0 && !one_chance_in(3))
{
- // sometimes, we just quit if a unique is already placed.
- if (which_unique >= 0 && !one_chance_in(3))
- {
- which_unique = -1;
- break;
- }
-
- which_unique = pick_unique(level_number);
+ which_unique = -1;
+ break;
}
- // usually, we'll have quit after a few tries. Make sure we don't
- // create unique[-1] by accident.
- if (which_unique == -1)
- break;
+ which_unique = pick_unique(level_number);
+ }
- // note: unique_creatures 40 + used by unique demons
- if (place_monster( not_used, which_unique, level_number,
- BEH_SLEEP, MHITNOT, false, 1, 1, true,
- PROX_ANYWHERE, 250, 0, no_monster_zones ))
- {
- totalplaced++;
- }
+ // usually, we'll have quit after a few tries. Make sure we don't
+ // create unique[-1] by accident.
+ if (which_unique == -1)
+ break;
+
+ // note: unique_creatures 40 + used by unique demons
+ if (place_monster( not_used, which_unique, level_number,
+ BEH_SLEEP, MHITNOT, false, 1, 1, true,
+ PROX_ANYWHERE, 250, 0, no_monster_zones ))
+ {
+ ++num_placed;
}
}
+ return num_placed;
+}
- // do aquatic and lava monsters:
+static int place_monster_vector(int* montypes, int numtypes,
+ int level_number, int num_to_place)
+{
+ int result = 0;
+ int not_used = 0;
+ for (int i = 0; i < num_to_place; i++)
+ {
+ if (place_monster( not_used, montypes[random2(numtypes)],
+ level_number, BEH_SLEEP, MHITNOT,
+ false, 1, 1, true, PROX_ANYWHERE, 250, 0,
+ no_monster_zones ))
+ {
+ ++result;
+ }
+ }
+ return result;
+}
+
- // count the number of lava and water tiles {dlb}:
- lava_spaces = 0;
- water_spaces = 0;
+static void place_aquatic_monsters(int level_number, char level_type)
+{
+ int lava_spaces = 0, water_spaces = 0;
+ int swimming_things[4];
- for (x = 0; x < GXM; x++)
+ // count the number of lava and water tiles {dlb}:
+ for (int x = 0; x < GXM; x++)
{
- for (y = 0; y < GYM; y++)
+ for (int y = 0; y < GYM; y++)
{
- if (grd[x][y] == DNGN_LAVA && level_number > 6)
- {
+ if (grd[x][y] == DNGN_LAVA)
lava_spaces++;
- }
- else if (grd[x][y] == DNGN_DEEP_WATER
- || grd[x][y] == DNGN_SHALLOW_WATER)
- {
+ if (grd[x][y]==DNGN_DEEP_WATER || grd[x][y]==DNGN_SHALLOW_WATER)
water_spaces++;
- }
}
}
- if (lava_spaces > 49)
+ if (lava_spaces > 49 && level_number > 6)
{
- for (i = 0; i < 4; i++)
+ for (int i = 0; i < 4; i++)
{
swimming_things[i] = MONS_LAVA_WORM + random2(3);
-
- //mv: this is really ugly, but easiest
- //IMO generation of water/lava beasts should be changed,
- //because we want data driven code and not things like it
if (one_chance_in(30))
swimming_things[i] = MONS_SALAMANDER;
}
- aq_creatures = random2avg(9, 2) + (random2(lava_spaces) / 10);
-
- if (aq_creatures > 15)
- aq_creatures = 15;
-
- for (i = 0; i < aq_creatures; i++)
- {
- if (place_monster( not_used, swimming_things[ random2(4) ],
- level_number, BEH_SLEEP, MHITNOT,
- false, 1, 1, true, PROX_ANYWHERE, 250, 0,
- no_monster_zones ))
- {
- totalplaced++;
- }
-
- if (totalplaced > 99)
- break;
- }
+ place_monster_vector(swimming_things, 4, level_number,
+ std::min(random2avg(9, 2) +
+ (random2(lava_spaces) / 10), 15));
}
if (water_spaces > 49)
{
- for (i = 0; i < 4; i++)
+ for (int i = 0; i < 4; i++)
{
- // mixing enums and math ticks me off !!! 15jan2000 {dlb}
swimming_things[i] = MONS_BIG_FISH + random2(4);
-
- // swamp worms and h2o elementals generated below: {dlb}
if (player_in_branch( BRANCH_SWAMP ) && !one_chance_in(3))
swimming_things[i] = MONS_SWAMP_WORM;
}
@@ -4884,24 +4843,36 @@ static void builder_monsters(int level_number, char level_type, int mon_wanted)
if (player_in_branch( BRANCH_COCYTUS ))
swimming_things[3] = MONS_WATER_ELEMENTAL;
- aq_creatures = random2avg(9, 2) + (random2(water_spaces) / 10);
+ place_monster_vector(swimming_things, 4, level_number,
+ std::min(random2avg(9, 2) +
+ (random2(water_spaces) / 10), 15));
+ }
+}
- if (aq_creatures > 15)
- aq_creatures = 15;
- for (i = 0; i < aq_creatures; i++)
- {
- if (place_monster( not_used, swimming_things[ random2(4) ],
- level_number, BEH_SLEEP, MHITNOT,
- false, 1, 1, true, PROX_ANYWHERE, 250, 0,
- no_monster_zones ))
- {
- totalplaced++;
- }
+static void builder_monsters(int level_number, char level_type, int mon_wanted)
+{
+ int not_used = 0;
+ if (level_type == LEVEL_PANDEMONIUM ||
+ player_in_branch(BRANCH_ECUMENICAL_TEMPLE))
+ return;
- if (totalplaced > 99)
- break;
- }
+ for (int i = 0; i < mon_wanted; i++)
+ place_monster( not_used, RANDOM_MONSTER, level_number, BEH_SLEEP,
+ MHITNOT, false, 1, 1, true, PROX_ANYWHERE, 250, 0,
+ no_monster_zones );
+
+ place_uniques(level_number, level_type);
+ place_aquatic_monsters(level_number, level_type);
+
+ // Special handling
+ 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 );
}
}
diff --git a/crawl-ref/source/mon-pick.cc b/crawl-ref/source/mon-pick.cc
index 1f7f9bbdf0..b06023d686 100644
--- a/crawl-ref/source/mon-pick.cc
+++ b/crawl-ref/source/mon-pick.cc
@@ -29,7 +29,7 @@ int mons_level(int mcls)
else if (you.level_type == LEVEL_PANDEMONIUM)
monster_level = ((mons_pan(mcls)) ? 52 : 0);
else
- monster_level=branches[(int)you.where_are_you].mons_level_function(mcls);
+ monster_level = your_branch().mons_level_function(mcls);
return monster_level;
}
@@ -42,7 +42,7 @@ int mons_rarity(int mcls)
if (you.level_type == LEVEL_ABYSS)
return mons_rare_abyss(mcls);
else
- return branches[(int)you.where_are_you].mons_rarity_function(mcls);
+ return your_branch().mons_rarity_function(mcls);
}
bool mons_abyss(int mcls)
diff --git a/crawl-ref/source/notes.cc b/crawl-ref/source/notes.cc
index f827cd7926..425e00e719 100644
--- a/crawl-ref/source/notes.cc
+++ b/crawl-ref/source/notes.cc
@@ -72,7 +72,7 @@ static int dungeon_branch_depth( unsigned char branch )
static bool is_noteworthy_dlevel( unsigned short place )
{
- unsigned const char branch = (unsigned char) ((place >> 8) & 0xFF);
+ const unsigned char branch = (unsigned char) ((place >> 8) & 0xFF);
const int lev = (place & 0xFF);
/* Special levels (Abyss, etc.) are always interesting */