]> granicus.if.org Git - nethack/commitdiff
add Japanese item names to discoveries list
authorPatR <rankin@nethack.org>
Thu, 19 Jan 2023 06:00:57 +0000 (22:00 -0800)
committerPatR <rankin@nethack.org>
Thu, 19 Jan 2023 06:00:57 +0000 (22:00 -0800)
When playing as a Samurai, add things like "osaku" to the discoveries
list even though they don't have separate descriptions to be used
when not yet discovered.  Non-magic ones are pre-discovered and
players can now use the '\' command to figure out what things like
"tanko" mean without resorting to '/?'.

"wooden harp" has been getting changed to "koto (harp)"; make that be
| koto [wooden harp] (koto)
"magic harp" has been staying as "magic harp (harp)"; add it to the
list of Japanese item names.  Since it's magic it isn't pre-discovered.
Once discovered it becomes
| magic koto [magic harp] (koto)

Those two needed special case handling, none of the other items did
aside from forcing them to be discoverable when lacking descriptions.
The discoveries list now has things like
| wakizashi [short sword]
| naginata [glaive] (single-edged polearm)
| gunyoki [food ration]
if--and only if--the hero is a Samurai.

doc/fixes3-7-0.txt
include/extern.h
src/o_init.c
src/objnam.c
src/u_init.c

index 1b57649b2ab2b5512d93b78960e50c46e0a01b22..bc6c2d077ff271f15dbf01f13d798999fc5688c2 100644 (file)
@@ -1931,6 +1931,7 @@ add 'sortvanquished' option to be able to set the preferred sort order without
        using 'm #vanquished' and to have it persist across save/restore
 have 'I u' mention whether there are any unpaid items on the floor (unusual
        but not impossible); it doesn't itemize them or show shop price
+add items given a Japanese name when playing as a Samurai to discoveries list
 
 
 Platform- and/or Interface-Specific New Features
index c1ba30964c50b9b5c3caa9958de1e1266189e91c..cb35482bc771c4d11ad130e78613e936a2164584 100644 (file)
@@ -1977,6 +1977,7 @@ extern char *makeplural(const char *);
 extern char *makesingular(const char *);
 extern struct obj *readobjnam(char *, struct obj *);
 extern int rnd_class(int, int);
+extern const char *Japanese_item_name(int, const char *);
 extern const char *armor_simple_name(struct obj *);
 extern const char *suit_simple_name(struct obj *);
 extern const char *cloak_simple_name(struct obj *);
index 80d4f8f59a4a47583768aa22498e1e24e9d6814c..50526b83720b276ab116376cb57d6112dbe493cc 100644 (file)
@@ -9,6 +9,8 @@ static void setgemprobs(d_level *);
 static void shuffle(int, int, boolean);
 static void shuffle_all(void);
 static int QSORTCALLBACK discovered_cmp(const genericptr, const genericptr);
+static char *sortloot_descr(int, char *);
+static char *disco_typename(int);
 static char *oclass_to_name(char, char *);
 
 #ifdef TILES_IN_GLYPHMAP
@@ -418,10 +420,15 @@ restnames(NHFILE* nhfp)
 }
 
 void
-discover_object(int oindx, boolean mark_as_known, boolean credit_hero)
+discover_object(
+    int oindx,
+    boolean mark_as_known,
+    boolean credit_hero)
 {
-    if (!objects[oindx].oc_name_known) {
-        register int dindx, acls = objects[oindx].oc_class;
+    if (!objects[oindx].oc_name_known
+        || (Role_if(PM_SAMURAI)
+            && Japanese_item_name(oindx, (const char *) 0))) {
+        int dindx, acls = objects[oindx].oc_class;
 
         /* Loop thru disco[] 'til we find the target (which may have been
            uname'd) or the next open slot; one or the other will be found
@@ -432,6 +439,11 @@ discover_object(int oindx, boolean mark_as_known, boolean credit_hero)
                 break;
         gd.disco[dindx] = oindx;
 
+        /* if already known, we forced an item with a Japanese name into
+           disco[] but don't want to exercise wisdom or update perminv */
+        if (objects[oindx].oc_name_known)
+            return;
+
         if (mark_as_known) {
             objects[oindx].oc_name_known = 1;
             if (credit_hero)
@@ -479,6 +491,12 @@ undiscover_object(int oindx)
 boolean
 interesting_to_discover(int i)
 {
+    /* most players who don't speak Japanese manage to figure out what
+       gunyoki, osaku, and so forth mean, but treat them as pre-discovered
+       to be disclosed by '\' */
+    if (Role_if(PM_SAMURAI) && Japanese_item_name(i, (const char *) 0))
+        return TRUE;
+
     /* Pre-discovered objects are now printed with a '*' */
     return (boolean) (objects[i].oc_uname != (char *) 0
                       || (objects[i].oc_name_known
@@ -507,7 +525,7 @@ discovered_cmp(const genericptr v1, const genericptr v2)
 }
 
 static char *
-sortloot_descr(int otyp,char * outbuf)
+sortloot_descr(int otyp, char *outbuf)
 {
     Loot sl_cookie;
     struct obj o;
@@ -601,6 +619,38 @@ choose_disco_sort(
     return n;
 }
 
+/* augment obj_typename() with explanation of Japanese item names */
+static char *
+disco_typename(int otyp)
+{
+    char *result = obj_typename(otyp);
+
+    if (Role_if(PM_SAMURAI) && Japanese_item_name(otyp, (const char *) 0)) {
+        char buf[BUFSZ];
+        const char *actualn = (((otyp != MAGIC_HARP && otyp != WOODEN_HARP)
+                                || objects[otyp].oc_name_known)
+                               ? OBJ_NAME(objects[otyp])
+                               /* undiscovered harp (since wooden harp is
+                                  non-magic so pre-discovered, only applies
+                                  to magic harp and will only be seen if
+                                  magic harp has been 'called' something) */
+                               : "harp");
+
+        if (!actualn) { /* won't happen; used to pacify static analyzer */
+            ;
+        } else if (strstri(result, " called")) {
+            Sprintf(buf, " [%s] called", actualn);
+            (void) strsubst(result, " called", buf);
+        } else if (strstri(result, " (")) {
+            Sprintf(buf, " [%s] (", actualn);
+            (void) strsubst(result, " (", buf);
+        } else {
+            Sprintf(eos(result), " [%s]", actualn);
+        }
+    }
+    return result;
+}
+
 /* the #known command - show discovered object types */
 int
 dodiscovered(void) /* free after Robert Viduya */
@@ -684,7 +734,7 @@ dodiscovered(void) /* free after Robert Viduya */
                 Strcpy(buf,  objects[dis].oc_pre_discovered ? "* " : "  ");
                 if (lootsort)
                     (void) sortloot_descr(dis, &buf[2]);
-                Strcat(buf, obj_typename(dis));
+                Strcat(buf, disco_typename(dis));
 
                 if (!alphabetized && !lootsort)
                     putstr(tmpwin, 0, buf);
@@ -916,7 +966,7 @@ doclassdisco(void)
                 Strcpy(buf,  objects[dis].oc_pre_discovered ? "* " : "  ");
                 if (lootsort)
                     (void) sortloot_descr(dis, &buf[2]);
-                Strcat(buf, obj_typename(dis));
+                Strcat(buf, disco_typename(dis));
 
                 if (!alphabetized && !lootsort)
                     putstr(tmpwin, 0, buf);
@@ -994,7 +1044,7 @@ rename_disco(void)
             any.a_int = dis;
             add_menu(tmpwin, &nul_glyphinfo, &any, 0, 0,
                      ATR_NONE, clr,
-                     obj_typename(dis), MENU_ITEMFLAGS_NONE);
+                     disco_typename(dis), MENU_ITEMFLAGS_NONE);
         }
     }
     if (ct == 0) {
index 617ae751df821b6e048571b8462baad8b636ce00..960247ac32f22313a750e89887f4b7057c757ec5 100644 (file)
@@ -54,7 +54,6 @@ static void readobjnam_parse_charges(struct _readobjnam_data *);
 static int readobjnam_postparse1(struct _readobjnam_data *);
 static int readobjnam_postparse2(struct _readobjnam_data *);
 static int readobjnam_postparse3(struct _readobjnam_data *);
-static const char *Japanese_item_name(int, const char *);
 
 struct Jitem {
     int item;
@@ -81,6 +80,7 @@ static const struct Jitem Japanese_items[] = {
     { GLAIVE, "naginata" },
     { LOCK_PICK, "osaku" },
     { WOODEN_HARP, "koto" },
+    { MAGIC_HARP, "magic koto" },
     { KNIFE, "shito" },
     { PLATE_MAIL, "tanko" },
     { HELMET, "kabuto" },
@@ -177,8 +177,11 @@ obj_typename(int otyp)
     const char *un = ocl->oc_uname;
     int nn = ocl->oc_name_known;
 
-    if (Role_if(PM_SAMURAI))
+    if (Role_if(PM_SAMURAI)) {
         actualn = Japanese_item_name(otyp, actualn);
+        if (otyp == WOODEN_HARP || otyp == MAGIC_HARP)
+            dn = "koto";
+    }
     /* generic items don't have an actual-name; we shouldn't ever be called
        for those; pacify static analyzer without resorting to impossible() */
     if (!actualn)
@@ -518,8 +521,11 @@ xname_flags(
     boolean known, dknown, bknown;
 
     buf = nextobuf() + PREFIX; /* leave room for "17 -3 " */
-    if (Role_if(PM_SAMURAI))
+    if (Role_if(PM_SAMURAI)) {
         actualn = Japanese_item_name(typ, actualn);
+        if (typ == WOODEN_HARP || typ == MAGIC_HARP)
+            dn = "koto";
+    }
     /* generic items don't have an actual-name; we shouldn't ever be called
        for those; pacify static analyzer without resorting to impossible() */
     if (!actualn)
@@ -4966,7 +4972,7 @@ rnd_class(int first, int last)
     return (first == last) ? first : STRANGE_OBJECT;
 }
 
-static const char *
+const char *
 Japanese_item_name(int i, const char *ordinaryname)
 {
     const struct Jitem *j = Japanese_items;
index 0b0895ec22134ca29420c1cade947d377bc75a33..59698c614717526f52fb05b56130a5a298d5470d 100644 (file)
@@ -729,7 +729,9 @@ u_init(void)
         skill_init(Skill_K);
         break;
     case PM_MONK: {
-        static short M_spell[] = { SPE_HEALING, SPE_PROTECTION, SPE_CONFUSE_MONSTER };
+        static short M_spell[] = {
+            SPE_HEALING, SPE_PROTECTION, SPE_CONFUSE_MONSTER
+        };
 
         Monk[M_BOOK].trotyp = M_spell[rn2(90) / 30]; /* [0..2] */
         ini_inv(Monk);
@@ -743,7 +745,7 @@ u_init(void)
         skill_init(Skill_Mon);
         break;
     }
-    case PM_CLERIC:
+    case PM_CLERIC: /* priest/priestess */
         ini_inv(Priest);
         if (!rn2(10))
             ini_inv(Magicmarker);
@@ -783,6 +785,14 @@ u_init(void)
             ini_inv(Blindfold);
         knows_class(WEAPON_CLASS); /* all weapons */
         knows_class(ARMOR_CLASS);
+        /* in order to assist non-Japanese speakers, pre-discover items
+           that switch to Japanese names when playing as a Samurai */
+        for (i = MAXOCLASSES; i < NUM_OBJECTS; ++i) {
+            if (objects[i].oc_magic) /* skip "magic koto" */
+                continue;
+            if (Japanese_item_name(i, (const char *) 0))
+                knows_object(i);
+        }
         skill_init(Skill_S);
         break;
     case PM_TOURIST: