summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Cline <zelgadis@sourceforge.net>2009-11-11 02:34:35 -0800
committerMatthew Cline <zelgadis@sourceforge.net>2009-11-11 02:34:35 -0800
commite4d5c6039f79b6952919882a74482695bffba6f9 (patch)
tree0b7d2b03d7f0b81890b4c46d678ecbc03097d414
parent9b1fdd7ba57c569890b38ea821b93e7f972b534d (diff)
downloadcrawl-ref-e4d5c6039f79b6952919882a74482695bffba6f9.tar.gz
crawl-ref-e4d5c6039f79b6952919882a74482695bffba6f9.zip
Place some of the altars outside of the Temple
Framework for placing altars outside the Temple, into what I call "overflow temples". It currently places twelve altars in the Ecumenical Temple and two outside at D:2 through D:9, with each of the two overflow altars being placed in a "temple" which consists of a bare altar. The overflow temples can actually contain any number of altars, but I'm not a vault designer, so I went the minimalistic route. The levels the overflow temples are placed on can be listed with the wizard command "&:".
-rw-r--r--crawl-ref/source/dat/temple.des13
-rw-r--r--crawl-ref/source/dungeon.cc141
-rw-r--r--crawl-ref/source/dungeon.h6
-rw-r--r--crawl-ref/source/maps.cc2
-rw-r--r--crawl-ref/source/newgame.cc1
-rw-r--r--crawl-ref/source/ng-init.cc74
-rw-r--r--crawl-ref/source/ng-init.h1
-rw-r--r--crawl-ref/source/wiz-dgn.cc25
8 files changed, 256 insertions, 7 deletions
diff --git a/crawl-ref/source/dat/temple.des b/crawl-ref/source/dat/temple.des
index 840a89dea7..bd8f5d3c05 100644
--- a/crawl-ref/source/dat/temple.des
+++ b/crawl-ref/source/dat/temple.des
@@ -893,3 +893,16 @@ bbbbbbbbbbbbbbb.B.bbbbbbbbbbbbbbb
bbbbbbbbbbbbbbb...bbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
ENDMAP
+
+##############################################################################
+# Overflow temples
+##############################################################################
+
+##############################################################################
+# Overflow temples with one altar, must have tag "overflow_temple_1"
+#
+NAME: overflow_temple_1_a
+TAGS: overflow_temple_1 allow_dup
+MAP
+B
+ENDMAP
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index 9b9998584e..13ceeba164 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -211,10 +211,14 @@ static void _dgn_load_colour_grid();
static void _dgn_map_colour_fixup();
// ALTAR FUNCTIONS
+static int _setup_temple_altars(CrawlHashTable &temple);
+static dungeon_feature_type _pick_temple_altar(vault_placement &place);
static dungeon_feature_type _pick_an_altar();
static void _place_altar();
static void _place_altars();
+static std::vector<god_type> _temple_altar_list;
+
typedef std::list<coord_def> coord_list;
// MISC FUNCTIONS
@@ -295,6 +299,9 @@ bool builder(int level_number, int level_type)
dgn_reset_level();
+ if (player_in_branch(BRANCH_ECUMENICAL_TEMPLE))
+ _setup_temple_altars(you.props);
+
// If we're getting low on available retries, disable random vaults
// and minivaults (special levels will still be placed).
if (tries < 5)
@@ -1617,6 +1624,97 @@ static void _dgn_verify_connectivity(unsigned nvaults)
}
}
+// Structure of OVERFLOW_TEMPLES:
+//
+// * A vector, with one cell per dungeon level (unset if there's no
+// overflow temples on that level).
+//
+// * The cell of the previous vector is a vector, with one overlfow
+// temple definition per cell.
+//
+// * The cell of the previous vector is a hash table, containing the
+// list of gods for the overflow temple and (optionally) the name of
+// the vault to use for the temple. If no map name is supplied,
+// it will randomly pick from vaults tagged "overflow_vault_num",
+// where "num" is the number of gods in the temple. Gods are listed
+// in the order their altars are placed.
+static void _build_overflow_temples(int level_number)
+{
+ if (!you.props.exists(OVERFLOW_TEMPLES_KEY))
+ // Levels built while in testing mode.
+ return;
+
+ CrawlVector &levels = you.props[OVERFLOW_TEMPLES_KEY].get_vector();
+
+ // Are we deeper than the last overflow temple?
+ if (level_number >= levels.size())
+ return;
+
+ CrawlStoreValue &val = levels[level_number];
+
+ // Does this level have an overflow temple?
+ if (val.get_flags() & SFLAG_UNSET)
+ return;
+
+ CrawlVector &temples = val.get_vector();
+
+ if (temples.size() == 0)
+ return;
+
+ if (!can_create_vault)
+ {
+ mpr("WARNING: Overriding can_create_vault",
+ MSGCH_DIAGNOSTICS);
+ can_create_vault = true;
+ }
+
+ mprf(MSGCH_DIAGNOSTICS, "Placing %lu overflow temples",
+ temples.size());
+
+ for (unsigned int i = 0; i < temples.size(); i++)
+ {
+ CrawlHashTable &temple = temples[i].get_table();
+
+ const int num_gods = _setup_temple_altars(temple);
+
+ const map_def *vault = NULL;
+
+ if (temple.exists(TEMPLE_MAP_KEY))
+ {
+ std::string name = temple[TEMPLE_MAP_KEY].get_string();
+
+ vault = find_map_by_name(name);
+ if (vault == NULL)
+ {
+ mprf(MSGCH_ERROR,
+ "Couldn't find overflow temple map '%s'!",
+ name.c_str());
+ }
+ }
+ else
+ {
+ std::string vault_tag =
+ make_stringf("overflow_temple_%d", num_gods);
+
+ vault = random_map_for_tag(vault_tag, true);
+ if (vault == NULL)
+ {
+ mprf(MSGCH_ERROR,
+ "Couldn't find overflow temple tag '%s'!",
+ vault_tag.c_str());
+ }
+ }
+
+ if (vault == NULL)
+ // Might as well build the rest of the level if we couldn't
+ // find the overflow temple map, so don't veto the level.
+ return;
+
+ if (!_ensure_vault_placed(_build_vaults(level_number, vault), false))
+ return;
+ }
+}
+
static void _build_dungeon_level(int level_number, int level_type)
{
spec_room sr;
@@ -1663,9 +1761,16 @@ static void _build_dungeon_level(int level_number, int level_type)
// Any further vaults must make sure not to disrupt level layout.
dgn_check_connectivity = !player_in_branch(BRANCH_SHOALS);
+ if (you.where_are_you == BRANCH_MAIN_DUNGEON)
+ {
+ _build_overflow_temples(level_number);
+
+ if (dgn_level_vetoed)
+ return;
+ }
+
// Try to place minivaults that really badly want to be placed. Still
// no guarantees, seeing this is a minivault.
-
_place_minivaults();
_place_branch_entrances( level_number, level_type );
_place_extra_vaults();
@@ -2517,6 +2622,18 @@ static const map_def *_dgn_random_map_for_place(bool minivault)
return (vault);
}
+static int _setup_temple_altars(CrawlHashTable &temple)
+{
+ CrawlVector god_list = temple[TEMPLE_GODS_KEY].get_vector();
+
+ _temple_altar_list.clear();
+
+ for (unsigned int i = 0; i < god_list.size(); i++)
+ _temple_altar_list.push_back( (god_type) god_list[i].get_byte() );
+
+ return ( (int) god_list.size() );
+}
+
// Returns BUILD_SKIP if we should skip further generation,
// BUILD_QUIT if we should immediately quit, and BUILD_CONTINUE
// otherwise.
@@ -4871,9 +4988,7 @@ static void _vault_grid( vault_placement &place,
(vgrid == ']') ? DNGN_STONE_STAIRS_DOWN_III :
(vgrid == '[') ? DNGN_STONE_STAIRS_UP_III :
(vgrid == 'A') ? DNGN_STONE_ARCH :
- (vgrid == 'B') ?
- static_cast<dungeon_feature_type>(
- DNGN_ALTAR_FIRST_GOD + place.altar_count) :// see below
+ (vgrid == 'B') ? _pick_temple_altar(place) :
(vgrid == 'C') ? _pick_an_altar() : // f(x) elsewhere {dlb}
(vgrid == 'I') ? DNGN_ORCISH_IDOL :
(vgrid == 'G') ? DNGN_GRANITE_STATUE :
@@ -4890,9 +5005,6 @@ static void _vault_grid( vault_placement &place,
// then, handle oddball grids {dlb}:
switch (vgrid)
{
- case 'B':
- place.altar_count++;
- break;
case '@':
place.exits.push_back( where );
break;
@@ -5311,6 +5423,21 @@ static void _many_pools(dungeon_feature_type pool_type)
}
} // end many_pools()
+static dungeon_feature_type _pick_temple_altar(vault_placement &place)
+{
+ if (_temple_altar_list.empty())
+ {
+ return (dungeon_feature_type)
+ (DNGN_ALTAR_FIRST_GOD + place.altar_count++);
+ }
+
+ const god_type god = _temple_altar_list.back();
+
+ _temple_altar_list.pop_back();
+
+ return altar_for_god(god);
+}
+
//jmf: Generate altar based on where you are, or possibly randomly.
static dungeon_feature_type _pick_an_altar()
{
diff --git a/crawl-ref/source/dungeon.h b/crawl-ref/source/dungeon.h
index f6932d1cb6..eb4fae762e 100644
--- a/crawl-ref/source/dungeon.h
+++ b/crawl-ref/source/dungeon.h
@@ -29,6 +29,12 @@
#define YOU_PORTAL_VAULT_NAMES_KEY "you_portal_vault_names_key"
+// See _build_overflow_temples() in dungeon.cc for details on overflow
+// temples.
+#define TEMPLE_GODS_KEY "temple_gods_key"
+#define OVERFLOW_TEMPLES_KEY "overflow_temples_key"
+#define TEMPLE_MAP_KEY "temple_map_key"
+
enum portal_type
{
PORTAL_NONE = 0,
diff --git a/crawl-ref/source/maps.cc b/crawl-ref/source/maps.cc
index 06a47f6100..7f6e304902 100644
--- a/crawl-ref/source/maps.cc
+++ b/crawl-ref/source/maps.cc
@@ -507,6 +507,7 @@ bool map_selector::accept(const map_def &mapdef) const
&& mapdef.place == place
&& !mapdef.has_tag("layout")
&& !mapdef.has_tag("place_unique")
+ && !mapdef.has_tag_prefix("overflow_temple_")
&& map_matches_layout_type(mapdef)
&& vault_unforbidden(mapdef));
case DEPTH:
@@ -522,6 +523,7 @@ bool map_selector::accept(const map_def &mapdef) const
&& !mapdef.has_tag("bazaar")
&& !mapdef.has_tag("layout")
&& !mapdef.has_tag("place_unique")
+ && !mapdef.has_tag_prefix("overflow_temple_")
&& (!check_layout || map_matches_layout_type(mapdef))
&& vault_unforbidden(mapdef));
case TAG:
diff --git a/crawl-ref/source/newgame.cc b/crawl-ref/source/newgame.cc
index 4223ef6c0e..f3115d6d48 100644
--- a/crawl-ref/source/newgame.cc
+++ b/crawl-ref/source/newgame.cc
@@ -893,6 +893,7 @@ game_start:
Generated_Levels.clear();
initialise_branch_depths();
+ initialise_temples();
init_level_connectivity();
// Generate the second name of Jiyva
diff --git a/crawl-ref/source/ng-init.cc b/crawl-ref/source/ng-init.cc
index 446c95af1a..ecc505cf05 100644
--- a/crawl-ref/source/ng-init.cc
+++ b/crawl-ref/source/ng-init.cc
@@ -10,9 +10,11 @@
#include "branch.h"
#include "describe.h"
+#include "dungeon.h"
#include "itemname.h"
#include "player.h"
#include "random.h"
+#include "store.h"
static unsigned char _random_potion_description()
{
@@ -64,6 +66,78 @@ void initialise_branch_depths()
branches[BRANCH_TOMB].startdepth = random_range(2, 3);
}
+#define MAX_OVERFLOW_LEVEL 9
+
+// Determine which altars go into the Ecumenical Temple, which go into
+// overflow temples, and on what level the overflow temples are.
+void initialise_temples()
+{
+ std::vector<god_type> god_list;
+
+ for (int i = 0; i < NUM_GODS; i++)
+ {
+ god_type god = (god_type) i;
+
+ // These never appear in any temples.
+ switch(god)
+ {
+ case GOD_NO_GOD:
+ case GOD_LUGONU:
+ case GOD_BEOGH:
+ case GOD_JIYVA:
+ continue;
+
+ default:
+ break;
+ }
+
+ god_list.push_back(god);
+ }
+
+ std::random_shuffle(god_list.begin(), god_list.end());
+
+ std::vector<god_type> overflow_gods;
+
+ while (god_list.size() > 12)
+ {
+ overflow_gods.push_back(god_list.back());
+ god_list.pop_back();
+ }
+
+ CrawlVector &temple_gods
+ = you.props[TEMPLE_GODS_KEY].new_vector(SV_BYTE);
+
+ for (unsigned int i = 0; i < god_list.size(); i++)
+ temple_gods.push_back( (char) god_list[i] );
+
+ CrawlVector &overflow_temples
+ = you.props[OVERFLOW_TEMPLES_KEY].new_vector(SV_VEC);
+ overflow_temples.resize(MAX_OVERFLOW_LEVEL);
+
+ // NOTE: The overflow temples don't have to contain only one
+ // altar; they can contain any number of altars, so long as there's
+ // at least one vault definition with the tag "overflow_temple_num"
+ // (where "num" is the number of altars).
+ for (unsigned int i = 0; i < overflow_gods.size(); i++)
+ {
+ const unsigned int level = random_range(2, MAX_OVERFLOW_LEVEL);
+
+ // List of overflow temples on this level.
+ CrawlVector &level_temples
+ = overflow_temples[level - 1].get_vector();
+
+ CrawlHashTable temple;
+
+ CrawlVector &gods
+ = temple[TEMPLE_GODS_KEY].new_vector(SV_BYTE);
+
+ // Only single-altar overflow temples for now.
+ gods.push_back( (char) overflow_gods[i] );
+
+ level_temples.push_back(temple);
+ }
+}
+
static int _get_random_porridge_desc()
{
return PDESCQ(PDQ_GLUGGY, one_chance_in(3) ? PDC_BROWN
diff --git a/crawl-ref/source/ng-init.h b/crawl-ref/source/ng-init.h
index 58fdce4514..dc41e8168d 100644
--- a/crawl-ref/source/ng-init.h
+++ b/crawl-ref/source/ng-init.h
@@ -3,6 +3,7 @@
void fix_up_jiyva_name();
void initialise_branch_depths();
+void initialise_temples();
void initialise_item_descriptions();
#endif
diff --git a/crawl-ref/source/wiz-dgn.cc b/crawl-ref/source/wiz-dgn.cc
index 5d178d02c1..2972d37398 100644
--- a/crawl-ref/source/wiz-dgn.cc
+++ b/crawl-ref/source/wiz-dgn.cc
@@ -366,6 +366,31 @@ void wizard_list_branches()
"this game", i, branches[i].longname);
}
}
+
+ if (!you.props.exists(OVERFLOW_TEMPLES_KEY))
+ return;
+
+ mpr("----", MSGCH_DIAGNOSTICS);
+ mpr("Overflow temples: ", MSGCH_DIAGNOSTICS);
+
+ CrawlVector &levels = you.props[OVERFLOW_TEMPLES_KEY].get_vector();
+
+ for (unsigned int i = 0; i < levels.size(); i++)
+ {
+ CrawlStoreValue &val = levels[i];
+
+ // Does this level have an overflow temple?
+ if (val.get_flags() & SFLAG_UNSET)
+ continue;
+
+ CrawlVector &temples = val.get_vector();
+
+ if (temples.size() == 0)
+ continue;
+
+ mprf(MSGCH_DIAGNOSTICS, "%lu on D:%lu", temples.size(),
+ i + 1);
+ }
}
void wizard_map_level()