summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/dat/vaults.des246
-rw-r--r--crawl-ref/source/dungeon.cc101
-rw-r--r--crawl-ref/source/mapdef.cc137
-rw-r--r--crawl-ref/source/mapdef.h98
-rw-r--r--crawl-ref/source/maps.cc39
-rw-r--r--crawl-ref/source/maps.h6
-rw-r--r--crawl-ref/source/util/levcomp.ypp9
7 files changed, 449 insertions, 187 deletions
diff --git a/crawl-ref/source/dat/vaults.des b/crawl-ref/source/dat/vaults.des
index 5ce6bbfda0..25dedd0e0d 100644
--- a/crawl-ref/source/dat/vaults.des
+++ b/crawl-ref/source/dat/vaults.des
@@ -368,23 +368,23 @@ TAGS: entry no_monster_gen
ORIENT: float
MAP
-xxxxxxxxxxxxxxxxxxxxxxx
-xxxxx{.....(.....[xxxxx
-xxxxx.............xxxxx
-xxxxxx...........xxxxxx
-xxxxxx...........xxxxxx
-xxxxxxx.........xxxxxxx
-xxxxxxx.........xxxxxxx
-xxxxxxxx.......xxxxxxxx
-xxxxxxxx.......xxxxxxxx
-xxxxxxxxx.....xxxxxxxxx
-xxxxxxxxx.....xxxxxxxxx
-xxxxxxxxxx...xxxxxxxxxx
-xxxxxxxxxx...xxxxxxxxxx
-xxxxxxxxxx...xxxxxxxxxx
-xxxxxxxxxx+++xxxxxxxxxx
-xxxxxxxxxx...xxxxxxxxxx
-ENDMAP
+xxxxxxxxxxxxxxx
+x{.....(.....[x
+x.............x
+xx...........xx
+xx...........xx
+xxx.........xxx
+xxx.........xxx
+xxxx.......xxxx
+xxxx.......xxxx
+xxxxx.....xxxxx
+xxxxx.....xxxxx
+xxxxxx...xxxxxx
+xxxxxx...xxxxxx
+xxxxxx...xxxxxx
+xxxxxx+++xxxxxx
+xxxxxx...xxxxxx
+ENDMAP
##############################################################################
# lemuel_entrance_muddy
@@ -393,31 +393,106 @@ NAME: lemuel_entrance_muddy
TAGS: entry no_monster_gen
ORIENT: float
MAP
-xxxxxxxxxxxxxxxxxxxxxxx
-xxxxx{..1..(.1ww.[xxxxx
-xxxxx1.........ww.xxxxx
-xxxxxx..w..1....1.xxxxx
-xxxxxx........2...xxxxx
-xxxxxw...1......w.xxxxx
-xxxxxw...........xxxxxx
-xxxxx.1....2......xxxxx
-xxxxx1......w2....xxxxx
-xxxxx............xxxxxx
-xxxxxx..........xxxxxxx
-xxxxxx..........xxxxxxx
-xxxxxx...2......xxxxxxx
-xxxxx...........xxxxxxx
-xxxxx.2.w......xxxxxxxx
-xxxxxxx..2.....xxxxxxxx
-xxxxxxx......2xxxxxxxxx
-xxx.........xxxxxxxxxxx
-xx..xx......xxxxxxxxxxx
-...xxxxx.....xxxxxxxxxx
-xxxxxxxxxx....xxxxxxxxx
-xxxxxxxxxxxx...xxxxxxxx
+xxxxxxxxxxxxxxxxxxx
+xxxxx{..1..(.1ww.[x
+xxxxx1.........ww.x
+xxxxxx..w..1....1.x
+xxxxxx........2...x
+xxxxxw...1......w.x
+xxxxxw...........xx
+xxxxx.1....2......x
+xxxxx1......w2....x
+xxxxx............xx
+xxxxxx..........xxx
+xxxxxx..........xxx
+xxxxxx...2......xxx
+xxxxx...........xxx
+xxxxx.2.w......xxxx
+xxxxxxx..2.....xxxx
+xxxxxxx......2xxxxx
+xxx.........xxxxxxx
+xx..xx......xxxxxxx
+...xxxxx.....xxxxxx
+xxxxxxxxxx....xxxxx
+xxxxxxxxxxxx...xxxx
ENDMAP
MONS: plant, fungus
+###################################
+# broad hall
+NAME: lemuel_hall
+TAGS: entry
+ORIENT: float
+
+MAP
+xxxxxxxxxxx
+x{...(...[x
+x.........x
+x.x.....x.x
+x.........x
+x.........x
+x.x.....x.x
+x.........x
+x.........x
+x.x.....x.x
+x.........x
+x.........x
+x.x.....x.x
+x.........x
+x.........x
+x.x.....x.x
+x.........x
+x@...@...@x
+ENDMAP
+
+###################################
+# broad hall with supply closet
+NAME: lemuel_hall2
+TAGS: entry
+ORIENT: float
+ITEM: meat ration / bread ration / beef jerky / spear / potion of water / apple / club / hammer / knife
+
+MAP
+xxxxxxxxxxxx
+x{...(...[xx
+x.........xx
+x.x.....x.xx
+x.........xx
+x.........xx
+x.x.....x.xx
+x.........xx
+x.........xxxxxx
+x.x.....x.xxxddx
+x.........=..ddx
+x.........xxxxxx
+x.x.....x.xx
+x.........xx
+x.........xx
+x.x.....x.xx
+x.........xx
+x@...@...@xx
+ENDMAP
+
+###################################
+# behind the green door
+NAME: lemuel_green
+TAGS: entry
+ORIENT: float
+
+MAP
+xxxxxxxxxxx
+x{...(...[x
+x.........x
+x.........x
+x.........x
+x.........x
+x.........x
+x.........x
+x.........x
+xbbbb+bbbbx
+x....@....x
+ENDMAP
+
##############################################################################
# David's entry vaults
##############################################################################
@@ -2902,6 +2977,99 @@ ENDMAP
# Regular vaults
##############################################################################
+###################################
+# Hellmouth (Lemuel)
+# note that other than the imps, the demons here cannot fly
+NAME: hellmouth_1
+FLAGS: no_rotate
+MONS: imp / quasit / shadow imp, hellion / rotting devil / iron devil / hairy devil / hell hound
+ITEM: good_item demon blade / good_item demon whip / good_item demon trident / wand of draining / wand of fire / ring of fire / Necronomicon / book of demonology / scroll of torment
+ORIENT: float
+
+MAP
+xxxxxxxxxxxxxxxxxxx
+xxxxxxxxlllxxxxxxxx
+xxxxxxlllAlllxxxxxx
+xxxlllll.d.llll.xxx
+xlllllll121lllll..x
+x.lllllll1llll....x
+x...llllllll......x
+x....llllll.......x
+x.....lllll.......x
+xxx....lll......xxx
+xxxx...lll.....xxxx
+xxxxx..ll.....xxxxx
+xxxxx.lll.....xxxxx
+xxxxxxlll....xxxxxx
+xxxxxxxlll...xxxxxx
+xxxxxxxxll..xxxxxxx
+xxxxxxxxll..xxxxxxx
+xxxxxxxxl.@xxxxxxxx
+ENDMAP
+
+###################################
+# Hellmouth 2 (Lemuel)
+# note that other than the imps, the demons here cannot fly
+NAME: hellmouth_2
+TAGS: no_monster_gen
+FLAGS: no_rotate
+MONS: imp / quasit / shadow imp / manes / lemure
+MONS: hellion / rotting devil / iron devil / hairy devil / hell hound
+ITEM: good_item demon blade / good_item demon whip / good_item demon trident / wand of draining / wand of fire / ring of fire / Necronomicon / book of demonology / scroll of torment
+ITEM: good_item demon blade / good_item demon whip / good_item demon trident
+ORIENT: float
+
+MAP
+.......bbbbbbbbbbbb.......
+....bbbb..........bbbb....
+..bbb....llllllll....bbb..
+.bb....llllllllllll....bb.
+.b....llllllllllllll....b.
+.b....llllll..llllll....b.
+.b....lll........lll....b.
+.b....ll....111...ll....b.
+.+....l....11211d..l....b.
+.+....l....12A21|e.l....b.
+.b....ll...11211d.ll....b.
+.b....lll...111..lll....b.
+.b....llll......llll....b.
+.b....llllll..llllll....b.
+.bb....llllllllllll....bb.
+..bbb....llllllll....bbb..
+....bbbb..........bbbb....
+.......bbbbbbbbbbbb.......
+ENDMAP
+
+###################################
+# Hellmouth 3 (Lemuel)
+NAME: hellmouth_3
+MONS: weight:50 imp / quasit / shadow imp / manes / lemure, hell hound
+ITEM: good_item demon blade / good_item demon whip / good_item demon trident
+ORIENT: float
+
+MAP
+................l.............
+..............................
+................l.............
+....ll..........l.............
+...lll..........l.............
+....l..........l..............
+.............lll..............
+..........lllllll.............
+........llllllllll............
+.......lll111111llll..........
+.......llll12Ad1lll...........
+........lll11111ll............
+.........lllll1ll.............
+...........llllll.............
+............llll......ll......
+.............ll........ll.....
+..............................
+...................l..........
+ENDMAP
+
+#############################################################################
+
NAME: vault_1
ORIENT: north
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index ce7989e770..959d44d3b6 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -147,10 +147,9 @@ static void jelly_pit(int level_number, spec_room &sr);
// VAULT FUNCTIONS
static void build_vaults(int level_number, int vault_number);
static void build_minivaults(int level_number, int force_vault);
-static int vault_grid( const vault_placement &,
+static int vault_grid( vault_placement &,
int level_number, int vx, int vy, int altar_count,
FixedVector < char, 7 > &acq_item_class,
- FixedVector < int, 7 > &mons_array,
char vgrid, std::vector<coord_def> &targets,
int &num_runes );
@@ -5187,17 +5186,9 @@ static void build_minivaults(int level_number, int force_vault)
acq_item_class[5] = OBJ_STAVES;
acq_item_class[6] = OBJ_MISCELLANY;
- FixedVector < int, 7 > mons_array(RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER);
-
map_type vgrid;
vault_placement place;
- vault_main(vgrid, mons_array, place, force_vault, level_number);
+ vault_main(vgrid, place, force_vault, level_number);
int vx, vy;
int v1x, v1y;
@@ -5274,7 +5265,7 @@ static void build_minivaults(int level_number, int force_vault)
{
altar_count = vault_grid( place,
level_number, vx, vy, altar_count,
- acq_item_class, mons_array,
+ acq_item_class,
grd[vx][vy], dummy,
num_runes );
}
@@ -5283,7 +5274,7 @@ static void build_minivaults(int level_number, int force_vault)
no_door_fixup_zones.push_back(
dgn_region( place.x, place.y, place.width, place.height ) );
- if (place.map->has_tag("no_pool_fixup"))
+ if (place.map.has_tag("no_pool_fixup"))
no_pool_fixup_zones.push_back(
dgn_region( place.x, place.y, place.width, place.height ) );
} // end build_minivaults()
@@ -5370,7 +5361,7 @@ static void build_rooms(const dgn_region_list &excluded,
}
}
-static coord_def dig_away_dir(const vault_placement &place,
+static coord_def dig_away_dir(vault_placement &place,
const coord_def &pos)
{
// Figure out which way we need to go to dig our way out of the vault.
@@ -5389,7 +5380,7 @@ static coord_def dig_away_dir(const vault_placement &place,
return (dig_dir);
}
-static void dig_away_from(const vault_placement &place, const coord_def &pos)
+static void dig_away_from(vault_placement &place, const coord_def &pos)
{
coord_def dig_dir = dig_away_dir(place, pos);
coord_def dig_at = pos;
@@ -5434,14 +5425,14 @@ static void dig_away_from(const vault_placement &place, const coord_def &pos)
}
static void dig_vault_loose(
- const vault_placement &place,
+ vault_placement &place,
std::vector<coord_def> &targets)
{
for (int i = 0, size = targets.size(); i < size; ++i)
dig_away_from(place, targets[i]);
}
-static void pick_float_exits(const vault_placement &place,
+static void pick_float_exits(vault_placement &place,
std::vector<coord_def> &targets)
{
std::vector<coord_def> possible_exits;
@@ -5494,19 +5485,10 @@ static void build_vaults(int level_number, int force_vault)
acq_item_class[5] = OBJ_STAVES;
acq_item_class[6] = OBJ_MISCELLANY;
- FixedVector < int, 7 > mons_array(RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER);
-
map_type vgrid;
vault_placement place;
- int gluggy =
- vault_main(vgrid, mons_array, place, force_vault, level_number);
+ int gluggy = vault_main(vgrid, place, force_vault, level_number);
int vx, vy;
int num_runes = 0;
@@ -5519,7 +5501,7 @@ static void build_vaults(int level_number, int force_vault)
{
altar_count = vault_grid( place,
level_number, vx, vy, altar_count,
- acq_item_class, mons_array,
+ acq_item_class,
vgrid[vy][vx],
target_connections,
num_runes );
@@ -5529,11 +5511,11 @@ static void build_vaults(int level_number, int force_vault)
no_door_fixup_zones.push_back(
dgn_region( place.x, place.y, place.width, place.height ) );
- if (place.map->has_tag("no_monster_gen"))
+ if (place.map.has_tag("no_monster_gen"))
no_monster_zones.push_back(
dgn_region( place.x, place.y, place.width, place.height ) );
- if (place.map->has_tag("no_pool_fixup"))
+ if (place.map.has_tag("no_pool_fixup"))
no_pool_fixup_zones.push_back(
dgn_region( place.x, place.y, place.width, place.height ) );
@@ -5547,7 +5529,7 @@ static void build_vaults(int level_number, int force_vault)
// Does this level require Dis treatment (metal wallification)?
// XXX: Change this so the level definition can explicitly state what
// kind of wallification it wants.
- const bool dis_wallify = place.map->has_tag("dis");
+ const bool dis_wallify = place.map.has_tag("dis");
const int v1x = place.x;
const int v1y = place.y;
@@ -5644,55 +5626,33 @@ static void build_vaults(int level_number, int force_vault)
}
} // end build_vaults()
-static const item_spec *dngn_item_by_weight(const item_spec_list &specs)
-{
- int cumulative = 0;
- const item_spec *spec = NULL;
- for (item_spec_list::const_iterator i = specs.begin();
- i != specs.end(); ++i)
- {
- const int weight = i->genweight;
- if (random2(cumulative += weight) < weight)
- spec = &*i;
- }
- return (spec);
-}
-
static void dngn_place_item_explicit(int index, int x, int y,
- const vault_placement &place,
+ vault_placement &place,
int level)
{
- const map_def *map = place.map;
- const std::vector<item_spec_list> &itemlist = map->items.get_items();
- if (index < 0 || index >= (int) itemlist.size())
+ item_list &sitems = place.map.items;
+
+ if (index < 0 || index >= (int) sitems.size())
{
// Non-fatal, but we warn even in non-debug mode so there's incentive
// to fix the problem.
mprf(MSGCH_DIAGNOSTICS, "Map '%s' requested invalid item index: %d",
- map->name.c_str(),
- index);
+ place.map.name.c_str(), index);
return;
}
- const item_spec *spec = dngn_item_by_weight(itemlist[index]);
- if (!spec)
- {
- mprf(MSGCH_DIAGNOSTICS, "Map '%s' bad item spec for %d",
- map->name.c_str(),
- index);
- return;
- }
+ const item_spec spec = sitems.get_item(index);
// Dummy object?
- if (spec->base_type == OBJ_UNASSIGNED)
+ if (spec.base_type == OBJ_UNASSIGNED)
return;
- if (spec->level >= 0)
- level = spec->level;
+ if (spec.level >= 0)
+ level = spec.level;
const int item_made =
- items( spec->allow_uniques, spec->base_type, spec->sub_type, true,
- level, spec->race );
+ items( spec.allow_uniques, spec.base_type, spec.sub_type, true,
+ level, spec.race );
if (item_made != NON_ITEM)
{
@@ -5704,12 +5664,11 @@ static void dngn_place_item_explicit(int index, int x, int y,
// returns altar_count - seems rather odd to me to force such a return
// when I believe the value is only used in the case of the ecumenical
// temple - oh, well... {dlb}
-static int vault_grid( const vault_placement &place,
+static int vault_grid( vault_placement &place,
int level_number,
int vx, int vy,
int altar_count,
FixedVector < char, 7 > &acq_item_class,
- FixedVector < int, 7 > &mons_array,
char vgrid,
std::vector<coord_def> &targets,
int &num_runes)
@@ -5828,13 +5787,13 @@ static int vault_grid( const vault_placement &place,
if (you.level_type == LEVEL_PANDEMONIUM)
{
- if (place.map->has_tag("mnoleg"))
+ if (place.map.has_tag("mnoleg"))
spec = RUNE_MNOLEG;
- else if (place.map->has_tag("lom_lobon"))
+ else if (place.map.has_tag("lom_lobon"))
spec = RUNE_LOM_LOBON;
- else if (place.map->has_tag("gloorx_vloq"))
+ else if (place.map.has_tag("gloorx_vloq"))
spec = RUNE_GLOORX_VLOQ;
- else if (place.map->has_tag("cerebov"))
+ else if (place.map.has_tag("cerebov"))
spec = RUNE_CEREBOV;
else
spec = RUNE_DEMONIC;
@@ -5898,7 +5857,7 @@ static int vault_grid( const vault_placement &place,
monster_type_thing = ((vgrid == '8'
|| vgrid == '9'
|| vgrid == '0') ? RANDOM_MONSTER
- : mons_array[(vgrid - '1')]);
+ : place.map.mons.get_monster(vgrid - '1'));
place_monster( not_used, monster_type_thing, monster_level, BEH_SLEEP,
MHITNOT, true, vx, vy, false);
diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc
index 878dfa4bf4..fc7c936304 100644
--- a/crawl-ref/source/mapdef.cc
+++ b/crawl-ref/source/mapdef.cc
@@ -7,6 +7,7 @@
#include "items.h"
#include "libutil.h"
#include "mapdef.h"
+#include "monplace.h"
#include "mon-util.h"
#include "stuff.h"
#include "dungeon.h"
@@ -557,26 +558,105 @@ bool map_def::has_tag(const std::string &tagwanted) const
// mons_list
//
-mons_list::mons_list() : mons_ids()
+mons_list::mons_list() : mons()
{
}
-const std::vector<int> &mons_list::get_ids() const
+int mons_list::fix_demon(int demon) const
{
- return (mons_ids);
+ demon = -100 - demon;
+ if (demon == DEMON_RANDOM)
+ demon = random2(DEMON_RANDOM);
+ return (summon_any_demon( demon ));
+}
+
+int mons_list::pick_monster(mons_spec_slot &slot)
+{
+ int totweight = 0;
+ int pick = RANDOM_MONSTER;
+
+ for (mons_spec_list::iterator i = slot.mlist.begin();
+ i != slot.mlist.end(); ++i)
+ {
+ const int weight = i->genweight;
+ if (random2(totweight += weight) < weight)
+ {
+ pick = i->mid;
+
+ if (pick < 0 && i->fix_mons)
+ pick = i->mid = fix_demon(pick);
+ }
+ }
+
+ if (pick < 0)
+ pick = fix_demon(pick);
+
+ if (slot.fix_slot)
+ {
+ slot.mlist.clear();
+ slot.mlist.push_back( mons_spec(pick) );
+ slot.fix_slot = false;
+ }
+
+ return (pick);
+}
+
+int mons_list::get_monster(int index)
+{
+ if (index < 0 || index >= (int) mons.size())
+ return (RANDOM_MONSTER);
+
+ return (pick_monster( mons[index] ));
}
void mons_list::clear()
{
- mons_ids.clear();
+ mons.clear();
}
-bool mons_list::add_mons(const std::string &s)
+mons_list::mons_spec_slot mons_list::parse_mons_spec(std::string spec)
{
- const int mid = mons_by_name(s);
- if (mid != MONS_PROGRAM_BUG)
- mons_ids.push_back(mid);
- return (mid != MONS_PROGRAM_BUG);
+ mons_spec_slot slot;
+
+ slot.fix_slot = strip_tag(spec, "fix_slot");
+
+ std::vector<std::string> specs = split_string("/", spec);
+
+ for (int i = 0, ssize = specs.size(); i < ssize; ++i)
+ {
+ std::string s = specs[i];
+ int weight = strip_number_tag(s, "weight:");
+ if (weight == TAG_UNFOUND || weight <= 0)
+ weight = 10;
+
+ const bool fixmons = strip_tag(s, "fix_mons");
+
+ trim_string(s);
+ const int mid = mons_by_name(s);
+
+ if (mid == MONS_PROGRAM_BUG)
+ {
+ error = make_stringf("unrecognised monster \"%s\"", s.c_str());
+ return (slot);
+ }
+
+ slot.mlist.push_back( mons_spec(mid, weight, fixmons) );
+ }
+
+ return (slot);
+}
+
+std::string mons_list::add_mons(const std::string &s)
+{
+ error.clear();
+
+ mons_spec_slot slotmons = parse_mons_spec(s);
+ if (!error.empty())
+ return (error);
+
+ mons.push_back( slotmons );
+
+ return (error);
}
int mons_list::mons_by_name(std::string name) const
@@ -642,16 +722,41 @@ void item_list::clear()
items.clear();
}
-const std::vector<item_spec_list> &item_list::get_items() const
+item_spec item_list::pick_item(item_spec_slot &slot)
+{
+ int cumulative = 0;
+ item_spec spec;
+ for (item_spec_list::const_iterator i = slot.ilist.begin();
+ i != slot.ilist.end(); ++i)
+ {
+ const int weight = i->genweight;
+ if (random2(cumulative += weight) < weight)
+ spec = *i;
+ }
+
+ if (slot.fix_slot)
+ {
+ slot.ilist.clear();
+ slot.ilist.push_back(spec);
+ slot.fix_slot = false;
+ }
+
+ return (spec);
+}
+
+item_spec item_list::get_item(int index)
{
- return (items);
+ if (index < 0 || index >= (int) items.size())
+ return (item_spec());
+
+ return (pick_item(items[index]));
}
std::string item_list::add_item(const std::string &spec)
{
error.clear();
- item_spec_list sp = parse_item_spec(spec);
+ item_spec_slot sp = parse_item_spec(spec);
if (error.empty())
items.push_back(sp);
@@ -777,16 +882,18 @@ void item_list::parse_raw_name(std::string name, item_spec &spec)
error = make_stringf("Bad item name: '%s'", name.c_str());
}
-item_spec_list item_list::parse_item_spec(std::string spec)
+item_list::item_spec_slot item_list::parse_item_spec(std::string spec)
{
lowercase(spec);
- item_spec_list list;
+ item_spec_slot list;
+
+ list.fix_slot = strip_tag(spec, "fix_slot");
std::vector<std::string> specifiers = split_string( "/", spec );
for (unsigned i = 0; i < specifiers.size() && error.empty(); ++i)
{
- list.push_back( parse_single_spec(specifiers[i]) );
+ list.ilist.push_back( parse_single_spec(specifiers[i]) );
}
return (list);
diff --git a/crawl-ref/source/mapdef.h b/crawl-ref/source/mapdef.h
index 7bf5682dd6..b0f0d23818 100644
--- a/crawl-ref/source/mapdef.h
+++ b/crawl-ref/source/mapdef.h
@@ -15,7 +15,8 @@
#include "enum.h"
#include "externs.h"
-enum map_flags {
+enum map_flags
+{
MAPF_PANDEMONIUM_VAULT = 0x01, // A pandemonium minivault.
MAPF_MIRROR_VERTICAL = 0x10, // The map may be mirrored vertically
@@ -23,7 +24,8 @@ enum map_flags {
MAPF_ROTATE = 0x40 // may be rotated
};
-class level_range {
+class level_range
+{
public:
int shallowest, deepest;
@@ -38,7 +40,8 @@ public:
int span() const;
};
-class map_lines {
+class map_lines
+{
public:
map_lines();
@@ -81,26 +84,63 @@ private:
bool solid_checked;
};
-class mons_list {
+class mons_list
+{
public:
mons_list();
void clear();
- const std::vector<int> &get_ids() const;
- // Returns false if the monster is unrecognised.
- bool add_mons(const std::string &s);
+ int get_monster(int index);
- size_t size() const { return mons_ids.size(); }
+ // Returns an error string if the monster is unrecognised.
+ std::string add_mons(const std::string &s);
+
+ size_t size() const { return mons.size(); }
+
+private:
+ struct mons_spec
+ {
+ int mid;
+ int genweight;
+ bool fix_mons;
+
+ mons_spec(int id = RANDOM_MONSTER, int gw = 10, bool _fixmons = false)
+ : mid(id), genweight(gw), fix_mons(_fixmons)
+ {
+ }
+ };
+ typedef std::vector<mons_spec> mons_spec_list;
+
+ struct mons_spec_slot
+ {
+ mons_spec_list mlist;
+ bool fix_slot;
+
+ mons_spec_slot(const mons_spec_list &list, bool fix = false)
+ : mlist(list), fix_slot(fix)
+ {
+ }
+
+ mons_spec_slot()
+ : mlist(), fix_slot(false)
+ {
+ }
+ };
private:
int mons_by_name(std::string name) const;
+ mons_spec_slot parse_mons_spec(std::string spec);
+ int pick_monster(mons_spec_slot &slot);
+ int fix_demon(int id) const;
private:
- std::vector<int> mons_ids;
+ std::vector< mons_spec_slot > mons;
+ std::string error;
};
-struct item_spec {
+struct item_spec
+{
int genweight;
int base_type, sub_type;
@@ -113,34 +153,47 @@ struct item_spec {
{
}
};
-
typedef std::vector<item_spec> item_spec_list;
-class item_list {
+class item_list
+{
public:
item_list() : items() { }
void clear();
- const std::vector<item_spec_list> &get_items() const;
- std::string add_item(const std::string &spec);
-
+ item_spec get_item(int index);
size_t size() const { return items.size(); }
+ std::string add_item(const std::string &spec);
+
+private:
+ struct item_spec_slot
+ {
+ item_spec_list ilist;
+ bool fix_slot;
+
+ item_spec_slot() : ilist(), fix_slot(false)
+ {
+ }
+ };
+
private:
item_spec item_by_specifier(const std::string &spec);
- item_spec_list parse_item_spec(std::string spec);
+ item_spec_slot parse_item_spec(std::string spec);
item_spec parse_single_spec(std::string s);
void parse_raw_name(std::string name, item_spec &spec);
void parse_random_by_class(std::string c, item_spec &spec);
+ item_spec pick_item(item_spec_slot &slot);
private:
- std::vector<item_spec_list> items;
+ std::vector<item_spec_slot> items;
std::string error;
};
// Not providing a constructor to make life easy for C-style initialisation.
-class map_def {
+class map_def
+{
public:
std::string name;
std::string tags;
@@ -175,14 +228,16 @@ public:
bool has_tag(const std::string &tag) const;
};
-class monster_chance {
+class monster_chance
+{
public:
int mclass;
int level;
int rarity;
};
-class level_def {
+class level_def
+{
public:
// The range of levels to which this def applies.
level_range range;
@@ -204,7 +259,8 @@ public:
std::vector<monster_chance> monsters;
};
-class dungeon_def {
+class dungeon_def
+{
public:
std::string idstr;
int id;
diff --git a/crawl-ref/source/maps.cc b/crawl-ref/source/maps.cc
index 80a637561b..5bc7097ce1 100644
--- a/crawl-ref/source/maps.cc
+++ b/crawl-ref/source/maps.cc
@@ -29,12 +29,10 @@
#include "levcomp.h"
static int write_vault(const map_def &mdef, map_type mt,
- FixedVector<int,7> &marray,
vault_placement &);
static int apply_vault_definition(
map_def &def,
map_type map,
- FixedVector<int,7> &marray,
vault_placement &);
static void resolve_map(map_def &def);
@@ -56,7 +54,6 @@ static std::vector<map_def> vdefs;
// anywhere, while other vault names are for specific level ranges, etc.
int vault_main(
map_type vgrid,
- FixedVector<int, 7>& mons_array,
vault_placement &place,
int which_vault,
int many_many )
@@ -77,20 +74,18 @@ int vault_main(
}
// NB - a return value of zero is not handled well by dungeon.cc (but there it is) 10mar2000 {dlb}
- return write_vault( vdefs[which_vault], vgrid, mons_array, place );
+ return write_vault( vdefs[which_vault], vgrid, place );
} // end vault_main()
static int write_vault(const map_def &mdef, map_type map,
- FixedVector<int, 7> &marray,
vault_placement &place)
{
- place.map = &mdef;
-
// Copy the map so we can monkey with it.
- map_def def = mdef;
- resolve_map(def);
+ place.map = mdef;
+ resolve_map(place.map);
- return (place.orient = apply_vault_definition(def, map, marray, place));
+ return (place.orient =
+ apply_vault_definition(place.map, map, place));
}
// Mirror the map if appropriate, resolve substitutable symbols (?),
@@ -109,28 +104,6 @@ static void resolve_map(map_def &map)
map.rotate( coinflip() );
}
-static void apply_monsters(
- const map_def &def,
- FixedVector<int,7> &marray)
-{
- const std::vector<int> &mids = def.mons.get_ids();
- size_t ndx = 0;
- for (int i = 0, size = mids.size(); i < size; ++i)
- {
- int mid = mids[i];
- if (mid < 0)
- {
- mid = -100 - mid;
- if (mid == DEMON_RANDOM)
- mid = random2(DEMON_RANDOM);
- mid = summon_any_demon( mid );
- }
-
- if (ndx < marray.size())
- marray[ndx++] = mid;
- }
-}
-
static void apply_vault_grid(map_def &def, map_type map,
vault_placement &place)
{
@@ -192,10 +165,8 @@ static void apply_vault_grid(map_def &def, map_type map,
static int apply_vault_definition(
map_def &def,
map_type map,
- FixedVector<int,7> &marray,
vault_placement &place)
{
- apply_monsters(def, marray);
apply_vault_grid(def, map, place);
int orient = def.orient;
diff --git a/crawl-ref/source/maps.h b/crawl-ref/source/maps.h
index 096ab50365..676d468190 100644
--- a/crawl-ref/source/maps.h
+++ b/crawl-ref/source/maps.h
@@ -14,6 +14,7 @@
#include "FixVec.h"
#include "dungeon.h"
+#include "mapdef.h"
class map_def;
struct vault_placement
@@ -21,16 +22,15 @@ struct vault_placement
int x, y;
int width, height;
int orient;
- const map_def *map;
+ map_def map;
vault_placement()
- : x(-1), y(-1), width(0), height(0), map(NULL)
+ : x(-1), y(-1), width(0), height(0), map()
{
}
};
int vault_main(map_type vgrid,
- FixedVector<int, 7>& mons_array,
vault_placement &vp,
int vault_force,
int many_many);
diff --git a/crawl-ref/source/util/levcomp.ypp b/crawl-ref/source/util/levcomp.ypp
index 6a16128b94..d223161b02 100644
--- a/crawl-ref/source/util/levcomp.ypp
+++ b/crawl-ref/source/util/levcomp.ypp
@@ -184,12 +184,13 @@ mnames : mname COMMA mnames
mname : MONSTER_NAME
{
- bool recognised = lc_map.mons.add_mons($1);
- if (!recognised)
+ std::string err = lc_map.mons.add_mons($1);
+ if (!err.empty())
{
char buf[300];
- snprintf(buf, sizeof buf, "unknown monster '%s'",
- $1);
+ snprintf(buf, sizeof buf,
+ "bad monster spec '%s' (%s)",
+ $1, err.c_str());
yyerror(buf);
}
if (lc_map.mons.size() > 7)