summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/describe.cc
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2009-01-11 13:50:07 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2009-01-11 13:50:07 +0000
commitd90612ecda4f3088e903280024b9aaf6a8279b8f (patch)
treea47f2bf9bf939818f595e4b268e2af095eb19dce /crawl-ref/source/describe.cc
parent6b7d71f720060c2023960aa7ab716063630d8332 (diff)
downloadcrawl-ref-d90612ecda4f3088e903280024b9aaf6a8279b8f.tar.gz
crawl-ref-d90612ecda4f3088e903280024b9aaf6a8279b8f.zip
Extend on Haran's monster resistance description. Thanks, Haran! :)
Now lists: * all resistances on one line, sorted by resistance level. * susceptibility * magic immunity * see/sense invisible * monster speed * flying/levitating An example output: A fire vortex A swirling cloud of flame. It is extremely resistant to fire, very resistant to electricity, and resistant to poison. It is susceptible to cold. It is immune to magical enchantments. It is fast. It can levitate. I also removed all those symbol/quote/etc. checks from the database lookup. Instead describe_monster() is now called directly, so the descriptions are now identical when (v)iewing a monster and when searching the database. In other news, I removed Eringya's Surprising Bouquet since I doubt we'll ever get it implemented, disagree balance-wise, and it was shamelessly nicked from Pratchett in the first place. Breaks saves. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@8411 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/describe.cc')
-rw-r--r--crawl-ref/source/describe.cc209
1 files changed, 207 insertions, 2 deletions
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index b725f8b10f..10d097170e 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -2590,6 +2590,205 @@ static std::string _describe_draconian(const monsters *mon)
return (description);
}
+static const char* _get_resist_name(mon_resist_flags res_type)
+{
+ switch (res_type)
+ {
+ case MR_RES_ELEC:
+ return "electricity";
+ case MR_RES_POISON:
+ return "poison";
+ case MR_RES_FIRE:
+ return "fire";
+ case MR_RES_STEAM:
+ return "steam";
+ case MR_RES_COLD:
+ return "cold";
+ case MR_RES_ACID:
+ return "acid";
+ default:
+ return "buggy resistance";
+ }
+}
+
+static int _get_resist_level(const mon_resist_def resist,
+ mon_resist_flags res_type)
+{
+ switch (res_type)
+ {
+ case MR_RES_ELEC:
+ return resist.elec;
+ case MR_RES_POISON:
+ return resist.poison;
+ case MR_RES_FIRE:
+ return resist.fire;
+ case MR_RES_STEAM:
+ return resist.steam;
+ case MR_RES_COLD:
+ return resist.cold;
+ case MR_RES_ACID:
+ return resist.acid;
+ default:
+ return (0);
+ }
+}
+
+// Describe a monster's (intrinsic) resistances, speed and a few other
+// attributes.
+static std::string _monster_stat_description(const monsters& mon)
+{
+ const char* modifiers[] = {
+ "susceptible", // -1
+ "resistant", // +1
+ "very resistant", // +2
+ "extremely resistant" // +3
+ };
+
+ const mon_resist_def resist = get_mons_resists(&mon);
+ std::vector<mon_resist_flags> resists;
+ resists.push_back(MR_RES_ELEC);
+ resists.push_back(MR_RES_POISON);
+ resists.push_back(MR_RES_FIRE);
+ resists.push_back(MR_RES_STEAM);
+ resists.push_back(MR_RES_COLD);
+ resists.push_back(MR_RES_ACID);
+
+ std::vector<std::string> extreme_resists;
+ std::vector<std::string> high_resists;
+ std::vector<std::string> base_resists;
+ std::vector<std::string> suscept;
+ for (unsigned int i = 0; i < resists.size(); ++i)
+ {
+ int level = _get_resist_level(resist, resists[i]);
+ const char* attackname = _get_resist_name(resists[i]);
+ if (level != 0)
+ {
+ const int offset = (level < 0) ? 0 : std::min(level, 3);
+ switch (offset)
+ {
+ case 0:
+ suscept.push_back(attackname);
+ break;
+ case 1:
+ base_resists.push_back(attackname);
+ break;
+ case 2:
+ high_resists.push_back(attackname);
+ break;
+ case 3:
+ extreme_resists.push_back(attackname);
+ break;
+ }
+ }
+ }
+
+ std::string result = "";
+ const char* pronoun = mons_pronoun(static_cast<monster_type>(mon.type),
+ PRONOUN_CAP, true);
+
+ std::vector<std::string> all_resists;
+ if (!extreme_resists.empty())
+ {
+ result = modifiers[3];
+ result += " to ";
+ result += comma_separated_line(extreme_resists.begin(),
+ extreme_resists.end(),
+ " and ", ", ");
+ all_resists.push_back(result);
+ }
+ if (!high_resists.empty())
+ {
+ result = modifiers[2];
+ result += " to ";
+ result += comma_separated_line(high_resists.begin(),
+ high_resists.end(),
+ " and ", ", ");
+ all_resists.push_back(result);
+ }
+ if (!base_resists.empty())
+ {
+ result = modifiers[1];
+ result += " to ";
+ result += comma_separated_line(base_resists.begin(),
+ base_resists.end(),
+ " and ", ", ");
+ all_resists.push_back(result);
+ }
+ if (!all_resists.empty())
+ {
+ result = pronoun;
+ result += " is ";
+ result += comma_separated_line(all_resists.begin(),
+ all_resists.end(),
+ ", and ", ", ");
+ result += ".$";
+ }
+
+ // Is monster susceptible to anything? (On a new line.)
+ if (!suscept.empty())
+ {
+ result += pronoun;
+ result += " is ";
+ result += modifiers[0];
+ result += " to ";
+ result += comma_separated_line(suscept.begin(),
+ suscept.end(),
+ " and ", ", ");
+ result += ".$";
+ }
+
+ // Magic resistance at MAG_IMMUNE.
+ if (mons_immune_magic(&mon))
+ {
+ result += pronoun;
+ result += " is immune to magical enchantments.$";
+ }
+
+ // Seeing/sensing invisible.
+ if (mons_class_flag(mon.type, M_SEE_INVIS))
+ {
+ result += pronoun;
+ result += " can see invisible.$";
+ }
+ else if (mons_class_flag(mon.type, M_SENSE_INVIS))
+ {
+ result += pronoun;
+ result += " can sense the presence of invisible creatures.$";
+ }
+
+ // Unusual monster speed.
+ const int speed = mons_speed(mon.type);
+ if (speed < 10 || speed > 10)
+ {
+ result += pronoun;
+ result += " is ";
+ if (speed < 7)
+ result += "very slow";
+ else if (speed < 10)
+ result += "slow";
+ else if (speed > 20)
+ result += "extremely fast";
+ else if (speed > 15)
+ result += "very fast";
+ else if (speed > 10)
+ result += "fast";
+ result += ".$";
+ }
+
+ // Can the monster fly/levitate?
+ const flight_type fly = mons_class_flies(mon.type);
+ if (fly != FL_NONE)
+ {
+ result += pronoun;
+ result += " can ";
+ result += (fly == FL_FLY ? "fly" : "levitate");
+ result += ".$";
+ }
+
+ return result;
+}
+
+/*
// Return a string of the form "She is resistant to fire."
static std::string _resistance_description(const char* pronoun,
int level, const char* attackname)
@@ -2621,6 +2820,7 @@ static std::string _monster_resists_string(const monsters& mon)
const mon_resist_def resist = get_mons_resists(&mon);
const char* pronoun = mons_pronoun(static_cast<monster_type>(mon.type),
PRONOUN_CAP, true);
+
std::string result;
// Not shown: hellfire, asphyxiation, sticky flames.
result += _resistance_description(pronoun, resist.elec, "electricity");
@@ -2631,7 +2831,8 @@ static std::string _monster_resists_string(const monsters& mon)
result += _resistance_description(pronoun, resist.acid, "acid");
return result;
}
-
+*/
+
//---------------------------------------------------------------
//
// describe_monsters
@@ -2773,7 +2974,11 @@ void describe_monsters(const monsters& mons)
// Don't leak or duplicate resistance information for ghosts/demons.
if (mons.type != MONS_PANDEMONIUM_DEMON && mons.type != MONS_PLAYER_GHOST)
- body << _monster_resists_string(mons);
+ {
+ std::string result = _monster_stat_description(mons);
+ if (!result.empty())
+ body << "$" << result;
+ }
if (!mons_can_use_stairs(&mons))
{