diff options
-rw-r--r-- | crawl-ref/source/Kills.cc | 20 | ||||
-rw-r--r-- | crawl-ref/source/direct.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/libutil.cc | 47 | ||||
-rw-r--r-- | crawl-ref/source/libutil.h | 7 | ||||
-rw-r--r-- | crawl-ref/source/travel.cc | 83 | ||||
-rw-r--r-- | crawl-ref/source/travel.h | 27 | ||||
-rw-r--r-- | crawl-ref/source/view.cc | 2 |
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 |