From 855ddbc5501cf3d1aacd6f1cf5d8e3bd9a099d92 Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Mon, 5 Aug 2002 09:54:07 +0000 Subject: [PATCH] armor & busy hands Fix some inconsistencies in armor handling. The 'T' command wouldn't let you take off a suit or shirt if you were wielding a cursed two-handed weapon, which makes sense; however, the 'A' command neglected to impose the same restriction. Also, the 'W' command had some code intended to prevent you from donning a suit or shirt while wielding such a cursed weapon, but it didn't work. This patch fixes the 'A' command's checks for whether an item can be removed and it makes the 'T' and 'R' commands use the same code as 'A' instead of maintaining multiple sets of checks. It also fixes the trivial 'W' problem and attempts to prevent the sequence of 1) get interrupted while removing a set of equipment including suit and/or shirt; 2) wield a cursed two-handed weapon or have already wielded one become cursed; 3) resume removing armor via 'A' but I haven't tried to trigger that situation to confirm the bug or this fix. --- doc/fixes34.1 | 2 + src/do_wear.c | 206 ++++++++++++++++++++++++-------------------------- src/mkobj.c | 13 ++-- src/wield.c | 4 +- 4 files changed, 113 insertions(+), 112 deletions(-) diff --git a/doc/fixes34.1 b/doc/fixes34.1 index b5860a7d0..0b4075045 100644 --- a/doc/fixes34.1 +++ b/doc/fixes34.1 @@ -182,6 +182,8 @@ invoking or applying an artifact must pass a touch_artifact check document 'D'rop BUCX behavior in the Guidebook remove levitation boots over a portal, the portal teleport is delayed until your next command is typed. +armor vs cursed two-handed weapon anomalies: with 'T', couldn't remove armor, + but with 'A', could remove it, and with 'W', could put it on Platform- and/or Interface-Specific Fixes diff --git a/src/do_wear.c b/src/do_wear.c index ea30d9c8b..cc79dad4f 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)do_wear.c 3.4 2002/03/28 */ +/* SCCS Id: @(#)do_wear.c 3.4 2002/08/03 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -966,6 +966,7 @@ cancel_don() static NEARDATA const char clothes[] = {ARMOR_CLASS, 0}; static NEARDATA const char accessories[] = {RING_CLASS, AMULET_CLASS, TOOL_CLASS, FOOD_CLASS, 0}; +/* the 'T' command */ int dotakeoff() { @@ -1016,41 +1017,17 @@ dotakeoff() You_cant("take that off."); return 0; } - if (otmp == uarmg && welded(uwep)) { - You("seem unable to take off the gloves while holding your %s.", - is_sword(uwep) ? c_sword : c_weapon); - uwep->bknown = TRUE; - return 0; - } else if (welded(uwep) && bimanual(uwep) && - (otmp == uarm -#ifdef TOURIST - || otmp == uarmu -#endif - )) { - You("seem unable to take off %s while holding your %s.", - the(xname(otmp)), is_sword(uwep) ? c_sword : c_weapon); - uwep->bknown = TRUE; - return 0; - } - if (otmp == uarmg && Glib) { - You_cant("remove the slippery gloves with your slippery fingers."); - return 0; - } - if (otmp == uarmf && u.utrap && (u.utraptype == TT_BEARTRAP || - u.utraptype == TT_INFLOOR)) { /* -3. */ - if(u.utraptype == TT_BEARTRAP) - pline_The("bear trap prevents you from pulling your %s out.", - body_part(FOOT)); - else - You("are stuck in the %s, and cannot pull your %s out.", - surface(u.ux, u.uy), makeplural(body_part(FOOT))); - return(0); - } - reset_remarm(); /* since you may change ordering */ + + reset_remarm(); /* clear takeoff_mask and taking_off */ + (void) select_off(otmp); + if (!takeoff_mask) return 0; + reset_remarm(); /* armoroff() doesn't use takeoff_mask */ + (void) armoroff(otmp); return(1); } +/* the 'R' command */ int doremring() { @@ -1073,32 +1050,13 @@ doremring() You("are not wearing that."); return(0); } - if(cursed(otmp)) return(0); - if(otmp->oclass == RING_CLASS || otmp->otyp == MEAT_RING) { - if (nolimbs(youmonst.data)) { - pline("It seems to be stuck."); - return(0); - } - if (uarmg && uarmg->cursed) { - uarmg->bknown = TRUE; - You( - "seem unable to remove your ring without taking off your gloves."); - return(0); - } - if (welded(uwep) && bimanual(uwep)) { - uwep->bknown = TRUE; - You( - "seem unable to remove the ring while your hands hold your %s.", - is_sword(uwep) ? c_sword : c_weapon); - return(0); - } - if (welded(uwep) && otmp==uright) { - uwep->bknown = TRUE; - You( - "seem unable to remove the ring while your right hand holds your %s.", - is_sword(uwep) ? c_sword : c_weapon); - return(0); - } + + reset_remarm(); /* clear takeoff_mask and taking_off */ + (void) select_off(otmp); + if (!takeoff_mask) return 0; + reset_remarm(); /* not used by Ring_/Amulet_/Blindf_off() */ + + if (otmp == uright || otmp == uleft) { /* Sometimes we want to give the off_msg before removing and * sometimes after; for instance, "you were wearing a moonstone * ring (on right hand)" is desired but "you were wearing a @@ -1107,10 +1065,14 @@ doremring() */ off_msg(otmp); Ring_off(otmp); - } else if(otmp->oclass == AMULET_CLASS) { + } else if (otmp == uamul) { Amulet_off(); off_msg(otmp); - } else Blindf_off(otmp); /* does its own off_msg */ + } else if (otmp == ublindf) { + Blindf_off(otmp); /* does its own off_msg */ + } else { + impossible("removing strange accessory?"); + } return(1); } @@ -1121,9 +1083,9 @@ register struct obj *otmp; { /* Curses, like chickens, come home to roost. */ if((otmp == uwep) ? welded(otmp) : (int)otmp->cursed) { - You("can't. %s to be cursed.", + You("can't. %s cursed.", (is_boots(otmp) || is_gloves(otmp) || otmp->quan > 1L) - ? "They seem" : "It seems"); + ? "They are" : "It is"); otmp->bknown = TRUE; return(1); } @@ -1228,11 +1190,11 @@ boolean noisy; } if (welded(uwep) && bimanual(uwep) && - (otmp == uarm + (is_suit(otmp) #ifdef TOURIST - || otmp == uarmu + || is_shirt(otmp) #endif - )) { + )) { if (noisy) You("cannot do that while holding your %s.", is_sword(uwep) ? c_sword : c_weapon); @@ -1660,45 +1622,82 @@ int select_off(otmp) register struct obj *otmp; { + struct obj *why; char buf[BUFSZ]; - if(!otmp) return(0); - if(cursed(otmp)) return(0); - if((otmp->oclass==RING_CLASS || otmp->otyp == MEAT_RING) - && nolimbs(youmonst.data)) - return(0); - if(welded(uwep) && (otmp==uarmg || otmp==uright || (otmp==uleft - && bimanual(uwep)))) { - You("cannot free a weapon hand to take off the ring."); - return(0); + if (!otmp) return 0; + *buf = '\0'; /* lint suppresion */ + + if (otmp == uright || otmp == uleft) { + if (nolimbs(youmonst.data)) { + pline_The("ring is stuck."); + return 0; + } + why = 0; /* the item which prevents ring removal */ + if (welded(uwep) && (otmp == uright || bimanual(uwep))) { + Sprintf(buf, "free a weapon %s", body_part(HAND)); + why = uwep; + } else if (uarmg && uarmg->cursed) { + Sprintf(buf, "take off your %s", c_gloves); + why = uarmg; + } + if (why) { + You("cannot %s to remove the ring.", buf); + why->bknown = TRUE; + return 0; + } } - if(uarmg && uarmg->cursed && (otmp==uright || otmp==uleft)) { - uarmg->bknown = TRUE; - You("cannot remove your gloves to take off the ring."); - return(0); + if (otmp == uarmg) { + if (welded(uwep)) { + You("are unable to take off your %s while wielding that %s.", + c_gloves, is_sword(uwep) ? c_sword : c_weapon); + uwep->bknown = TRUE; + return 0; + } else if (Glib) { + You_cant("take off the slippery %s with your slippery %s.", + c_gloves, makeplural(body_part(FINGER))); + return 0; + } } - if(otmp == uarmf && u.utrap && (u.utraptype == TT_BEARTRAP || - u.utraptype == TT_INFLOOR)) { - return (0); + if (otmp == uarmf) { + if (u.utrap && u.utraptype == TT_BEARTRAP) { + pline_The("bear trap prevents you from pulling your %s out.", + body_part(FOOT)); + return 0; + } else if (u.utrap && u.utraptype == TT_INFLOOR) { + You("are stuck in the %s, and cannot pull your %s out.", + surface(u.ux, u.uy), makeplural(body_part(FOOT))); + return 0; + } } - if((otmp==uarm + if (otmp == uarm #ifdef TOURIST - || otmp==uarmu + || otmp == uarmu #endif - ) && uarmc && uarmc->cursed) { - Strcpy(buf, the(xname(uarmc))); - You("cannot remove %s to take off %s.", buf, the(xname(otmp))); - uarmc->bknown = TRUE; - return(0); - } + ) { + why = 0; /* the item which prevents disrobing */ + if (uarmc && uarmc->cursed) { + Sprintf(buf, "remove your %s", cloak_simple_name(uarmc)); + why = uarmc; #ifdef TOURIST - if(otmp==uarmu && uarm && uarm->cursed) { - Strcpy(buf, the(xname(uarm))); - You("cannot remove %s to take off %s.", buf, the(xname(otmp))); - uarm->bknown = TRUE; - return(0); - } + } else if (otmp == uarmu && uarm && uarm->cursed) { + Sprintf(buf, "remove your %s", c_suit); + why = uarm; #endif + } else if (welded(uwep) && bimanual(uwep)) { + Sprintf(buf, "release your %s", + is_sword(uwep) ? c_sword : + (uwep->otyp == BATTLE_AXE) ? c_axe : c_weapon); + why = uwep; + } + if (why) { + You("cannot %s to take off %s.", buf, the(xname(otmp))); + why->bknown = TRUE; + return 0; + } + } + /* fundamental, but other impediments are checked first */ + if (cursed(otmp)) return 0; if(otmp == uarm) takeoff_mask |= WORN_ARMOR; else if(otmp == uarmc) takeoff_mask |= WORN_CLOAK; @@ -1787,13 +1786,13 @@ take_off() register int i; register struct obj *otmp; - if(taking_off) { - if(todelay > 0) { - + if (taking_off) { + if (todelay > 0) { todelay--; return(1); /* still busy */ - } else if((otmp = do_takeoff())) off_msg(otmp); - + } else { + if ((otmp = do_takeoff())) off_msg(otmp); + } takeoff_mask &= ~taking_off; taking_off = 0L; } @@ -1865,18 +1864,13 @@ take_off() return(1); /* get busy */ } -#endif /* OVLB */ -#ifdef OVL1 - void reset_remarm() { taking_off = takeoff_mask = 0L; } -#endif /* OVL1 */ -#ifdef OVLB - +/* the 'A' command */ int doddoremarm() { diff --git a/src/mkobj.c b/src/mkobj.c index d1a564060..6ea149f81 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)mkobj.c 3.4 2001/12/03 */ +/* SCCS Id: @(#)mkobj.c 3.4 2002/08/02 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -709,18 +709,21 @@ register struct obj *otmp; { otmp->blessed = 0; otmp->cursed = 1; - if (otmp->otyp == LUCKSTONE - || (otmp->oartifact && spec_ability(otmp, SPFX_LUCK))) + /* welded two-handed weapon interferes with some armor removal */ + if (otmp == uwep && bimanual(uwep)) reset_remarm(); + /* some cursed items need immediate updating */ + if (carried(otmp) && (otmp->otyp == LUCKSTONE || + (otmp->oartifact && spec_ability(otmp, SPFX_LUCK)))) set_moreluck(); else if (otmp->otyp == BAG_OF_HOLDING) otmp->owt = weight(otmp); else if (otmp->otyp == FIGURINE) { if (otmp->corpsenm != NON_PM - && !dead_species(otmp->corpsenm,TRUE) + && !dead_species(otmp->corpsenm,TRUE) && (carried(otmp) || mcarried(otmp))) attach_fig_transform_timeout(otmp); } - return; + return; } void diff --git a/src/wield.c b/src/wield.c index 2b8c975f9..f9f424a93 100644 --- a/src/wield.c +++ b/src/wield.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)wield.c 3.4 2002/05/13 */ +/* SCCS Id: @(#)wield.c 3.4 2002/08/03 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -260,6 +260,8 @@ dowield() return (0); } else if (welded(uwep)) { weldmsg(uwep); + /* previously interrupted armor removal mustn't be resumed */ + reset_remarm(); return (0); } -- 2.40.0