From: PatR Date: Fri, 11 Mar 2022 19:00:44 +0000 (-0800) Subject: more artifact tracking X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7a335eb0306f15d4d80e4f8aef87bff25566dbfc;p=nethack more artifact tracking This should have been broken up into multiple pieces but they're all lumped together. I did ultimately throw away a fourth change. Implement artiexist[].bones and artiexist[].rndm artifact creation tracking bits that were added recently. Doesn't need to increment EDITLEVEL this time. Add a new wizard mode feature: if you use `a to show discovered artifacts, it will prompt about whether to show the tracking bits for all artifacts instead. If not using menustyle traditional, you need at least one artifact to have been discovered in order to have 'a' choice available when selecting what class of discovered objects to show for the '`' command. artifact_gift(), aritfact_wish(), and so forth return a value that none of the existing callers use, so cast their calls to (void). --- diff --git a/include/extern.h b/include/extern.h index e7c6802e6..7eb43e2b3 100644 --- a/include/extern.h +++ b/include/extern.h @@ -77,6 +77,7 @@ extern int artifact_gift(struct obj *, boolean); extern int artifact_wish(struct obj *, boolean); extern int artifact_named(struct obj *, boolean); extern int artifact_viadip(struct obj *, boolean); +extern int artifact_bones(struct obj *, boolean); extern boolean arti_immune(struct obj *, int); extern boolean spec_ability(struct obj *, unsigned long); extern boolean confers_luck(struct obj *); @@ -93,6 +94,7 @@ extern int spec_dbon(struct obj *, struct monst *, int); extern void discover_artifact(xchar); extern boolean undiscovered_artifact(xchar); extern int disp_artifact_discoveries(winid); +extern void dump_artifact_info(winid); extern boolean artifact_hit(struct monst *, struct monst *, struct obj *, int *, int); extern int doinvoke(void); diff --git a/src/artifact.c b/src/artifact.c index 7ef079dab..d249b1944 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -52,7 +52,7 @@ struct arti_info { Bitfield(bones, 1); /* came from bones file; not (yet?) implemented */ }; /* array of flags tracking which artifacts exist, indexed by ART_xx; - ART_xx values are 1..N, element [0] isn't used */ + ART_xx values are 1..N, element [0] isn't used; no terminator needed */ static struct arti_info artiexist[1 + NROFARTIFACTS]; /* discovery list; for N discovered artifacts, the first N entries are ART_xx values in discovery order, the remaining (NROFARTIFACTS-N) slots are 0 */ @@ -216,6 +216,8 @@ mk_artifact( otmp->oartifact = m; artiexist[m] = zero_artiexist; artiexist[m].exists = 1; + /* default creation reason is 'random'; caller can revise it */ + artiexist[m].rndm = 1; } } else { /* nothing appropriate could be found; return original object */ @@ -365,8 +367,9 @@ nartifact_exist(void) /* * TODO: - * artifact_gift(), artifact_wish(), artifact_named(), and artifact_viadip() - * are nearly identical and should be folded into a single routine. + * artifact_gift(), artifact_wish(), artifact_named(), artifact_viadip(), + * and artifact_bones() are nearly identical and should be folded into a + * single routine. */ /* mark artifact as a divine gift or query if it has been marked as such */ @@ -459,6 +462,28 @@ artifact_viadip( return 0; } +/* mark artifact as coming from a bones file or query if it did */ +int +artifact_bones( + struct obj *otmp, + boolean set) /* True, mark otmp->oartifact as bones */ +{ + int a = otmp->oartifact; + + if (a) { + if (set && !artiexist[a].bones) { + /* clear all bits; most are mutually exclusive */ + artiexist[a] = zero_artiexist; + /* set bones bit and force exists bit back on */ + artiexist[a].bones = 1; + artiexist[a].exists = 1; + /* don't mark artifact from bones as found */ + } + return (int) artiexist[a].bones; /* cast: convert unsigned bitfield */ + } + return 0; +} + boolean spec_ability(struct obj *otmp, unsigned long abil) { @@ -1049,7 +1074,6 @@ discover_artifact(xchar m) for (i = 0; i < NROFARTIFACTS; i++) if (artidisco[i] == 0 || artidisco[i] == m) { artidisco[i] = m; - artiexist[i].found = 1; /* (we expect this to already be set) */ return; } /* there is one slot per artifact, so we should never reach the @@ -1078,6 +1102,7 @@ int disp_artifact_discoveries(winid tmpwin) /* supplied by dodiscover() */ { int i, m, otyp; + const char *algnstr; char buf[BUFSZ]; for (i = 0; i < NROFARTIFACTS; i++) { @@ -1090,13 +1115,50 @@ disp_artifact_discoveries(winid tmpwin) /* supplied by dodiscover() */ putstr(tmpwin, iflags.menu_headings, "Artifacts"); m = artidisco[i]; otyp = artilist[m].otyp; + algnstr = align_str(artilist[m].alignment); + if (!strcmp(algnstr, "unaligned")) + algnstr = "non-aligned"; + Sprintf(buf, " %s [%s %s]", artiname(m), - align_str(artilist[m].alignment), simple_typename(otyp)); + algnstr, simple_typename(otyp)); putstr(tmpwin, 0, buf); } return i; } +/* (wizard mode only) show all artifacts and their flags */ +void +dump_artifact_info(winid tmpwin) +{ + int m; + char buf[BUFSZ], buf2[BUFSZ]; + + putstr(tmpwin, iflags.menu_headings, "Artifacts"); + for (m = 1; m <= NROFARTIFACTS; ++m) { + Sprintf(buf2, "[%s%s%s%s%s%s%s%s]", + /* if any of these are non-zero we expect .exists to be too + so no leading space for it */ + artiexist[m].exists ? "exists" : "", + artiexist[m].found ? " found" : "", + artiexist[m].gift ? " gift" : "", + artiexist[m].wish ? " wish" : "", + artiexist[m].named ? " named" : "", + artiexist[m].viadip ? " viadip" : "", + artiexist[m].rndm ? " random" : "", + artiexist[m].bones ? " bones" : ""); +#if 0 /* 'tmpwin' here is a text window, not a menu */ + if (iflags.menu_tab_sep) + Sprintf(buf, " %s\t%s", artiname(m), buf2); + else +#else + /* "The Platinum Yendorian Express Card" is 35 characters */ + Sprintf(buf, " %-36.36s%s", artiname(m), buf2); +#endif + putstr(tmpwin, 0, buf); + } + return; +} + /* * Magicbane's intrinsic magic is incompatible with normal * enchantment magic. Thus, its effects have a negative diff --git a/src/bones.c b/src/bones.c index f9c56f489..bd9f29573 100644 --- a/src/bones.c +++ b/src/bones.c @@ -71,6 +71,7 @@ resetobjs(struct obj *ochain, boolean restore) free_oname(otmp); } else { artifact_exists(otmp, safe_oname(otmp), TRUE, FALSE); + (void) artifact_bones(otmp, TRUE); } } else if (has_oname(otmp)) { sanitize_name(ONAME(otmp)); diff --git a/src/do_name.c b/src/do_name.c index 3bac70e0b..921bb9490 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1341,7 +1341,7 @@ oname(struct obj *obj, const char *name, unsigned oflgs) if (obj->unpaid) alter_cost(obj, 0L); if (via_naming) { - artifact_named(obj, TRUE); + (void) artifact_named(obj, TRUE); /* violate illiteracy conduct since successfully wrote arti-name */ if (!u.uconduct.literate++) diff --git a/src/fountain.c b/src/fountain.c index dc9d2779a..36830a483 100644 --- a/src/fountain.c +++ b/src/fountain.c @@ -404,7 +404,7 @@ dipfountain(register struct obj *obj) pline("As the hand retreats, the fountain disappears!"); obj = oname(obj, artiname(ART_EXCALIBUR), ONAME_FOUND_ARTI); discover_artifact(ART_EXCALIBUR); - artifact_viadip(obj, TRUE); + (void) artifact_viadip(obj, TRUE); bless(obj); obj->oeroded = obj->oeroded2 = 0; obj->oerodeproof = TRUE; diff --git a/src/o_init.c b/src/o_init.c index e02b2be9d..bea7c6a75 100644 --- a/src/o_init.c +++ b/src/o_init.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 o_init.c $NHDT-Date: 1646953028 2022/03/10 22:57:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.56 $ */ +/* NetHack 3.7 o_init.c $NHDT-Date: 1646950588 2022/03/10 22:16:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.56 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -892,6 +892,15 @@ doclassdisco(void) You(havent_discovered_any, unique_items); break; case 'a': + /* note: this will work all the time for menustyle traditional + but requires at least one artifact discovery for other styles + [could fix that by forcing the 'a' choice into the pick-class + menu when running in wizard mode] */ + if (wizard && yn("Dump information about all artifacts?") == 'y') { + dump_artifact_info(tmpwin); + ct = NROFARTIFACTS; /* non-zero vs zero is what matters below */ + break; + } /* disp_artifact_discoveries() includes a header */ ct = disp_artifact_discoveries(tmpwin); if (!ct) diff --git a/src/pray.c b/src/pray.c index baeda569d..f532566bb 100644 --- a/src/pray.c +++ b/src/pray.c @@ -857,7 +857,7 @@ gcrownu(void) Your("sword shines brightly for a moment."); obj = oname(obj, artiname(ART_EXCALIBUR), ONAME_FOUND_ARTI); if (obj && obj->oartifact == ART_EXCALIBUR) { - artifact_gift(obj, TRUE); /* u.ugifts++; */ + (void) artifact_gift(obj, TRUE); /* u.ugifts++; */ livelog_printf(LL_DIVINEGIFT | LL_ARTIFACT, "wielded %s transformed into %s", lbuf, artiname(ART_EXCALIBUR)); @@ -880,7 +880,7 @@ gcrownu(void) obj->spe = 1; at_your_feet("A sword"); dropy(obj); - artifact_gift(obj, TRUE); /* u.ugifts++; */ + (void) artifact_gift(obj, TRUE); /* u.ugifts++; */ livelog_printf(LL_DIVINEGIFT | LL_ARTIFACT, "bestowed with %s", artiname(ART_VORPAL_BLADE)); } @@ -904,7 +904,7 @@ gcrownu(void) obj->spe = 1; at_your_feet(An(swordbuf)); dropy(obj); - artifact_gift(obj, TRUE); /* u.ugifts++; */ + (void) artifact_gift(obj, TRUE); /* u.ugifts++; */ livelog_printf(LL_DIVINEGIFT | LL_ARTIFACT, "bestowed with %s", artiname(ART_STORMBRINGER)); } @@ -1868,7 +1868,7 @@ dosacrifice(void) at_your_feet(upstart(buf)); dropy(otmp); godvoice(u.ualign.type, "Use my gift wisely!"); - artifact_gift(otmp, TRUE); /* u.ugifts++; */ + (void) artifact_gift(otmp, TRUE); /* u.ugifts++; */ u.ublesscnt = rnz(300 + (50 * nartifacts)); exercise(A_WIS, TRUE); livelog_printf (LL_DIVINEGIFT | LL_ARTIFACT, diff --git a/src/zap.c b/src/zap.c index 2d32b315d..5a340d14a 100644 --- a/src/zap.c +++ b/src/zap.c @@ -5602,7 +5602,7 @@ makewish(void) if (otmp->oartifact) /* update artifact bookkeeping; doesn't produce a livelog event */ - artifact_wish(otmp, TRUE); /* calls found_artifact() */ + (void) artifact_wish(otmp, TRUE); /* calls found_artifact() */ } /* wisharti conduct handled in readobjnam() */