]> granicus.if.org Git - nethack/commitdiff
fix M159 - crash at end of prayer
authornethack.rankin <nethack.rankin>
Fri, 2 Sep 2005 06:00:44 +0000 (06:00 +0000)
committernethack.rankin <nethack.rankin>
Fri, 2 Sep 2005 06:00:44 +0000 (06:00 +0000)
     Fix the crash caused by division by zero (attempt to compute rn2(0))
when deciding prayer boon for a character whose Luck went negative during
the course of the prayer.  <email deleted> triggered it
by killing a shopkeeper with the ongoing damage from a scroll of stinking
cloud; his non-chaotic character was branded a murderer and lost two points
of Luck after the prayer was already in progress.  (Prayers fail when Luck
is already negative, so the code to pick a boon expects non-negative values;
the fact that is always adds at least +2 leads to me to suspect that someone
already realized that luck timeout on Friday 13th could result in Luck of -1
at the end of a successful prayer--that value doesn't trigger this crash.)

doc/fixes34.4
src/pray.c

index 6531f21bdc7ac992de7a65f8d72f50c72a128018..2c429a4a4e641810c662a93d9bbafa479bb77e47 100644 (file)
@@ -140,6 +140,7 @@ weaken "farming" strategy
 don't suppress corpse if you kill your own steed
 fix typo in tourist quest leader's greeting
 fix grammar for graveyard sounds when polymorphed
+avoid divide by zero crash if Luck drops below -1 while a prayer is in progress
 
 
 Platform- and/or Interface-Specific Fixes
index 500c82f6bd2e23f34396405f530bc9f4c7a06018..05d544d79bc6b0116b43d70ceeaa6b987ec9e2d0 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)pray.c     3.5     2005/06/24      */
+/*     SCCS Id: @(#)pray.c     3.5     2005/08/31      */
 /* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -844,8 +844,22 @@ pleased(g_align)
            /* if hero was in trouble, but got better, no special favor */
            if (p_trouble == 0) pat_on_head = 1;
        } else {
-           int action = rn1(Luck + (on_altar() ? 3 + on_shrine() : 2), 1);
-
+           int action, prayer_luck;
+
+           /* Negative luck is normally impossible here (can_pray() forces
+              prayer failure in that situation), but it's possible for
+              Luck to drop during the period of prayer occupation and
+              become negative by the time we get here.  [Reported case
+              was lawful character whose stinking cloud caused a delayed
+              killing of a peaceful human, triggering the "murderer"
+              penalty while successful prayer was in progress.  It could
+              also happen due to inconvenient timing on Friday 13th, but
+              the magnitude there (-1) isn't big enough to cause trouble.]
+              We don't bother remembering start-of-prayer luck, just make
+              sure it's at least -1 so that Luck+2 is big enough to avoid
+              a divide by zero crash when generating a random number.  */
+           prayer_luck = max(Luck, -1);        /* => (prayer_luck + 2 > 0) */
+           action = rn1(prayer_luck + (on_altar() ? 3 + on_shrine() : 2), 1);
            if (!on_altar()) action = min(action, 3);
            if (u.ualign.record < STRIDENT)
                action = (u.ualign.record > 0 || !rnl(2)) ? 1 : 0;