]> granicus.if.org Git - nethack/commitdiff
B13004 spellbook destruction
authorcohrs <cohrs>
Wed, 16 Oct 2002 05:46:20 +0000 (05:46 +0000)
committercohrs <cohrs>
Wed, 16 Oct 2002 05:46:20 +0000 (05:46 +0000)
When reading a cursed or too-hard book that's covered in contact poison
(presumably in the too-hard case, reading it made the poison), and you die,
the book would not be in the bones.  remove in_use mark while assessing
damage.

On the other hand, not From a bug report, the message in the "6" case says
the book explodes, but had a 1/3 chance of not disappearing in the normal
case, and 100% chance of remaining if cursed while reading - when the
player survives.  Return a flag to allow the book to be destroyed in this
case.  No work needed for the death case; in_use is set.

src/spell.c

index 924fea916558e3fb5ed1e867f61b4ae3af63045f..350233bd2a3b1112672ef1f64ad3ac616185d0ab 100644 (file)
@@ -21,7 +21,7 @@ static NEARDATA struct obj *book;     /* last/current book being xscribed */
        ((char)((spell < 26) ? ('a' + spell) : ('A' + spell - 26)))
 
 STATIC_DCL int FDECL(spell_let_to_idx, (CHAR_P));
-STATIC_DCL void FDECL(cursed_book, (int));
+STATIC_DCL boolean FDECL(cursed_book, (struct obj *bp));
 STATIC_DCL void FDECL(deadbook, (struct obj *));
 STATIC_PTR int NDECL(learn);
 STATIC_DCL boolean FDECL(getspell, (int *));
@@ -102,10 +102,13 @@ char ilet;
     return -1;
 }
 
-STATIC_OVL void
-cursed_book(lev)
-       register int    lev;
+/* TRUE: book should be destroyed by caller */
+STATIC_OVL boolean
+cursed_book(bp)
+       struct obj *bp;
 {
+       int lev = objects[bp->otyp].oc_level;
+
        switch(rn2(lev)) {
        case 0:
                You_feel("a wrenching sensation.");
@@ -145,9 +148,12 @@ cursed_book(lev)
                             Blind ? "feel" : "look");
                    break;
                }
+               /* temp disable in_use; death should not destroy the book */
+               bp->in_use = FALSE;
                losestr(Poison_resistance ? rn1(2,1) : rn1(4,3));
                losehp(rnd(Poison_resistance ? 6 : 10),
                       "contact-poisoned spellbook", KILLED_BY_AN);
+               bp->in_use = TRUE;
                break;
        case 6:
                if(Antimagic) {
@@ -156,14 +162,14 @@ cursed_book(lev)
                } else {
                    pline("As you read the book, it %s in your %s!",
                          explodes, body_part(FACE));
-                   losehp (2*rnd(10)+5, "exploding rune", KILLED_BY_AN);
+                   losehp(2*rnd(10)+5, "exploding rune", KILLED_BY_AN);
                }
-               break;
+               return TRUE;
        default:
                rndcurse();
                break;
        }
-       return;
+       return FALSE;
 }
 
 /* special effects for The Book of the Dead */
@@ -335,7 +341,11 @@ learn()
        if (i == MAXSPELL) impossible("Too many spells memorized!");
 
        if (book->cursed) {     /* maybe a demon cursed it */
-               cursed_book(objects[booktype].oc_level);
+           if (cursed_book(book)) {
+               useup(book);
+               book = 0;
+               return 0;
+           }
        }
        if (costly) check_unpaid(book);
        book = 0;
@@ -417,11 +427,12 @@ register struct obj *spellbook;
                }
 
                if (too_hard) {
-                   cursed_book(objects[booktype].oc_level);
+                   boolean gone = cursed_book(spellbook);
+
                    nomul(delay);                       /* study time */
                    delay = 0;
-                   if(!rn2(3)) {
-                       pline_The("spellbook crumbles to dust!");
+                   if(gone || !rn2(3)) {
+                       if (!gone) pline_The("spellbook crumbles to dust!");
                        if (!objects[spellbook->otyp].oc_name_known &&
                                !objects[spellbook->otyp].oc_uname)
                            docall(spellbook);