diff --git a/src/artifact.c b/src/artifact.c index d63345e4e..5734b89bd 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 artifact.c $NHDT-Date: 1646652747 2022/03/07 11:32:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.180 $ */ +/* NetHack 3.7 artifact.c $NHDT-Date: 1646688062 2022/03/07 21:21:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.181 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -285,7 +285,7 @@ artifact_exists( return; } -/* make an artifact as 'found' */ +/* mark an artifact as 'found' */ void found_artifact(int a) { @@ -1427,13 +1427,16 @@ artifact_hit(struct monst *magr, struct monst *mdef, struct obj *otmp, drain = (mhpmax > m_lev) ? (mhpmax - (m_lev + 1)) : 0; if (vis) { + /* call distant_name() for possible side-effects even if + the result won't be printed */ + char *otmpname = distant_name(otmp, xname); + if (otmp->oartifact == ART_STORMBRINGER) pline_The("%s blade draws the %s from %s!", hcolor(NH_BLACK), life, mon_nam(mdef)); else pline("%s draws the %s from %s!", - The(distant_name(otmp, xname)), life, - mon_nam(mdef)); + The(otmpname), life, mon_nam(mdef)); } if (mdef->m_lev == 0) { /* losing a level when at 0 is fatal */ @@ -1459,17 +1462,23 @@ artifact_hit(struct monst *magr, struct monst *mdef, struct obj *otmp, } else { /* youdefend */ int oldhpmax = u.uhpmax; - if (Blind) + if (Blind) { You_feel("an %s drain your %s!", (otmp->oartifact == ART_STORMBRINGER) ? "unholy blade" : "object", life); - else if (otmp->oartifact == ART_STORMBRINGER) - pline_The("%s blade drains your %s!", hcolor(NH_BLACK), life); - else - pline("%s drains your %s!", The(distant_name(otmp, xname)), - life); + } else { + /* call distant_name() for possible side-effects even if + the result won't be printed */ + char *otmpname = distant_name(otmp, xname); + + if (otmp->oartifact == ART_STORMBRINGER) + pline_The("%s blade drains your %s!", + hcolor(NH_BLACK), life); + else + pline("%s drains your %s!", The(otmpname), life); + } losexp("life drainage"); if (magr && magr->mhp < magr->mhpmax) { magr->mhp += (oldhpmax - u.uhpmax + 1) / 2; diff --git a/src/dogmove.c b/src/dogmove.c index a00860d22..39da00b38 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dogmove.c $NHDT-Date: 1646652766 2022/03/07 11:32:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.111 $ */ +/* NetHack 3.7 dogmove.c $NHDT-Date: 1646688063 2022/03/07 21:21:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.112 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -222,7 +222,7 @@ dog_eat(struct monst *mtmp, boolean poly, grow, heal, eyes, slimer, deadmimic; int nutrit, res, corpsenm; long oprice; - char objnambuf[BUFSZ]; + char objnambuf[BUFSZ], *obj_name; objnambuf[0] = '\0'; if (edog->hungrytime < g.moves) @@ -288,14 +288,18 @@ dog_eat(struct monst *mtmp, pet as "it". However, we want "it" if invisible/unsensed pet eats visible food. */ if (sawpet || (seeobj && canspotmon(mtmp))) { + /* call distant_name() for possible side-effects even if the + result won't be printed */ + obj_name = distant_name(obj, doname); if (tunnels(mtmp->data)) pline("%s digs in.", noit_Monnam(mtmp)); else pline("%s %s %s.", noit_Monnam(mtmp), - devour ? "devours" : "eats", distant_name(obj, doname)); - } else if (seeobj) - pline("It %s %s.", devour ? "devours" : "eats", - distant_name(obj, doname)); + devour ? "devours" : "eats", obj_name); + } else if (seeobj) { + obj_name = distant_name(obj, doname); + pline("It %s %s.", devour ? "devours" : "eats", obj_name); + } } if (obj->unpaid) { Strcpy(objnambuf, xname(obj)); @@ -316,9 +320,11 @@ dog_eat(struct monst *mtmp, costly_alteration(obj, COST_DEGRD); obj->oerodeproof = 0; mtmp->mstun = 1; - if (canseemon(mtmp) && flags.verbose) { - pline("%s spits %s out in disgust!", Monnam(mtmp), - distant_name(obj, doname)); + if (canseemon(mtmp)) { + obj_name = distant_name(obj, doname); /* (see above) */ + if (flags.verbose) + pline("%s spits %s out in disgust!", + Monnam(mtmp), obj_name); } } else if (obj == uball) { unpunish(); @@ -417,7 +423,7 @@ dog_hunger(struct monst *mtmp, struct edog *edog) static int dog_invent(struct monst *mtmp, struct edog *edog, int udist) { - register int omx, omy, carryamt = 0; + int omx, omy, carryamt = 0; struct obj *obj, *otmp; if (mtmp->msleeping || !mtmp->mcanmove) @@ -465,15 +471,16 @@ dog_invent(struct monst *mtmp, struct edog *edog, int udist) if (carryamt != obj->quan) otmp = splitobj(obj, carryamt); if (cansee(omx, omy)) { - if (otmp->oartifact) { - otmp->dknown = 1; /* see mpickstuff() */ - find_artifact(otmp); - } + /* call distant_name() for possible side-effects + even if the result won't be printed; should be + done before extract+pickup for distant_name() + -> doname() -> xname() -> find_artifact() + while otmp is still on floor */ + char *otmpname = distant_name(otmp, doname); + if (flags.verbose) - pline("%s picks up %s.", Monnam(mtmp), - ((distu(omx, omy) <= 5) - ? doname(otmp) - : distant_name(otmp, doname))); + pline("%s picks up %s.", + Monnam(mtmp), otmpname); } obj_extract_self(otmp); newsym(omx, omy); diff --git a/src/mon.c b/src/mon.c index 8b291186d..59d41aa78 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1646652768 2022/03/07 11:32:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.414 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1646688064 2022/03/07 21:21:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.415 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1097,10 +1097,11 @@ movemon(void) * has young and old forms). */ int -meatmetal(register struct monst* mtmp) +meatmetal(struct monst *mtmp) { - register struct obj *otmp; + struct obj *otmp; struct permonst *ptr; + char *otmpname; int poly, grow, heal, mstone, vis = canseemon(mtmp); /* If a pet, eating is handled separately, in dog.c */ @@ -1118,24 +1119,33 @@ meatmetal(register struct monst* mtmp) if (is_metallic(otmp) && !obj_resists(otmp, 5, 95) && touch_artifact(otmp, mtmp)) { if (mtmp->data == &mons[PM_RUST_MONSTER] && otmp->oerodeproof) { - if (vis && flags.verbose) { - pline("%s eats %s!", Monnam(mtmp), - distant_name(otmp, doname)); + if (vis) { + /* call distant_name() for its side-effects even when + !verbose so won't be printed */ + otmpname = distant_name(otmp, doname); + if (flags.verbose) + pline("%s eats %s!", Monnam(mtmp), otmpname); } /* The object's rustproofing is gone now */ otmp->oerodeproof = 0; mtmp->mstun = 1; - if (vis && flags.verbose) { - pline("%s spits %s out in disgust!", Monnam(mtmp), - distant_name(otmp, doname)); + if (vis) { + /* (see above; format even if it won't be printed) */ + otmpname = distant_name(otmp, doname); + if (flags.verbose) + pline("%s spits %s out in disgust!", + Monnam(mtmp), otmpname); } } else { - /* [should this be canseemon()?] */ - if (cansee(mtmp->mx, mtmp->my) && flags.verbose) - pline("%s eats %s!", Monnam(mtmp), - distant_name(otmp, doname)); - else if (flags.verbose) - You_hear("a crunching sound."); + if (cansee(mtmp->mx, mtmp->my)) { + /* (see above; format even if it won't be printed) */ + otmpname = distant_name(otmp, doname); + if (flags.verbose) + pline("%s eats %s!", Monnam(mtmp), otmpname); + } else { + if (flags.verbose) + You_hear("a crunching sound."); + } mtmp->meating = otmp->owt / 2 + 1; /* Heal up to the object's weight in hp */ if (mtmp->mhp < mtmp->mhpmax) { @@ -1200,7 +1210,7 @@ meatobj(struct monst* mtmp) /* for gelatinous cubes */ struct obj *otmp, *otmp2; struct permonst *ptr, *original_ptr = mtmp->data; int poly, grow, heal, eyes, count = 0, ecount = 0, vis = canseemon(mtmp); - char buf[BUFSZ]; + char buf[BUFSZ], *otmpname; buf[0] = '\0'; /* If a pet, eating is handled separately, in dog.c */ @@ -1261,9 +1271,11 @@ meatobj(struct monst* mtmp) /* for gelatinous cubes */ && !slimeproof(mtmp->data))) { /* engulf */ ++ecount; + /* call distant_name() for its possible side-effects even if + the result won't be printed */ + otmpname = distant_name(otmp, doname); if (ecount == 1) - Sprintf(buf, "%s engulfs %s.", Monnam(mtmp), - distant_name(otmp, doname)); + Sprintf(buf, "%s engulfs %s.", Monnam(mtmp), otmpname); else if (ecount == 2) Sprintf(buf, "%s engulfs several objects.", Monnam(mtmp)); obj_extract_self(otmp); @@ -1274,9 +1286,10 @@ meatobj(struct monst* mtmp) /* for gelatinous cubes */ /* devour */ ++count; if (cansee(mtmp->mx, mtmp->my)) { + /* (see above; distant_name() sometimes has side-effects */ + otmpname = distant_name(otmp, doname); if (flags.verbose) - pline("%s eats %s!", Monnam(mtmp), - distant_name(otmp, doname)); + pline("%s eats %s!", Monnam(mtmp), otmpname); /* give this one even if !verbose */ if (otmp->oclass == SCROLL_CLASS && objdescr_is(otmp, "YUM YUM")) @@ -1389,8 +1402,12 @@ meatcorpse(struct monst* mtmp) /* for purple worms and other voracious monsters otmp = splitobj(otmp, 1L); if (cansee(x, y) && canseemon(mtmp)) { + /* call distant_name() for its possible side-effects even if + the result won't be printed */ + char *otmpname = distant_name(otmp, doname); + if (flags.verbose) - pline("%s eats %s!", Monnam(mtmp), distant_name(otmp, doname)); + pline("%s eats %s!", Monnam(mtmp), otmpname); } else { if (flags.verbose) You_hear("a masticating sound."); @@ -1553,24 +1570,13 @@ mpickstuff(struct monst *mtmp, const char *str) otmp3 = splitobj(otmp, carryamt); } if (cansee(mtmp->mx, mtmp->my)) { - /* find an artifact as monster picks it up if its location - can be seen, even if monster itself can't be seen or - is far away at the time; the longer distance than for - seeing item "up close" is mostly for pets rummaging in - shops; we prefer to have an artifact in such situation - described as 'found in a shop' or 'found on floor' now - rather than 'carried by a monster' when later dropped */ - if (otmp3->oartifact) { - otmp3->dknown = 1; - find_artifact(otmp3); - } + /* call distant_name() for its possible side-effects even + if the result won't be printed; do it before the extract + from floor and subsequent pickup by mtmp */ + char *otmpname = distant_name(otmp, doname); if (flags.verbose) - /* see 'otmp3' "up close" if within a knight's jump */ - pline("%s picks up %s.", Monnam(mtmp), - ((distu(mtmp->mx, mtmp->my) <= 5) - ? doname(otmp3) - : distant_name(otmp3, doname))); + pline("%s picks up %s.", Monnam(mtmp), otmpname); } obj_extract_self(otmp3); /* remove from floor */ (void) mpickobj(mtmp, otmp3); /* may merge and free otmp3 */ diff --git a/src/muse.c b/src/muse.c index 98764a69b..67e9f8456 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 muse.c $NHDT-Date: 1620329779 2021/05/06 19:36:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.143 $ */ +/* NetHack 3.7 muse.c $NHDT-Date: 1646688066 2022/03/07 21:21:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.159 $ */ /* Copyright (C) 1990 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ @@ -1993,7 +1993,8 @@ mloot_container( container->cknown = 0; /* hero no longer knows container's contents * even if [attempted] removal is observed */ if (!*contnr_nam) { - /* xname sets dknown, distant_name doesn't */ + /* xname sets dknown, distant_name might depending on its own + idea about nearness */ Strcpy(contnr_nam, an(nearby ? xname(container) : distant_name(container, xname))); } @@ -2563,10 +2564,9 @@ mon_consume_unstone( obj->quan = 1L; pline("%s %s %s.", Monnam(mon), - (obj->oclass == POTION_CLASS) - ? "quaffs" - : (obj->otyp == TIN) ? "opens and eats the contents of" - : "eats", + ((obj->oclass == POTION_CLASS) ? "quaffs" + : (obj->otyp == TIN) ? "opens and eats the contents of" + : "eats"), distant_name(obj, doname)); obj->quan = save_quan; } else if (!Deaf) diff --git a/src/music.c b/src/music.c index 9cd41d124..7bb46aa62 100644 --- a/src/music.c +++ b/src/music.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 music.c $NHDT-Date: 1596498191 2020/08/03 23:43:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.69 $ */ +/* NetHack 3.7 music.c $NHDT-Date: 1646688067 2022/03/07 21:21:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.77 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -701,7 +701,7 @@ do_play_instrument(struct obj* instr) || instr->otyp == TOOLED_HORN || instr->otyp == FROST_HORN || instr->otyp == FIRE_HORN || instr->otyp == BUGLE) && !can_blow(&g.youmonst)) { - You("are incapable of playing %s.", the(distant_name(instr, xname))); + You("are incapable of playing %s.", thesimpleoname(instr)); return ECMD_OK; } if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE diff --git a/src/objnam.c b/src/objnam.c index 3c9aa7f20..cb9290870 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 objnam.c $NHDT-Date: 1646652769 2022/03/07 11:32:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.347 $ */ +/* NetHack 3.7 objnam.c $NHDT-Date: 1646688068 2022/03/07 21:21:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.348 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -294,24 +294,52 @@ obj_is_pname(struct obj* obj) } /* Give the name of an object seen at a distance. Unlike xname/doname, - * we don't want to set dknown if it's not set already. - */ + we usually don't want to set dknown if it's not set already. */ char * -distant_name(struct obj* obj, char* (*func)(OBJ_P)) +distant_name( + struct obj *obj, /* object to be formatted */ + char *(*func)(OBJ_P)) /* formatting routine (usually xname or doname) */ { char *str; + xchar ox = 0, oy = 0; + /* + * (r * r): square of the x or y distance; + * (r * r) * 2: sum of squares of both x and y distances + * (r * r) * 2 - r: instead of a square extending from the hero, + * round the corners (so shorter distance imposed for diagonal). + * + * distu() matrix convering a range of 3+ for one quadrant: + * 16 17 - - - + * 9 10 13 18 - + * 4 5 8 13 - + * 1 2 5 10 17 + * @ 1 4 9 16 + * Theoretical r==1 would yield 1. + * r==2 yields 6, functionally equivalent to 5, a knight's jump, + * r==3, the xray range of the Eyes of the Overworld, yields 15. + */ + int r = (u.xray_range > 2) ? u.xray_range : 2, + neardist = (r * r) * 2 - r; /* same as r*r + r*(r-1) */ - /* 3.6.1: this used to save Blind, set it, make the call, then restore - * the saved value; but the Eyes of the Overworld override blindness - * and let characters wearing them get dknown set for distant items. - * - * TODO? if the hero is wearing those Eyes, figure out whether the - * object is within X-ray radius and only treat it as distant when - * beyond that radius. Logic is iffy but result might be interesting. - */ - ++g.distantname; - str = (*func)(obj); - --g.distantname; + /* this maybe-nearby part used to be replicated in multiple callers */ + if (get_obj_location(obj, &ox, &oy, 0) && cansee(ox, oy) + && (obj->oartifact || distu(ox, oy) <= neardist)) { + /* side-effects: treat as having been seen up close; + cansee() is True hence hero isn't Blind so if 'func' is + the usual doname or xname, obj->dknown will become set + and then for an artifact, find_artifact() will be called */ + str = (*func)(obj); + } else { + /* prior to 3.6.1, this used to save current blindness state, + explicitly set state to hero-is-blind, make the call (which + won't set obj->dknown when blind), then restore the saved + value; but the Eyes of the Overworld override blindness and + would let characters wearing them get obj->dknown set for + distant items, so the external flag was added */ + ++g.distantname; + str = (*func)(obj); + --g.distantname; + } return str; } @@ -902,9 +930,10 @@ minimal_xname(struct obj *obj) bareobj.spe = obj->spe; /* bufp will be an obuf[] and a pointer into middle of that is viable */ - bufp = distant_name(&bareobj, xname); /* xname(&bareobj) */ + bufp = distant_name(&bareobj, xname); + /* undo forced setting of bareobj.blessed for cleric (preist[ess]) */ if (!strncmp(bufp, "uncursed ", 9)) - bufp += 9; /* Role_if(PM_CLERIC) */ + bufp += 9; objects[otyp].oc_uname = saveobcls.oc_uname; objects[otyp].oc_name_known = saveobcls.oc_name_known; diff --git a/src/steal.c b/src/steal.c index ff257e4a9..cb0d94873 100644 --- a/src/steal.c +++ b/src/steal.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 steal.c $NHDT-Date: 1646652771 2022/03/07 11:32:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.97 $ */ +/* NetHack 3.7 steal.c $NHDT-Date: 1646688070 2022/03/07 21:21:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.98 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -678,14 +678,9 @@ mdrop_obj( { int omx = mon->mx, omy = mon->my; long unwornmask = obj->owornmask; - - /* if an artifact, find dropped item 'carried by a monster' rather - than later finding it on the floor, even if not very close to the - drop and even if the monster itself can't be seen */ - if (obj->oartifact && cansee(omx, omy)) { - obj->dknown = 1; - find_artifact(obj); - } + /* call distant_name() for its possible side-effects even if the result + might not be printed, and do it before extracing obj from minvent */ + char *obj_name = distant_name(obj, doname); extract_from_minvent(mon, obj, FALSE, TRUE); /* don't charge for an owned saddle on dead steed (provided @@ -698,7 +693,7 @@ mdrop_obj( } /* obj_no_longer_held(obj); -- done by place_object */ if (verbosely && cansee(omx, omy)) - pline("%s drops %s.", Monnam(mon), distant_name(obj, doname)); + pline("%s drops %s.", Monnam(mon), obj_name); if (!flooreffects(obj, omx, omy, "fall")) { place_object(obj, omx, omy); stackobj(obj); diff --git a/src/weapon.c b/src/weapon.c index dc082f591..935e9f058 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 weapon.c $NHDT-Date: 1629243070 2021/08/17 23:31:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.95 $ */ +/* NetHack 3.7 weapon.c $NHDT-Date: 1646688071 2022/03/07 21:21:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.100 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -703,11 +703,12 @@ possibly_unwield(struct monst *mon, boolean polyspot) if (!attacktype(mon->data, AT_WEAP)) { setmnotwielded(mon, mw_tmp); mon->weapon_check = NO_WEAPON_WANTED; - obj_extract_self(obj); + /* if we're going to call distant_name(), do so before extract_self */ if (cansee(mon->mx, mon->my)) { pline("%s drops %s.", Monnam(mon), distant_name(obj, doname)); newsym(mon->mx, mon->my); } + obj_extract_self(obj); /* might be dropping object into water or lava */ if (!flooreffects(obj, mon->mx, mon->my, "drop")) { if (polyspot) diff --git a/src/wizard.c b/src/wizard.c index 89fc73a26..c90cd4ff5 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wizard.c $NHDT-Date: 1596498229 2020/08/03 23:43:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.68 $ */ +/* NetHack 3.7 wizard.c $NHDT-Date: 1646688073 2022/03/07 21:21:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.85 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -414,9 +414,7 @@ tactics(struct monst *mtmp) if ((otmp = on_ground(which_arti(targ))) != 0) { if (cansee(mtmp->mx, mtmp->my)) pline("%s picks up %s.", Monnam(mtmp), - (distu(mtmp->mx, mtmp->my) <= 5) - ? doname(otmp) - : distant_name(otmp, doname)); + distant_name(otmp, doname)); obj_extract_self(otmp); (void) mpickobj(mtmp, otmp); return 1;