diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 1b57649b2..bc6c2d077 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -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 diff --git a/include/extern.h b/include/extern.h index c1ba30964..cb35482bc 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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 *); diff --git a/src/o_init.c b/src/o_init.c index 80d4f8f59..50526b837 100644 --- a/src/o_init.c +++ b/src/o_init.c @@ -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) { diff --git a/src/objnam.c b/src/objnam.c index 617ae751d..960247ac3 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -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; diff --git a/src/u_init.c b/src/u_init.c index 0b0895ec2..59698c614 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -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: