diff --git a/doc/fixes34.4 b/doc/fixes34.4 index 33918a2df..59ae297b1 100644 --- a/doc/fixes34.4 +++ b/doc/fixes34.4 @@ -61,6 +61,7 @@ incorrect screen display if engulfer gets turned to stone when trying to swallow while hero is poly'd into cockatrice panic on subsequent move if engulfer gets turned to stone and poly'd hero also has attached ball&chain +give more specific messages when dropping weapons due to slippery fingers Platform- and/or Interface-Specific Fixes diff --git a/include/extern.h b/include/extern.h index 11db72c19..fd1d4c28d 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2303,6 +2303,7 @@ E int NDECL(dosuspend); /* ### weapon.c ### */ +E const char *FDECL(weapon_descr, (struct obj *)); E int FDECL(hitval, (struct obj *,struct monst *)); E int FDECL(dmgval, (struct obj *,struct monst *)); E struct obj *FDECL(select_rwep, (struct monst *)); diff --git a/src/do_wear.c b/src/do_wear.c index d6b2bf82c..a9b8c3643 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)do_wear.c 3.4 2004/06/30 */ +/* SCCS Id: @(#)do_wear.c 3.4 2004/10/29 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1616,8 +1616,8 @@ glibr() { register struct obj *otmp; int xfl = 0; - boolean leftfall, rightfall; - const char *otherwep = 0; + boolean leftfall, rightfall, wastwoweap = FALSE; + const char *otherwep = 0, *thiswep, *which, *hand; leftfall = (uleft && !uleft->cursed && (!uwep || !welded(uwep) || !bimanual(uwep))); @@ -1643,31 +1643,53 @@ glibr() otmp = uswapwep; if (u.twoweap && otmp) { - otherwep = is_sword(otmp) ? c_sword : - makesingular(oclass_names[(int)otmp->oclass]); - Your("%s %sslips from your %s.", - otherwep, - xfl ? "also " : "", - makeplural(body_part(HAND))); - setuswapwep((struct obj *)0); + /* secondary weapon doesn't need nearly as much handling as + primary; when in two-weapon mode, we know it's one-handed + with something else in the other hand and also that it's + a weapon or weptool rather than something unusual, plus + we don't need to compare its type with the primary */ + otherwep = is_sword(otmp) ? c_sword : weapon_descr(otmp); + if (otmp->quan > 1L) otherwep = makeplural(otherwep); + hand = body_part(HAND); + which = "left "; + Your("%s %s%s from your %s%s.", + otherwep, xfl ? "also " : "", + otense(otmp, "slip"), which, hand); xfl++; + wastwoweap = TRUE; + setuswapwep((struct obj *)0); /* clears u.twoweap */ if (otmp->otyp != LOADSTONE || !otmp->cursed) dropx(otmp); } otmp = uwep; if (otmp && !welded(otmp)) { - const char *thiswep; + long savequan = otmp->quan; /* nice wording if both weapons are the same type */ - thiswep = is_sword(otmp) ? c_sword : - makesingular(oclass_names[(int)otmp->oclass]); - if (otherwep && strcmp(thiswep, otherwep)) otherwep = 0; - - /* changed so cursed weapons don't fall, GAN 10/30/86 */ - Your("%s%s %sslips from your %s.", - otherwep ? "other " : "", thiswep, - xfl ? "also " : "", - makeplural(body_part(HAND))); + thiswep = is_sword(otmp) ? c_sword : weapon_descr(otmp); + if (otherwep && strcmp(thiswep, makesingular(otherwep))) + otherwep = 0; + if (otmp->quan > 1L) { + /* most class names for unconventional wielded items + are ok, but if wielding multiple apples or rations + we don't want "your foods slip", so force non-corpse + food to be singular; skipping makeplural() isn't + enough--we need to fool otense() too */ + if (!strcmp(thiswep, "food")) otmp->quan = 1L; + else thiswep = makeplural(thiswep); + } + hand = body_part(HAND); + which = ""; + if (bimanual(otmp)) + hand = makeplural(hand); + else if (wastwoweap) + which = "right "; /* preceding msg was about left */ + pline("%s %s%s %s%s from your %s%s.", + !strncmp(thiswep, "corpse", 6) ? "The" : "Your", + otherwep ? "other " : "", thiswep, xfl ? "also " : "", + otense(otmp, "slip"), which, hand); + /* xfl++; */ + otmp->quan = savequan; setuwep((struct obj *)0); if (otmp->otyp != LOADSTONE || !otmp->cursed) dropx(otmp); diff --git a/src/weapon.c b/src/weapon.c index 9275fb38a..a9c3985cc 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)weapon.c 3.4 2004/06/12 */ +/* SCCS Id: @(#)weapon.c 3.4 2004/10/29 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -101,6 +101,47 @@ static NEARDATA const char kebabable[] = { S_XORN, S_DRAGON, S_JABBERWOCK, S_NAGA, S_GIANT, '\0' }; +/* weapon's skill category name for use as generalized description of weapon */ +const char *weapon_descr(obj) +struct obj *obj; +{ + int skill = weapon_type(obj); + const char *descr = P_NAME(skill); + + /* assorted special cases */ + switch (skill) { + case P_NONE: + /* not a weapon: use item class name; override "food" for corpses */ + descr = (obj->otyp == CORPSE) ? "corpse" : + oclass_names[(int)obj->oclass]; + break; + case P_SLING: + if (is_ammo(obj)) + descr = (obj->otyp == ROCK || is_graystone(obj)) ? "stone" : + /* avoid "rock"; what about known glass? */ + (obj->oclass == GEM_CLASS) ? "gem" : + /* in case somebody adds odd sling ammo */ + oclass_names[(int)obj->oclass]; + break; + case P_BOW: + if (is_ammo(obj)) descr = "arrow"; + break; + case P_CROSSBOW: + if (is_ammo(obj)) descr = "bolt"; + break; + case P_FLAIL: + if (obj->otyp == GRAPPLING_HOOK) descr = "hook"; + break; + case P_PICK_AXE: + /* even if "dwarvish mattock" hasn't been discovered yet */ + if (obj->otyp == DWARVISH_MATTOCK) descr = "mattock"; + break; + default: + break; + } + return makesingular(descr); +} + /* * hitval returns an integer representing the "to hit" bonuses * of "otmp" against the monster.