diff --git a/doc/fixes36.1 b/doc/fixes36.1 index bf9cc0be9..051820f47 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -139,6 +139,11 @@ monsters fleeing up the upstairs on level 1 were supposed to escape the monster hitting fire-dealing monster with weapon triggered passive damage to weapon every time, when hero doing so only had 1/6 chance per hit hitting steam vortex with flammable weapon would damage the weapon with fire +if a non-cursed spellbook being read becomes cursed and hero recognizes that + (bknown is set), interrupt reading +if a non-cursed spellbook being read becomes cursed and hero doesn't notice, + don't leave it flagged as in-use (hence to be deleted during the + next save/restore cycle) if contact-poison cursed book effect occurs Platform- and/or Interface-Specific Fixes diff --git a/include/extern.h b/include/extern.h index 3c0abfaab..7b6fe3d0c 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2197,6 +2197,7 @@ E boolean FDECL(load_special, (const char *)); /* ### spell.c ### */ +E void FDECL(book_cursed, (struct obj *)); #ifdef USE_TRAMPOLI E int NDECL(learn); #endif diff --git a/src/mkobj.c b/src/mkobj.c index 277fe8b46..ef0af3eec 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1247,12 +1247,14 @@ void curse(otmp) register struct obj *otmp; { + unsigned already_cursed; int old_light = 0; if (otmp->oclass == COIN_CLASS) return; if (otmp->lamplit) old_light = arti_light_radius(otmp); + already_cursed = otmp->cursed; otmp->blessed = 0; otmp->cursed = 1; /* welded two-handed weapon interferes with some armor removal */ @@ -1263,14 +1265,18 @@ register struct obj *otmp; if (otmp == uswapwep && u.twoweap) drop_uswapwep(); /* some cursed items need immediate updating */ - if (carried(otmp) && confers_luck(otmp)) + if (carried(otmp) && confers_luck(otmp)) { set_moreluck(); - else if (otmp->otyp == BAG_OF_HOLDING) + } else if (otmp->otyp == BAG_OF_HOLDING) { otmp->owt = weight(otmp); - else if (otmp->otyp == FIGURINE) { + } else if (otmp->otyp == FIGURINE) { if (otmp->corpsenm != NON_PM && !dead_species(otmp->corpsenm, TRUE) && (carried(otmp) || mcarried(otmp))) attach_fig_transform_timeout(otmp); + } else if (otmp->oclass == SPBOOK_CLASS) { + /* if book hero is reading becomes cursed, interrupt */ + if (!already_cursed) + book_cursed(otmp); } if (otmp->lamplit) maybe_adjust_light(otmp, old_light); diff --git a/src/spell.c b/src/spell.c index 436919276..6110a8472 100644 --- a/src/spell.c +++ b/src/spell.c @@ -120,6 +120,7 @@ STATIC_OVL boolean cursed_book(bp) struct obj *bp; { + boolean was_in_use; int lev = objects[bp->otyp].oc_level; int dmg = 0; @@ -149,11 +150,12 @@ struct obj *bp; break; } /* temp disable in_use; death should not destroy the book */ + was_in_use = bp->in_use; 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; + bp->in_use = was_in_use; break; case 6: if (Antimagic) { @@ -322,6 +324,17 @@ struct obj *book2; return; } +/* 'book' has just become cursed; if we're reading it and realize it is + now cursed, interrupt */ +void +book_cursed(book) +struct obj *book; +{ + if (occupation == learn && context.spbook.book == book + && book->cursed && book->bknown && multi >= 0) + stop_occupation(); +} + STATIC_PTR int learn(VOID_ARGS) { @@ -344,9 +357,8 @@ learn(VOID_ARGS) context.spbook.delay = 0; return 0; } - if (context - .spbook.delay) { /* not if (context.spbook.delay++), so at end - delay == 0 */ + if (context.spbook.delay) { + /* not if (context.spbook.delay++), so at end delay == 0 */ context.spbook.delay++; return 1; /* still busy */ } @@ -516,15 +528,16 @@ register struct obj *spellbook; too_hard = TRUE; } else { /* uncursed - chance to fail */ - int read_ability = - ACURR(A_INT) + 4 + u.ulevel / 2 - - 2 * objects[booktype].oc_level - + ((ublindf && ublindf->otyp == LENSES) ? 2 : 0); + int read_ability = ACURR(A_INT) + 4 + u.ulevel / 2 + - 2 * objects[booktype].oc_level + + ((ublindf && ublindf->otyp == LENSES) ? 2 : 0); + /* only wizards know if a spell is too difficult */ if (Role_if(PM_WIZARD) && read_ability < 20 && !confused) { char qbuf[QBUFSZ]; + Sprintf(qbuf, - "This spellbook is %sdifficult to comprehend. Continue?", + "This spellbook is %sdifficult to comprehend. Continue?", (read_ability < 12 ? "very " : "")); if (yn(qbuf) != 'y') { spellbook->in_use = FALSE;