diff options
Diffstat (limited to 'crawl-ref')
-rw-r--r-- | crawl-ref/source/dat/vaults.des | 246 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.cc | 101 | ||||
-rw-r--r-- | crawl-ref/source/mapdef.cc | 137 | ||||
-rw-r--r-- | crawl-ref/source/mapdef.h | 98 | ||||
-rw-r--r-- | crawl-ref/source/maps.cc | 39 | ||||
-rw-r--r-- | crawl-ref/source/maps.h | 6 | ||||
-rw-r--r-- | crawl-ref/source/util/levcomp.ypp | 9 |
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) |