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 *);
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);
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 */
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 */
/*
* 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 */
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)
{
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
disp_artifact_discoveries(winid tmpwin) /* supplied by dodiscover() */
{
int i, m, otyp;
+ const char *algnstr;
char buf[BUFSZ];
for (i = 0; i < NROFARTIFACTS; i++) {
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
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));
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++)
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;
-/* 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. */
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)
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));
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));
}
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));
}
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,
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() */