diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index e8f7323b4..b6375af04 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1068,6 +1068,8 @@ if hero's action caused engulfer to expel swallowed hero, it might do so onto throwing recoil while levitating could send hero out of shop while carrying unpaid items, triggering sanity check warnings; once outside, taking a step other than back into the shop was treated as a robbery +if punished and iron ball was cursed and wielded--so welded to hand--falling + when doors would drop it instead of keeping it welded Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/ball.c b/src/ball.c index 8d0794d9c..c3d542ef7 100644 --- a/src/ball.c +++ b/src/ball.c @@ -22,7 +22,7 @@ static struct breadcrumbs bcpbreadcrumbs = {0}, bcubreadcrumbs = {0}; void ballrelease(boolean showmsg) { - if (carried(uball)) { + if (carried(uball) && !welded(uball)) { if (showmsg) pline("Startled, you drop the iron ball."); if (uwep == uball) @@ -44,6 +44,9 @@ ballfall(void) { boolean gets_hit; + if (uball && carried(uball) && welded(uball)) + return; + gets_hit = (((uball->ox != u.ux) || (uball->oy != u.uy)) && ((uwep == uball) ? FALSE : (boolean) rn2(5))); ballrelease(TRUE); @@ -996,7 +999,7 @@ drag_down(void) */ forward = carried(uball) && (uwep == uball || !uwep || !rn2(3)); - if (carried(uball)) + if (carried(uball) && !welded(uball)) You("lose your grip on the iron ball."); cls(); /* previous level is still displayed although you diff --git a/src/do.c b/src/do.c index 9d13d6421..17c8ca290 100644 --- a/src/do.c +++ b/src/do.c @@ -595,6 +595,19 @@ canletgo(struct obj *obj, const char *word) Norep("You cannot %s %s you are wearing.", word, something); return FALSE; } + if (obj == uwep && welded(uwep)) { + /* no weldmsg(), so uwep->bknown might become set silently + if word is "" */ + if (*word) { + const char *hand = body_part(HAND); + + if (bimanual(uwep)) + hand = makeplural(hand); + Norep("You cannot %s %s welded to your %s.", word, something, + hand); + } + return FALSE; + } if (obj->otyp == LOADSTONE && obj->cursed) { /* getobj() kludge sets corpsenm to user's specified count when refusing to split a stack of cursed loadstones */ @@ -1612,7 +1625,8 @@ goto_level( You("fall down the %s.", ga.at_ladder ? "ladder" : "stairs"); if (Punished) { drag_down(); - ballrelease(FALSE); + if (!welded(uball)) + ballrelease(FALSE); } /* falling off steed has its own losehp() call */ if (u.usteed) @@ -1632,7 +1646,7 @@ goto_level( } else { /* trap door or level_tele or In_endgame */ u_on_rndspot((up ? 1 : 0) | (was_in_W_tower ? 2 : 0)); if (falling) { - if (Punished) + if (Punished && !welded(uball)) ballfall(); selftouch("Falling, you"); do_fall_dmg = TRUE; diff --git a/src/wield.c b/src/wield.c index 5971b75ef..c9b9ef89a 100644 --- a/src/wield.c +++ b/src/wield.c @@ -1030,11 +1030,15 @@ void weldmsg(struct obj *obj) { long savewornmask; + const char *hand = body_part(HAND); + if (bimanual(obj)) + hand = makeplural(hand); savewornmask = obj->owornmask; - pline("%s welded to your %s!", Yobjnam2(obj, "are"), - bimanual(obj) ? (const char *) makeplural(body_part(HAND)) - : body_part(HAND)); + obj->owornmask = 0L; /* suppress doname()'s "(weapon in hand)"; + * Yobjnam2() doesn't actually need this because + * it is based on xname() rather than doname() */ + pline("%s welded to your %s!", Yobjnam2(obj, "are"), hand); obj->owornmask = savewornmask; }