held artifacts evading your grasp (trunk only)

From a bug report, trying
to invoke a wielded artifact after changing alignment resulted in "the
<artifact> evades your grasp" but it remained wielded, contradicting the
message.  This adjusts the message in touch_artifact() if the object is
already in inventory, and adds retouch_object() to handle cases where
failing to be able to touch ought to force unwearing/unwielding.
This commit is contained in:
nethack.rankin
2007-03-10 05:54:17 +00:00
parent b8a51d3649
commit f67a4547ac
7 changed files with 73 additions and 15 deletions
+3
View File
@@ -194,6 +194,9 @@ if normal game save file is restored via `nethack -X', restore in normal
mode--with save file deletion--and require confirmation ala 'X' mode--with save file deletion--and require confirmation ala 'X'
command to make deferred switch into explore mode command to make deferred switch into explore mode
stethoscope applied to hiding mimic will bring it out of hiding stethoscope applied to hiding mimic will bring it out of hiding
rephrase "<artifact> evades your grasp" message if artifact is already held
artifacts which subsequently evade your grasp/control after already being
worn or wielded become unworn/unwielded
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes
+1
View File
@@ -84,6 +84,7 @@ E boolean FDECL(artifact_has_invprop, (struct obj *,UCHAR_P));
E long FDECL(arti_cost, (struct obj *)); E long FDECL(arti_cost, (struct obj *));
E struct obj *FDECL(what_gives, (long *)); E struct obj *FDECL(what_gives, (long *));
E void FDECL(Sting_effects, (int)); E void FDECL(Sting_effects, (int));
E int FDECL(retouch_object, (struct obj **,BOOLEAN_P));
/* ### attrib.c ### */ /* ### attrib.c ### */
+1 -1
View File
@@ -2974,7 +2974,7 @@ doapply()
obj = getobj(class_list, "use or apply"); obj = getobj(class_list, "use or apply");
if(!obj) return 0; if(!obj) return 0;
if (obj->oartifact && !touch_artifact(obj, &youmonst)) if (!retouch_object(&obj, FALSE))
return 1; /* evading your grasp costs a turn; just be return 1; /* evading your grasp costs a turn; just be
grateful that you don't drop it as well */ grateful that you don't drop it as well */
+57 -4
View File
@@ -1,4 +1,4 @@
/* SCCS Id: @(#)artifact.c 3.5 2006/06/08 */ /* SCCS Id: @(#)artifact.c 3.5 2007/03/05 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -559,7 +559,12 @@ touch_artifact(obj,mon)
/* can pick it up unless you're totally non-synch'd with the artifact */ /* can pick it up unless you're totally non-synch'd with the artifact */
if (badclass && badalign && self_willed) { if (badclass && badalign && self_willed) {
if (yours) pline("%s your grasp!", Tobjnam(obj, "evade")); if (yours) {
if (obj->where != OBJ_INVENT)
pline("%s your grasp!", Tobjnam(obj, "evade"));
else
pline("%s beyond your control!", Tobjnam(obj, "are"));
}
return 0; return 0;
} }
@@ -1200,11 +1205,11 @@ static NEARDATA const char invoke_types[] = { ALL_CLASSES, 0 };
int int
doinvoke() doinvoke()
{ {
register struct obj *obj; struct obj *obj;
obj = getobj(invoke_types, "invoke"); obj = getobj(invoke_types, "invoke");
if (!obj) return 0; if (!obj) return 0;
if (obj->oartifact && !touch_artifact(obj, &youmonst)) return 1; if (!retouch_object(&obj, FALSE)) return 1;
return arti_invoke(obj); return arti_invoke(obj);
} }
@@ -1596,4 +1601,52 @@ int orc_count;
} }
} }
/* called when hero is wielding/applying/invoking a carried item, or
after undergoing a transformation (alignment change, lycanthropy)
which might affect item access */
int
retouch_object(objp, loseit)
struct obj **objp; /* might be destroyed or unintentionally dropped */
boolean loseit; /* whether to drop it if hero can longer touch it */
{
struct obj *obj = *objp;
if (touch_artifact(obj, &youmonst)) {
/* nothing to do if hero can successfully handle this object */
if (!(objects[obj->otyp].oc_material == SILVER &&
(u.ulycn >= LOW_PM || hates_silver(youmonst.data))))
return 1;
/* we didn't get "<obj> evades your grasp" message; give alt message */
You_cant("handle %s anymore!", thesimpleoname(obj));
}
/* removing a worn item might result in loss of levitation,
dropping the hero onto a polymorph trap or into water or
lava and potentially dropping or destroying the item */
if (obj->owornmask) {
struct obj *otmp;
remove_worn_item(obj, FALSE);
for (otmp = invent; otmp; otmp = otmp->nobj)
if (otmp == obj) break;
if (!otmp) *objp = obj = 0;
}
/* if we still have it and caller wants us to drop it, do so now */
if (loseit && obj) {
if (Levitation) {
freeinv(obj);
hitfloor(obj);
} else {
/* dropx gives a message iff item lands on an altar */
if (!IS_ALTAR(levl[u.ux][u.uy].typ))
pline("%s to the %s.",
Tobjnam(obj, "drop"), surface(u.ux, u.uy));
dropx(obj);
}
*objp = obj = 0; /* no longer in inventory */
}
return 0;
}
/*artifact.c*/ /*artifact.c*/
+6 -7
View File
@@ -1152,11 +1152,9 @@ register int pm;
break; break;
} }
if (catch_lycanthropy && defends(AD_WERE, uwep)) { if (catch_lycanthropy) {
if (!touch_artifact(uwep, &youmonst)) { if (u.twoweap) (void)retouch_object(&uswapwep, TRUE);
dropx(uwep); if (uwep) (void)retouch_object(&uwep, TRUE);
uwepgone();
}
} }
return; return;
@@ -2250,7 +2248,7 @@ struct obj *otmp;
int int
doeat() /* generic "eat" command funtion (see cmd.c) */ doeat() /* generic "eat" command funtion (see cmd.c) */
{ {
register struct obj *otmp; struct obj *otmp;
int basenutrit; /* nutrition of full item */ int basenutrit; /* nutrition of full item */
boolean dont_start = FALSE, nodelicious = FALSE; boolean dont_start = FALSE, nodelicious = FALSE;
@@ -2276,7 +2274,8 @@ doeat() /* generic "eat" command funtion (see cmd.c) */
* mails, players who polymorph back to human in the middle of their * mails, players who polymorph back to human in the middle of their
* metallic meal, etc.... * metallic meal, etc....
*/ */
if (otmp->oartifact && !touch_artifact(otmp, &youmonst)) { if (!(carried(otmp) ? retouch_object(&otmp, FALSE) :
touch_artifact(otmp, &youmonst))) {
return 1; return 1;
} else if (!is_edible(otmp)) { } else if (!is_edible(otmp)) {
You("cannot eat that!"); You("cannot eat that!");
+3 -1
View File
@@ -1,4 +1,4 @@
/* SCCS Id: @(#)mhitu.c 3.5 2006/08/07 */ /* SCCS Id: @(#)mhitu.c 3.5 2007/03/09 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1230,6 +1230,8 @@ dopois:
You_feel("feverish."); You_feel("feverish.");
exercise(A_CON, FALSE); exercise(A_CON, FALSE);
u.ulycn = monsndx(mdat); u.ulycn = monsndx(mdat);
if (u.twoweap) (void)retouch_object(&uswapwep, TRUE);
if (uwep) (void)retouch_object(&uwep, TRUE);
} }
break; break;
case AD_SGLD: case AD_SGLD:
+2 -2
View File
@@ -150,11 +150,11 @@ struct obj *wep;
} else if (wep->otyp == CORPSE && cant_wield_corpse(wep)) { } else if (wep->otyp == CORPSE && cant_wield_corpse(wep)) {
/* hero must have been life-saved to get here; use a turn */ /* hero must have been life-saved to get here; use a turn */
res++; /* corpse won't be wielded */ res++; /* corpse won't be wielded */
} else if (uarms && bimanual(wep)) } else if (uarms && bimanual(wep)) {
You("cannot wield a two-handed %s while wearing a shield.", You("cannot wield a two-handed %s while wearing a shield.",
is_sword(wep) ? "sword" : is_sword(wep) ? "sword" :
wep->otyp == BATTLE_AXE ? "axe" : "weapon"); wep->otyp == BATTLE_AXE ? "axe" : "weapon");
else if (wep->oartifact && !touch_artifact(wep, &youmonst)) { } else if (!retouch_object(&wep, FALSE)) {
res++; /* takes a turn even though it doesn't get wielded */ res++; /* takes a turn even though it doesn't get wielded */
} else { } else {
/* Weapon WILL be wielded after this point */ /* Weapon WILL be wielded after this point */