]> granicus.if.org Git - nethack/commitdiff
wishing for artifacts
authorPatR <rankin@nethack.org>
Sat, 2 Apr 2022 07:28:48 +0000 (00:28 -0700)
committerPatR <rankin@nethack.org>
Sat, 2 Apr 2022 07:28:48 +0000 (00:28 -0700)
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".

doc/fixes3-7-0.txt
include/extern.h
src/artifact.c
src/do_name.c
src/end.c
src/objnam.c

index 9f276be80108a7fa030fed24212f916f34831c25..20c3996350fc15947e173a6205a1bbe868b5f2f3 100644 (file)
@@ -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
index 73c108b8bb241ce2a2304650b312153fed493a9d..ac6a48826ec1d798b7078a1f1cf8e3aa2179f333 100644 (file)
@@ -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);
index 7e3ca12a29b9388b64f54e9bd397185c96193e51..7d251ce33c578c841dcfe02c7997f61d5298a0b9 100644 (file)
@@ -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));
index b1f0d9ea5abcde82c8b3ffc1074183f5499fb619..0880333bcbdae6d5c589fa3b80ba13356392382e 100644 (file)
@@ -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) {
index 6519a8729911cd4f5dc67b343a85d88ac1d716f6..6c928dd619d0c543389e9275caf603fd3ea919f7 100644 (file)
--- 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);
index 2938ca516403308fce621a4954c4a48bad4a94bf..7bf853fc98cea984f3e268ff0ad465c91db37004 100644 (file)
@@ -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) */