From: PatR Date: Mon, 7 Mar 2022 11:33:01 +0000 (-0800) Subject: livelog event for finding artifacts X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f65e652e2e03b842ff05f49deb3606e47fb715e6;p=nethack livelog event for finding artifacts Log artifacts found on the floor, or carried by monsters if hero sees those monsters do something with them. Shown to player via #chronicle and included in dumplog. For most cases, finding is based on having the artifact object be formatted for display. So walking across one won't notice it if pile size inhibits showing items at its location, even if the artifact is on top. Taking stuff out of a container won't notice an artifact if a subset of the contents chosen by class or BUCX filter doesn't include it unless player has used ':' to look inside. Seeing an artifact be picked up by a monster (even if the monster itself is unseen) or being dropped (possibly upon death) will find an artifact even if beyond the normal range of having it be treated as seen up close. Random treasure drop items are excluded since they are placed directly on the floor rather than going into a dying monster's inventory and then dropped with its other stuff. --- diff --git a/src/artifact.c b/src/artifact.c index 300605918..d63345e4e 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 artifact.c $NHDT-Date: 1620326528 2021/05/06 18:42:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.167 $ */ +/* NetHack 3.7 artifact.c $NHDT-Date: 1646652747 2022/03/07 11:32:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.180 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -292,14 +292,46 @@ found_artifact(int a) artiexist[a].found = 1; } -/* if an artifact hasn't already been designated 'found', do that now */ +/* if an artifact hasn't already been designated 'found', do that now + and generate a livelog event about finding it */ void find_artifact(struct obj *otmp) { int a = otmp->oartifact; if (a && !artiexist[a].found) { + char buf[BUFSZ]; + const char *where; + found_artifact(a); /* artiexist[a].found = 1 */ + /* + * Unlike costly_spot(), inside_shop() includes the "free spot" + * in front of the door. And it doesn't care whether or not + * there is a shopkeeper present. + * + * If hero sees a monster pick up a not-yet-found artifact, it + * will have its dknown flag set even if far away and will be + * described as 'found on the floor'. Similarly for dropping + * (possibly upon monster's death), dknown will be set and the + * artifact will be described as 'carried by a monster'. + * That's handled by caller: dog_invent(), mpickstuff(), or + * mdrop_obj() so that we get called before obj->where changes. + */ + where = ((otmp->where == OBJ_FLOOR) + ? ((inside_shop(otmp->ox, otmp->oy) != NO_ROOM) + ? " in a shop" + : " on the floor") + /* artifacts aren't created in containers but could be + inside one if it comes from a bones level */ + : (otmp->where == OBJ_CONTAINED) ? " in a container" + /* perhaps probing, or seeing monster wield artifact */ + : (otmp->where == OBJ_MINVENT) ? " carried by a monster" + /* catchall: probably in inventory, picked up while + blind but now seen; there's no previous_where to + figure out how it got here */ + : ""); + (void) strsubst(strcpy(buf, artiname(a)), "The ", "the "); + livelog_printf(LL_ARTIFACT, "found %s%s", buf, where); } } @@ -1001,7 +1033,8 @@ Mb_hit(struct monst *magr, /* attacker */ { struct permonst *old_uasmon; const char *verb; - boolean youattack = (magr == &g.youmonst), youdefend = (mdef == &g.youmonst), + boolean youattack = (magr == &g.youmonst), + youdefend = (mdef == &g.youmonst), resisted = FALSE, do_stun, do_confuse, result; int attack_indx, fakeidx, scare_dieroll = MB_MAX_DIEROLL / 2; diff --git a/src/dogmove.c b/src/dogmove.c index b6b4efabc..a00860d22 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dogmove.c $NHDT-Date: 1645311270 2022/02/19 22:54:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.108 $ */ +/* NetHack 3.7 dogmove.c $NHDT-Date: 1646652766 2022/03/07 11:32:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.111 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -464,9 +464,17 @@ dog_invent(struct monst *mtmp, struct edog *edog, int udist) otmp = obj; if (carryamt != obj->quan) otmp = splitobj(obj, carryamt); - if (cansee(omx, omy) && flags.verbose) - pline("%s picks up %s.", Monnam(mtmp), - distant_name(otmp, doname)); + if (cansee(omx, omy)) { + if (otmp->oartifact) { + otmp->dknown = 1; /* see mpickstuff() */ + find_artifact(otmp); + } + if (flags.verbose) + pline("%s picks up %s.", Monnam(mtmp), + ((distu(omx, omy) <= 5) + ? doname(otmp) + : distant_name(otmp, doname))); + } obj_extract_self(otmp); newsym(omx, omy); (void) mpickobj(mtmp, otmp); diff --git a/src/mon.c b/src/mon.c index 99d669ba5..8b291186d 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1646184187 2022/03/02 01:23:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.412 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1646652768 2022/03/07 11:32:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.414 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1553,6 +1553,18 @@ 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); + } + if (flags.verbose) /* see 'otmp3' "up close" if within a knight's jump */ pline("%s picks up %s.", Monnam(mtmp), diff --git a/src/objnam.c b/src/objnam.c index 59ae1c197..3c9aa7f20 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 objnam.c $NHDT-Date: 1644347179 2022/02/08 19:06:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.343 $ */ +/* NetHack 3.7 objnam.c $NHDT-Date: 1646652769 2022/03/07 11:32:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.347 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -513,6 +513,28 @@ xname_flags( bknown = obj->bknown; } + /* + * Maybe find a previously unseen artifact. + * + * Assumption 1: if an artifact object is being formatted, it is + * being shown to the hero (on floor, or looking into container, + * or probing a monster, or seeing a monster wield it). + * Assumption 2: if in a pile that has been stepped on, the + * artifact won't be noticed for cases where the pile to too deep + * to be auto-shown, unless the player explicitly looks at that + * spot (via ':'). Might need to make an exception somehow (at + * the point where the decision whether to auto-show gets made?) + * when an artifact is on the top of the pile. + * Assumption 3: since this is used for livelog events, not being + * 100% correct won't negatively affect the player's current game. + * + * We use the real obj->dknown rather than the override_ID variant + * so that wizard-mode ^I doesn't cause a not-yet-seen artifact in + * inventory (picked up while blind, still blind) to become found. + */ + if (obj->oartifact && obj->dknown) + find_artifact(obj); + if (obj_is_pname(obj)) goto nameit; switch (obj->oclass) { diff --git a/src/steal.c b/src/steal.c index eccf3dae3..ff257e4a9 100644 --- a/src/steal.c +++ b/src/steal.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 steal.c $NHDT-Date: 1620329782 2021/05/06 19:36:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.90 $ */ +/* NetHack 3.7 steal.c $NHDT-Date: 1646652771 2022/03/07 11:32:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.97 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -679,6 +679,14 @@ 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); + } + extract_from_minvent(mon, obj, FALSE, TRUE); /* don't charge for an owned saddle on dead steed (provided that the hero is within the same shop at the time) */ diff --git a/src/uhitm.c b/src/uhitm.c index 120fb7a2f..4116da820 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 uhitm.c $NHDT-Date: 1641668224 2022/01/08 18:57:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.328 $ */ +/* NetHack 3.7 uhitm.c $NHDT-Date: 1646652773 2022/03/07 11:32:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.344 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1768,6 +1768,11 @@ steal_it(struct monst *mdef, struct attack *mattk) if (!Upolyd) break; /* no longer have ability to steal */ unwornmask = otmp->owornmask; + /* this would take place when doname() formats the object for + the hold_another_object() call, but we want to do it before + otmp gets removed from mdef's inventory */ + if (otmp->oartifact && !Blind) + find_artifact(otmp); /* take the object away from the monster */ extract_from_minvent(mdef, otmp, TRUE, FALSE); /* special message for final item; no need to check owornmask because diff --git a/src/zap.c b/src/zap.c index 365f6df4f..cf6180dd1 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 zap.c $NHDT-Date: 1646322469 2022/03/03 15:47:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.400 $ */ +/* NetHack 3.7 zap.c $NHDT-Date: 1646652775 2022/03/07 11:32:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.401 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2032,7 +2032,8 @@ bhito(struct obj *obj, struct obj *otmp) } /* KMH, conduct */ if (!u.uconduct.polypiles++) - livelog_printf(LL_CONDUCT, "polymorphed %s first object", uhis()); + livelog_printf(LL_CONDUCT, "polymorphed %s first object", + uhis()); /* any saved lock context will be dangerously obsolete */ if (Is_box(obj)) @@ -5594,6 +5595,10 @@ makewish(void) return; } + if (otmp->oartifact) + /* update artifact bookkeeping; doesn't produce a livelog event */ + found_artifact(otmp->oartifact); + maybe_LL_arti = ((prev_artwish < u.uconduct.wisharti) ? LL_ARTIFACT : 0L); /* KMH, conduct */ if (!u.uconduct.wishes++)