]> granicus.if.org Git - nethack/commitdiff
Fix #436: writing type-named scrolls
authorMichael Meyer <me@entrez.cc>
Fri, 16 Jul 2021 12:16:22 +0000 (08:16 -0400)
committerMichael Meyer <me@entrez.cc>
Tue, 20 Jul 2021 19:03:26 +0000 (15:03 -0400)
When using a marker, it is possible to write a scroll based on the
type-name assigned to it by the user.  Somewhat unintuitively, this
system broke down if the assigned name was identical to the real name of
a scroll type: trying to write a scroll by its previously-assigned name
'scare mon' or 'id' would be guaranteed to succeed, but this wouldn't be
the case if the user-assigned name was 'scare monster' or 'identify'.

Revise dowrite(write.c) to prefer a user-assigned type-name to the
real name of a scroll that isn't already formally known, while
continuing to prefer the real name of an identified scroll to both.

Fixes #436

src/write.c

index 1614735eae179f9ea42f9090fd86a6cc2fb9c05f..20c4ba3bd243e5f6b969696d8b58b1d304065a91 100644 (file)
@@ -179,8 +179,20 @@ dowrite(struct obj *pen)
         if (!OBJ_NAME(objects[i]))
             continue;
 
-        if (!strcmpi(OBJ_NAME(objects[i]), nm))
-            goto found;
+        if (!strcmpi(OBJ_NAME(objects[i]), nm)) {
+            if (objects[i].oc_name_known
+                /* spellbooks can only be written by_name, so no need to
+                   hold out for a 'better' by_descr match */
+                || paper->oclass == SPBOOK_CLASS) {
+                by_descr = FALSE;
+                goto found;
+            } else if (!deferralchance) {
+                /* save item in case there are no better by_descr matches;
+                   don't increment deferralchance so that the first uname
+                   match will always override this */
+                deferred = i;
+            }
+        }
         if (!strcmpi(OBJ_DESCR(objects[i]), nm)) {
             by_descr = TRUE;
             goto found;
@@ -200,15 +212,17 @@ dowrite(struct obj *pen)
              *   and 2/3 chance to keep previous 50:50
              *   choice; so on for higher match counts.
              */
-            && !rn2(++deferralchance))
+            && !rn2(++deferralchance)) {
             deferred = i;
+            /* writing by user-assigned name is same as by description:
+               fails for books, works for scrolls (having an assigned
+               type name guarantees presence on discoveries list) */
+            by_descr = TRUE;
+        }
     }
-    /* writing by user-assigned name is same as by description:
-       fails for books, works for scrolls (having an assigned
-       type name guarantees presence on discoveries list) */
+
     if (deferred) {
         i = deferred;
-        by_descr = TRUE;
         goto found;
     }