summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authorzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-13 01:00:01 +0000
committerzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-13 01:00:01 +0000
commit42d0d63ae25d7ec3e5ded02ae77489cc5e8371f9 (patch)
treedfa131b93bdbc36c38bc31adb71d717ce44a659b /crawl-ref
parent43d6d67d143b01bacbf10dad61f460c7446db1fb (diff)
downloadcrawl-ref-42d0d63ae25d7ec3e5ded02ae77489cc5e8371f9.tar.gz
crawl-ref-42d0d63ae25d7ec3e5ded02ae77489cc5e8371f9.zip
Breaks savefile compatibility.
Allow Shadow Creatures spell (along with anything that uses create_monster(), mons_place(), place_monster() or pick_random_monster()) to work in portal vaults; only fixed ziggurats to use it. Must be done by manually calling dgn.set_random_mon_list(); can't automatically set it from MONS since the actual frequency of the monster specified that way is controlled by the number of 1/2/3/etc symbols that are in the map combined with symbol shufflings and substitutions. Can add an RMONS keyword to handle it if needed. Limitations: can only use level id or monster type + base type. Monster number (specific number of hydra heads), colour, items, band, and patrolling are all discarded/ignored. This can be improved if it's too limiting. New per-level env.properties CrawlHashTable stores the information. env.properties can be used to store new per-level data without breaking savefile compatibility (though changing the handling of old data in env.properties can still break compatibility). Random monster spawn rate is now controlled by the per-level env.spawn_random_rate (though the default rates are all the same as before), in case any weird portal vaults want to turn on random monster spawning. Could also be used to alter the random spawn rate for places like Vault:8 Prevented Shadow Creatues from working in the Temple. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7816 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/dat/clua/ziggurat.lua10
-rw-r--r--crawl-ref/source/dungeon.cc23
-rw-r--r--crawl-ref/source/externs.h12
-rw-r--r--crawl-ref/source/files.cc3
-rw-r--r--crawl-ref/source/luadgn.cc104
-rw-r--r--crawl-ref/source/mapdef.cc13
-rw-r--r--crawl-ref/source/mapdef.h4
-rw-r--r--crawl-ref/source/mon-util.cc29
-rw-r--r--crawl-ref/source/monplace.cc247
-rw-r--r--crawl-ref/source/monplace.h12
-rw-r--r--crawl-ref/source/tags.cc9
-rw-r--r--crawl-ref/source/travel.cc11
12 files changed, 462 insertions, 15 deletions
diff --git a/crawl-ref/source/dat/clua/ziggurat.lua b/crawl-ref/source/dat/clua/ziggurat.lua
index df33ae1aa0..a022da3c27 100644
--- a/crawl-ref/source/dat/clua/ziggurat.lua
+++ b/crawl-ref/source/dat/clua/ziggurat.lua
@@ -230,7 +230,7 @@ local function monster_creator_fn(arg)
end
return mcreator(x, y)
end
- return { fn = mspec }
+ return { fn = mspec, spec = arg }
elseif atyp == "table" then
if not arg.cond or arg.cond() then
return util.cathash(monster_creator_fn(arg.spec), arg)
@@ -273,6 +273,9 @@ mset_if(depth_lt(6), "place:Pan")
local drac_creator = dgn.monster_fn("random draconian")
local function mons_drac_gen(x, y, nth)
+ if nth == 1 then
+ dgn.set_random_mon_list("random draconian")
+ end
set_random_floor_colour()
return drac_creator(x, y)
end
@@ -283,6 +286,7 @@ local pan_critter_fn = dgn.monster_fn("place:Pan")
local function mons_panlord_gen(x, y, nth)
set_random_floor_colour()
if nth == 1 then
+ dgn.set_random_mon_list("place:Pan")
return pan_lord_fn(x, y)
else
return pan_critter_fn(x, y)
@@ -591,6 +595,10 @@ end
local function ziggurat_furnish(centre, entry, exit)
local monster_generation = choose_monster_set()
+ if type(monster_generation.spec) == "string" then
+ dgn.set_random_mon_list(monster_generation.spec)
+ end
+
-- If we're going to spawn jellies, do our loot protection thing.
if monster_generation.jelly_protect then
zig().level.jelly_protect = true
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index 335aba7330..3a43bfe349 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -883,6 +883,9 @@ static void _reset_level()
dgn_check_connectivity = false;
dgn_zones = 0;
+ // Forget level properties.
+ env.properties.clear();
+
// Blank level with DNGN_ROCK_WALL.
grd.init(DNGN_ROCK_WALL);
env.grid_colours.init(BLACK);
@@ -924,6 +927,26 @@ static void _reset_level()
else
env.level_flags = 0;
+ // Set default random monster generation rate (smaller is more often,
+ // except that 0 == no random monsters).
+ if (you.level_type == LEVEL_DUNGEON)
+ {
+ if (you.where_are_you == BRANCH_ECUMENICAL_TEMPLE)
+ env.spawn_random_rate = 0;
+ else
+ env.spawn_random_rate = 240;
+ }
+ else if (you.level_type == LEVEL_ABYSS
+ || you.level_type == LEVEL_PANDEMONIUM)
+ {
+ // Abyss spawn rate is set for those characters that start out in the
+ // Abyss; otherwise the number is ignored in the Abyss.
+ env.spawn_random_rate = 50;
+ }
+ else
+ // No random monsters in Labyrinths and portal vaualts.
+ env.spawn_random_rate = 0;
+
env.floor_colour = BLACK;
env.rock_colour = BLACK;
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index 4be82a7c62..7cdaad0d20 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -491,6 +491,7 @@ public:
}
static level_id parse_level_id(const std::string &s) throw (std::string);
+ static level_id from_packed_place(const unsigned short place);
unsigned short packed_place() const;
std::string describe(bool long_name = false, bool with_number = true) const;
@@ -1685,7 +1686,16 @@ public:
FixedVector< monster_type, 20 > mons_alloc;
map_markers markers;
- double elapsed_time; // used during level load
+ // Place to associate arbitrary data with a particular level.
+ // Sort of like player::atribute
+ CrawlHashTable properties;
+
+ // Rate at which random monsters spawn, with lower numbers making
+ // them spawn more often (5 or less causes one to spawn about every
+ // 5 turns). Set to 0 to stop random generation.
+ int spawn_random_rate;
+
+ double elapsed_time; // used during level load
// Number of turns the player has spent on this level.
int turns_on_level;
diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc
index 4bdf77b5f1..17aa7aaece 100644
--- a/crawl-ref/source/files.cc
+++ b/crawl-ref/source/files.cc
@@ -9,6 +9,7 @@
#include "AppHdr.h"
#include "delay.h"
#include "files.h"
+#include "monplace.h"
#include "version.h"
#include <string.h>
@@ -1292,6 +1293,8 @@ bool load( dungeon_feature_type stair_taken, load_mode_type load_mode,
setup_environment_effects();
+ setup_vault_mon_list();
+
// Inform user of level's annotation.
if (load_mode != LOAD_VISITOR
&& !get_level_annotation().empty()
diff --git a/crawl-ref/source/luadgn.cc b/crawl-ref/source/luadgn.cc
index 79a97ed07b..e4f9096681 100644
--- a/crawl-ref/source/luadgn.cc
+++ b/crawl-ref/source/luadgn.cc
@@ -28,6 +28,7 @@
#include "maps.h"
#include "misc.h"
#include "mon-util.h"
+#include "monplace.h"
#include "spl-util.h"
#include "state.h"
#include "stuff.h"
@@ -601,6 +602,108 @@ static int dgn_change_branch_flags(lua_State *ls)
return (1);
}
+static int dgn_set_random_mon_list(lua_State *ls)
+{
+ if (you.level_type != LEVEL_PORTAL_VAULT)
+ {
+ luaL_error(ls, "Can only be used in portal vaults.");
+ return (0);
+ }
+
+ mons_list mlist = _lua_get_mlist(ls, 1);
+
+ if (mlist.size() == 0)
+ return (0);
+
+ if (mlist.size() > 1)
+ {
+ luaL_argerror(ls, 1, "Mon list must contain only one slot.");
+ return (0);
+ }
+
+ const int num_mons = mlist.slot_size(0);
+
+ if (num_mons == 0)
+ {
+ luaL_argerror(ls, 1, "Mon list is empty.");
+ return (0);
+ }
+
+ std::vector<mons_spec> mons;
+ int num_lords = 0;
+ for (int i = 0; i < num_mons; i++)
+ {
+ mons_spec mon = mlist.get_monster(0, i);
+
+ // Pandemonium lords are pseudo-unique, so don't randomly generate
+ // them.
+ if (mon.mid == MONS_PANDEMONIUM_DEMON)
+ {
+ num_lords++;
+ continue;
+ }
+
+ std::string name;
+ if (mon.place.is_valid())
+ {
+ if (mon.place.level_type == LEVEL_LABYRINTH
+ || mon.place.level_type == LEVEL_PORTAL_VAULT)
+ {
+ std::string err;
+ err = make_stringf("mon #%d: Can't use Lab or Portal as a "
+ "monster place.", i + 1);
+ luaL_argerror(ls, 1, err.c_str());
+ return(0);
+ }
+ name = mon.place.describe();
+ }
+ else
+ {
+ if (mon.mid == RANDOM_MONSTER || mon.monbase == RANDOM_MONSTER)
+ {
+ std::string err;
+ err = make_stringf("mon #%d: can't use random monster in "
+ "list specifying random monsters", i + 1);
+ luaL_argerror(ls, 1, err.c_str());
+ return(0);
+ }
+ name = mons_type_name(mon.mid, DESC_PLAIN);
+ }
+
+ mons.push_back(mon);
+
+ if (mon.number != 0)
+ mprf(MSGCH_ERROR, "dgn.set_random_mon_list() : number for %s "
+ "being discarded.",
+ name.c_str());
+
+ if (mon.band)
+ mprf(MSGCH_ERROR, "dgn.set_random_mon_list() : band request for "
+ "%s being ignored.",
+ name.c_str());
+
+ if (mon.colour != BLACK)
+ mprf(MSGCH_ERROR, "dgn.set_random_mon_list() : colour for "
+ "%s being ignored.",
+ name.c_str());
+
+ if (mon.items.size() > 0)
+ mprf(MSGCH_ERROR, "dgn.set_random_mon_list() : items for "
+ "%s being ignored.",
+ name.c_str());
+ } // for (int i = 0; i < num_mons; i++)
+
+ if (mons.size() == 0 && num_lords > 0)
+ {
+ luaL_argerror(ls, 1, "Mon list contains only pandemonium lords.");
+ return (0);
+ }
+
+ set_vault_mon_list(mons);
+
+ return (0);
+}
+
static int dgn_chance(lua_State *ls)
{
MAP(ls, 1, map);
@@ -2799,6 +2902,7 @@ static const struct luaL_reg dgn_lib[] =
{ "items_at", dgn_items_at },
{ "change_level_flags", dgn_change_level_flags },
{ "change_branch_flags", dgn_change_branch_flags },
+ { "set_random_mon_list", dgn_set_random_mon_list },
{ "get_floor_colour", dgn_get_floor_colour },
{ "get_rock_colour", dgn_get_rock_colour },
{ "change_floor_colour", dgn_change_floor_colour },
diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc
index 7266116331..446583ef5c 100644
--- a/crawl-ref/source/mapdef.cc
+++ b/crawl-ref/source/mapdef.cc
@@ -1990,6 +1990,19 @@ mons_spec mons_list::get_monster(int index)
return (pick_monster( mons[index] ));
}
+mons_spec mons_list::get_monster(int slot_index, int list_index) const
+{
+ if (slot_index < 0 || slot_index >= (int) mons.size())
+ return mons_spec(RANDOM_MONSTER);
+
+ const mons_spec_list &list = mons[slot_index].mlist;
+
+ if (list_index < 0 || list_index >= (int) list.size())
+ return mons_spec(RANDOM_MONSTER);
+
+ return list[list_index];
+}
+
void mons_list::clear()
{
mons.clear();
diff --git a/crawl-ref/source/mapdef.h b/crawl-ref/source/mapdef.h
index 8b2a40260e..68d62b5851 100644
--- a/crawl-ref/source/mapdef.h
+++ b/crawl-ref/source/mapdef.h
@@ -447,12 +447,14 @@ public:
void clear();
mons_spec get_monster(int index);
+ mons_spec get_monster(int slot_index, int list_index) const;
// Returns an error string if the monster is unrecognised.
std::string add_mons(const std::string &s, bool fix_slot = false);
std::string set_mons(int slot, const std::string &s);
- size_t size() const { return mons.size(); }
+ size_t size() const { return mons.size(); }
+ size_t slot_size(int slot) const { return mons[slot].mlist.size(); }
private:
typedef std::vector<mons_spec> mons_spec_list;
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 38be768b2f..f0e7e8ea33 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -2105,7 +2105,34 @@ std::string mons_type_name(int type, description_level_type desc )
}
}
- result += get_monster_data(type)->name;
+ switch(type)
+ {
+ case RANDOM_MONSTER:
+ result += "random monster";
+ return (result);
+ case RANDOM_DRACONIAN:
+ result += "random draconian";
+ return (result);
+ case RANDOM_BASE_DRACONIAN:
+ result += "random base draconian";
+ return (result);
+ case RANDOM_NONBASE_DRACONIAN:
+ result += "random nonbase draconian";
+ return (result);
+ case WANDERING_MONSTER:
+ result += "wandering monster";
+ return (result);
+ }
+
+ const monsterentry *me = get_monster_data(type);
+ ASSERT(me != NULL);
+ if (me == NULL)
+ {
+ result += make_stringf("invalid type %d", type);
+ return (result);
+ }
+
+ result += me->name;
// Vowel fix: Change 'a orc' to 'an orc'.
if (result.length() >= 3
diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc
index 753095e6b3..a95a26a04f 100644
--- a/crawl-ref/source/monplace.cc
+++ b/crawl-ref/source/monplace.cc
@@ -29,6 +29,14 @@
#include "traps.h"
#include "view.h"
+static std::vector<int> vault_mon_types;
+static std::vector<int> vault_mon_bases;
+static std::vector<int> vault_mon_weights;
+
+#define VAULT_MON_TYPES_KEY "vault_mon_types"
+#define VAULT_MON_BASES_KEY "vault_mon_bases"
+#define VAULT_MON_WEIGHTS_KEY "vault_mon_weights"
+
// NEW place_monster -- note that power should be set to:
// 51 for abyss
// 52 for pandemonium
@@ -41,6 +49,14 @@
#define BIG_BAND 20
+static monster_type _resolve_monster_type(monster_type mon_type,
+ proximity_type proximity,
+ monster_type &base_type,
+ coord_def &pos,
+ unsigned mmask,
+ dungeon_char_type *stair_type,
+ int *lev_mons);
+
static void _define_zombie( int mid, monster_type ztype,
monster_type cs, int power, coord_def pos );
static monster_type _band_member(band_type band, int power);
@@ -219,10 +235,19 @@ void spawn_random_monsters()
return;
}
+ if (env.spawn_random_rate == 0)
+ {
+#ifdef DEBUG_MON_CREATION
+ mpr("random monster gen turned off", MSGCH_DIAGNOSTICS);
+#endif
+ return;
+ }
+
+ const int rate = (you.char_direction == GDT_DESCENDING) ?
+ env.spawn_random_rate : 8;
+
// Place normal dungeon monsters, but not in player LOS.
- if (you.level_type == LEVEL_DUNGEON
- && !player_in_branch( BRANCH_ECUMENICAL_TEMPLE )
- && x_chance_in_y(5, (you.char_direction == GDT_DESCENDING) ? 240 : 8))
+ if (you.level_type == LEVEL_DUNGEON && x_chance_in_y(5, rate))
{
#ifdef DEBUG_MON_CREATION
mpr("Create wandering monster...", MSGCH_DIAGNOSTICS);
@@ -245,7 +270,8 @@ void spawn_random_monsters()
// look a bit strange for a place as chaotic as the Abyss. Then again,
// the player is unlikely to meet all of them and notice this.)
if (you.level_type == LEVEL_ABYSS
- && (you.char_direction != GDT_GAME_START || one_chance_in(10)))
+ && (you.char_direction != GDT_GAME_START
+ || x_chance_in_y(5, rate)))
{
mons_place(mgen_data(WANDERING_MONSTER));
viewwindow(true, false);
@@ -253,28 +279,58 @@ void spawn_random_monsters()
}
// Place Pandemonium monsters.
- if (you.level_type == LEVEL_PANDEMONIUM && one_chance_in(10))
+ if (you.level_type == LEVEL_PANDEMONIUM && x_chance_in_y(5, rate))
{
pandemonium_mons();
viewwindow(true, false);
+ return;
+ }
+
+ // A portal vault *might* decide to turn on random monster spawning,
+ // but it's off by default.
+ if (you.level_type == LEVEL_PORTAL_VAULT && x_chance_in_y(5, rate))
+ {
+ mons_place(mgen_data(WANDERING_MONSTER));
+ viewwindow(true, false);
}
- // No monsters in the Labyrinth, or the Ecumenical Temple, or in Bazaars.
+ // No random monsters in the Labyrinth.
}
monster_type pick_random_monster(const level_id &place)
{
- int level = place.absdepth();
+ int level;
+ if (place.level_type == LEVEL_PORTAL_VAULT)
+ level = you.your_level;
+ else
+ level = place.absdepth();
return pick_random_monster(place, level, level);
}
monster_type pick_random_monster(const level_id &place, int power,
int &lev_mons)
{
- if (place.level_type == LEVEL_LABYRINTH
- || place.level_type == LEVEL_PORTAL_VAULT)
- {
+ if (place.level_type == LEVEL_LABYRINTH)
+ return (MONS_PROGRAM_BUG);
+
+ if (place == BRANCH_ECUMENICAL_TEMPLE)
return (MONS_PROGRAM_BUG);
+
+ if (place.level_type == LEVEL_PORTAL_VAULT)
+ {
+ monster_type base_type = (monster_type) 0;
+ coord_def dummy1;
+ dungeon_char_type dummy2;
+ monster_type type =
+ _resolve_monster_type(RANDOM_MONSTER, PROX_ANYWHERE, base_type,
+ dummy1, 0, &dummy2, &lev_mons);
+
+#if DEBUG || DEBUG_DIAGNOSTICS
+ if (base_type != 0 && base_type != MONS_PROGRAM_BUG)
+ mpr("Random portal vault mon discarding base type.",
+ MSGCH_ERROR);
+#endif
+ return (type);
}
monster_type mon_type = MONS_PROGRAM_BUG;
@@ -395,7 +451,7 @@ bool drac_colour_incompatible(int drac, int colour)
static monster_type _resolve_monster_type(monster_type mon_type,
proximity_type proximity,
- monster_type base_type,
+ monster_type &base_type,
coord_def &pos,
unsigned mmask,
dungeon_char_type *stair_type,
@@ -495,6 +551,44 @@ static monster_type _resolve_monster_type(monster_type mon_type,
mon_type = MONS_DANCING_WEAPON;
else
{
+ if (you.level_type == LEVEL_PORTAL_VAULT)
+ {
+ if (vault_mon_types.size() == 0)
+ return (MONS_PROGRAM_BUG);
+
+ int i = choose_random_weighted(vault_mon_weights.begin(),
+ vault_mon_weights.end());
+ int type = vault_mon_types[i];
+ int base = vault_mon_bases[i];
+
+ if (type == -1)
+ {
+ place = level_id::from_packed_place(base);
+ // If lev_mons is set to you.your_level, it was probably
+ // set as a default meaning "the current dungeon depth",
+ // which for a portal vault using it's own definition
+ // of random monsters means "the depth of whatever place
+ // we're using for picking the random monster".
+ if (*lev_mons == you.your_level)
+ *lev_mons = place.absdepth();
+ // pick_random_monster() is called below
+ }
+ else
+ {
+ base_type = (monster_type) base;
+ mon_type = (monster_type) type;
+ if (mon_type == RANDOM_DRACONIAN
+ || mon_type == RANDOM_BASE_DRACONIAN
+ || mon_type == RANDOM_NONBASE_DRACONIAN)
+ {
+ mon_type =
+ _resolve_monster_type(mon_type, proximity,
+ base_type, pos, mmask,
+ stair_type, lev_mons);
+ }
+ return (mon_type);
+ }
+ }
// Now pick a monster of the given branch and level.
mon_type = pick_random_monster(place, *lev_mons, *lev_mons);
}
@@ -2836,3 +2930,134 @@ void monster_pathfind::update_pos(coord_def npos, int total)
add_new_pos(npos, total);
}
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Random monsters for portal vaults.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+void set_vault_mon_list(const std::vector<mons_spec> &list)
+{
+ CrawlHashTable &props = env.properties;
+
+ props.erase(VAULT_MON_TYPES_KEY);
+ props.erase(VAULT_MON_BASES_KEY);
+ props.erase(VAULT_MON_WEIGHTS_KEY);
+
+ unsigned int size = list.size();
+ if (size == 0)
+ {
+ setup_vault_mon_list();
+ return;
+ }
+
+ props[VAULT_MON_TYPES_KEY].new_vector(SV_LONG).resize(size);
+ props[VAULT_MON_BASES_KEY].new_vector(SV_LONG).resize(size);
+ props[VAULT_MON_WEIGHTS_KEY].new_vector(SV_LONG).resize(size);
+
+ CrawlVector &type_vec = props[VAULT_MON_TYPES_KEY];
+ CrawlVector &base_vec = props[VAULT_MON_BASES_KEY];
+ CrawlVector &weight_vec = props[VAULT_MON_WEIGHTS_KEY];
+
+ for (unsigned int i = 0; i < size; i++)
+ {
+ const mons_spec &spec = list[i];
+
+ if (spec.place.is_valid())
+ {
+ ASSERT(spec.place.level_type != LEVEL_LABYRINTH
+ && spec.place.level_type != LEVEL_PORTAL_VAULT);
+ type_vec[i] = (long) -1;
+ base_vec[i] = (long) spec.place.packed_place();
+ }
+ else
+ {
+ ASSERT(spec.mid != RANDOM_MONSTER
+ && spec.monbase != RANDOM_MONSTER);
+ type_vec[i] = (long) spec.mid;
+ base_vec[i] = (long) spec.monbase;
+ }
+ weight_vec[i] = (long) spec.genweight;
+ }
+
+ setup_vault_mon_list();
+}
+
+void get_vault_mon_list(std::vector<mons_spec> &list)
+{
+ list.clear();
+
+ CrawlHashTable &props = env.properties;
+
+ if (!props.exists(VAULT_MON_TYPES_KEY))
+ return;
+
+ ASSERT(props.exists(VAULT_MON_BASES_KEY));
+ ASSERT(props.exists(VAULT_MON_WEIGHTS_KEY));
+
+ CrawlVector &type_vec = props[VAULT_MON_TYPES_KEY];
+ CrawlVector &base_vec = props[VAULT_MON_BASES_KEY];
+ CrawlVector &weight_vec = props[VAULT_MON_WEIGHTS_KEY];
+
+ ASSERT(type_vec.size() == base_vec.size());
+ ASSERT(type_vec.size() == weight_vec.size());
+
+ unsigned int size = type_vec.size();
+ for (unsigned int i = 0; i < size; i++)
+ {
+ int type = (long) type_vec[i];
+ int base = (long) base_vec[i];
+
+ mons_spec spec;
+
+ if (type == -1)
+ {
+ spec.place = level_id::from_packed_place(base);
+ ASSERT(spec.place.is_valid());
+ ASSERT(spec.place.level_type != LEVEL_LABYRINTH
+ && spec.place.level_type != LEVEL_PORTAL_VAULT);
+ }
+ else
+ {
+ spec.mid = type;
+ spec.monbase = (monster_type) base;
+ ASSERT(spec.mid != RANDOM_MONSTER
+ && spec.monbase != RANDOM_MONSTER);
+ }
+ spec.genweight = (long) weight_vec[i];
+
+ list.push_back(spec);
+ }
+}
+
+void setup_vault_mon_list()
+{
+ vault_mon_types.clear();
+ vault_mon_bases.clear();
+ vault_mon_weights.clear();
+
+ std::vector<mons_spec> list;
+ get_vault_mon_list(list);
+
+ unsigned int size = list.size();
+
+ vault_mon_types.resize(size);
+ vault_mon_bases.resize(size);
+ vault_mon_weights.resize(size);
+
+ for (unsigned int i = 0; i < size; i++)
+ {
+ if (list[i].place.is_valid())
+ {
+ vault_mon_types[i] = -1;
+ vault_mon_bases[i] = list[i].place.packed_place();
+ }
+ else
+ {
+ vault_mon_types[i] = list[i].mid;
+ vault_mon_bases[i] = list[i].monbase;
+ }
+ vault_mon_weights[i] = list[i].genweight;
+ }
+}
diff --git a/crawl-ref/source/monplace.h b/crawl-ref/source/monplace.h
index 2b4529e59f..24be04f149 100644
--- a/crawl-ref/source/monplace.h
+++ b/crawl-ref/source/monplace.h
@@ -340,6 +340,18 @@ coord_def find_newmons_square_contiguous(monster_type mons_class,
void spawn_random_monsters();
+/* ***********************************************************************
+ * called from: luadgn
+ * *********************************************************************** */
+void set_vault_mon_list(const std::vector<mons_spec> &list);
+
+void get_vault_mon_list(std::vector<mons_spec> &list);
+
+/* ***********************************************************************
+ * called from: files
+ * *********************************************************************** */
+void setup_vault_mon_list();
+
class monster_pathfind
{
public:
diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc
index 9f1bae2103..ce8154f240 100644
--- a/crawl-ref/source/tags.cc
+++ b/crawl-ref/source/tags.cc
@@ -1726,7 +1726,10 @@ static void tag_construct_level(writer &th)
marshallCoord(th, env.sanctuary_pos);
marshallByte(th, env.sanctuary_time);
+ marshallLong(th, env.spawn_random_rate);
+
env.markers.write(th);
+ env.properties.write(th);
}
void marshallItem(writer &th, const item_def &item)
@@ -2003,6 +2006,7 @@ void tag_construct_level_tiles(writer &th)
static void tag_read_level( reader &th, char minorVersion )
{
+
env.floor_colour = unmarshallByte(th);
env.rock_colour = unmarshallByte(th);
@@ -2070,7 +2074,12 @@ static void tag_read_level( reader &th, char minorVersion )
unmarshallCoord(th, env.sanctuary_pos);
env.sanctuary_time = unmarshallByte(th);
+ env.spawn_random_rate = unmarshallLong(th);
+
env.markers.read(th, minorVersion);
+
+ env.properties.clear();
+ env.properties.read(th);
}
static void tag_read_level_items(reader &th, char minorVersion)
diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc
index ea38dd925a..ecef971888 100644
--- a/crawl-ref/source/travel.cc
+++ b/crawl-ref/source/travel.cc
@@ -3118,6 +3118,17 @@ level_id level_id::parse_level_id(const std::string &s) throw (std::string)
return level_id(br, dep);
}
+level_id level_id::from_packed_place(const unsigned short place)
+{
+ level_id id;
+
+ id.branch = (branch_type) place_branch(place);
+ id.depth = place_depth(place);
+ id.level_type = (level_area_type) place_type(place);
+
+ return (id);
+}
+
// NOTE: see also marshall_level_id
void level_id::save(writer& outf) const
{