From ec99383b8138274d5838a01261aaca23bb0f46db Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 25 Apr 2024 17:41:06 -0700 Subject: [PATCH] engraving with stack of cursed weapons Fix a FIXME added for issue #1233. When engraving, if the writing implement is a stack of cursed weapons which are welded to the hero's hand, just write in the dust rather than engrave in the floor, in order to keep the whole stack welded. Only applies when the stack is actively welded. Other stacks of cursed weapons will have one split from the stack to perform the engraving, otherwise engraving could be used to determine whether a stack is cursed without the risk of wielding it. --- doc/fixes3-7-0.txt | 3 +++ src/engrave.c | 33 +++++++++++++++++---------------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index de708cbd0..9233a7751 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1402,6 +1402,9 @@ pets and peacefuls avoid a location hero just kicked shopkeepers bill you for using their bear trap or land mine when engraving with a stack of eligible weapons, split one off the stack and dull it rather than dull the whole stack +when engraving with a stack of cursed weapons, treat it differently if that + stack is welded to hero's hand: write in dust and leave whole stack + welded rather than split one off stack to engrave on floor Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/src/engrave.c b/src/engrave.c index d6f7e828b..6c3e11207 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -763,10 +763,16 @@ doengrave_sfx_item(struct _doengrave_ctx *de) if (is_art(de->otmp, ART_FIRE_BRAND)) { de->type = BURN; /* doesn't dull weapon */ } else if (is_blade(de->otmp)) { - if ((int) de->otmp->spe > -3) - de->type = ENGRAVE; + /* if non-blade or welded or too dull, engraving type stays set + to DUST; feedback for that is only given for bladed weapons */ + if (welded(de->otmp)) + pline("%s can only scratch the %s.", + Yname2(de->otmp), surface(u.ux, u.uy)); + else if ((int) de->otmp->spe <= -3) + pline("%s too dull for engraving.", + Yobjnam2(de->otmp, "are")); else - pline("%s too dull for engraving.", Yobjnam2(de->otmp, "are")); + de->type = ENGRAVE; } break; @@ -1101,7 +1107,10 @@ doengrave(void) /* Tell adventurer what is going on */ if (de->otmp != &hands_obj) You("%s the %s with %s%s.", de->everb, de->eloc, - (de->type == ENGRAVE && de->otmp->quan > 1L) ? "one of " : "", + /* since doname() yields "N items" when quantity is more than + one, match that by using "1 of" rather than "one of" when + informating the player that the stack will be split */ + (de->type == ENGRAVE && de->otmp->quan > 1L) ? "1 of " : "", doname(de->otmp)); else You("%s the %s with your %s.", @@ -1264,20 +1273,14 @@ engrave(void) if (dulling_wep) { boolean splitstack = FALSE, dulled = FALSE; - /* 'stylus' is guaranteed to be a weapon */ + /* 'dulling_wep' guarantees that 'stylus' is a weapon which is + not welded to the hero's hand(s) */ if (stylus->quan > 1L) { if (firsttime) pline("One of %s gets dull.", yname(stylus)); - /* - * FIXME? - * If 'stylus' is a stack that's welded to hero's hand, - * ordinarily it couldn't be split. This allows the player - * to unweld one at a time (dulling in the process) until - * there is only one left. Is that what we really want? - * [Perhaps caller should reject welded stack, or set type - * to DUST instead of ENGRAVE?] - */ stylus = gc.context.engraving.stylus = splitobj(stylus, 1L); + /* if stack is wielded or quivered, the split-off one isn't */ + stylus->owornmask = 0L; splitstack = TRUE; } else { /* normal case: stylus->quan==1 */ @@ -1311,8 +1314,6 @@ engrave(void) } } if (splitstack) { - /* 'stylus' has been split off; remainder might still be worn */ - stylus->owornmask = 0L; obj_extract_self(stylus); stylus = hold_another_object(stylus, "You drop one %s!", doname(stylus), (char *) NULL);