git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@956 c06c8d41-db1a-0410-9941-cceddc491573
JQFQX7IWSJ4TYWVUVXAFMCPSAN67PRMNECDQI5WMON2JFMQVVUEQC 4NEULAWXO2BTDHJLIVHBJQDYK5626KU3W35VUJXYESIIF3USLVWQC 2NCKGJDDPPGP2NXYYPEPVRJIIWEP6M7HE6WYMQN3UNNN3C2JIRFQC RIRJ746W5ESARX4HUEA4JRVAKXXF3WYVXUCFFONPJMMKWHQAGI2AC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC WKTZHLOJ65WSK6FR5MF7RWGSMZ22T2D6LHB66FV3IPGXIBLYHHNAC 34C4U6EQWERY75GZJKUCM5KVGU2OUICETS5LGZF6RMKMZT4R5SQAC A3CO4KBFTFU3ZSHWRY2OPPX3MMTFV7OUCZGL7Q4Y2FU7JO4AP7MAC MSQI3TH6T62JAXQGLL52QZCWAMC372TGB6ZNNRDGUGMJKBNNV2VAC SVUM62ARSXH6RUBFRWS6KAQC7PTNTMGSV2GPZJQQJ4GNEML2HBVQC UPU5QYUWCXSX233JNGE37QEN5TG5HDRGLNSCEKHH3GPU4AEXW3KAC 5E7K2S4F4QDZC5UH3JVMYQ5SFJIKIATZII4EJL7IOT66ZBJ5GUPQC SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC C52GDIYN6W4WNYL2QV7L7OKFBVLPFSBQAEBCX44PAXCZ5H7JXCJQC UFLQ2LXPSQHE3XF57FPHQZIQPJUCFHB3Y5DMNZMRHOCV4LYKJGGQC I5N4EIR6SCLLRGKRBUKW5FKUVYK62EA5DOWIAS5XFIHZQKMCXWBAC 6CHNAAPWNROCQNX6EWPLXZOWX5HHKL5ZOHO24XRMNQTQF3CWB3VQC class subst_spec{public:subst_spec(int torepl, bool fix, const glyph_replacements_t &repls);int key() const{return (foo);}int value();private:int foo; // The thing to replace.bool fix; // If true, the first replacement fixes the value.int frozen_value;glyph_replacements_t repl;};
}std::string map_lines::clean_shuffle(std::string s){return replace_all_of(s, " \t", "");}std::string map_lines::check_block_shuffle(const std::string &s){const std::vector<std::string> segs = split_string("/", s);const unsigned seglen = segs[0].length();for (int i = 1, size = segs.size(); i < size; ++i){if (seglen != segs[i].length())return ("block shuffle segment length mismatch");}return ("");}std::string map_lines::check_shuffle(std::string &s){if (s.find(',') != std::string::npos)return ("use / for block shuffle, or multiple SHUFFLE: lines");s = clean_shuffle(s);if (s.find('/') != std::string::npos)return check_block_shuffle(s);return ("");}std::string map_lines::parse_glyph_replacements(std::string s,glyph_replacements_t &gly){s = replace_all_of(s, "\t", " ");std::vector<std::string> segs = split_string(" ", s);for (int i = 0, size = segs.size(); i < size; ++i){const std::string &is = segs[i];if (is.length() > 2 && is[1] == ':'){const int glych = is[0];int weight = atoi( is.substr(2).c_str() );if (weight < 1)weight = 10;gly.push_back( glyph_weighted_replacement_t(glych, weight) );}else{for (int c = 0, cs = is.length(); c < cs; ++c)gly.push_back( glyph_weighted_replacement_t(is[c], 10) );}}return ("");}std::string map_lines::add_subst(const std::string &sub){std::string s = trimmed_string(sub);if (s.empty())return ("");std::string::size_typenorm = s.find("="),fixe = s.find(":");const std::string::size_type sep = norm < fixe? norm : fixe;if (sep == std::string::npos)return ("malformed SUBST declaration - must use = or :");const bool fixed = (sep == fixe);std::string what_to_subst = trimmed_string(sub.substr(0, sep));std::string substitute = trimmed_string(sub.substr(sep + 1));if (what_to_subst.length() != 1)return make_stringf("selector '%s' must be exactly one character",what_to_subst.c_str());glyph_replacements_t repl;std::string err = parse_glyph_replacements(substitute, repl);if (!err.empty())return (err);substitutions.push_back(subst_spec( what_to_subst[0], fixed, repl ) );return ("");}std::string map_lines::add_shuffle(const std::string &raws){std::string s = raws;const std::string err = check_shuffle(s);if (err.empty())shuffles.push_back(s);return (err);
if (fillins.empty() || fillins.find('?') != std::string::npos)return;for (int i = 0, size = lines.size(); i < size; ++i)resolve(lines[i], fillins);
for (int i = 0, size = substitutions.size(); i < size; ++i){for (int y = 0, ysize = lines.size(); y < ysize; ++y)subst(lines[y], substitutions[i]);}
}std::string map_def::clean_shuffle(std::string s){return replace_all_of(s, " \t", "");}std::string map_def::check_block_shuffle(const std::string &s){const std::vector<std::string> segs = split_string("/", s);const unsigned seglen = segs[0].length();for (int i = 1, size = segs.size(); i < size; ++i){if (seglen != segs[i].length())return ("block shuffle segment length mismatch");}return ("");
std::string map_def::check_shuffle(std::string &s){if (s.find(',') != std::string::npos)return ("use / for block shuffle, or multiple SHUFFLE: lines");s = clean_shuffle(s);if (s.find('/') != std::string::npos)return check_block_shuffle(s);return ("");}std::string map_def::add_shuffle(const std::string &raws){std::string s = raws;const std::string err = check_shuffle(s);if (err.empty())shuffles.push_back(s);return (err);}
/////////////////////////////////////////////////////////////////////////// subst_specsubst_spec::subst_spec(int torepl, bool dofix, const glyph_replacements_t &g): foo(torepl), fix(dofix), frozen_value(0), repl(g){}int subst_spec::value(){if (frozen_value)return (frozen_value);int cumulative = 0;int chosen = 0;for (int i = 0, size = repl.size(); i < size; ++i){if (random2(cumulative += repl[i].second) < repl[i].second)chosen = repl[i].first;}if (fix)frozen_value = chosen;return (chosen);}
# Several SHUFFLE lines are possible.
# Several SHUFFLE: lines can be used, and the shuffles will be applied in# order.## SUBST:# The SUBST: directive allows you to specify a placeholder symbol that is# replaced with a random glyph from a set. For instance:# SUBST: ? = TUV# will replace occurrences of ? with one of TUV.# SUBST: ? = T U V# does the same thing - whitespace is not significant.# SUBST: ? = T:20 U V# makes T twice as likely to be used as U or V (the default weight# is 10). Note that there has to be at least one space after T:20# and that whitespace in T:20 is not permitted.# SUBST: ? : TUV# replaces occurrences of ? with one of TUV, and guarantees that all# occurrences of ? will get the same replacement symbol.# The placeholder symbol can be any non-space, printable character apart from# : and =. The replacement symbols can be any non-space printable character,# including : and = ("SUBST: ? = +=:123def" is valid).
# 1-7 - monster array monster. See section below on MONS: arrays for more inf
# 1-7 - monster array monster. See section below on MONS: arrays for more# information## A vault always has its body between MAP and ENDMAP commands. Furthermore,# several other additional commands are possible (some of them mandatory).
# ORIENT: LINES:# Some kind of orient: line is mandatory, unless you want the vault to be a# minivault, which is usually not what you want. Valid orient: lines are:# float: The dungeon builder will put your vault wherever it wants to.# some_direction: The vault will lie along the mentioned side of the map:
# NAME# Each vault/level/map must have a unique name. Underscores and digits are ok.## ORIENT: (north | northwest | ... | float | encompass)# Some kind of ORIENT: line is mandatory, unless you want the vault to be a# minivault, which is usually not what you want. Valid values are:# "float": The dungeon builder will put your vault wherever it wants to.# "some_direction": The vault will lie along the mentioned side of the map:
# vault. They create an array with up to 8 positions. What's in the first# position in the array will be used when the dungeon builder sees a "d" in the# vault definition, the second will be used for "e"s, etc. Positions are# comma-separated. Positions can contain multiple possibilities, one of which# the builder will choose randomly. Separate such multiple possibilities usin# a slash. Note that "nothing" (without the quotes) is a valid possibility.
# vault. They create an array with up to 8 positions. What's in the first# position in the array will be used when the dungeon builder sees a "d" in# the vault definition, the second will be used for "e"s, etc. Positions are# comma-separated; several ITEM: lines are possible as well.# Positions can contain multiple possibilities, one of which the builder will# choose randomly. Separate such multiple possibilities using a slash. Note# that "nothing" (without the quotes) is a valid possibility. The random# choice is done for each individual occurence of the letter.
# Modifiers: "good_item" makes the builder try to make the item a good one.# "any" by itself lets it plop down any object -- and you can combine "any"# with "good_item." "any" plus an item class gives a random item of that clas# (e.g. "any book").
# Modifiers:# "good_item" makes the builder try to make the item a good one.# "any" by itself gives random choice; you can combine "any" with "good_item."# "any book", "any misc" etc. gives a random item of that class.
# entry: this tag MUST be there for a vault to be pickable as an entry vault.# no_monster_gen: this tag prevents monster generation at the time of# the vault's creation. Highly advised for entry vaults with# a player-hostile geography, MUST-HAVE for those with water# or lava.# no_pool_fixup: prevents water squares next to land from being randomly conv# from deep water (the default) to shallow.
# "entry": this tag MUST be there for a vault to be pickable as an entry vault.# "no_monster_gen": this tag prevents monster generation at the time of# the vault's creation. Highly advised for entry vaults with# a player-hostile geography, MUST-HAVE for those with water# or lava.# "no_pool_fixup": prevents water squares next to land from being randomly# converted from deep water (the default) to shallow.# "branch_entry" eg. "orc_entry", "lair_entry" etc. If chosen, these maps# will contain the stairs for that branch. Use "O" to place# the stairs. Branch entries should go to splev.des.
# no_rotate: Normally, the dungeon builder can, at its whim, rotate your vault# This flag tells it, "hey, don't do that to my vault!"# no_hmirror: Like no_rotate, but for horizontal mirroring.# no_vmirror: Like no_rotate, but for vertical mirroring.
# "no_rotate": Normally, the dungeon builder can, at its whim, rotate your# vault. This flag tells it, "hey, don't do that to my vault!"# "no_hmirror": Like no_rotate, but for horizontal mirroring.# "no_vmirror": Like no_rotate, but for vertical mirroring.
# note that a lot of the vaults are in there mainly to add some
# SHUFFLE:# This allows you to randomly permute glyphs on the map. There are two ways:# SHUFFLE: 123w (i.e. list of glyphs, NOT comma-separated)# could, for example, swap all occurences of "1" with "2",# as well as swapping all "3" with "w" (or any other of the 23# possibilities).# SHUFFLE: 12/3w (i.e. list of slash-separated blocks of same size)# will either do nothing or swap all "1" with "3" and then also# swap "2" with "w" everywhere.# Several SHUFFLE: lines can be used, and the shuffles will be applied in# order.## SUBST:# The SUBST: directive allows you to specify a placeholder symbol that is# replaced with a random glyph from a set. For instance:# SUBST: ? = TUV# will replace occurrences of ? with one of TUV.# SUBST: ? = T U V# does the same thing - whitespace is not significant.# SUBST: ? = T:20 U V# makes T twice as likely to be used as U or V (the default weight# is 10). Note that there has to be at least one space after T:20# and that whitespace in T:20 is not permitted.# SUBST: ? : TUV# replaces occurrences of ? with one of TUV, and guarantees that all# occurrences of ? will get the same replacement symbol.# The placeholder symbol can be any non-space, printable character apart from# : and =. The replacement symbols can be any non-space printable character,# including : and = ("SUBST: ? = +=:123def" is valid).## SUBST: lines can safely replace symbols with themselves:## SUBST: w = wW## Multiple SUBST: lines can be used, and will be applied in order.# Substitutions are performed after any declared shuffles.## Note that a lot of the vaults are in there mainly to add some
# that form the border have a rock wall padding at least 6 deep. For instance,# if your map is ORIENT: north, you must have a 6 deep border of rock wall (or# any other kind of wall) along the northern, eastern, and western edges of the# map. If you're doing a fullscreen map (encompass), you must pad all around# the map with 6 layers of wall. For ORIENT: encompass maps, you don't need to# explicitly include the padding provided you make the map small enough that# the padding can be provided automatically.
# forming the border have a rock wall padding at least 6 deep. For instance,# if your map is ORIENT: north, you must have a 6 deep border of rock wall# (or any other kind of wall) along the northern, eastern, and western edges# of the map. If you're doing a fullscreen map (encompass), you must pad all# around the map with 6 layers of wall. For ORIENT: encompass maps, you# don't need to explicitly include the padding provided you make the map# small enough that the padding can be provided automatically.
# You do not have to place all of the stairs unless the level is full# screen, in which case you must place all except the extra stairs (># and <). The <> stairs can be put anywhere and in any quantities but# do not have to be there. Any of the other stairs which are not# present in the vault will be randomly placed outside it. Also# generally try to avoid rooms with no exit.
# You do not have to place all of the stairs unless the level is full screen,# in which case you must place all except the extra stairs (> and <). The <># stairs can be put anywhere and in any quantities but do not have to be# there. Any of the other stairs which are not present in the vault will be# randomly placed outside it. Also generally try to avoid rooms with no exit.
# You can use the templates below to build vaults. The entry point# '@' must be present (except full-screen vaults where it must not# and orient:float maps, where it is optional - the builder will# randomly convert '.' spaces on edges to entry points if needed) and# be on an edge of the vault.
# You can use the templates below to build vaults. The entry point '@' must# be present (except full-screen vaults where it must not and orient:float# maps, where it is optional - the builder will randomly convert '.' spaces# on edges to entry points if needed) and be on an edge of the vault.
# levels. They're placed *after* normal map generation, whereas normal vaults# are placed before generating the rest of the level. There's no way to# guarantee generation of a minivault on a particular level, whereas vaults# can be forced to appear using a PLACE: attribute.
# levels. They're placed *after* normal map generation, whereas normal# vaults are placed before generating the rest of the level. There's no way# to guarantee generation of a minivault on a particular level, whereas# vaults can be forced to appear using a PLACE: attribute.
" levdes.vim:"" Basic Vim syntax highlighting for Dungeon Crawl Stone Soup level design" (.des) files."" This syntax highlighting script is distributed under the terms of the" Crawl Public License. See licence.txt for details.
" Vim syntax file" Language: Dungeon Crawl level design (.des) files." Maintainer: Darshan Shaligram <scintilla@gmail.com>" Last Change: 2007 Feb 20" Remark: Basic Vim syntax highlighting for Dungeon Crawl Stone Soup" level design (.des) files.
syn keyword desDeclarator NAME: ORIENT: DEPTH: PLACE: MONS: FLAGS: SYMBOL: default-depth: TAGS: CHANCE: ITEM: SHUFFLE:syn keyword desOrientation encompass north south east west northeast northwest southeast southwest float
syn region desSubst start=/^SUBST:\s*/ end=/$/ contains=desSubstDec,desSubstArg,desSubstSep,@desMapElements keependsyn region desShuffle start=/^SHUFFLE:\s*/ end=/$/ contains=desShuffleDec,desMapFrag keepend
syn keyword desSubstDec SUBST: containedsyn keyword desShuffleDec SHUFFLE: containedsyn keyword desDeclarator NAME: ORIENT: DEPTH: PLACE: MONS: FLAGS: default-depth: TAGS: CHANCE: ITEM:syn keyword desOrientation encompass north south east west northeast northwest southeast southwest float no_hmirror no_vmirror no_rotate entry pan no_pool_fixup no_monster_gen generate_awake