]> granicus.if.org Git - nethack/commitdiff
fix #H5856 - Amulet draining energy
authorPatR <rankin@nethack.org>
Thu, 14 Sep 2017 07:57:50 +0000 (00:57 -0700)
committerPatR <rankin@nethack.org>
Thu, 14 Sep 2017 07:57:50 +0000 (00:57 -0700)
The sequence
  You feel the amulet draining your energy away.
  You don't have enough energy to cast that spell.
didn't use any energy or cost any time so the player could try over
and over until the randomly chosen drain amount happened to be low
enough to succeed.

The old behavior was that the cost of the current cast attempt got
incresed by a random amount.  Now, if hero already lacks sufficient
energy to cast the spell, the Amulet's effect won't take place, the
second message will be given, and no energy or time will be consumed.
When there is enough energy to cast the spell, the drain effect will
occur and some energy will be used up immediately (instead of
increasing the cost of this attempt).  The energy drain might then
result in the second message, but if so, a turn will be used.

No longer increasing the energy cost of the current cast has a
side-effect on not increasing the hunger penalty for the current cast
(since that is based on the energy cost) but the energy drain message
doesn't actually imply any effect on hunger.

doc/fixes36.1
src/spell.c

index a481a914b66951a406cbd7e5f42f0f20e2602f4a..15b87e4253ed0a8cde70ca90f9a72207aa07fe31 100644 (file)
@@ -431,6 +431,9 @@ when polymorphed into something with a passive counterattack, being 'killed'
 when returning to quest nemesis' level, the message for some roles (A,S,T,W)
        referred to sensing presence of the quest artifact even if had been
        removed from that level; give an alternate message in that situation
+when the Amulet increased spell casting cost, nothing actually happened (aside
+       from the message about feeling the Amulet drain the hero's power) if
+       hero lacked sufficient energy to cast the spell
 
 
 Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository
index dba05de6cba25455938421cee19ba6c8c5ed7cfc..955620f575382634c28e9154d43b5dc43d5696c4 100644 (file)
@@ -883,7 +883,7 @@ int spell;
 boolean atme;
 {
     int energy, damage, chance, n, intell;
-    int skill, role_skill;
+    int skill, role_skill, res = 0;
     boolean confused = (Confusion != 0);
     boolean physical_damage = FALSE;
     struct obj *pseudo;
@@ -933,13 +933,29 @@ boolean atme;
         return 1;
     }
 
-    if (u.uhave.amulet) {
+    /* if the cast attempt is already going to fail due to insufficient
+       energy (ie, u.uen < energy), the Amulet's drain effect won't kick
+       in and no turn will be consumed; however, when it does kick in,
+       the attempt may fail due to lack of energy after the draining, in
+       which case a turn will be used up in addition to the energy loss */
+    if (u.uhave.amulet && u.uen >= energy) {
         You_feel("the amulet draining your energy away.");
-        energy += rnd(2 * energy);
+        /* this used to be 'energy += rnd(2 * energy)' (without 'res'),
+           so if amulet-induced cost was more than u.uen, nothing
+           (except the "don't have enough energy" message) happened
+           and player could just try again (and again and again...);
+           now we drain some energy immediately, which has a
+           side-effect of not increasing the hunger aspect of casting */
+        u.uen -= rnd(2 * energy);
+        if (u.uen < 0)
+            u.uen = 0;
+        context.botl = 1;
+        res = 1; /* time is going to elapse even if spell doesn't get cast */
     }
+
     if (energy > u.uen) {
         You("don't have enough energy to cast that spell.");
-        return 0;
+        return res;
     } else {
         if (spellid(spell) != SPE_DETECT_FOOD) {
             int hungr = energy * 2;