summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/xom.cc
diff options
context:
space:
mode:
authorJohanna Ploog <j-p-e-g@users.sourceforge.net>2009-12-09 21:31:02 +0100
committerJohanna Ploog <j-p-e-g@users.sourceforge.net>2009-12-09 21:31:02 +0100
commitb8f3c183df87ee55833ab561fa12ed324da5a913 (patch)
tree2be4120a6fc0053dc049ba066e68b1ebfe701a01 /crawl-ref/source/xom.cc
parentf4efe0a7c1422dede865ea5f9d8e2d96978b2f9f (diff)
downloadcrawl-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.cc119
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
{