summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEnne Walker <ennewalker@users.sourceforge.net>2009-10-29 21:35:11 -0400
committerEnne Walker <ennewalker@users.sourceforge.net>2009-10-29 21:42:17 -0400
commit2029620b5925ac34023e887fd47488f5e1c2180a (patch)
tree1b123a89b1e7781cec7f97e910d9664b5f44ad77
parent2386094200a314bee252ca9cb6a229ee42953f5a (diff)
downloadcrawl-ref-2029620b5925ac34023e887fd47488f5e1c2180a.tar.gz
crawl-ref-2029620b5925ac34023e887fd47488f5e1c2180a.zip
Allow assignment to multiple glyphs at once.
All glyph assignment declarations in maps (e.g. COLOUR, KPROP, FTILE) can now assign multiple glyphs simultaneously. This should make some vault definitions less cumbersome. See the doc for more details.
-rw-r--r--crawl-ref/docs/develop/level_design.txt43
-rw-r--r--crawl-ref/source/dat/entry.des16
-rw-r--r--crawl-ref/source/dat/mini.des10
-rw-r--r--crawl-ref/source/mapdef.cc134
-rw-r--r--crawl-ref/source/mapdef.h54
5 files changed, 182 insertions, 75 deletions
diff --git a/crawl-ref/docs/develop/level_design.txt b/crawl-ref/docs/develop/level_design.txt
index 2a8889c193..f0e9f73eae 100644
--- a/crawl-ref/docs/develop/level_design.txt
+++ b/crawl-ref/docs/develop/level_design.txt
@@ -753,11 +753,8 @@ FTILE: . = floor_grass:20 / floor_dirt / none
underneath it will be the tile that was specified.
If a feature that normally covers the floor (e.g. rock walls) is
- destroyed, this floor tile will be used in place of the normal floor.
- Thus, it can be useful even for non-floor features.
-
- For convenience, multiple glyphs can be specified together as a
- group, e.g. ".[{( = floor_orc".
+ destroyed, this floor tile will be used in place of the normal
+ floor. Thus, it can be useful even for non-floor features.
Like COLOUR, this should be used sparingly.
@@ -1009,6 +1006,9 @@ MARKER: A = feat:<feature_name> or lua:<marker_expr>
SHUFFLE: Oa/|c
MARKER: O = lua:<expr>
+Handling long lines
+-------------------
+
For most map headers, you can split long lines by ending the line that will be
continued on the next line with \ as:
@@ -1040,6 +1040,39 @@ ITEM: potion of\
Crawl will see "potion ofhealing", not "potion of healing".
+Assigning multiple glyphs at once
+---------------------------------
+
+Declarations that modify glyphs allow multiple glyphs to be assigned
+simultaneously as a convenience. For example, the following declaration will
+assign floor_orc as the tile to be used for all up stair cases and floor:
+
+ FTILE: .[{( = floor_orc
+
+This case is identical to the longer syntax:
+
+ FTILE: . = floor_orc
+ FTILE: [ = floor_orc
+ FTILE: { = floor_orc
+ FTILE: ( = floor_orc
+
+Using : instead of = while assigning glyphs will assign the same value to all
+glyphs. In the following example, the glyphs A, B, and C will either all
+contain gold or all contain nothing:
+
+ KITEM: ABC : gold / nothing
+
+Note: The number of items assigned in an NSUBST expression applies to the
+entire group of glyphs being assigned. For example:
+
+ # Among all A, B, and C glyphs, make one a floor and the rest walls.
+ NSUBST: ABC = 1:. / *:x
+
+ # Make one A glyph floor, one B glyph floor, and one C glyph floor.
+ # Make the rest of the A, B, and C glyphs walls.
+ NSUBST: A = 1:. / *:x
+ NSUBST: B = 1:. / *:x
+ NSUBST: C = 1:. / *:x
E. Conditionalising levels
=============================
diff --git a/crawl-ref/source/dat/entry.des b/crawl-ref/source/dat/entry.des
index 326afcdcce..f450e26af3 100644
--- a/crawl-ref/source/dat/entry.des
+++ b/crawl-ref/source/dat/entry.des
@@ -51,10 +51,7 @@ KFEAT: T = net trap
# ("Ack! Now I'm trapped too! Help!") so I coded it in. ^.^
NSUBST: M = 2=E / *=M E:2
KFEAT: E = teleport trap
-KFEAT: M = shallow_water
-KFEAT: N = shallow_water
-KFEAT: O = shallow_water
-KFEAT: Q = shallow_water
+KFEAT: MNOQ = shallow_water
SHUFFLE: M/N/O/P/Q
SUBST: P = MNO
#
@@ -3507,13 +3504,13 @@ MONS: w:30 nothing / ooze / w:2 jelly / giant cockroach / w:2 worm / \
# There is a very slight chance that a jelly or an intelligent monster
# (hobgoblin) might spawn inside near the door. This is okay; added an exit.
ORIENT: float
-FTILE: 1234+ABCDEabcde = floor_dirt
+FTILE: 1234+ABCDEabcdem = floor_dirt
SHUFFLE: abcde / fghij
# Don't let auto-explore open the door and unleash the caged monsters.
KPROP: + = force_exclude
SUBST: f=A, g=B, h=C, i=D, j=E
-SUBST: a=mx, b=mx, c=mx, d=mx, e=mx
-SUBST: A:mx, B:mx, C:mx, D:mx, E:mx
+SUBST: abcde = mx
+SUBST: ABCDE : mx
SUBST: ===++
SHUFFLE: xc, 123
KMASK: T = no_monster_gen
@@ -4898,8 +4895,7 @@ TAGS: entry no_rotate no_pool_fixup
ORIENT: northwest
MONS: plant
FTILE: .t1 = floor_lair
-KMASK: w = no_monster_gen
-KMASK: W = no_monster_gen
+KMASK: Ww = no_monster_gen
MAP
ttttttttttttttttttttttttttttttttttttttttttt
tttttttttttt1ttttttwwtttttttttttttttttttttt
@@ -4945,7 +4941,7 @@ SUBST: ' = .
inside = '.'
})
if crawl.coinflip() then
- map_smear({iterations=20, smear='x', onto='.W', boxy = true})
+ map_smear({iterations=20, smear='x', onto='.W', boxy=true})
end
}}
SUBST: W:xw
diff --git a/crawl-ref/source/dat/mini.des b/crawl-ref/source/dat/mini.des
index c033235a67..dd45054201 100644
--- a/crawl-ref/source/dat/mini.des
+++ b/crawl-ref/source/dat/mini.des
@@ -906,14 +906,8 @@ ENDMAP
#
NAME: minivault_13
SHUFFLE: AB, CD, EH/FG
-KFEAT: A = any trap
-KFEAT: C = any trap
-KFEAT: E = any trap
-KFEAT: H = any trap
-KITEM: A = gold / nothing
-KITEM: B = gold / nothing
-KITEM: C = gold / nothing
-KITEM: D = gold / nothing
+KFEAT: ACEH = any trap
+KITEM: ABCD = gold / nothing
SUBST: F = G:100 F:1
KMONS: F = orange crystal statue / silver statue / ice statue
MAP
diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc
index 960531bc8c..e05d021a99 100644
--- a/crawl-ref/source/mapdef.cc
+++ b/crawl-ref/source/mapdef.cc
@@ -423,11 +423,11 @@ std::string map_lines::add_feature_marker(const std::string &s)
{
std::string key, arg;
int sep = 0;
- std::string err = mapdef_split_key_item(s, &key, &sep, &arg);
+ std::string err = mapdef_split_key_item(s, &key, &sep, &arg, -1);
if (!err.empty())
return (err);
- map_marker_spec spec(key[0], arg);
+ map_marker_spec spec(key, arg);
spec.apply_transform(*this);
return ("");
@@ -436,7 +436,7 @@ std::string map_lines::add_feature_marker(const std::string &s)
std::string map_lines::add_lua_marker(const std::string &key,
const lua_datum &function)
{
- map_marker_spec spec(key[0], function);
+ map_marker_spec spec(key, function);
spec.apply_transform(*this);
return ("");
}
@@ -628,7 +628,7 @@ std::string map_lines::add_colour(const std::string &sub)
std::string key;
std::string substitute;
- std::string err = mapdef_split_key_item(sub, &key, &sep, &substitute);
+ std::string err = mapdef_split_key_item(sub, &key, &sep, &substitute, -1);
if (!err.empty())
return (err);
@@ -637,7 +637,7 @@ std::string map_lines::add_colour(const std::string &sub)
if (!err.empty())
return (err);
- colour_spec spec(key[0], sep == ':', colours);
+ colour_spec spec(key, sep == ':', colours);
overlay_colours(spec);
return ("");
@@ -664,7 +664,7 @@ std::string map_lines::add_fproperty(const std::string &sub)
std::string key;
std::string substitute;
- std::string err = mapdef_split_key_item(sub, &key, &sep, &substitute);
+ std::string err = mapdef_split_key_item(sub, &key, &sep, &substitute, -1);
if (!err.empty())
return (err);
@@ -673,7 +673,7 @@ std::string map_lines::add_fproperty(const std::string &sub)
if (!err.empty())
return (err);
- fprop_spec spec(key[0], sep == ':', fprops);
+ fprop_spec spec(key, sep == ':', fprops);
overlay_fprops(spec);
return ("");
@@ -690,7 +690,7 @@ std::string map_lines::add_subst(const std::string &sub)
std::string key;
std::string substitute;
- std::string err = mapdef_split_key_item(sub, &key, &sep, &substitute);
+ std::string err = mapdef_split_key_item(sub, &key, &sep, &substitute, -1);
if (!err.empty())
return (err);
@@ -699,7 +699,7 @@ std::string map_lines::add_subst(const std::string &sub)
if (!err.empty())
return (err);
- subst_spec spec(key[0], sep == ':', repl);
+ subst_spec spec(key, sep == ':', repl);
subst(spec);
return ("");
@@ -713,8 +713,8 @@ std::string map_lines::parse_nsubst_spec(const std::string &s,
std::string err = mapdef_split_key_item(s, &key, &sep, &arg, -1);
if (!err.empty())
return err;
- const int keyval = key == "*"? -1 : atoi(key.c_str());
- if (!keyval)
+ const int count = key == "*"? -1 : atoi(key.c_str());
+ if (!count)
return make_stringf("Illegal spec: %s", s.c_str());
glyph_replacements_t repl;
@@ -722,7 +722,7 @@ std::string map_lines::parse_nsubst_spec(const std::string &s,
if (!err.empty())
return (err);
- spec = subst_spec(keyval, sep == ':', repl);
+ spec = subst_spec(count, sep == ':', repl);
return ("");
}
@@ -733,7 +733,7 @@ std::string map_lines::add_nsubst(const std::string &s)
int sep;
std::string key, arg;
- std::string err = mapdef_split_key_item(s, &key, &sep, &arg);
+ std::string err = mapdef_split_key_item(s, &key, &sep, &arg, -1);
if (!err.empty())
return (err);
@@ -757,7 +757,7 @@ std::string map_lines::add_nsubst(const std::string &s)
substs.push_back(spec);
}
- nsubst_spec spec(key[0], substs);
+ nsubst_spec spec(key, substs);
nsubst(spec);
return ("");
@@ -903,12 +903,13 @@ void map_lines::clear()
void map_lines::subst(std::string &s, subst_spec &spec)
{
std::string::size_type pos = 0;
- while ((pos = s.find(spec.key(), pos)) != std::string::npos)
+ while ((pos = s.find_first_of(spec.key, pos)) != std::string::npos)
s[pos++] = spec.value();
}
void map_lines::subst(subst_spec &spec)
{
+ ASSERT(!spec.key.empty());
for (int y = 0, ysize = lines.size(); y < ysize; ++y)
subst(lines[y], spec);
}
@@ -921,7 +922,7 @@ void map_lines::overlay_colours(colour_spec &spec)
for (int y = 0, ysize = lines.size(); y < ysize; ++y)
{
std::string::size_type pos = 0;
- while ((pos = lines[y].find(spec.key, pos)) != std::string::npos)
+ while ((pos = lines[y].find_first_of(spec.key, pos)) != std::string::npos)
{
(*overlay)(pos, y).colour = spec.get_colour();
++pos;
@@ -937,7 +938,7 @@ void map_lines::overlay_fprops(fprop_spec &spec)
for (int y = 0, ysize = lines.size(); y < ysize; ++y)
{
std::string::size_type pos = 0;
- while ((pos = lines[y].find(spec.key, pos)) != std::string::npos)
+ while ((pos = lines[y].find_first_of(spec.key, pos)) != std::string::npos)
{
(*overlay)(pos, y).property |= spec.get_property();
++pos;
@@ -972,7 +973,7 @@ void map_lines::nsubst(nsubst_spec &spec)
for (int y = 0, ysize = lines.size(); y < ysize; ++y)
{
std::string::size_type pos = 0;
- while ((pos = lines[y].find(spec.key, pos)) != std::string::npos)
+ while ((pos = lines[y].find_first_of(spec.key, pos)) != std::string::npos)
positions.push_back(coord_def(pos++, y));
}
std::random_shuffle(positions.begin(), positions.end(), random2);
@@ -982,7 +983,7 @@ void map_lines::nsubst(nsubst_spec &spec)
for (int i = 0, vsize = spec.specs.size();
i < vsize && pcount < psize; ++i)
{
- const int nsubsts = spec.specs[i].key();
+ const int nsubsts = spec.specs[i].count;
pcount += apply_nsubst(positions, pcount, nsubsts, spec.specs[i]);
}
}
@@ -1212,6 +1213,21 @@ std::vector<coord_def> map_lines::find_glyph(int gly) const
return (points);
}
+std::vector<coord_def> map_lines::find_glyph(const std::string &glyphs) const
+{
+ std::vector<coord_def> points;
+ for (int y = height() - 1; y >= 0; --y)
+ {
+ for (int x = width() - 1; x >= 0; --x)
+ {
+ const coord_def c(x, y);
+ if (glyphs.find((*this)(c)) != std::string::npos)
+ points.push_back(c);
+ }
+ }
+ return (points);
+}
+
coord_def map_lines::find_first_glyph(int gly) const
{
for (int y = 0, h = height(); y < h; ++y)
@@ -2087,38 +2103,55 @@ keyed_mapspec *map_def::mapspec_for_key(int key)
std::string map_def::add_key_field(
const std::string &s,
- std::string (keyed_mapspec::*set_field)(const std::string &s, bool fixed))
+ std::string (keyed_mapspec::*set_field)(const std::string &s, bool fixed),
+ void (keyed_mapspec::*copy_field)(keyed_mapspec &spec))
{
int separator = 0;
std::string key, arg;
- std::string err = mapdef_split_key_item(s, &key, &separator, &arg);
+ std::string err = mapdef_split_key_item(s, &key, &separator, &arg, -1);
if (!err.empty())
return (err);
- keyed_mapspec &km = keyspecs[key[0]];
- km.key_glyph = key[0];
- return ((km.*set_field)(arg, separator == ':'));
+ keyed_mapspec &kmbase = keyspecs[key[0]];
+ kmbase.key_glyph = key[0];
+ err = ((kmbase.*set_field)(arg, separator == ':'));
+ if (!err.empty())
+ return (err);
+
+ size_t len = key.length();
+ for (size_t i = 1; i < len; i++)
+ {
+ keyed_mapspec &km = keyspecs[key[i]];
+ km.key_glyph = key[i];
+ ((km.*copy_field)(kmbase));
+ }
+
+ return (err);
}
std::string map_def::add_key_item(const std::string &s)
{
- return add_key_field(s, &keyed_mapspec::set_item);
+ return add_key_field(s, &keyed_mapspec::set_item,
+ &keyed_mapspec::copy_item);
}
std::string map_def::add_key_feat(const std::string &s)
{
- return add_key_field(s, &keyed_mapspec::set_feat);
+ return add_key_field(s, &keyed_mapspec::set_feat,
+ &keyed_mapspec::copy_feat);
}
std::string map_def::add_key_mons(const std::string &s)
{
- return add_key_field(s, &keyed_mapspec::set_mons);
+ return add_key_field(s, &keyed_mapspec::set_mons,
+ &keyed_mapspec::copy_mons);
}
std::string map_def::add_key_mask(const std::string &s)
{
- return add_key_field(s, &keyed_mapspec::set_mask);
+ return add_key_field(s, &keyed_mapspec::set_mask,
+ &keyed_mapspec::copy_mask);
}
///////////////////////////////////////////////////////////////////
@@ -2413,7 +2446,10 @@ std::string mons_list::add_mons(const std::string &s, bool fix)
return (error);
if (fix)
+ {
slotmons.fix_slot = true;
+ pick_monster(slotmons);
+ }
mons.push_back( slotmons );
@@ -2723,7 +2759,11 @@ std::string item_list::add_item(const std::string &spec, bool fix)
if (error.empty())
{
if (fix)
+ {
sp.fix_slot = true;
+ pick_item(sp);
+ }
+
items.push_back(sp);
}
@@ -3164,8 +3204,13 @@ item_list::item_spec_slot item_list::parse_item_spec(std::string spec)
/////////////////////////////////////////////////////////////////////////
// subst_spec
-subst_spec::subst_spec(int torepl, bool dofix, const glyph_replacements_t &g)
- : foo(torepl), fix(dofix), frozen_value(0), repl(g)
+subst_spec::subst_spec(std::string _k, bool _f, const glyph_replacements_t &g)
+ : key(_k), count(-1), fix(_f), frozen_value(0), repl(g)
+{
+}
+
+subst_spec::subst_spec(int _count, bool dofix, const glyph_replacements_t &g)
+ : key(""), count(_count), fix(dofix), frozen_value(0), repl(g)
{
}
@@ -3189,7 +3234,7 @@ int subst_spec::value()
//////////////////////////////////////////////////////////////////////////
// nsubst_spec
-nsubst_spec::nsubst_spec(int _key, const std::vector<subst_spec> &_specs)
+nsubst_spec::nsubst_spec(std::string _key, const std::vector<subst_spec> &_specs)
: key(_key), specs(_specs)
{
}
@@ -3329,9 +3374,19 @@ std::string keyed_mapspec::set_feat(const std::string &s, bool fix)
err.clear();
parse_features(s);
feat.fix_slot = fix;
+
+ // Fix this feature.
+ if (fix)
+ get_feat();
+
return (err);
}
+void keyed_mapspec::copy_feat(keyed_mapspec &spec)
+{
+ feat = spec.feat;
+}
+
void keyed_mapspec::parse_features(const std::string &s)
{
feat.feats.clear();
@@ -3433,6 +3488,7 @@ std::string keyed_mapspec::set_mons(const std::string &s, bool fix)
if (!error.empty())
return (error);
}
+
return ("");
}
@@ -3449,6 +3505,7 @@ std::string keyed_mapspec::set_item(const std::string &s, bool fix)
if (!err.empty())
return (err);
}
+
return (err);
}
@@ -3482,6 +3539,21 @@ std::string keyed_mapspec::set_mask(const std::string &s, bool garbage)
return (err);
}
+void keyed_mapspec::copy_mons(keyed_mapspec &spec)
+{
+ mons = spec.mons;
+}
+
+void keyed_mapspec::copy_item(keyed_mapspec &spec)
+{
+ item = spec.item;
+}
+
+void keyed_mapspec::copy_mask(keyed_mapspec &spec)
+{
+ map_mask = spec.map_mask;
+}
+
feature_spec keyed_mapspec::get_feat()
{
return feat.get_feat('.');
diff --git a/crawl-ref/source/mapdef.h b/crawl-ref/source/mapdef.h
index 41c5bc3c33..a02f89393e 100644
--- a/crawl-ref/source/mapdef.h
+++ b/crawl-ref/source/mapdef.h
@@ -105,19 +105,19 @@ class map_lines;
class subst_spec
{
public:
- subst_spec(int torepl, bool fix, const glyph_replacements_t &repls);
- subst_spec() : foo(0), fix(false), frozen_value(0), repl() { }
-
- int key() const
- {
- return (foo);
- }
+ subst_spec(std::string torepl, bool fix, const glyph_replacements_t &repls);
+ subst_spec(int count, bool fix, const glyph_replacements_t &repls);
+ subst_spec() : key(""), count(-1), fix(false), frozen_value(0), repl() { }
int value();
-private:
- int foo; // The thing to replace.
- bool fix; // If true, the first replacement fixes the value.
+public:
+ std::string key;
+ // If this is part of an nsubst spec, how many to replace.
+ // -1 corresponds to all (i.e. '*')
+ int count;
+
+ bool fix;
int frozen_value;
glyph_replacements_t repl;
@@ -126,9 +126,9 @@ private:
class nsubst_spec
{
public:
- nsubst_spec(int key, const std::vector<subst_spec> &specs);
+ nsubst_spec(std::string key, const std::vector<subst_spec> &specs);
public:
- int key;
+ std::string key;
std::vector<subst_spec> specs;
};
@@ -141,7 +141,7 @@ public:
class colour_spec
{
public:
- colour_spec(int _key, bool _fix, const map_colour_list &clist)
+ colour_spec(std::string _key, bool _fix, const map_colour_list &clist)
: key(_key), fix(_fix), fixed_colour(BLACK), colours(clist)
{
}
@@ -149,7 +149,7 @@ public:
int get_colour();
public:
- int key;
+ std::string key;
bool fix;
int fixed_colour;
map_colour_list colours;
@@ -164,7 +164,7 @@ public:
class fprop_spec
{
public:
- fprop_spec(int _key, bool _fix, const map_fprop_list &flist)
+ fprop_spec(std::string _key, bool _fix, const map_fprop_list &flist)
: key(_key), fix(_fix), fixed_prop(FPROP_NONE), fprops(flist)
{
}
@@ -172,7 +172,7 @@ public:
int get_property();
public:
- int key;
+ std::string key;
bool fix;
int fixed_prop;
map_fprop_list fprops;
@@ -180,7 +180,7 @@ public:
#ifdef USE_TILE
typedef std::pair<int, int> map_weighted_tile;
-class map_tile_list : public std::vector<map_weighted_colour>
+class map_tile_list : public std::vector<map_weighted_tile>
{
public:
bool parse(const std::string &s, int weight);
@@ -210,16 +210,16 @@ public:
class map_marker_spec
{
public:
- int key;
+ std::string key;
std::string marker;
// Special handling for Lua markers:
std::auto_ptr<lua_datum> lua_fn;
- map_marker_spec(int _key, const std::string &mark)
+ map_marker_spec(std::string _key, const std::string &mark)
: key(_key), marker(mark), lua_fn() { }
- map_marker_spec(int _key, const lua_datum &fn)
+ map_marker_spec(std::string _key, const lua_datum &fn)
: key(_key), marker(), lua_fn(new lua_datum(fn)) { }
std::string apply_transform(map_lines &map);
@@ -253,6 +253,7 @@ public:
std::string add_rocktile(const std::string &s);
#endif
+ std::vector<coord_def> find_glyph(const std::string &glyphs) const;
std::vector<coord_def> find_glyph(int glyph) const;
coord_def find_first_glyph(int glyph) const;
coord_def find_first_glyph(const std::string &glyphs) const;
@@ -576,11 +577,21 @@ public:
public:
keyed_mapspec();
+ // Parse the string and set the given entry. If fix is true,
+ // then whatever is selected for the first feature will be
+ // permanently fixed.
std::string set_feat(const std::string &s, bool fix);
std::string set_mons(const std::string &s, bool fix);
std::string set_item(const std::string &s, bool fix);
std::string set_mask(const std::string &s, bool garbage);
+ // Copy from the given mapspec. If that entry is fixed,
+ // it should be pre-selected prior to the copy.
+ void copy_feat(keyed_mapspec &spec);
+ void copy_mons(keyed_mapspec &spec);
+ void copy_item(keyed_mapspec &spec);
+ void copy_mask(keyed_mapspec &spec);
+
feature_spec get_feat();
mons_list &get_monsters();
item_list &get_items();
@@ -805,7 +816,8 @@ private:
std::string add_key_field(
const std::string &s,
std::string (keyed_mapspec::*set_field)(
- const std::string &s, bool fixed));
+ const std::string &s, bool fixed),
+ void (keyed_mapspec::*copy_field)(keyed_mapspec &spec));
};
const int CHANCE_ROLL = 10000;