add Japanese item names to discoveries list

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.
This commit is contained in:
PatR
2023-01-18 22:00:57 -08:00
parent bb8656c190
commit 8952ea9bb5
5 changed files with 81 additions and 13 deletions

View 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 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 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 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 Platform- and/or Interface-Specific New Features

View File

@@ -1977,6 +1977,7 @@ extern char *makeplural(const char *);
extern char *makesingular(const char *); extern char *makesingular(const char *);
extern struct obj *readobjnam(char *, struct obj *); extern struct obj *readobjnam(char *, struct obj *);
extern int rnd_class(int, int); 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 *armor_simple_name(struct obj *);
extern const char *suit_simple_name(struct obj *); extern const char *suit_simple_name(struct obj *);
extern const char *cloak_simple_name(struct obj *); extern const char *cloak_simple_name(struct obj *);

View File

@@ -9,6 +9,8 @@ static void setgemprobs(d_level *);
static void shuffle(int, int, boolean); static void shuffle(int, int, boolean);
static void shuffle_all(void); static void shuffle_all(void);
static int QSORTCALLBACK discovered_cmp(const genericptr, const genericptr); 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 *); static char *oclass_to_name(char, char *);
#ifdef TILES_IN_GLYPHMAP #ifdef TILES_IN_GLYPHMAP
@@ -418,10 +420,15 @@ restnames(NHFILE* nhfp)
} }
void 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) { if (!objects[oindx].oc_name_known
register int dindx, acls = objects[oindx].oc_class; || (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 /* 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 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; break;
gd.disco[dindx] = oindx; 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) { if (mark_as_known) {
objects[oindx].oc_name_known = 1; objects[oindx].oc_name_known = 1;
if (credit_hero) if (credit_hero)
@@ -479,6 +491,12 @@ undiscover_object(int oindx)
boolean boolean
interesting_to_discover(int i) 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 '*' */ /* Pre-discovered objects are now printed with a '*' */
return (boolean) (objects[i].oc_uname != (char *) 0 return (boolean) (objects[i].oc_uname != (char *) 0
|| (objects[i].oc_name_known || (objects[i].oc_name_known
@@ -507,7 +525,7 @@ discovered_cmp(const genericptr v1, const genericptr v2)
} }
static char * static char *
sortloot_descr(int otyp,char * outbuf) sortloot_descr(int otyp, char *outbuf)
{ {
Loot sl_cookie; Loot sl_cookie;
struct obj o; struct obj o;
@@ -601,6 +619,38 @@ choose_disco_sort(
return n; 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 */ /* the #known command - show discovered object types */
int int
dodiscovered(void) /* free after Robert Viduya */ dodiscovered(void) /* free after Robert Viduya */
@@ -684,7 +734,7 @@ dodiscovered(void) /* free after Robert Viduya */
Strcpy(buf, objects[dis].oc_pre_discovered ? "* " : " "); Strcpy(buf, objects[dis].oc_pre_discovered ? "* " : " ");
if (lootsort) if (lootsort)
(void) sortloot_descr(dis, &buf[2]); (void) sortloot_descr(dis, &buf[2]);
Strcat(buf, obj_typename(dis)); Strcat(buf, disco_typename(dis));
if (!alphabetized && !lootsort) if (!alphabetized && !lootsort)
putstr(tmpwin, 0, buf); putstr(tmpwin, 0, buf);
@@ -916,7 +966,7 @@ doclassdisco(void)
Strcpy(buf, objects[dis].oc_pre_discovered ? "* " : " "); Strcpy(buf, objects[dis].oc_pre_discovered ? "* " : " ");
if (lootsort) if (lootsort)
(void) sortloot_descr(dis, &buf[2]); (void) sortloot_descr(dis, &buf[2]);
Strcat(buf, obj_typename(dis)); Strcat(buf, disco_typename(dis));
if (!alphabetized && !lootsort) if (!alphabetized && !lootsort)
putstr(tmpwin, 0, buf); putstr(tmpwin, 0, buf);
@@ -994,7 +1044,7 @@ rename_disco(void)
any.a_int = dis; any.a_int = dis;
add_menu(tmpwin, &nul_glyphinfo, &any, 0, 0, add_menu(tmpwin, &nul_glyphinfo, &any, 0, 0,
ATR_NONE, clr, ATR_NONE, clr,
obj_typename(dis), MENU_ITEMFLAGS_NONE); disco_typename(dis), MENU_ITEMFLAGS_NONE);
} }
} }
if (ct == 0) { if (ct == 0) {

View File

@@ -54,7 +54,6 @@ static void readobjnam_parse_charges(struct _readobjnam_data *);
static int readobjnam_postparse1(struct _readobjnam_data *); static int readobjnam_postparse1(struct _readobjnam_data *);
static int readobjnam_postparse2(struct _readobjnam_data *); static int readobjnam_postparse2(struct _readobjnam_data *);
static int readobjnam_postparse3(struct _readobjnam_data *); static int readobjnam_postparse3(struct _readobjnam_data *);
static const char *Japanese_item_name(int, const char *);
struct Jitem { struct Jitem {
int item; int item;
@@ -81,6 +80,7 @@ static const struct Jitem Japanese_items[] = {
{ GLAIVE, "naginata" }, { GLAIVE, "naginata" },
{ LOCK_PICK, "osaku" }, { LOCK_PICK, "osaku" },
{ WOODEN_HARP, "koto" }, { WOODEN_HARP, "koto" },
{ MAGIC_HARP, "magic koto" },
{ KNIFE, "shito" }, { KNIFE, "shito" },
{ PLATE_MAIL, "tanko" }, { PLATE_MAIL, "tanko" },
{ HELMET, "kabuto" }, { HELMET, "kabuto" },
@@ -177,8 +177,11 @@ obj_typename(int otyp)
const char *un = ocl->oc_uname; const char *un = ocl->oc_uname;
int nn = ocl->oc_name_known; int nn = ocl->oc_name_known;
if (Role_if(PM_SAMURAI)) if (Role_if(PM_SAMURAI)) {
actualn = Japanese_item_name(otyp, actualn); 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 /* generic items don't have an actual-name; we shouldn't ever be called
for those; pacify static analyzer without resorting to impossible() */ for those; pacify static analyzer without resorting to impossible() */
if (!actualn) if (!actualn)
@@ -518,8 +521,11 @@ xname_flags(
boolean known, dknown, bknown; boolean known, dknown, bknown;
buf = nextobuf() + PREFIX; /* leave room for "17 -3 " */ buf = nextobuf() + PREFIX; /* leave room for "17 -3 " */
if (Role_if(PM_SAMURAI)) if (Role_if(PM_SAMURAI)) {
actualn = Japanese_item_name(typ, actualn); 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 /* generic items don't have an actual-name; we shouldn't ever be called
for those; pacify static analyzer without resorting to impossible() */ for those; pacify static analyzer without resorting to impossible() */
if (!actualn) if (!actualn)
@@ -4966,7 +4972,7 @@ rnd_class(int first, int last)
return (first == last) ? first : STRANGE_OBJECT; return (first == last) ? first : STRANGE_OBJECT;
} }
static const char * const char *
Japanese_item_name(int i, const char *ordinaryname) Japanese_item_name(int i, const char *ordinaryname)
{ {
const struct Jitem *j = Japanese_items; const struct Jitem *j = Japanese_items;

View File

@@ -729,7 +729,9 @@ u_init(void)
skill_init(Skill_K); skill_init(Skill_K);
break; break;
case PM_MONK: { 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] */ Monk[M_BOOK].trotyp = M_spell[rn2(90) / 30]; /* [0..2] */
ini_inv(Monk); ini_inv(Monk);
@@ -743,7 +745,7 @@ u_init(void)
skill_init(Skill_Mon); skill_init(Skill_Mon);
break; break;
} }
case PM_CLERIC: case PM_CLERIC: /* priest/priestess */
ini_inv(Priest); ini_inv(Priest);
if (!rn2(10)) if (!rn2(10))
ini_inv(Magicmarker); ini_inv(Magicmarker);
@@ -783,6 +785,14 @@ u_init(void)
ini_inv(Blindfold); ini_inv(Blindfold);
knows_class(WEAPON_CLASS); /* all weapons */ knows_class(WEAPON_CLASS); /* all weapons */
knows_class(ARMOR_CLASS); 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); skill_init(Skill_S);
break; break;
case PM_TOURIST: case PM_TOURIST: