summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/libutil.cc71
-rw-r--r--crawl-ref/source/libutil.h19
-rw-r--r--crawl-ref/source/spells2.cc62
3 files changed, 58 insertions, 94 deletions
diff --git a/crawl-ref/source/libutil.cc b/crawl-ref/source/libutil.cc
index d94ba252a8..25e705a0ec 100644
--- a/crawl-ref/source/libutil.cc
+++ b/crawl-ref/source/libutil.cc
@@ -564,77 +564,6 @@ int snprintf( char *str, size_t size, const char *format, ... )
#endif
-//////////////////////////////////////////////////////////////////////////
-// named_thing_collection
-
-named_thing_collection::named_thing_collection()
- : names(), nnames(0u)
-{
-}
-
-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());
-}
-
-/////////////////////////////////////////////////////////////////////////
-
///////////////////////////////////////////////////////////////////////
// Pattern matching
diff --git a/crawl-ref/source/libutil.h b/crawl-ref/source/libutil.h
index 42102991a4..6ee786b452 100644
--- a/crawl-ref/source/libutil.h
+++ b/crawl-ref/source/libutil.h
@@ -21,25 +21,6 @@
#include <vector>
#include <map>
-// 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;
-};
-
extern const char *standard_plural_qualifiers[];
// Applies a description type to a name, but does not pluralise! You
diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc
index b0893d8f5c..1488c8e036 100644
--- a/crawl-ref/source/spells2.cc
+++ b/crawl-ref/source/spells2.cc
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <string.h>
+#include <sstream>
#include "externs.h"
@@ -816,6 +817,59 @@ void holy_word(int pow, bool silent)
} // end "for tu"
} // end holy_word()
+typedef std::pair<const monsters*,int> counted_monster;
+typedef std::vector<counted_monster> counted_monster_list;
+static void record_monster_by_name(counted_monster_list &list,
+ const monsters *mons)
+{
+ const std::string name = mons->name(DESC_PLAIN);
+ for (counted_monster_list::iterator i = list.begin(); i != list.end(); ++i)
+ {
+ if (i->first->name(DESC_PLAIN) == name)
+ {
+ i->second++;
+ return;
+ }
+ }
+ list.push_back( counted_monster(mons, 1) );
+}
+
+static int monster_count(const counted_monster_list &list)
+{
+ int nmons = 0;
+ for (counted_monster_list::const_iterator i = list.begin();
+ i != list.end(); ++i)
+ {
+ nmons += i->second;
+ }
+ return (nmons);
+}
+
+static std::string describe_monsters(const counted_monster_list &list)
+{
+ std::ostringstream out;
+
+ description_level_type desc = DESC_CAP_THE;
+ for (counted_monster_list::const_iterator i = list.begin();
+ i != list.end(); desc = DESC_NOCAP_THE)
+ {
+ const counted_monster &cm(*i);
+ if (i != list.begin())
+ {
+ ++i;
+ out << (i == list.end()? " and " : ", ");
+ }
+ else
+ ++i;
+
+ const std::string name =
+ cm.second > 1? pluralise(cm.first->name(desc))
+ : cm.first->name(desc);
+ out << name;
+ }
+ return (out.str());
+}
+
// poisonous light passes right through invisible players
// and monsters, and so, they are unaffected by this spell --
// assumes only you can cast this spell (or would want to)
@@ -841,7 +895,7 @@ void cast_toxic_radiance(void)
poison_player(2);
}
- named_thing_collection affected_monsters;
+ counted_monster_list affected_monsters;
// determine which monsters are hit by the radiance: {dlb}
for (int toxy = 0; toxy < MAX_MONSTERS; toxy++)
{
@@ -862,7 +916,7 @@ void cast_toxic_radiance(void)
affected = true;
if (affected)
- affected_monsters.add_thing(monster->name(DESC_PLAIN));
+ record_monster_by_name(affected_monsters, monster);
}
else if (player_see_invis())
{
@@ -877,8 +931,8 @@ void cast_toxic_radiance(void)
{
const std::string message =
make_stringf("%s %s poisoned.",
- affected_monsters.describe(DESC_CAP_THE).c_str(),
- affected_monsters.size() == 1? "is" : "are");
+ describe_monsters(affected_monsters).c_str(),
+ monster_count(affected_monsters) == 1? "is" : "are");
if (static_cast<int>(message.length()) < get_number_of_cols() - 2)
mpr(message.c_str());
else