OSDN Git Service

update year to 2018
[jnethack/source.git] / src / role.c
index ffa0cac..915cf6c 100644 (file)
@@ -1,10 +1,11 @@
-/* NetHack 3.6 role.c  $NHDT-Date: 1446861770 2015/11/07 02:02:50 $  $NHDT-Branch: master $:$NHDT-Revision: 1.34 $ */
+/* NetHack 3.6 role.c  $NHDT-Date: 1463561393 2016/05/18 08:49:53 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.38 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985-1999. */
+/*-Copyright (c) Robert Patrick Rankin, 2012. */
 /* NetHack may be freely redistributed.  See license for details. */
 
 /* JNetHack Copyright */
 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
-/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016            */
+/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2018            */
 /* JNetHack may be freely redistributed.  See license for details. */
 
 #include "hack.h"
@@ -1071,7 +1072,7 @@ const struct Align aligns[] = {
 static struct {
     boolean roles[SIZE(roles)];
     short mask;
-} filter;
+} rfilter;
 
 STATIC_DCL int NDECL(randrole_filtered);
 STATIC_DCL char *FDECL(promptsep, (char *, int));
@@ -1352,7 +1353,7 @@ int rolenum, racenum, gendnum, alignnum;
     short allow;
 
     if (rolenum >= 0 && rolenum < SIZE(roles) - 1) {
-        if (filter.roles[rolenum])
+        if (rfilter.roles[rolenum])
             return FALSE;
         allow = roles[rolenum].allow;
         if (racenum >= 0 && racenum < SIZE(races) - 1
@@ -1368,7 +1369,7 @@ int rolenum, racenum, gendnum, alignnum;
     } else {
         /* random; check whether any selection is possible */
         for (i = 0; i < SIZE(roles) - 1; i++) {
-            if (filter.roles[i])
+            if (rfilter.roles[i])
                 continue;
             allow = roles[i].allow;
             if (racenum >= 0 && racenum < SIZE(races) - 1
@@ -1420,7 +1421,7 @@ int rolenum, racenum, gendnum, alignnum;
     short allow;
 
     if (racenum >= 0 && racenum < SIZE(races) - 1) {
-        if (filter.mask & races[racenum].selfmask)
+        if (rfilter.mask & races[racenum].selfmask)
             return FALSE;
         allow = races[racenum].allow;
         if (rolenum >= 0 && rolenum < SIZE(roles) - 1
@@ -1436,7 +1437,7 @@ int rolenum, racenum, gendnum, alignnum;
     } else {
         /* random; check whether any selection is possible */
         for (i = 0; i < SIZE(races) - 1; i++) {
-            if (filter.mask & races[i].selfmask)
+            if (rfilter.mask & races[i].selfmask)
                 continue;
             allow = races[i].allow;
             if (rolenum >= 0 && rolenum < SIZE(roles) - 1
@@ -1454,9 +1455,9 @@ int rolenum, racenum, gendnum, alignnum;
     }
 }
 
-/* pick a random race subject to any rolenum/gendnum/alignnum constraints */
-/* If pickhow == PICK_RIGID a race is returned only if there is  */
-/* a single possibility */
+/* Pick a random race subject to any rolenum/gendnum/alignnum constraints.
+   If pickhow == PICK_RIGID a race is returned only if there is
+   a single possibility. */
 int
 pick_race(rolenum, gendnum, alignnum, pickhow)
 int rolenum, gendnum, alignnum, pickhow;
@@ -1493,7 +1494,7 @@ int alignnum UNUSED;
     short allow;
 
     if (gendnum >= 0 && gendnum < ROLE_GENDERS) {
-        if (filter.mask & genders[gendnum].allow)
+        if (rfilter.mask & genders[gendnum].allow)
             return FALSE;
         allow = genders[gendnum].allow;
         if (rolenum >= 0 && rolenum < SIZE(roles) - 1
@@ -1506,7 +1507,7 @@ int alignnum UNUSED;
     } else {
         /* random; check whether any selection is possible */
         for (i = 0; i < ROLE_GENDERS; i++) {
-            if (filter.mask & genders[i].allow)
+            if (rfilter.mask & genders[i].allow)
                 continue;
             allow = genders[i].allow;
             if (rolenum >= 0 && rolenum < SIZE(roles) - 1
@@ -1562,7 +1563,7 @@ int alignnum;
     short allow;
 
     if (alignnum >= 0 && alignnum < ROLE_ALIGNS) {
-        if (filter.mask & aligns[alignnum].allow)
+        if (rfilter.mask & aligns[alignnum].allow)
             return FALSE;
         allow = aligns[alignnum].allow;
         if (rolenum >= 0 && rolenum < SIZE(roles) - 1
@@ -1575,7 +1576,7 @@ int alignnum;
     } else {
         /* random; check whether any selection is possible */
         for (i = 0; i < ROLE_ALIGNS; i++) {
-            if (filter.mask & aligns[i].allow)
+            if (rfilter.mask & aligns[i].allow)
                 return FALSE;
             allow = aligns[i].allow;
             if (rolenum >= 0 && rolenum < SIZE(roles) - 1
@@ -1590,11 +1591,10 @@ int alignnum;
     }
 }
 
-/* pick a random alignment subject to any rolenum/racenum/gendnum constraints
- */
-/* alignment and gender are not comparable (and also not constrainable) */
-/* If pickhow == PICK_RIGID an alignment is returned only if there is  */
-/* a single possibility */
+/* Pick a random alignment subject to any rolenum/racenum/gendnum constraints;
+   alignment and gender are not comparable (and also not constrainable).
+   If pickhow == PICK_RIGID an alignment is returned only if there is
+   a single possibility. */
 int
 pick_align(rolenum, racenum, gendnum, pickhow)
 int rolenum, racenum, gendnum, pickhow;
@@ -1623,6 +1623,8 @@ int rolenum, racenum, gendnum, pickhow;
 void
 rigid_role_checks()
 {
+    int tmp;
+
     /* Some roles are limited to a single race, alignment, or gender and
      * calling this routine prior to XXX_player_selection() will help
      * prevent an extraneous prompt that actually doesn't allow
@@ -1633,14 +1635,27 @@ rigid_role_checks()
      */
     if (flags.initrole == ROLE_RANDOM) {
         /* If the role was explicitly specified as ROLE_RANDOM
-         * via -uXXXX-@ then choose the role in here to narrow down
-         * later choices. Pick a random role in this case.
+         * via -uXXXX-@ or OPTIONS=role:random then choose the role
+         * in here to narrow down later choices.
          */
         flags.initrole = pick_role(flags.initrace, flags.initgend,
                                    flags.initalign, PICK_RANDOM);
         if (flags.initrole < 0)
             flags.initrole = randrole_filtered();
     }
+    if (flags.initrace == ROLE_RANDOM
+        && (tmp = pick_race(flags.initrole, flags.initgend,
+                            flags.initalign, PICK_RANDOM)) != ROLE_NONE)
+        flags.initrace = tmp;
+    if (flags.initalign == ROLE_RANDOM
+        && (tmp = pick_align(flags.initrole, flags.initrace,
+                             flags.initgend, PICK_RANDOM)) != ROLE_NONE)
+        flags.initalign = tmp;
+    if (flags.initgend == ROLE_RANDOM
+        && (tmp = pick_gend(flags.initrole, flags.initrace,
+                            flags.initalign, PICK_RANDOM)) != ROLE_NONE)
+        flags.initgend = tmp;
+
     if (flags.initrole != ROLE_NONE) {
         if (flags.initrace == ROLE_NONE)
             flags.initrace = pick_race(flags.initrole, flags.initgend,
@@ -1662,13 +1677,13 @@ const char *bufp;
     boolean reslt = TRUE;
 
     if ((i = str2role(bufp)) != ROLE_NONE && i != ROLE_RANDOM)
-        filter.roles[i] = TRUE;
+        rfilter.roles[i] = TRUE;
     else if ((i = str2race(bufp)) != ROLE_NONE && i != ROLE_RANDOM)
-        filter.mask |= races[i].selfmask;
+        rfilter.mask |= races[i].selfmask;
     else if ((i = str2gend(bufp)) != ROLE_NONE && i != ROLE_RANDOM)
-        filter.mask |= genders[i].allow;
+        rfilter.mask |= genders[i].allow;
     else if ((i = str2align(bufp)) != ROLE_NONE && i != ROLE_RANDOM)
-        filter.mask |= aligns[i].allow;
+        rfilter.mask |= aligns[i].allow;
     else
         reslt = FALSE;
     return reslt;
@@ -1679,10 +1694,10 @@ gotrolefilter()
 {
     int i;
 
-    if (filter.mask)
+    if (rfilter.mask)
         return TRUE;
     for (i = 0; i < SIZE(roles); ++i)
-        if (filter.roles[i])
+        if (rfilter.roles[i])
             return TRUE;
     return FALSE;
 }
@@ -1693,8 +1708,8 @@ clearrolefilter()
     int i;
 
     for (i = 0; i < SIZE(roles); ++i)
-        filter.roles[i] = FALSE;
-    filter.mask = 0;
+        rfilter.roles[i] = FALSE;
+    rfilter.mask = 0;
 }
 
 #define BP_ALIGN 0
@@ -1947,7 +1962,11 @@ int buflen, rolenum, racenum, gendnum, alignnum;
 */
     const char *defprompt = "\93K\93\96\82É\83L\83\83\83\89\83N\83^\81[\82ð\91I\82ñ\82Å\82æ\82¢\82Å\82·\82©\81H[ynaq] ";
     int num_post_attribs = 0;
+#if 0 /*JP*/
     char tmpbuf[BUFSZ], *p;
+#else
+    char tmpbuf[BUFSZ];
+#endif
 
     if (buflen < QBUFSZ)
         return (char *) defprompt;
@@ -1988,7 +2007,20 @@ int buflen, rolenum, racenum, gendnum, alignnum;
      * Now append the post attributes to it
      */
     num_post_attribs = post_attribs;
-    if (post_attribs) {
+    if (!num_post_attribs) {
+        /* some constraints might have been mutually exclusive, in which case
+           some prompting that would have been omitted is needed after all */
+        if (flags.initrole == ROLE_NONE && !pa[BP_ROLE])
+            pa[BP_ROLE] = ++post_attribs;
+        if (flags.initrace == ROLE_NONE && !pa[BP_RACE])
+            pa[BP_RACE] = ++post_attribs;
+        if (flags.initalign == ROLE_NONE && !pa[BP_ALIGN])
+            pa[BP_ALIGN] = ++post_attribs;
+        if (flags.initgend == ROLE_NONE && !pa[BP_GEND])
+            pa[BP_GEND] = ++post_attribs;
+        num_post_attribs = post_attribs;
+    }
+    if (num_post_attribs) {
         if (pa[BP_RACE]) {
             (void) promptsep(eos(buf), num_post_attribs);
 /*
@@ -2037,22 +2069,21 @@ plnamesuffix()
     char *sptr, *eptr;
     int i;
 
-#ifdef GENERIC_USERNAMES
-    {
-        /* some generic user names will be ignored in favor of prompting */
-        const char *uptr = GENERIC_USERNAMES;
-
-        i = (int) strlen(plname);
-        if ((sptr = strstri(uptr, plname)) != 0
-            && (sptr == uptr || sptr[-1] == ' ')
-            && (sptr[i] == ' ' || sptr[i] == '\0'))
-            *plname = '\0'; /* call askname() */
+    /* some generic user names will be ignored in favor of prompting */
+    if (sysopt.genericusers) {
+       if (*sysopt.genericusers == '*') *plname = '\0';
+       else {
+           i = (int)strlen(plname);
+           if ((sptr = strstri(sysopt.genericusers, plname)) != 0
+               && (sptr == sysopt.genericusers || sptr[-1] == ' ')
+               && (sptr[i] == ' ' || sptr[i] == '\0'))
+               *plname = '\0'; /* call askname() */
+       }
     }
-#endif
 
     do {
         if (!*plname)
-            askname(); /* fill plname[] if necessary */
+            askname(); /* fill plname[] if necessary, or set defer_plname */
 
         /* Look for tokens delimited by '-' */
         if ((eptr = index(plname, '-')) != (char *) 0)
@@ -2073,7 +2104,7 @@ plnamesuffix()
             else if ((i = str2align(sptr)) != ROLE_NONE)
                 flags.initalign = i;
         }
-    } while (!*plname);
+    } while (!*plname && !iflags.defer_plname);
 
     /* commas in the plname confuse the record file, convert to spaces */
     for (sptr = plname; *sptr; sptr++) {
@@ -2201,9 +2232,10 @@ winid where;
 
 /* add a "pick alignment first"-type entry to the specified menu */
 void
-role_menu_extra(which, where)
+role_menu_extra(which, where, preselect)
 int which;
 winid where;
+boolean preselect;
 {
     static NEARDATA const char RS_menu_let[] = {
         '=',  /* name */
@@ -2233,7 +2265,7 @@ winid where;
         what = "\90E\8bÆ";
         f = r;
         for (i = 0; i < SIZE(roles); ++i)
-            if (i != f && !filter.roles[i])
+            if (i != f && !rfilter.roles[i])
                 break;
         if (i == SIZE(roles)) {
 /*JP
@@ -2264,7 +2296,7 @@ winid where;
                 constrainer = "\90E\8bÆ";
                 forcedvalue = races[c].noun;
             } else if (f >= 0
-                       && (allowmask & ~filter.mask) == races[f].selfmask) {
+                       && (allowmask & ~rfilter.mask) == races[f].selfmask) {
                 /* if there is only one race choice available due to user
                    options disallowing others, race menu entry is disabled */
 /*JP
@@ -2298,7 +2330,7 @@ winid where;
                 constrainer = "\90E\8bÆ";
                 forcedvalue = genders[g].adj;
             } else if (f >= 0
-                       && (allowmask & ~filter.mask) == genders[f].allow) {
+                       && (allowmask & ~rfilter.mask) == genders[f].allow) {
                 /* if there is only one gender choice available due to user
                    options disallowing other, gender menu entry is disabled */
 /*JP
@@ -2348,7 +2380,7 @@ winid where;
                 constrainer = "\8eí\91°";
         }
         if (f >= 0 && !constrainer
-            && (ROLE_ALIGNMASK & ~filter.mask) == aligns[f].allow) {
+            && (ROLE_ALIGNMASK & ~rfilter.mask) == aligns[f].allow) {
             /* if there is only one alignment choice available due to user
                options disallowing others, algn menu entry is disabled */
 /*JP
@@ -2377,7 +2409,7 @@ winid where;
         Sprintf(buf, "%4s%s forces %s", "", constrainer, forcedvalue);
 */
         Sprintf(buf, "%4s\82±\82Ì%s\82Å\82Í%s\82Ì\82Ý", "", constrainer, forcedvalue);
-        add_menu(where, NO_GLYPH, &any, ' ', 0, ATR_NONE, buf,
+        add_menu(where, NO_GLYPH, &any, 0, 0, ATR_NONE, buf,
                  MENU_UNSELECTED);
     } else if (what) {
         any.a_int = RS_menu_arg(which);
@@ -2389,7 +2421,7 @@ winid where;
                  MENU_UNSELECTED);
     } else if (which == RS_filter) {
         any.a_int = RS_menu_arg(RS_filter);
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         add_menu(where, NO_GLYPH, &any, '~', 0, ATR_NONE,
                  "Reset role/race/&c filtering", MENU_UNSELECTED);
 #else
@@ -2398,18 +2430,18 @@ winid where;
 #endif
     } else if (which == ROLE_RANDOM) {
         any.a_int = ROLE_RANDOM;
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         add_menu(where, NO_GLYPH, &any, '*', 0, ATR_NONE, "Random",
-                 MENU_UNSELECTED);
+                 preselect ? MENU_SELECTED : MENU_UNSELECTED);
 #else
         add_menu(where, NO_GLYPH, &any, '*', 0, ATR_NONE, "\83\89\83\93\83_\83\80",
                  MENU_UNSELECTED);
 #endif
     } else if (which == ROLE_NONE) {
         any.a_int = ROLE_NONE;
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         add_menu(where, NO_GLYPH, &any, 'q', 0, ATR_NONE, "Quit",
-                 MENU_UNSELECTED);
+                 preselect ? MENU_SELECTED : MENU_UNSELECTED);
 #else
         add_menu(where, NO_GLYPH, &any, 'q', 0, ATR_NONE, "\94²\82¯\82é",
                  MENU_UNSELECTED);
@@ -2532,7 +2564,10 @@ role_init()
         urole.cgod = roles[flags.pantheon].cgod;
     }
     /* 0 or 1; no gods are neuter, nor is gender randomized */
+/*JP
     quest_status.godgend = !strcmpi(align_gtitle(alignmnt), "goddess");
+*/
+    quest_status.godgend = !strcmpi(align_gtitle(alignmnt), "\8f\97\90_");
 
     /* Fix up infravision */
     if (mons[urace.malenum].mflags3 & M3_INFRAVISION) {