git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2535 c06c8d41-db1a-0410-9941-cceddc491573
3JKKL6VSKQHBBTKEBSADZVCNXZLL4S6KN2W7G2CY5OBOMMUTIWXQC
7Y5HSDFKA5TPLS2TWTRFMQVX6UXUDHXU5MUMXQSDFAIY4THQ3BIQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
X5WLJCJVW55SXZVP7IKP7ADCJIGNKN4PKAXFECVR6TNK7XSMZR7QC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
UOW2X5KTUHYCM73SWNOSJPHUKWVLF3OJTNSISSSENEURBX2XWHVQC
YHSVOROKPYS33Y4RYZRVZTE3G5LXOFX52HEDNLV6HIXOJYNOKH3QC
5V47S4NNTHWTSAHV3YLO2VGH7JTUIYJ3GBPDN5ZM4UQALT2ZEXDQC
AVSMB4Y6F6ZMMNNPOAQQZ34OWC6N5JOURTEWFTUKDWMIIMLWWJUAC
SVKXVPIRSLANKYBFFZ5OTGQAB6GXSLSMGQEBWAE7ATSITBACOCFQC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
} // end cast_toxic_radiance()
if (!affected_monsters.empty())
{
const std::string message =
make_stringf("%s %s poisoned.",
affected_monsters.describe(DESC_CAP_THE).c_str(),
affected_monsters.size() == 1? "is" : "are");
if (static_cast<int>(message.length()) < get_number_of_cols() - 2)
mpr(message.c_str());
else
// Exclamation mark to suggest that a lot of creatures were
// affected.
mpr("The monsters around you are poisoned!");
}
}
// A collection of named things that can be stacked. The collection merges
// things that should be merged (by name) and outputs a comma-separated list
// with the preferred description type.
class named_thing_collection
{
public:
named_thing_collection();
void add_thing(const std::string &name);
std::string describe(description_level_type desc,
const char **plural_qualifiers = NULL,
const char **no_qualifier_suffix = NULL) const;
size_t size() const;
bool empty() const;
private:
typedef std::map<std::string, int> name_count_map;
name_count_map names;
size_t nnames;
};
// Applies a description type to a name, but does not pluralise! You
// must pluralise the name if needed. The quantity is used to prefix the
// name with a quantity if appropriate.
std::string apply_description(description_level_type desc,
const std::string &name,
int quantity = 1,
bool num_in_words = false);
std::string number_to_string(unsigned number, bool in_words)
{
return (in_words? number_in_words(number) : make_stringf("%u", number));
}
std::string apply_description(description_level_type desc,
const std::string &name,
int quantity, bool in_words)
{
switch (desc)
{
case DESC_CAP_THE:
return ("The " + name);
case DESC_NOCAP_THE:
return ("the " + name);
case DESC_CAP_A:
return (quantity > 1?
number_to_string(quantity, in_words) + name
: article_a(name, false));
case DESC_NOCAP_A:
return (quantity > 1?
number_to_string(quantity, in_words) + name
: article_a(name, true));
case DESC_CAP_YOUR:
return ("Your " + name);
case DESC_NOCAP_YOUR:
return ("your " + name);
case DESC_PLAIN:
default:
return (name);
}
}
void named_thing_collection::add_thing(const std::string &name)
{
names[name]++;
nnames++;
}
size_t named_thing_collection::size() const
{
return (nnames);
}
bool named_thing_collection::empty() const
{
return (!nnames);
}
std::string named_thing_collection::describe(
description_level_type desc,
const char **plural_qualifiers,
const char **no_qualifier_suffixes) const
{
if (empty())
return ("");
std::ostringstream out;
for (name_count_map::const_iterator i = names.begin();
i != names.end(); )
{
const std::pair<std::string, int> &curr(*i);
if (i != names.begin())
{
++i;
out << (i == names.end()? " and " : ", ");
}
else
++i;
const std::string name =
curr.second > 1? pluralise(curr.first, plural_qualifiers,
no_qualifier_suffixes)
: curr.first;
out << apply_description(desc, name, curr.second);
switch (desc)
{
case DESC_CAP_A:
desc = DESC_NOCAP_A;
break;
case DESC_CAP_THE:
desc = DESC_NOCAP_THE;
break;
case DESC_CAP_YOUR: case DESC_NOCAP_YOUR:
desc = DESC_PLAIN;
break;
default:
break;
}
}
return (out.str());
}
/////////////////////////////////////////////////////////////////////////