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() */