summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/ouch.cc
diff options
context:
space:
mode:
authorNicholas Feinberg <pleasingfung@gmail.com>2014-07-16 23:03:03 -0700
committerNicholas Feinberg <pleasingfung@gmail.com>2014-07-23 22:53:32 -0700
commitbc4cca05f1829bd4bb812008c01682b204ee4975 (patch)
tree51c83a2c6429ab4b2de55d416ea2ab293f16f8c4 /crawl-ref/source/ouch.cc
parentb26780ba51a322670314796f630ee78383294f54 (diff)
downloadcrawl-ref-bc4cca05f1829bd4bb812008c01682b204ee4975.tar.gz
crawl-ref-bc4cca05f1829bd4bb812008c01682b204ee4975.zip
Put heavily drained players out of their misery
Draining is now limited, based on your level. If you get drained further when you're already very heavily drained, you take very sizeable amounts of damage. Hopefully this will kill you. The death messaging seems to work, but it's not ideal. Possibly someone can adjust that.
Diffstat (limited to 'crawl-ref/source/ouch.cc')
-rw-r--r--crawl-ref/source/ouch.cc63
1 files changed, 55 insertions, 8 deletions
diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc
index a33a047b07..72bb98a69c 100644
--- a/crawl-ref/source/ouch.cc
+++ b/crawl-ref/source/ouch.cc
@@ -257,7 +257,9 @@ int check_your_resists(int hurted, beam_type flavour, string source,
hurted, true);
if (doEffects)
- drain_exp(true, min(75, 35 + original * 2 / 3));
+ drain_player(min(75, 35 + original * 2 / 3),
+ beam ? beam->beam_source : -1,
+ source.c_str(), true);
break;
case BEAM_ICE:
@@ -506,7 +508,19 @@ void lose_level(int death_source, const char *aux)
ouch(0, death_source, KILLED_BY_DRAINING, aux);
}
-bool drain_exp(bool announce_full, int power, bool ignore_protection)
+/**
+ * Drain the player.
+ *
+ * @param power The amount by which to drain the player.
+ * @param death_source The index of the monster causing the draining.
+ * @param cause The source of the draining. (May be null.)
+ * @param announce_full Whether to print messages even when fully resisting
+ * the drain.
+ * @param ignore_protection Whether to ignore the player's rN.
+ * @return Whether draining occurred.
+ */
+bool drain_player(int power, int death_source, const char* cause,
+ bool announce_full, bool ignore_protection)
{
const int protection = player_prot_life();
@@ -524,22 +538,52 @@ bool drain_exp(bool announce_full, int power, bool ignore_protection)
power /= (protection * 2);
}
- if (power > 0)
+ if (power <= 0)
+ return false;
+
+ // at xl27, at worst go from skill 27 to ~19
+ // at xl1, at worst go from skill 3 to 1, or 4 to 2
+ const int MAX_DRAIN = ignore_protection ? INT_MAX :
+ 150 + you.experience_level * 10;
+ const int drain_power = max(0,
+ min(MAX_DRAIN - you.attribute[ATTR_XP_DRAIN],
+ power));
+ const int pain_power = power - drain_power;
+
+ if (pain_power)
+ {
+ mpr("You feel horribly drained!");
+ xom_is_stimulated(25);
+ }
+ else
{
mpr("You feel drained.");
xom_is_stimulated(15);
+ }
- you.attribute[ATTR_XP_DRAIN] += power;
+ if (drain_power)
+ {
+ you.attribute[ATTR_XP_DRAIN] += drain_power;
// Losing skills may affect AC/EV.
you.redraw_armour_class = true;
you.redraw_evasion = true;
- dprf("Drained by %d points (%d total)", power, you.attribute[ATTR_XP_DRAIN]);
+ dprf("Drained by %d points (%d total)", drain_power,
+ you.attribute[ATTR_XP_DRAIN]);
+ }
- return true;
+ if (pain_power)
+ {
+ // -- just die already!
+ const int pain_damage = pain_power / 5
+ + get_real_hp(true) * pain_power / 200;
+ ouch(pain_damage, death_source, KILLED_BY_DRAINING, NULL,
+ announce_full, cause, false);
+ dprf("%d overflow drain/pain points -> %d damage", pain_power,
+ pain_damage);
}
- return false;
+ return true;
}
static void _xom_checks_damage(kill_method_type death_type,
@@ -946,7 +990,10 @@ void ouch(int dam, int death_source, kill_method_type death_type,
_maybe_fog(dam);
_powered_by_pain(dam);
if (drain_amount > 0)
- drain_exp(true, drain_amount, true);
+ {
+ drain_player(drain_amount, death_source,
+ "taking damage in shadow form", true, true);
+ }
}
if (you.hp > 0)
return;