diff --git a/include/extern.h b/include/extern.h index 5d404f0a0..0c5056614 100644 --- a/include/extern.h +++ b/include/extern.h @@ -3799,6 +3799,7 @@ extern struct monst *revive(struct obj *, boolean) NONNULLARG1; extern int unturn_dead(struct monst *) NONNULLARG1; extern void unturn_you(void); extern void cancel_item(struct obj *) NONNULLARG1; +extern void blank_novel(struct obj *) NONNULLARG1; extern boolean drain_item(struct obj *, boolean) NO_NNARGS; /* tests !obj */ extern boolean obj_unpolyable(struct obj *) NONNULLARG1; extern struct obj *poly_obj(struct obj *, int) NONNULLARG1; diff --git a/src/trap.c b/src/trap.c index 356771b60..de0c66c8a 100644 --- a/src/trap.c +++ b/src/trap.c @@ -4613,16 +4613,8 @@ water_damage( obj->spestudied = rn2(obj->spestudied); obj->dknown = 0; /* blanking a novel is more involved than blanking a spellbook */ - if (otyp == SPE_NOVEL) { /* old type */ - obj->novelidx = 0; /* overloads corpsenm, not used for splbooks */ - free_oname(obj); - /* novels weigh less than spellbooks; apparently blanking them - magically makes them become heavier */ - do { - obj->owt = weight(obj); - obj = (obj->where == OBJ_CONTAINED) ? obj->ocontainer : 0; - } while (obj); - } + if (otyp == SPE_NOVEL) /* old type */ + blank_novel(obj); if (in_invent) update_inventory(); return ER_DAMAGED; diff --git a/src/zap.c b/src/zap.c index 8b1c9f863..71eaa49ab 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1255,9 +1255,11 @@ cancel_item(struct obj *obj) || obj->oclass == WEAPON_CLASS || is_weptool(obj))) || otyp == POT_ACID || otyp == POT_SICKNESS - || (otyp == POT_WATER && (obj->blessed || obj->cursed))) { + || (otyp == POT_WATER && (obj->blessed || obj->cursed)) + /* not magic; cancels to blank spellbook */ + || otyp == SPE_NOVEL) { int cancelled_spe = (obj->oclass == WAND_CLASS - || obj->otyp == CRYSTAL_BALL) ? -1 : 0; + || otyp == CRYSTAL_BALL) ? -1 : 0; if (obj->spe != cancelled_spe && otyp != WAN_CANCELLATION /* can't cancel cancellation */ @@ -1273,10 +1275,12 @@ cancel_item(struct obj *obj) obj->spe = 0; break; case SPBOOK_CLASS: - if (otyp != SPE_CANCELLATION && otyp != SPE_NOVEL - && otyp != SPE_BOOK_OF_THE_DEAD) { + if (otyp != SPE_CANCELLATION && otyp != SPE_BOOK_OF_THE_DEAD) { costly_alteration(obj, COST_CANCEL); obj->otyp = SPE_BLANK_PAPER; + /* cancelling a novel is more involved than a spellbook */ + if (otyp == SPE_NOVEL) /* old type */ + blank_novel(obj); } break; case POTION_CLASS: @@ -1313,6 +1317,20 @@ cancel_item(struct obj *obj) return; } +/* soaking or cancelling a novel converts it into a blank spellbook but + needs more than just changing its otyp (caller is responsible for that) */ +void +blank_novel(struct obj *obj) +{ + assert(obj->otyp == SPE_BLANK_PAPER); + /* novelidx overloads corpsenm, not used for spellbooks */ + obj->novelidx = 0; + free_oname(obj); /* get rid of [former] novel's title */ + /* a blank spellbook weighs more than a novel; update obj's weight and + recursively the weight of any container holding it */ + container_weight(obj); +} + /* Remove a positive enchantment or charge from obj, * possibly carried by you or a monster */