diff options
author | Johanna Ploog <j-p-e-g@users.sourceforge.net> | 2009-12-09 21:31:02 +0100 |
---|---|---|
committer | Johanna Ploog <j-p-e-g@users.sourceforge.net> | 2009-12-09 21:31:02 +0100 |
commit | b8f3c183df87ee55833ab561fa12ed324da5a913 (patch) | |
tree | 2be4120a6fc0053dc049ba066e68b1ebfe701a01 /crawl-ref/source/xom.cc | |
parent | f4efe0a7c1422dede865ea5f9d8e2d96978b2f9f (diff) | |
download | crawl-ref-b8f3c183df87ee55833ab561fa12ed324da5a913.tar.gz crawl-ref-b8f3c183df87ee55833ab561fa12ed324da5a913.zip |
Make Xom sometimes (< 5% chance) revive the player after death.
The chance of this happening depends strongly on tension and mood, as well
as type of death. I also tried the normal protection from harm but I figure
it's more interesting this way. :D
Diffstat (limited to 'crawl-ref/source/xom.cc')
-rw-r--r-- | crawl-ref/source/xom.cc | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/crawl-ref/source/xom.cc b/crawl-ref/source/xom.cc index bc07ae3ffa..d4df0e71d1 100644 --- a/crawl-ref/source/xom.cc +++ b/crawl-ref/source/xom.cc @@ -23,6 +23,7 @@ #include "map_knowledge.h" #include "feature.h" #include "goditem.h" +#include "hiscores.h" #include "it_use2.h" #include "itemprop.h" #include "items.h" @@ -3787,6 +3788,124 @@ void xom_death_message(const kill_method_type killed_by) // All others just get ignored by Xom. } +static int _death_is_worth_saving(const kill_method_type killed_by, + const char *aux) +{ + switch (killed_by) + { + // These don't count. + case KILLED_BY_LEAVING: + case KILLED_BY_WINNING: + case KILLED_BY_QUITTING: + + // These are too much hassle. + case KILLED_BY_LAVA: + case KILLED_BY_WATER: + case KILLED_BY_DRAINING: + case KILLED_BY_STARVATION: + case KILLED_BY_ROTTING: + + // Don't protect the player from these. + case KILLED_BY_SELF_AIMED: + case KILLED_BY_TARGETTING: + return (false); + + // Only if not caused by equipment. + case KILLED_BY_STUPIDITY: + case KILLED_BY_WEAKNESS: + case KILLED_BY_CLUMSINESS: + if (strstr(aux, "wielding") == NULL && strstr(aux, "wearing") == NULL + && strstr(aux, "removing") == NULL) + { + return (true); + } + return (false); + + // Everything else is fair game. + default: + return (true); + } +} + +static std::string _get_death_type_keyword(const kill_method_type killed_by) +{ + switch (killed_by) + { + case KILLED_BY_MONSTER: + case KILLED_BY_BEAM: + case KILLED_BY_BEOGH_SMITING: + case KILLED_BY_TSO_SMITING: + case KILLED_BY_DIVINE_WRATH: + return "actor"; + default: + return "general"; + } +} + +bool xom_saves_your_life(const int dam, const int death_source, + const kill_method_type death_type, const char *aux, + bool see_source) +{ + if (you.religion != GOD_XOM || _xom_feels_nasty()) + return (false); + + // If this happens, don't bother. + if (you.hp_max < 1 || you.experience_level < 1) + return (false); + + // Generally a rare effect. + if (!one_chance_in(20)) + return (false); + + if (!_death_is_worth_saving(death_type, aux)) + return (false); + + // In addition, the chance depends on the current tension and Xom's mood. + const int death_tension = get_tension(GOD_XOM, false); + if (death_tension < random2(5) || !xom_is_nice(death_tension)) + return (false); + + // Fake death message. + mpr("You die..."); + more(); + + const std::string key = _get_death_type_keyword(death_type); + std::string speech = _get_xom_speech("life saving " + key); + if (speech.find("@xom_plaything@") != std::string::npos) + { + std::string toy_name = (you.piety > 180) ? "teddy bear" : + (you.piety > 80) ? "toy" + : "plaything"; + + speech = replace_all(speech, "@xom_plaything@", toy_name); + } + god_speaks(GOD_XOM, speech.c_str()); + + // Give back some hp. + if (you.hp < 1) + you.hp = 1 + random2(you.hp_max/4); + + // Make sure all stats are at least 1. + if (you.strength < 1) + you.strength = 1; + if (you.dex < 1) + you.dex = 1; + if (you.intel < 1) + you.intel = 1; + + god_speaks(GOD_XOM, "Xom revives you!"); + + // Ideally, this should contain the death cause but that is too much + // trouble for now. + take_note( Note(NOTE_XOM_REVIVAL) ); + + // Make sure Xom doesn't get bored within the next couple of turns. + if (you.gift_timeout < 10) + you.gift_timeout = 10; + + return (true); +} + #ifdef WIZARD struct xom_effect_count { |