summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/Kills.cc20
-rw-r--r--crawl-ref/source/direct.cc2
-rw-r--r--crawl-ref/source/dungeon.cc2
-rw-r--r--crawl-ref/source/libutil.cc47
-rw-r--r--crawl-ref/source/libutil.h7
-rw-r--r--crawl-ref/source/travel.cc83
-rw-r--r--crawl-ref/source/travel.h27
-rw-r--r--crawl-ref/source/view.cc2
8 files changed, 130 insertions, 60 deletions
diff --git a/crawl-ref/source/Kills.cc b/crawl-ref/source/Kills.cc
index 14516c5010..1f3b8c7d37 100644
--- a/crawl-ref/source/Kills.cc
+++ b/crawl-ref/source/Kills.cc
@@ -352,22 +352,6 @@ static const char *modifier_suffixes[] =
"zombie", "skeleton", "simulacrum", NULL,
};
-// Naively prefix A/an to a monster name. At the moment, we don't have monster
-// names that demand more sophistication (maybe ynoxinul - don't know how
-// that's pronounced).
-static std::string article_a(const std::string &name)
-{
- if (!name.length()) return name;
- switch (name[0])
- {
- case 'a': case 'e': case 'i': case 'o': case 'u':
- case 'A': case 'E': case 'I': case 'O': case 'U':
- return "An " + name;
- default:
- return "A " + name;
- }
-}
-
// For a non-unique monster, prefixes a suitable article if we have only one
// kill, else prefixes a kill count and pluralises the monster name.
static std::string n_names(const std::string &name, int n)
@@ -376,10 +360,10 @@ static std::string n_names(const std::string &name, int n)
{
char buf[20];
snprintf(buf, sizeof buf, "%d ", n);
- return buf + pluralise(name, modifier_suffixes);
+ return buf + pluralise(name, standard_plural_qualifiers, modifier_suffixes);
}
else
- return article_a(name);
+ return article_a(name, false);
}
// Returns a string describing the number of times a unique has been killed.
diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc
index ab8e845a92..92512cc899 100644
--- a/crawl-ref/source/direct.cc
+++ b/crawl-ref/source/direct.cc
@@ -1336,7 +1336,7 @@ std::string feature_description(dungeon_feature_type grid,
case DNGN_STONE_STAIRS_DOWN_III:
return ("A stone staircase leading down.");
case DNGN_ROCK_STAIRS_UP:
- return ("A rock staircase leading upwards.");
+ return ("A rock staircase leading up.");
case DNGN_STONE_STAIRS_UP_I:
case DNGN_STONE_STAIRS_UP_II:
case DNGN_STONE_STAIRS_UP_III:
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index 3e07b2873f..d133f8609c 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -2541,7 +2541,7 @@ static void beehive(spec_room &sr)
} // end beehive()
static bool safe_minivault_place(int v1x, int v1y,
- const vault_placement &place)
+ const vault_placement &place)
{
dgn_region reg(v1x, v1y, place.width, place.height);
if (reg.overlaps_any(vault_zones))
diff --git a/crawl-ref/source/libutil.cc b/crawl-ref/source/libutil.cc
index 14fe074a33..09f86ce2fd 100644
--- a/crawl-ref/source/libutil.cc
+++ b/crawl-ref/source/libutil.cc
@@ -129,23 +129,46 @@ int ends_with(const std::string &s, const char *suffixes[])
return (0);
}
+// Naively prefix A/an to a noun.
+std::string article_a(const std::string &name, bool lowercase)
+{
+ if (!name.length()) return name;
+ const char *a = lowercase? "a " : "A ";
+ const char *an = lowercase? "an " : "An ";
+ switch (name[0])
+ {
+ case 'a': case 'e': case 'i': case 'o': case 'u':
+ case 'A': case 'E': case 'I': case 'O': case 'U':
+ return an + name;
+ default:
+ return a + name;
+ }
+}
+
+const char *standard_plural_qualifiers[] =
+{
+ " of ", " labeled "
+};
+
// Pluralises a monster or item name. This'll need to be updated for
// correctness whenever new monsters/items are added.
-std::string pluralise(const std::string &name,
- const char *no_of[])
+std::string pluralise(const std::string &name,
+ const char *qualifiers[],
+ const char *no_qualifier[])
{
std::string::size_type pos;
- // Pluralise first word of names like 'eye of draining' or
- // 'scrolls labeled FOOBAR', but only if the whole name is not
- // suffixed by a supplied modifier, such as 'zombie' or 'skeleton'
- if ( (pos = name.find(" of ")) != std::string::npos
- && !ends_with(name, no_of) )
- return pluralise(name.substr(0, pos)) + name.substr(pos);
- else if ( (pos = name.find(" labeled ")) != std::string::npos
- && !ends_with(name, no_of) )
- return pluralise(name.substr(0, pos)) + name.substr(pos);
- else if (ends_with(name, "us"))
+ if (qualifiers)
+ {
+ for (int i = 0; qualifiers[i]; ++i)
+ if ((pos = name.find(qualifiers[i])) != std::string::npos
+ && !ends_with(name, no_qualifier))
+ {
+ return pluralise(name.substr(0, pos)) + name.substr(pos);
+ }
+ }
+
+ if (ends_with(name, "us"))
// Fungus, ufetubus, for instance.
return name.substr(0, name.length() - 2) + "i";
else if (ends_with(name, "larva") || ends_with(name, "amoeba"))
diff --git a/crawl-ref/source/libutil.h b/crawl-ref/source/libutil.h
index 137fe261e1..2277e835b8 100644
--- a/crawl-ref/source/libutil.h
+++ b/crawl-ref/source/libutil.h
@@ -19,11 +19,16 @@
#include <string>
#include <vector>
+extern const char *standard_plural_qualifiers[];
+
std::string lowercase_string(std::string s);
std::string &lowercase(std::string &s);
std::string &uppercase(std::string &s);
bool ends_with(const std::string &s, const std::string &suffix);
-std::string pluralise(const std::string &name,
+
+std::string article_a(const std::string &name, bool lowercase = true);
+std::string pluralise(const std::string &name,
+ const char *stock_plural_quals[] = standard_plural_qualifiers,
const char *no_of[] = NULL);
std::string number_in_words(unsigned number, int pow = 0);
diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc
index d579e0752d..529d3c6a47 100644
--- a/crawl-ref/source/travel.cc
+++ b/crawl-ref/source/travel.cc
@@ -628,7 +628,7 @@ bool is_branch_stair(int gridx, int gridy)
return (next.branch != curr.branch);
}
-bool is_stair(unsigned gridc)
+bool is_stair(dungeon_feature_type gridc)
{
return (is_travelable_stair(gridc)
|| gridc == DNGN_ENTER_ABYSS
@@ -641,7 +641,7 @@ bool is_stair(unsigned gridc)
/*
* Returns true if the given dungeon feature can be considered a stair.
*/
-bool is_travelable_stair(unsigned gridc)
+bool is_travelable_stair(dungeon_feature_type gridc)
{
switch (gridc)
{
@@ -2254,7 +2254,7 @@ void start_translevel_travel(bool prompt_for_destination)
}
}
-command_type stair_direction(int stair)
+command_type stair_direction(dungeon_feature_type stair)
{
return ((stair < DNGN_STONE_STAIRS_UP_I
|| stair > DNGN_ROCK_STAIRS_UP)
@@ -2975,7 +2975,7 @@ void LevelInfo::get_stairs(std::vector<coord_def> &st)
{
for (int x = 0; x < GXM; ++x)
{
- int grid = grd[x][y];
+ dungeon_feature_type grid = grd[x][y];
int envc = env.map[x][y].object;
if ((x == you.x_pos && y == you.y_pos)
@@ -3547,7 +3547,8 @@ void runrest::check_mp()
// explore_discoveries
explore_discoveries::explore_discoveries()
- : es_flags(0), current_level(NULL), items(), stairs(), shops(), altars()
+ : es_flags(0), current_level(NULL), items(), stairs(),
+ portals(), shops(), altars()
{
}
@@ -3556,12 +3557,27 @@ std::string explore_discoveries::cleaned_feature_description(
{
std::string s = lowercase_first(feature_description(grid));
if (s.length() && s[s.length() - 1] == '.')
- {
s.erase(s.length() - 1);
- }
+ if (s.find("a ") != std::string::npos)
+ s = s.substr(2);
+ else if (s.find("an ") != std::string::npos)
+ s = s.substr(3);
return (s);
}
+bool explore_discoveries::merge_feature(
+ std::vector< explore_discoveries::named_thing<int> > &v,
+ const explore_discoveries::named_thing<int> &feat) const
+{
+ for (int i = 0, size = v.size(); i < size; ++i)
+ if (feat == v[i])
+ {
+ ++v[i].thing;
+ return (true);
+ }
+ return (false);
+}
+
void explore_discoveries::found_feature(const coord_def &pos,
dungeon_feature_type grid)
{
@@ -3572,22 +3588,34 @@ void explore_discoveries::found_feature(const coord_def &pos,
}
else if (is_stair(grid) && ES_stair)
{
- stairs.push_back(
- named_thing<int>(
- cleaned_feature_description(grid), grid ) );
+ const named_thing<int> stair(cleaned_feature_description(grid), 1);
+ add_stair(stair);
es_flags |= ES_STAIR;
}
else if (is_altar(grid)
&& ES_altar
&& !player_in_branch(BRANCH_ECUMENICAL_TEMPLE))
{
- altars.push_back(
- named_thing<int>(
- cleaned_feature_description(grid), grid ) );
- es_flags |= ES_ALTAR;
+ const named_thing<int> altar(cleaned_feature_description(grid), 1);
+ if (!merge_feature(altars, altar))
+ altars.push_back(altar);
+ es_flags |= ES_ALTAR;
}
}
+void explore_discoveries::add_stair(
+ const explore_discoveries::named_thing<int> &stair)
+{
+ if (merge_feature(stairs, stair) || merge_feature(portals, stair))
+ return;
+
+ // Hackadelic
+ if (stair.name.find("stair") != std::string::npos)
+ stairs.push_back(stair);
+ else
+ portals.push_back(stair);
+}
+
void explore_discoveries::add_item(const item_def &i)
{
if (is_stackable_item(i))
@@ -3659,6 +3687,28 @@ template <class C> void explore_discoveries::say_any(
mprf("%s", message.c_str());
}
+std::vector<std::string> explore_discoveries::apply_quantities(
+ const std::vector< named_thing<int> > &v) const
+{
+ static const char *feature_plural_qualifiers[] =
+ {
+ " leading ", " back to ", " to ", " of "
+ };
+
+ std::vector<std::string> things;
+ for (int i = 0, size = v.size(); i < size; ++i)
+ {
+ const named_thing<int> &nt = v[i];
+ if (nt.thing == 1)
+ things.push_back(article_a(nt.name));
+ else
+ things.push_back(number_in_words(nt.thing)
+ + " "
+ + pluralise(nt.name, feature_plural_qualifiers));
+ }
+ return (things);
+}
+
bool explore_discoveries::prompt_stop() const
{
if (!es_flags)
@@ -3666,8 +3716,9 @@ bool explore_discoveries::prompt_stop() const
say_any(items, "Found %s items.");
say_any(shops, "Found %s shops.");
- say_any(altars, "Found %s altars.");
- say_any(stairs, "Found %s stairs.");
+ say_any(apply_quantities(altars), "Found %s altars.");
+ say_any(apply_quantities(portals), "Found %s gates.");
+ say_any(apply_quantities(stairs), "Found %s stairs.");
return ((Options.explore_stop_prompt & es_flags) != es_flags
|| prompt_stop_explore(es_flags));
diff --git a/crawl-ref/source/travel.h b/crawl-ref/source/travel.h
index a5a964ef76..522bec1554 100644
--- a/crawl-ref/source/travel.h
+++ b/crawl-ref/source/travel.h
@@ -32,9 +32,9 @@ void clear_excludes();
unsigned char is_waypoint(int x, int y);
void update_excludes();
bool is_exclude_root(const coord_def &p);
-bool is_stair(unsigned gridc);
-bool is_travelable_stair(unsigned gridc);
-command_type stair_direction(int stair_feat);
+bool is_stair(dungeon_feature_type gridc);
+bool is_travelable_stair(dungeon_feature_type gridc);
+command_type stair_direction(dungeon_feature_type stair_feat);
command_type direction_to_command( char x, char y );
bool is_resting( void );
bool can_travel_interlevel();
@@ -298,13 +298,6 @@ public:
bool prompt_stop() const;
private:
- template <class C> void say_any(const C &coll, const char *stub) const;
- template <class citer> bool has_duplicates(citer, citer) const;
-
- std::string cleaned_feature_description(dungeon_feature_type feature) const;
- void add_item(const item_def &item);
-
-private:
template <class Z> struct named_thing {
std::string name;
Z thing;
@@ -322,8 +315,22 @@ private:
const LevelStashes *current_level;
std::vector< named_thing<item_def> > items;
std::vector< named_thing<int> > stairs;
+ std::vector< named_thing<int> > portals;
std::vector< named_thing<int> > shops;
std::vector< named_thing<int> > altars;
+
+private:
+ template <class C> void say_any(const C &coll, const char *stub) const;
+ template <class citer> bool has_duplicates(citer, citer) const;
+
+ std::string cleaned_feature_description(dungeon_feature_type feature) const;
+ void add_item(const item_def &item);
+ void add_stair(const named_thing<int> &stair);
+ std::vector<std::string> apply_quantities(
+ const std::vector< named_thing<int> > &v) const;
+ bool merge_feature(
+ std::vector< named_thing<int> > &v,
+ const named_thing<int> &feat) const;
};
struct stair_info
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index c3d3faa66f..f37c8c05b6 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -1004,7 +1004,7 @@ void item_grid()
const item_def &eitem = mitm[igrd[count_x][count_y]];
unsigned short &ecol = env.show_col[ix][iy];
- const int grid = grd[count_x][count_y];
+ const dungeon_feature_type grid = grd[count_x][count_y];
if (Options.stair_item_brand && is_stair(grid))
ecol |= COLFLAG_STAIR_ITEM;
else