From: PatR Date: Sat, 2 Apr 2022 07:28:48 +0000 (-0700) Subject: wishing for artifacts X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=eea362249c09f5ed1dcf3af5b43500cbdd6180af;p=nethack wishing for artifacts Use 'fuzzymatch(,," -",)' when checking whether the name specified in a player's wish text matches an artifact name so that extra or omitted spaces and dashes are ignored. Wishing for "firebrand" will yield "Fire Brand" and "demon bane" will yield "Demonbane". --- diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 9f276be80..20c399635 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -859,6 +859,8 @@ when teleporting, don't consider pits/spiked pits/trap doors/holes as unsafe try to avoid locations with engraved Elbereth or scare monster scroll when creating new monsters or picking teleport destinations for monsters who are susceptible to those +be more flexible when wishing checks for artifact name matches; now allows + "firebrand" or "fire-brand" to yield "Fire Brand" Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 73c108b8b..ac6a48826 100644 --- a/include/extern.h +++ b/include/extern.h @@ -67,7 +67,7 @@ extern void save_artifacts(NHFILE *); extern void restore_artifacts(NHFILE *); extern const char *artiname(int); extern struct obj *mk_artifact(struct obj *, aligntyp); -extern const char *artifact_name(const char *, short *); +extern const char *artifact_name(const char *, short *, boolean); extern boolean exist_artifact(int, const char *); extern void artifact_exists(struct obj *, const char *, boolean, unsigned); extern void found_artifact(int); diff --git a/src/artifact.c b/src/artifact.c index 7e3ca12a2..7d251ce33 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -234,7 +234,10 @@ mk_artifact( * is non-NULL. */ const char * -artifact_name(const char *name, short *otyp) +artifact_name( + const char *name, /* string from player that might be an artifact name */ + short *otyp_p, /* secondary output */ + boolean fuzzy) /* whether to allow extra or omitted spaces or dashes */ { register const struct artifact *a; register const char *aname; @@ -246,9 +249,10 @@ artifact_name(const char *name, short *otyp) aname = a->name; if (!strncmpi(aname, "the ", 4)) aname += 4; - if (!strcmpi(name, aname)) { - if (otyp) - *otyp = a->otyp; + if (!fuzzy ? !strcmpi(name, aname) + : fuzzymatch(name, aname, " -", TRUE)) { + if (otyp_p) + *otyp_p = a->otyp; return a->name; } } @@ -2147,8 +2151,9 @@ Sting_effects(int orc_count) /* new count (warn_obj_cnt is old count); -1 is a f after undergoing a transformation (alignment change, lycanthropy, polymorph) which might affect item access */ int -retouch_object(struct obj **objp, /* might be destroyed or unintentionally dropped */ - boolean loseit) /* whether to drop it if hero can longer touch it */ +retouch_object( + struct obj **objp, /* might be destroyed or unintentionally dropped */ + boolean loseit) /* whether to drop it if hero can longer touch it */ { struct obj *obj = *objp; @@ -2206,7 +2211,8 @@ retouch_object(struct obj **objp, /* might be destroyed or unintentionally dropp freeinv(obj); hitfloor(obj, TRUE); } else { - /* dropx gives a message iff item lands on an altar */ + /* dropx gives a message if a dropped item lands on an altar; + we provide one for other terrain */ if (!IS_ALTAR(levl[u.ux][u.uy].typ)) pline("%s to the %s.", Tobjnam(obj, "fall"), surface(u.ux, u.uy)); diff --git a/src/do_name.c b/src/do_name.c index b1f0d9ea5..0880333bc 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1269,7 +1269,8 @@ do_oname(register struct obj *obj) */ /* relax restrictions over proper capitalization for artifacts */ - if ((aname = artifact_name(buf, &objtyp)) != 0 && objtyp == obj->otyp) + if ((aname = artifact_name(buf, &objtyp, TRUE)) != 0 + && objtyp == obj->otyp) Strcpy(buf, aname); if (obj->oartifact) { diff --git a/src/end.c b/src/end.c index 6519a8729..6c928dd61 100644 --- a/src/end.c +++ b/src/end.c @@ -1104,7 +1104,6 @@ artifact_score( char pbuf[BUFSZ]; struct obj *otmp; long value, points; - short dummy; /* object type returned by artifact_name() */ for (otmp = list; otmp; otmp = otmp->nobj) { if (otmp->oartifact || otmp->otyp == BELL_OF_OPENING @@ -1120,7 +1119,7 @@ artifact_score( /* assumes artifacts don't have quan > 1 */ Sprintf(pbuf, "%s%s (worth %ld %s and %ld points)", the_unique_obj(otmp) ? "The " : "", - otmp->oartifact ? artifact_name(xname(otmp), &dummy) + otmp->oartifact ? artiname(otmp->oartifact) : OBJ_NAME(objects[otmp->otyp]), value, currency(value), points); putstr(endwin, 0, pbuf); diff --git a/src/objnam.c b/src/objnam.c index 2938ca516..7bf853fc9 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1113,7 +1113,7 @@ doname_base( format the name like the corresponding artifact, which may or may not want "the" prefix and when it doesn't, avoid "a"/"an" prefix too */ fake_arti = (obj->otyp == SLIME_MOLD - && (aname = artifact_name(bp, (short *) 0)) != 0); + && (aname = artifact_name(bp, (short *) 0, FALSE)) != 0); force_the = (fake_arti && !strncmpi(aname, "the ", 4)); prefix[0] = '\0'; @@ -1899,7 +1899,7 @@ the(const char* str) has assigned a capitalized proper name as his/her fruit, unless it matches an artifact name */ || (fruit_from_name(str, TRUE, (int *) 0) - && ((aname = artifact_name(str, (short *) 0)) == 0 + && ((aname = artifact_name(str, (short *) 0, FALSE)) == 0 || strncmpi(aname, "the ", 4) == 0))) { /* not a proper name, needs an article */ insert_the = TRUE; @@ -3890,10 +3890,10 @@ readobjnam_postparse1(struct _readobjnam_data *d) d->bp += 8; } - /* intercept pudding globs here; they're a valid wish target, + /* Intercept pudding globs here; they're a valid wish target, * but we need them to not get treated like a corpse. - * - * also don't let player wish for multiple globs. + * If a count is specified, it will be used to magnify weight + * rather than to specify quantity (which is always 1 for globs). */ i = (int) strlen(d->bp); d->p = (char *) 0; @@ -4415,7 +4415,7 @@ readobjnam_postparse3(struct _readobjnam_data *d) short objtyp; /* Perhaps it's an artifact specified by name, not type */ - d->name = artifact_name(d->actualn, &objtyp); + d->name = artifact_name(d->actualn, &objtyp, TRUE); if (d->name) { d->typ = objtyp; return 2; /*goto typfnd;*/ @@ -4855,22 +4855,18 @@ readobjnam(char *bp, struct obj *no_wish) set_tin_variety(d.otmp, d.tvariety); if (d.name) { - const char *aname; + const char *aname, *novelname; short objtyp; /* an artifact name might need capitalization fixing */ - aname = artifact_name(d.name, &objtyp); + aname = artifact_name(d.name, &objtyp, TRUE); if (aname && objtyp == d.otmp->otyp) d.name = aname; /* 3.6 tribute - fix up novel */ - if (d.otmp->otyp == SPE_NOVEL) { - const char *novelname; - - novelname = lookup_novel(d.name, &d.otmp->novelidx); - if (novelname) - d.name = novelname; - } + if (d.otmp->otyp == SPE_NOVEL + && (novelname = lookup_novel(d.name, &d.otmp->novelidx)) != 0) + d.name = novelname; d.otmp = oname(d.otmp, d.name, ONAME_WISH); /* name==aname => wished for artifact (otmp->oartifact => got it) */