-/* NetHack 3.7 extern.h $NHDT-Date: 1646838387 2022/03/09 15:06:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1068 $ */
+/* NetHack 3.7 extern.h $NHDT-Date: 1646870811 2022/03/10 00:06:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1069 $ */
/* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */
extern void found_artifact(int);
extern void find_artifact(struct obj *);
extern int nartifact_exist(void);
+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 boolean arti_immune(struct obj *, int);
extern boolean spec_ability(struct obj *, unsigned long);
extern boolean confers_luck(struct obj *);
-/* NetHack 3.7 patchlevel.h $NHDT-Date: 1646451566 2022/03/05 03:39:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.201 $ */
+/* NetHack 3.7 patchlevel.h $NHDT-Date: 1646870832 2022/03/10 00:07:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.202 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2012. */
/* NetHack may be freely redistributed. See license for details. */
* Incrementing EDITLEVEL can be used to force invalidation of old bones
* and save files.
*/
-#define EDITLEVEL 51
+#define EDITLEVEL 52
/*
* Development status possibilities.
-/* NetHack 3.7 artifact.c $NHDT-Date: 1646688062 2022/03/07 21:21:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.181 $ */
+/* NetHack 3.7 artifact.c $NHDT-Date: 1646870837 2022/03/10 00:07:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.182 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
of hit points that will fit in a 15 bit integer. */
#define FATAL_DAMAGE_MODIFIER 200
-/* artifact tracking */
+/* artifact tracking; gift and wish imply found; it also gets set for items
+ seen on the floor, in containers, and wielded or dropped by monsters */
struct arti_info {
Bitfield(exists, 1); /* True if corresponding artifact has been created */
Bitfield(found, 1); /* True if artifact is known by hero to exist */
+ Bitfield(gift, 1); /* True if artifact was created as a prayer reward */
+ Bitfield(wish, 1); /* True if artifact was created via wish */
+ Bitfield(named, 1); /* True if artifact was made by naming an item */
+ Bitfield(viadip, 1); /* True if dipped long sword became Excalibur */
+ Bitfield(rndm, 1); /* randomly generated; not (yet?) implemented */
+ 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 */
* bulk re-init if game restart ever gets implemented. They are saved
* and restored but that is done through this file so they can be local.
*/
+static const struct arti_info zero_artiexist; /* all bits zero */
static void hack_artifacts(void);
static boolean attacks(int, struct obj *);
if (otmp) {
otmp = oname(otmp, a->name, ONAME_NO_FLAGS);
otmp->oartifact = m;
+ artiexist[m] = zero_artiexist;
artiexist[m].exists = 1;
- artiexist[m].found = 0;
}
} else {
/* nothing appropriate could be found; return original object */
return FALSE;
}
+/* an artifact has just been created or is being "un-created" for a chance
+ to be created again later */
void
artifact_exists(
struct obj *otmp,
const char *name,
- boolean mod, /* True: exists, False: being uncreated */
+ boolean mod, /* True: exists, False: being un-created */
boolean knwn) /* True: hero knows it exists */
{
register const struct artifact *a;
otmp->age = 0;
if (otmp->otyp == RIN_INCREASE_DAMAGE)
otmp->spe = 0;
+ /* clear all the flag bits, then maybe set a couple of them */
+ artiexist[m] = zero_artiexist;
artiexist[m].exists = mod ? 1 : 0;
artiexist[m].found = (mod && knwn) ? 1 : 0;
break;
void
found_artifact(int a)
{
- artiexist[a].found = 1;
+ if (a < 1 || a > NROFARTIFACTS)
+ impossible("found_artifact: invalid artifact index! (%d)", a);
+ else if (!artiexist[a].exists)
+ impossible("found_artifact: artifact doesn't exist yet? (%d)", a);
+ else
+ artiexist[a].found = 1;
}
/* if an artifact hasn't already been designated 'found', do that now
int a = otmp->oartifact;
if (a && !artiexist[a].found) {
- char buf[BUFSZ];
const char *where;
found_artifact(a); /* artiexist[a].found = 1 */
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);
+ livelog_printf(LL_ARTIFACT, "found %s%s",
+ bare_artifactname(otmp), where);
}
}
return a;
}
+/*
+ * TODO:
+ * artifact_gift(), artifact_wish(), artifact_named(), and artifact_viadip()
+ * 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 */
+int
+artifact_gift(
+ struct obj *otmp,
+ boolean set) /* True, mark otmp->oartifact as gift; False, ask if it is */
+{
+ int a = otmp->oartifact;
+
+ if (a) {
+ if (set && !artiexist[a].gift) {
+ /* clear all bits; most are mutually exclusive */
+ artiexist[a] = zero_artiexist;
+ /* set gift bit and force exists bit back on */
+ artiexist[a].gift = 1;
+ artiexist[a].exists = 1;
+ found_artifact(a); /* assume hero is aware of the gift... */
+
+ u.ugifts++; /* used to be done at several places in pray.c */
+ }
+ return (int) artiexist[a].gift; /* cast: convert unsigned bitfield */
+ }
+ return 0;
+}
+
+/* mark artifact as a player wish or query if it has been marked as such */
+int
+artifact_wish(
+ struct obj *otmp,
+ boolean set) /* True, mark otmp->oartifact as wish; False, ask if it is */
+{
+ int a = otmp->oartifact;
+
+ if (a) {
+ if (set && !artiexist[a].wish) {
+ /* clear all bits; most are mutually exclusive */
+ artiexist[a] = zero_artiexist;
+ /* set wish bit and force exists bit back on */
+ artiexist[a].wish = 1;
+ artiexist[a].exists = 1;
+ found_artifact(a); /* assume hero is aware of wish outcome */
+ }
+ return (int) artiexist[a].wish; /* cast: convert unsigned bitfield */
+ }
+ return 0;
+}
+
+/* mark artifact as created via naming or query if it is marked as such */
+int
+artifact_named(
+ struct obj *otmp,
+ boolean set) /* True, mark otmp->oartifact as named */
+{
+ int a = otmp->oartifact;
+
+ if (a) {
+ if (set && !artiexist[a].named) {
+ /* clear all bits; most are mutually exclusive */
+ artiexist[a] = zero_artiexist;
+ /* set named bit and force exists bit back on */
+ artiexist[a].named = 1;
+ artiexist[a].exists = 1;
+ found_artifact(a); /* hero should be aware of naming outcome */
+ }
+ return (int) artiexist[a].named; /* cast: convert unsigned bitfield */
+ }
+ return 0;
+}
+
+/* mark artifact as created via dipping or query if it is marked as such */
+int
+artifact_viadip(
+ struct obj *otmp,
+ boolean set) /* True, mark otmp->oartifact as viadip */
+{
+ int a = otmp->oartifact;
+
+ if (a) {
+ if (set && !artiexist[a].viadip) {
+ /* clear all bits; most are mutually exclusive */
+ artiexist[a] = zero_artiexist;
+ /* set viadip bit and force exists bit back on */
+ artiexist[a].viadip = 1;
+ artiexist[a].exists = 1;
+ found_artifact(a); /* hero is aware of dip outcome */
+ }
+ return (int) artiexist[a].viadip; /* cast: convert unsigned bitfield */
+ }
+ return 0;
+}
+
boolean
spec_ability(struct obj *otmp, unsigned long abil)
{
-/* NetHack 3.7 do_name.c $NHDT-Date: 1644347168 2022/02/08 19:06:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.231 $ */
+/* NetHack 3.7 do_name.c $NHDT-Date: 1646870842 2022/03/10 00:07:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.239 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Pasi Kallinen, 2018. */
/* NetHack may be freely redistributed. See license for details. */
if (obj->unpaid)
alter_cost(obj, 0L);
if (via_naming) {
+ artifact_named(obj, TRUE);
+
/* violate illiteracy conduct since successfully wrote arti-name */
if (!u.uconduct.literate++)
livelog_printf(LL_CONDUCT | LL_ARTIFACT,
-/* NetHack 3.7 fountain.c $NHDT-Date: 1596498170 2020/08/03 23:42:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.69 $ */
+/* NetHack 3.7 fountain.c $NHDT-Date: 1646870844 2022/03/10 00:07:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.78 $ */
/* Copyright Scott R. Turner, srt@ucla, 10/27/86 */
/* NetHack may be freely redistributed. See license for details. */
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);
bless(obj);
obj->oeroded = obj->oeroded2 = 0;
obj->oerodeproof = TRUE;
-/* NetHack 3.7 pray.c $NHDT-Date: 1646838389 2022/03/09 15:06:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.163 $ */
+/* NetHack 3.7 pray.c $NHDT-Date: 1646870846 2022/03/10 00:07:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.164 $ */
/* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */
/* NetHack may be freely redistributed. See license for details. */
s_suffix(mon_nam(u.ustuck)), mbodypart(u.ustuck, STOMACH));
} else {
pline("%s %s %s your %s!", str,
- Blind ? "lands" : vtense(str, "appear"),
- Levitation ? "beneath" : "at", makeplural(body_part(FOOT)));
+ vtense(str, Blind ? "land" : "appear"),
+ Levitation ? "beneath" : "at",
+ makeplural(body_part(FOOT)));
}
}
* even if hero doesn't know book */
bless(obj);
obj->bknown = 1; /* ok to skip set_bknown() */
- at_your_feet("A spellbook");
+ obj->dknown = 1;
+ at_your_feet(upstart(ansimpleoname(obj)));
dropy(obj);
- u.ugifts++;
+ u.ugifts++; /* bypass artifact_gift() */
/* not an artifact, but treat like one for this situation;
classify as a spoiler in case player hasn't IDed the book yet */
livelog_printf(LL_DIVINEGIFT | LL_ARTIFACT | LL_SPOILER,
Your("sword shines brightly for a moment.");
obj = oname(obj, artiname(ART_EXCALIBUR), ONAME_FOUND_ARTI);
if (obj && obj->oartifact == ART_EXCALIBUR) {
- u.ugifts++;
+ 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);
- u.ugifts++;
+ 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);
- u.ugifts++;
+ artifact_gift(obj, TRUE); /* u.ugifts++; */
livelog_printf(LL_DIVINEGIFT | LL_ARTIFACT,
"bestowed with %s", artiname(ART_STORMBRINGER));
}
if (otmp->otyp == SPE_BLANK_PAPER || !rn2(100))
makeknown(otmp->otyp);
bless(otmp);
- /* note: Hallucination case can't happen because we only get
- called for a boon and boons are only bestowed if all troubles
- (including hallucination) have been cured/repaired; might
- apply in variants that offer "always high" as a play option
- and classify hallucinating as not trouble or not fixable */
- at_your_feet(Hallucination ? "A thesarus"
- : Blind ? "A spellbook"
- /* "An orange spellbook" or "A spellbook of knock"
- depending on discoveries */
- : upstart(ansimpleoname(otmp)));
+ at_your_feet(upstart(ansimpleoname(otmp)));
place_object(otmp, u.ux, u.uy);
newsym(u.ux, u.uy);
}
&& !rn2(10 + (2 * u.ugifts * nartifacts))) {
otmp = mk_artifact((struct obj *) 0, a_align(u.ux, u.uy));
if (otmp) {
+ char buf[BUFSZ];
+
if (otmp->spe < 0)
otmp->spe = 0;
if (otmp->cursed)
uncurse(otmp);
otmp->oerodeproof = TRUE;
- at_your_feet("An object");
+ Strcpy(buf, (Hallucination ? "a doodad"
+ : Blind ? "an object"
+ : ansimpleoname(otmp)));
+ if (!Blind)
+ Sprintf(eos(buf), " named %s",
+ bare_artifactname(otmp));
+ at_your_feet(upstart(buf));
dropy(otmp);
godvoice(u.ualign.type, "Use my gift wisely!");
- u.ugifts++;
+ artifact_gift(otmp, TRUE); /* u.ugifts++; */
u.ublesscnt = rnz(300 + (50 * nartifacts));
exercise(A_WIS, TRUE);
livelog_printf (LL_DIVINEGIFT | LL_ARTIFACT,
-/* NetHack 3.7 zap.c $NHDT-Date: 1646652775 2022/03/07 11:32:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.401 $ */
+/* NetHack 3.7 zap.c $NHDT-Date: 1646870848 2022/03/10 00:07:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.402 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
struct obj *otmp, nothing;
long maybe_LL_arti;
int tries = 0;
- int prev_artwish = u.uconduct.wisharti;
+ int oldwisharti = u.uconduct.wisharti;
promptbuf[0] = '\0';
nothing = cg.zeroobj; /* lint suppression; only its address matters */
return;
}
- if (otmp->oartifact)
- /* update artifact bookkeeping; doesn't produce a livelog event */
- found_artifact(otmp->oartifact);
+ if (otmp != &cg.zeroobj) {
+ /* treat as if seen up close even if hero is blind and hasn't
+ touched it yet */
+ otmp->dknown = 1;
+
+ if (otmp->oartifact)
+ /* update artifact bookkeeping; doesn't produce a livelog event */
+ artifact_wish(otmp, TRUE); /* calls found_artifact() */
+ }
- maybe_LL_arti = ((prev_artwish < u.uconduct.wisharti) ? LL_ARTIFACT : 0L);
+ /* wisharti conduct handled in readobjnam() */
+ maybe_LL_arti = ((oldwisharti < u.uconduct.wisharti) ? LL_ARTIFACT : 0L);
/* KMH, conduct */
if (!u.uconduct.wishes++)
livelog_printf((LL_CONDUCT | LL_WISH | maybe_LL_arti),
"made %s first wish - \"%s\"", uhis(), bufcpy);
- else if (!prev_artwish && u.uconduct.wisharti) /* wisharti conduct handled
- * in readobjnam() above */
+ else if (!oldwisharti && u.uconduct.wisharti)
livelog_printf((LL_CONDUCT | LL_WISH | LL_ARTIFACT),
"made %s first artifact wish - \"%s\"", uhis(), bufcpy);
else
livelog_printf((LL_WISH | maybe_LL_arti),
"wished for \"%s\"", bufcpy);
+ /* TODO? maybe generate a second event decribing what was received since
+ those just echo player's request rather than show actual result */
if (otmp != &cg.zeroobj) {
const char