-/* 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"
static struct {
boolean roles[SIZE(roles)];
short mask;
-} filter;
+} rfilter;
STATIC_DCL int NDECL(randrole_filtered);
STATIC_DCL char *FDECL(promptsep, (char *, int));
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
} 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
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
} 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
}
}
-/* 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;
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
} 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
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
} 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
}
}
-/* 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;
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
*/
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,
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;
{
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;
}
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
*/
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;
* 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);
/*
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)
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++) {
/* 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 */
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
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
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
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
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);
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
#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);
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) {