00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef __MAPDEF_H__
00011 #define __MAPDEF_H__
00012
00013 #include <string>
00014 #include <vector>
00015 #include <cstdio>
00016 #include <memory>
00017
00018 #include "dlua.h"
00019 #include "enum.h"
00020 #include "externs.h"
00021 #include "matrix.h"
00022 #include "fprop.h"
00023 #include "makeitem.h"
00024 #include "travel_defs.h"
00025
00026
00027 static const int INVALID_HEIGHT = -31999;
00028
00029
00030
00031 class map_load_exception : public std::exception
00032 {
00033 public:
00034 map_load_exception(const std::string &_mapname) : mapname(_mapname) { }
00035 ~map_load_exception() throw () { }
00036 const char *what() const throw()
00037 {
00038 return mapname.c_str();
00039 }
00040 private:
00041 std::string mapname;
00042 };
00043
00044
00045
00046 enum map_section_type
00047 {
00048 MAP_NONE = -1,
00049 MAP_NORTH = 1,
00050 MAP_SOUTH,
00051 MAP_EAST,
00052 MAP_WEST,
00053 MAP_NORTHWEST,
00054 MAP_NORTHEAST,
00055 MAP_SOUTHWEST,
00056 MAP_SOUTHEAST,
00057 MAP_ENCOMPASS,
00058
00059
00060
00061 MAP_FLOAT,
00062
00063 MAP_NUM_SECTION_TYPES
00064 };
00065
00066 struct raw_range
00067 {
00068 branch_type branch;
00069 int shallowest, deepest;
00070 bool deny;
00071 };
00072
00073 struct level_range
00074 {
00075 public:
00076 level_area_type level_type;
00077 branch_type branch;
00078 int shallowest, deepest;
00079 bool deny;
00080
00081 public:
00082 level_range(const raw_range &range);
00083 level_range(branch_type br = BRANCH_MAIN_DUNGEON, int s = -1, int d = -1);
00084
00085 void set(int s, int d = -1);
00086 void set(const std::string &branch, int s, int d) throw (std::string);
00087
00088 void reset();
00089 bool matches(const level_id &) const;
00090 bool matches(int depth) const;
00091
00092 void write(writer&) const;
00093 void read(reader&);
00094
00095 bool valid() const;
00096 int span() const;
00097
00098 static level_range parse(std::string lr) throw (std::string);
00099
00100 std::string describe() const;
00101 std::string str_depth_range() const;
00102
00103 bool operator == (const level_range &lr) const;
00104
00105 operator raw_range () const;
00106 operator std::string () const
00107 {
00108 return describe();
00109 }
00110
00111 private:
00112 static void parse_partial(level_range &lr, const std::string &s)
00113 throw (std::string);
00114 static void parse_depth_range(const std::string &s, int *low, int *high)
00115 throw (std::string);
00116 };
00117
00118 typedef std::pair<int,int> glyph_weighted_replacement_t;
00119 typedef std::vector<glyph_weighted_replacement_t> glyph_replacements_t;
00120
00121 class map_lines;
00122
00123 class subst_spec
00124 {
00125 public:
00126 subst_spec(std::string torepl, bool fix, const glyph_replacements_t &repls);
00127 subst_spec(int count, bool fix, const glyph_replacements_t &repls);
00128 subst_spec() : key(""), count(-1), fix(false), frozen_value(0), repl() { }
00129
00130 int value();
00131
00132 public:
00133 std::string key;
00134
00135
00136 int count;
00137
00138 bool fix;
00139 int frozen_value;
00140
00141 glyph_replacements_t repl;
00142 };
00143
00144 class nsubst_spec
00145 {
00146 public:
00147 nsubst_spec(std::string key, const std::vector<subst_spec> &specs);
00148 public:
00149 std::string key;
00150 std::vector<subst_spec> specs;
00151 };
00152
00153 typedef std::pair<int, int> map_weighted_colour;
00154 class map_colour_list : public std::vector<map_weighted_colour>
00155 {
00156 public:
00157 bool parse(const std::string &s, int weight);
00158 };
00159 class colour_spec
00160 {
00161 public:
00162 colour_spec(std::string _key, bool _fix, const map_colour_list &clist)
00163 : key(_key), fix(_fix), fixed_colour(BLACK), colours(clist)
00164 {
00165 }
00166
00167 int get_colour();
00168
00169 public:
00170 std::string key;
00171 bool fix;
00172 int fixed_colour;
00173 map_colour_list colours;
00174 };
00175
00176 typedef std::pair<unsigned long, int> map_weighted_fprop;
00177 class map_fprop_list : public std::vector<map_weighted_fprop>
00178 {
00179 public:
00180 bool parse(const std::string &fp, int weight);
00181 };
00182
00183 typedef std::pair<int, int> map_weighted_fheight;
00184 class map_featheight_list : public std::vector<map_weighted_fheight>
00185 {
00186 public:
00187 bool parse(const std::string &fp, int weight);
00188 };
00189
00190 class fprop_spec
00191 {
00192 public:
00193 fprop_spec(std::string _key, bool _fix, const map_fprop_list &flist)
00194 : key(_key), fix(_fix), fixed_prop(FPROP_NONE), fprops(flist)
00195 {
00196 }
00197
00198 unsigned long get_property();
00199
00200 public:
00201 std::string key;
00202 bool fix;
00203 unsigned long fixed_prop;
00204 map_fprop_list fprops;
00205 };
00206
00207 class fheight_spec
00208 {
00209 public:
00210 fheight_spec(std::string _key, bool _fix,
00211 const map_featheight_list &_fheights)
00212 : key(_key), fix(_fix), fixed_height(INVALID_HEIGHT),
00213 fheights(_fheights)
00214 {
00215 }
00216 int get_height();
00217 public:
00218 std::string key;
00219 bool fix;
00220 int fixed_height;
00221 map_featheight_list fheights;
00222 };
00223
00224 #ifdef USE_TILE
00225 typedef std::pair<std::string, int> map_weighted_tile;
00226 class map_tile_list : public std::vector<map_weighted_tile>
00227 {
00228 public:
00229 bool parse(const std::string &s, int weight);
00230 };
00231
00232 class tile_spec
00233 {
00234 public:
00235 tile_spec(const std::string &_key, bool _fix, bool _rand, bool _last, bool _floor, bool _feat, const map_tile_list &_tiles)
00236 : key(_key), fix(_fix), chose_fixed(false), no_random(_rand), last_tile(_last), floor(_floor), feat(_feat),
00237 fixed_tile(""), tiles(_tiles)
00238 {
00239 }
00240
00241 std::string get_tile();
00242
00243 public:
00244 std::string key;
00245 bool fix;
00246 bool chose_fixed;
00247 bool no_random;
00248 bool last_tile;
00249 bool floor;
00250 bool feat;
00251 std::string fixed_tile;
00252 map_tile_list tiles;
00253 };
00254 #endif
00255
00256 class map_marker_spec
00257 {
00258 public:
00259 std::string key;
00260 std::string marker;
00261
00262
00263 std::auto_ptr<lua_datum> lua_fn;
00264
00265 map_marker_spec(std::string _key, const std::string &mark)
00266 : key(_key), marker(mark), lua_fn() { }
00267
00268 map_marker_spec(std::string _key, const lua_datum &fn)
00269 : key(_key), marker(), lua_fn(new lua_datum(fn)) { }
00270
00271 std::string apply_transform(map_lines &map);
00272
00273 private:
00274 map_marker *create_marker();
00275 };
00276
00277 typedef std::pair<std::string, int> map_weighted_string;
00278 class map_string_list : public std::vector<map_weighted_string>
00279 {
00280 public:
00281 bool parse(const std::string &fp, int weight);
00282 };
00283 class string_spec
00284 {
00285 public:
00286 string_spec(std::string _key, bool _fix, const map_string_list &slist)
00287 : key(_key), fix(_fix), fixed_str(""), strlist(slist)
00288 {
00289 }
00290
00291 std::string get_property();
00292
00293 public:
00294 std::string key;
00295 bool fix;
00296 std::string fixed_str;
00297 map_string_list strlist;
00298 };
00299
00300 template<class T>
00301 std::string parse_weighted_str(const std::string &cspec, T &list);
00302
00303 class map_def;
00304 class rectangle_iterator;
00305 struct keyed_mapspec;
00306 class map_lines
00307 {
00308 public:
00309 class iterator {
00310 public:
00311 iterator(map_lines &ml, const std::string &key);
00312 operator bool () const;
00313 coord_def operator ++ ();
00314 coord_def operator ++ (int);
00315 coord_def operator * () const;
00316 private:
00317 void advance();
00318 private:
00319 map_lines &maplines;
00320 std::string key;
00321 coord_def p;
00322 };
00323
00324 public:
00325 map_lines();
00326 map_lines(const map_lines &);
00327 ~map_lines();
00328
00329 map_lines &operator = (const map_lines &);
00330
00331 bool in_map(const coord_def &pos) const;
00332
00333 void add_line(const std::string &s);
00334 std::string add_nsubst(const std::string &st);
00335 std::string add_subst(const std::string &st);
00336 std::string add_shuffle(const std::string &s);
00337 std::string add_colour(const std::string &col);
00338 std::string add_fproperty(const std::string &sub);
00339 std::string add_fheight(const std::string &arg);
00340 void clear_markers();
00341
00342 void write_maplines(writer &) const;
00343 void read_maplines(reader&);
00344
00345 #ifdef USE_TILE
00346 std::string add_floortile(const std::string &s);
00347 std::string add_rocktile(const std::string &s);
00348 std::string add_spec_tile(const std::string &s);
00349 #endif
00350
00351 std::vector<coord_def> find_glyph(const std::string &glyphs) const;
00352 std::vector<coord_def> find_glyph(int glyph) const;
00353 coord_def find_first_glyph(int glyph) const;
00354 coord_def find_first_glyph(const std::string &glyphs) const;
00355
00356
00357
00358 bool find_bounds(int glyph, coord_def &tl, coord_def &br) const;
00359
00360 bool find_bounds(const char *glyph_str, coord_def &tl, coord_def &br) const;
00361
00362 void set_orientation(const std::string &s);
00363
00364 int width() const;
00365 int height() const;
00366 coord_def size() const;
00367
00368 int glyph(int x, int y) const;
00369 int glyph(const coord_def &) const;
00370 bool is_solid(int gly) const;
00371
00372 bool solid_borders(map_section_type border);
00373
00374
00375 void normalise(char fillc = ' ');
00376
00377
00378 void rotate(bool clockwise);
00379 void hmirror();
00380 void vmirror();
00381
00382 void clear();
00383
00384 void add_marker(map_marker *marker);
00385 std::string add_feature_marker(const std::string &desc);
00386 std::string add_lua_marker(const std::string &key,
00387 const lua_datum &fn);
00388
00389 void apply_markers(const coord_def &pos);
00390 void apply_grid_overlay(const coord_def &pos);
00391 void apply_overlays(const coord_def &pos);
00392
00393 const std::vector<std::string> &get_lines() const;
00394 std::vector<std::string> &get_lines();
00395
00396 rectangle_iterator get_iter() const;
00397 char operator () (const coord_def &c) const;
00398 char& operator () (const coord_def &c);
00399 char operator () (int x, int y) const;
00400 char& operator () (int x, int y);
00401
00402 const keyed_mapspec *mapspec_at(const coord_def &c) const;
00403 keyed_mapspec *mapspec_at(const coord_def &c);
00404
00405 std::string add_key_item(const std::string &s);
00406 std::string add_key_mons(const std::string &s);
00407 std::string add_key_feat(const std::string &s);
00408 std::string add_key_mask(const std::string &s);
00409
00410 bool in_bounds(const coord_def &c) const;
00411
00412
00413 void extend(int min_width, int min_height, char fill);
00414
00415 bool fill_zone(travel_distance_grid_t &tpd, const coord_def &start,
00416 const coord_def &tl, const coord_def &br, int zone,
00417 const char *wanted, const char *passable) const;
00418
00419 int count_feature_in_box(const coord_def &tl, const coord_def &br,
00420 const char *feat) const;
00421
00422 void fill_mask_matrix(const std::string &glyphs, const coord_def &tl,
00423 const coord_def &br, Matrix<bool> &flags);
00424
00425
00426 void merge_subvault(const coord_def &tl, const coord_def &br,
00427 const Matrix<bool> &mask, const map_def &vault);
00428 private:
00429 void init_from(const map_lines &map);
00430 template <typename V> void clear_vector(V &vect);
00431 void vmirror_markers();
00432 void hmirror_markers();
00433 void rotate_markers(bool clock);
00434 void vmirror_marker(map_marker *, int par);
00435 void hmirror_marker(map_marker *, int par);
00436 void rotate_marker(map_marker *, int par);
00437 void translate_marker(void (map_lines::*xform)(map_marker *, int par),
00438 int par = 0);
00439
00440 void resolve_shuffle(const std::string &shuffle);
00441 void subst(std::string &s, subst_spec &spec);
00442 void subst(subst_spec &);
00443 void nsubst(nsubst_spec &);
00444 void bind_overlay();
00445 void overlay_colours(colour_spec &);
00446 void overlay_fprops(fprop_spec &);
00447 void overlay_fheights(fheight_spec &);
00448
00449
00450 typedef FixedVector<int, 256> keyspec_map;
00451 void merge_cell(int x, int y, const map_def &vault, int vx, int vy,
00452 int keyspec_idx);
00453
00454 #ifdef USE_TILE
00455 void overlay_tiles(tile_spec &);
00456 #endif
00457 void check_borders();
00458 std::string shuffle(std::string s);
00459 std::string block_shuffle(const std::string &s);
00460 std::string check_shuffle(std::string &s);
00461 std::string check_block_shuffle(const std::string &s);
00462 std::string clean_shuffle(std::string s);
00463 std::string parse_nsubst_spec(const std::string &s,
00464 subst_spec &spec);
00465 int apply_nsubst(std::vector<coord_def> &pos,
00466 int start, int nsub,
00467 subst_spec &spec);
00468 std::string parse_glyph_replacements(std::string s,
00469 glyph_replacements_t &gly);
00470
00471 #ifdef USE_TILE
00472 std::string add_tile(const std::string &sub, bool is_floor, bool is_feat);
00473 #endif
00474
00475 std::string add_key_field(
00476 const std::string &s,
00477 std::string (keyed_mapspec::*set_field)(
00478 const std::string &s, bool fixed),
00479 void (keyed_mapspec::*copy_field)(const keyed_mapspec &spec));
00480
00481 const keyed_mapspec *mapspec_for_key(int key) const;
00482 keyed_mapspec *mapspec_for_key(int key);
00483
00484 friend class subst_spec;
00485 friend class nsubst_spec;
00486 friend class shuffle_spec;
00487 friend class map_marker_spec;
00488 friend class colour_spec;
00489 friend class tile_spec;
00490
00491 private:
00492 std::vector<map_marker *> markers;
00493 std::vector<std::string> lines;
00494
00495 struct overlay_def
00496 {
00497 overlay_def() :
00498 colour(0), rocktile(""), floortile(""), tile(""),
00499 no_random(false), last_tile(false), property(0), height(INVALID_HEIGHT),
00500 keyspec_idx(0)
00501 {}
00502 int colour;
00503 std::string rocktile;
00504 std::string floortile;
00505 std::string tile;
00506 bool no_random;
00507 bool last_tile;
00508 int property;
00509 int height;
00510 int keyspec_idx;
00511 };
00512 typedef Matrix<overlay_def> overlay_matrix;
00513 std::auto_ptr<overlay_matrix> overlay;
00514
00515 typedef std::map<int, keyed_mapspec> keyed_specs;
00516 keyed_specs keyspecs;
00517 int next_keyspec_idx;
00518
00519 enum
00520 {
00521 SUBVAULT_GLYPH = 1,
00522 };
00523
00524 int map_width;
00525 bool solid_north, solid_east, solid_south, solid_west;
00526 bool solid_checked;
00527 };
00528
00529 enum item_spec_type
00530 {
00531 ISPEC_GOOD = -2,
00532 ISPEC_SUPERB = -3,
00533 ISPEC_DAMAGED = -4,
00534 ISPEC_BAD = -5,
00535 ISPEC_RANDART = -6,
00536 ISPEC_ACQUIREMENT = -9,
00537 };
00538
00539 class mons_spec;
00540 class item_spec
00541 {
00542 public:
00543 int genweight;
00544
00545 object_class_type base_type;
00546 int sub_type;
00547 int plus, plus2;
00548 int ego;
00549 int allow_uniques;
00550 int level;
00551 int race;
00552 int item_special;
00553 int qty;
00554 int acquirement_source;
00555 level_id place;
00556
00557
00558 CrawlHashTable props;
00559
00560 item_spec() : genweight(10), base_type(OBJ_RANDOM), sub_type(OBJ_RANDOM),
00561 plus(-1), plus2(-1), ego(0), allow_uniques(1), level(-1),
00562 race(MAKE_ITEM_RANDOM_RACE), item_special(0), qty(0),
00563 acquirement_source(0), place(), props(),
00564 _corpse_monster_spec(NULL)
00565 {
00566 }
00567
00568 item_spec(const item_spec &other);
00569 item_spec &operator = (const item_spec &other);
00570 ~item_spec();
00571
00572 bool corpselike() const;
00573 const mons_spec &corpse_monster_spec() const;
00574 void set_corpse_monster_spec(const mons_spec &spec);
00575
00576 private:
00577 mons_spec *_corpse_monster_spec;
00578
00579 private:
00580 void release_corpse_monster_spec();
00581 };
00582 typedef std::vector<item_spec> item_spec_list;
00583
00584 class item_list
00585 {
00586 public:
00587 item_list() : items() { }
00588
00589 void clear();
00590
00591 item_spec get_item(int index);
00592 size_t size() const { return items.size(); }
00593 bool empty() const { return items.empty(); }
00594
00595 std::string add_item(const std::string &spec, bool fix = false);
00596 std::string set_item(int index, const std::string &spec);
00597
00598
00599 void set_from_slot(const item_list &list, int slot_index);
00600
00601 private:
00602 struct item_spec_slot
00603 {
00604 item_spec_list ilist;
00605 bool fix_slot;
00606
00607 item_spec_slot() : ilist(), fix_slot(false)
00608 {
00609 }
00610 };
00611
00612 private:
00613 item_spec item_by_specifier(const std::string &spec);
00614 item_spec_slot parse_item_spec(std::string spec);
00615 void build_deck_spec(std::string s, item_spec* spec);
00616 item_spec parse_single_spec(std::string s);
00617 int parse_acquirement_source(const std::string &source);
00618 void parse_raw_name(std::string name, item_spec &spec);
00619 void parse_random_by_class(std::string c, item_spec &spec);
00620 item_spec pick_item(item_spec_slot &slot);
00621 item_spec parse_corpse_spec(item_spec &result, std::string s);
00622 bool monster_corpse_is_valid(monster_type *, const std::string &name,
00623 bool corpse, bool skeleton, bool chunk);
00624
00625 private:
00626 std::vector<item_spec_slot> items;
00627 std::string error;
00628 };
00629
00630 class mons_spec
00631 {
00632 public:
00633 int mid;
00634 level_id place;
00635 monster_type monbase;
00636 mon_attitude_type attitude;
00637 int number;
00638 int quantity;
00639 int genweight, mlevel;
00640 bool fix_mons;
00641 bool generate_awake;
00642 bool patrolling;
00643 bool band;
00644 int colour;
00645
00646 god_type god;
00647 bool god_gift;
00648
00649 int hd;
00650 int hp;
00651 int abjuration_duration;
00652 int summon_type;
00653
00654 item_list items;
00655 std::string monname;
00656 std::string non_actor_summoner;
00657
00658 bool explicit_spells;
00659 monster_spells spells;
00660 unsigned long extra_monster_flags;
00661
00662 CrawlHashTable props;
00663
00664 mons_spec(int id = RANDOM_MONSTER,
00665 monster_type base = MONS_NO_MONSTER,
00666 int num = 0,
00667 int gw = 10, int ml = 0,
00668 bool _fixmons = false, bool awaken = false, bool patrol = false)
00669 : mid(id), place(), monbase(base), attitude(ATT_HOSTILE), number(num),
00670 quantity(1), genweight(gw), mlevel(ml), fix_mons(_fixmons),
00671 generate_awake(awaken), patrolling(false), band(false),
00672 colour(BLACK), god(GOD_NO_GOD), god_gift(false), hd(0), hp(0),
00673 abjuration_duration(0), summon_type(0), items(), monname(""),
00674 non_actor_summoner(""), explicit_spells(false), spells(),
00675 extra_monster_flags(0L), props()
00676 {
00677 }
00678 };
00679
00680 class mons_list
00681 {
00682 public:
00683 mons_list();
00684
00685 void clear();
00686
00687
00688 void set_from_slot(const mons_list &list, int slot_index);
00689
00690 mons_spec get_monster(int index);
00691 mons_spec get_monster(int slot_index, int list_index) const;
00692
00693
00694 std::string add_mons(const std::string &s, bool fix_slot = false);
00695 std::string set_mons(int slot, const std::string &s);
00696
00697 size_t size() const { return mons.size(); }
00698 size_t slot_size(int slot) const { return mons[slot].mlist.size(); }
00699
00700 private:
00701 typedef std::vector<mons_spec> mons_spec_list;
00702
00703 struct mons_spec_slot
00704 {
00705 mons_spec_list mlist;
00706 bool fix_slot;
00707
00708 mons_spec_slot(const mons_spec_list &list, bool fix = false)
00709 : mlist(list), fix_slot(fix)
00710 {
00711 }
00712
00713 mons_spec_slot()
00714 : mlist(), fix_slot(false)
00715 {
00716 }
00717 };
00718
00719 private:
00720 mons_spec mons_by_name(std::string name) const;
00721 mons_spec drac_monspec(std::string name) const;
00722 void get_zombie_type(std::string s, mons_spec &spec) const;
00723 mons_spec get_hydra_spec(const std::string &name) const;
00724 mons_spec get_slime_spec(const std::string &name) const;
00725 mons_spec get_zombified_monster(const std::string &name,
00726 monster_type zomb) const;
00727 mons_spec_slot parse_mons_spec(std::string spec);
00728 void parse_mons_spells(mons_spec &slot, const std::string &spells);
00729 mons_spec pick_monster(mons_spec_slot &slot);
00730 int fix_demon(int id) const;
00731 bool check_mimic(const std::string &s, int *mid, bool *fix) const;
00732
00733 private:
00734 std::vector< mons_spec_slot > mons;
00735 std::string error;
00736 };
00737
00738 struct feature_spec
00739 {
00740 int genweight;
00741 int feat;
00742 int shop;
00743 int trap;
00744 int glyph;
00745
00746 feature_spec(int f, int wt = 10)
00747 : genweight(wt), feat(f), shop(-1),
00748 trap(-1), glyph(-1)
00749 { }
00750 feature_spec() : genweight(0), feat(0), shop(-1), trap(-1), glyph(-1) { }
00751 };
00752
00753 typedef std::vector<feature_spec> feature_spec_list;
00754 struct feature_slot
00755 {
00756 feature_spec_list feats;
00757 bool fix_slot;
00758
00759 feature_slot();
00760 feature_spec get_feat(int default_glyph);
00761 };
00762
00763 struct map_flags
00764 {
00765 unsigned long flags_set, flags_unset;
00766
00767 map_flags();
00768 void clear();
00769
00770 static map_flags parse(const std::string flag_list[],
00771 const std::string &s) throw(std::string);
00772 };
00773
00774
00775 struct keyed_mapspec
00776 {
00777 public:
00778 int key_glyph;
00779
00780 feature_slot feat;
00781 item_list item;
00782 mons_list mons;
00783 map_flags map_mask;
00784
00785 public:
00786 keyed_mapspec();
00787
00788
00789
00790
00791 std::string set_feat(const std::string &s, bool fix);
00792 std::string set_mons(const std::string &s, bool fix);
00793 std::string set_item(const std::string &s, bool fix);
00794 std::string set_mask(const std::string &s, bool garbage);
00795 std::string set_height(const std::string &s, bool garbage);
00796
00797
00798
00799 void copy_feat(const keyed_mapspec &spec);
00800 void copy_mons(const keyed_mapspec &spec);
00801 void copy_item(const keyed_mapspec &spec);
00802 void copy_mask(const keyed_mapspec &spec);
00803 void copy_height(const keyed_mapspec &spec);
00804
00805 feature_spec get_feat();
00806 mons_list &get_monsters();
00807 item_list &get_items();
00808 map_flags &get_mask();
00809
00810 private:
00811 std::string err;
00812
00813 private:
00814 void parse_features(const std::string &);
00815 feature_spec_list parse_feature(const std::string &s);
00816 feature_spec parse_shop(std::string s, int weight);
00817 feature_spec parse_trap(std::string s, int weight);
00818 };
00819
00820 class map_def;
00821 class dlua_set_map
00822 {
00823 public:
00824 dlua_set_map(map_def *map);
00825 ~dlua_set_map();
00826 private:
00827 std::auto_ptr<lua_datum> old_map;
00828 };
00829
00830 class map_def;
00831 dungeon_feature_type map_feature_at(map_def *map,
00832 const coord_def &c,
00833 int rawfeat);
00834
00835 struct map_file_place
00836 {
00837 std::string filename;
00838 int lineno;
00839
00840 map_file_place(const std::string &s = "", int line = 0)
00841 : filename(s), lineno(line)
00842 {
00843 }
00844
00845 void clear()
00846 {
00847 filename.clear();
00848 lineno = 0;
00849 }
00850 };
00851
00852 const int DEFAULT_CHANCE_PRIORITY = 100;
00853 struct map_chance
00854 {
00855 int chance_priority;
00856 int chance;
00857 map_chance() : chance_priority(-1), chance(-1) { }
00858 map_chance(int _priority, int _chance)
00859 : chance_priority(_priority), chance(_chance) { }
00860 map_chance(int _chance)
00861 : chance_priority(DEFAULT_CHANCE_PRIORITY), chance(_chance) { }
00862 bool valid() const { return chance_priority >= 0 && chance >= 0; }
00863 bool dummy_chance() const { return chance_priority == 0 && chance >= 0; }
00864 std::string describe() const;
00865
00866 bool roll() const;
00867 void write(writer &) const;
00868 void read(reader &);
00869 };
00870
00871
00872 struct map_chance_pair
00873 {
00874 int priority;
00875 int chance;
00876 };
00877
00878 typedef std::vector<level_range> depth_ranges_v;
00879 class depth_ranges
00880 {
00881 private:
00882 depth_ranges_v depths;
00883 public:
00884 static depth_ranges parse_depth_ranges(
00885 const std::string &depth_ranges_string);
00886 void read(reader &);
00887 void write(writer &) const;
00888 void clear() { depths.clear(); }
00889 bool empty() const { return depths.empty(); }
00890 bool is_usable_in(const level_id &lid) const;
00891 void add_depth(const level_range &range) { depths.push_back(range); }
00892 void add_depths(const depth_ranges &other_ranges);
00893 std::string describe() const;
00894 };
00895
00896 template <typename X>
00897 struct depth_range_X
00898 {
00899 depth_ranges depths;
00900 X depth_thing;
00901 depth_range_X() : depths(), depth_thing() { }
00902 depth_range_X(const std::string &depth_range_string, const X &thing)
00903 : depths(depth_ranges::parse_depth_ranges(depth_range_string)),
00904 depth_thing(thing)
00905 {
00906 }
00907 bool is_usable_in(const level_id &lid) const
00908 {
00909 return depths.is_usable_in(lid);
00910 }
00911 template <typename reader_fn_type>
00912 static depth_range_X read(reader &inf, reader_fn_type reader_fn)
00913 {
00914 depth_range_X range_x;
00915 range_x.depths.read(inf);
00916 range_x.depth_thing = reader_fn(inf);
00917 return range_x;
00918 }
00919 template <typename writer_fn_type>
00920 void write(writer &outf, writer_fn_type writer_fn) const
00921 {
00922 depths.write(outf);
00923 writer_fn(outf, depth_thing);
00924 }
00925 };
00926
00927 template <typename X>
00928 class depth_ranges_X
00929 {
00930 private:
00931 typedef std::vector<depth_range_X<X> > depth_range_X_v;
00932
00933 X default_thing;
00934 depth_range_X_v depth_range_Xs;
00935 public:
00936 depth_ranges_X() : default_thing(), depth_range_Xs() { }
00937 depth_ranges_X(const X &_default_thing)
00938 : default_thing(_default_thing), depth_range_Xs() { }
00939 void clear(const X &_default_X = X())
00940 {
00941 depth_range_Xs.clear();
00942 set_default(_default_X);
00943 }
00944 void set_default(const X &_default_X)
00945 {
00946 default_thing = _default_X;
00947 }
00948 X get_default() const { return default_thing; }
00949 void add_range(const std::string &depth_range_string,
00950 const X &thing)
00951 {
00952 depth_range_Xs.push_back(depth_range_X<X>(depth_range_string, thing));
00953 }
00954 X depth_value(const level_id &lid) const
00955 {
00956 typename depth_range_X_v::const_iterator i = depth_range_Xs.begin();
00957 for ( ; i != depth_range_Xs.end(); ++i)
00958 if (i->is_usable_in(lid))
00959 return i->depth_thing;
00960 return default_thing;
00961 }
00962 template <typename reader_fn_type>
00963 static depth_ranges_X read(reader &inf, reader_fn_type reader_fn)
00964 {
00965 depth_ranges_X ranges;
00966 ranges.clear(reader_fn(inf));
00967 const int count = unmarshallShort(inf);
00968 for (int i = 0; i < count; ++i)
00969 ranges.depth_range_Xs.push_back(
00970 depth_range_X<X>::read(inf, reader_fn));
00971 return ranges;
00972 }
00973 template <typename writer_fn_type>
00974 void write(writer &outf, writer_fn_type writer_fn) const
00975 {
00976 writer_fn(outf, default_thing);
00977 marshallShort(outf, depth_range_Xs.size());
00978 for (int i = 0, size = depth_range_Xs.size(); i < size; ++i)
00979 depth_range_Xs[i].write(outf, writer_fn);
00980 }
00981 };
00982
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008 class map_def
01009 {
01010 public:
01011 std::string name;
01012
01013 std::string description;
01014 std::string tags;
01015 level_id place;
01016
01017 depth_ranges depths;
01018 map_section_type orient;
01019
01020 typedef depth_ranges_X<map_chance> range_chance_t;
01021 typedef depth_ranges_X<int> range_weight_t;
01022
01023 range_chance_t _chance;
01024 range_weight_t _weight;
01025
01026 int weight_depth_mult;
01027 int weight_depth_div;
01028
01029 std::vector<std::string> welcome_messages;
01030
01031 map_lines map;
01032 mons_list mons;
01033 item_list items;
01034
01035 static bool valid_item_array_glyph(int gly);
01036 static int item_array_glyph_to_slot(int gly);
01037 static bool valid_monster_array_glyph(int gly);
01038 static bool valid_monster_glyph(int gly);
01039 static int monster_array_glyph_to_slot(int gly);
01040
01041 std::vector<mons_spec> random_mons;
01042
01043 map_flags level_flags, branch_flags;
01044
01045 dlua_chunk prelude, mapchunk, main, validate, veto, epilogue;
01046
01047 map_file_place place_loaded_from;
01048
01049 map_def *original;
01050
01051 uint8_t rock_colour, floor_colour;
01052 std::string rock_tile, floor_tile;
01053
01054 dungeon_feature_type border_fill_type;
01055 private:
01056
01057 bool index_only;
01058 mutable long cache_offset;
01059 std::string file;
01060
01061 typedef Matrix<bool> subvault_mask;
01062 subvault_mask *svmask;
01063
01064
01065 bool validating_map_flag;
01066
01067 public:
01068 map_def();
01069
01070 std::string desc_or_name() const;
01071
01072 std::string describe() const;
01073 void init();
01074 void reinit();
01075
01076 void load();
01077 void strip();
01078
01079 int weight(const level_id &lid) const;
01080 map_chance chance(const level_id &lid) const;
01081
01082 bool in_map(const coord_def &p) const;
01083 bool map_already_used() const;
01084
01085 coord_def size() const { return coord_def(map.width(), map.height()); }
01086
01087 std::vector<coord_def> find_glyph(int glyph) const;
01088 coord_def find_first_glyph(int glyph) const;
01089 coord_def find_first_glyph(const std::string &glyphs) const;
01090
01091 void write_index(writer&) const;
01092 void write_full(writer&) const;
01093 void write_maplines(writer &) const;
01094
01095 void read_index(reader&);
01096 void read_full(reader&, bool check_cache_version);
01097 void read_maplines(reader&);
01098
01099 void set_file(const std::string &s);
01100 std::string run_lua(bool skip_main);
01101 bool run_hook(const std::string &hook_name, bool die_on_lua_error = false);
01102 bool run_postplace_hook(bool die_on_lua_error = false);
01103 void copy_hooks_from(const map_def &other_map,
01104 const std::string &hook_name);
01105
01106
01107
01108 bool test_lua_validate(bool croak = false);
01109
01110
01111 bool test_lua_veto();
01112
01113
01114 bool run_lua_epilogue(bool croak = false);
01115
01116 std::string validate_map_def(const depth_ranges &);
01117 std::string validate_temple_map();
01118
01119 bool is_validating() const { return (validating_map_flag); }
01120
01121 void add_prelude_line(int line, const std::string &s);
01122 void add_main_line(int line, const std::string &s);
01123
01124 void hmirror();
01125 void vmirror();
01126 void rotate(bool clockwise);
01127 void normalise();
01128 std::string resolve();
01129 void fixup();
01130
01131 bool is_usable_in(const level_id &lid) const;
01132
01133 const keyed_mapspec *mapspec_at(const coord_def &c) const;
01134 keyed_mapspec *mapspec_at(const coord_def &c);
01135
01136 bool has_depth() const;
01137 void add_depth(const level_range &depth);
01138 void add_depths(const depth_ranges &depth);
01139
01140 bool can_dock(map_section_type) const;
01141 coord_def dock_pos(map_section_type) const;
01142 coord_def float_dock();
01143 coord_def float_place();
01144 coord_def float_aligned_place() const;
01145 coord_def float_random_place() const;
01146
01147 std::vector<coord_def> anchor_points() const;
01148
01149 bool is_minivault() const;
01150 bool is_overwritable_layout() const;
01151 bool has_tag(const std::string &tag) const;
01152 bool has_tag_prefix(const std::string &tag) const;
01153 bool has_tag_suffix(const std::string &suffix) const;
01154
01155 template <typename TagIterator>
01156 bool has_any_tag(TagIterator begin, TagIterator end) const
01157 {
01158 for ( ; begin != end; ++begin)
01159 if (has_tag(*begin))
01160 return true;
01161 return false;
01162 }
01163
01164 std::vector<std::string> get_tags() const;
01165
01166 std::vector<std::string> get_shuffle_strings() const;
01167 std::vector<std::string> get_subst_strings() const;
01168
01169 int glyph_at(const coord_def &c) const;
01170
01171
01172 std::string subvault_from_tagstring(const std::string &s);
01173 bool is_subvault() const;
01174 void apply_subvault_mask();
01175 bool subvault_cell_valid(const coord_def &c) const;
01176 int subvault_width() const;
01177 int subvault_height() const;
01178
01179
01180 int subvault_mismatch_count(const coord_def &place) const;
01181
01182 public:
01183 struct map_feature_finder
01184 {
01185 map_def ↦
01186 map_feature_finder(map_def &map_) : map(map_) { }
01187
01188
01189 dungeon_feature_type operator () (const coord_def &c) const
01190 {
01191 return (map_feature_at(&map, c, -1));
01192 }
01193 };
01194
01195 struct map_bounds_check
01196 {
01197 map_def ↦
01198 map_bounds_check(map_def &map_) : map(map_) { }
01199 bool operator () (const coord_def &c) const
01200 {
01201 return (c.x >= 0 && c.x < map.map.width()
01202 && c.y >= 0 && c.y < map.map.height());
01203 }
01204 };
01205
01206 private:
01207 void write_depth_ranges(writer&) const;
01208 void read_depth_ranges(reader&);
01209 bool test_lua_boolchunk(dlua_chunk &, bool def = false, bool croak = false);
01210 std::string rewrite_chunk_errors(const std::string &s) const;
01211 std::string apply_subvault(string_spec &);
01212 std::string validate_map_placeable();
01213 };
01214
01215 const int CHANCE_ROLL = 10000;
01216
01217 void map_register_flag(const std::string &flag);
01218
01219 std::string escape_string(std::string in, const std::string &toesc,
01220 const std::string &escapewith);
01221
01222 std::string mapdef_split_key_item(const std::string &s,
01223 std::string *key,
01224 int *separator,
01225 std::string *arg,
01226 int key_max_len = 1);
01227
01228 const char *map_section_name(int msect);
01229
01230 int store_tilename_get_index(const std::string tilename);
01231 #endif