EDIT_GETLIN vs monpolycontrol
For wizard mode 'monpolycontrol', the getlin() answer buffer for the "Change <monster> @ <x,y> into what kind of monster?" prompt is also used to format the coordinate portion of that prompt, so when EDIT_GETLIN is enabled getlin() was inadvertently given "<x,y>" to use as default response. Clear it after the prompt is formatted instead of via an initializer. Also, shorten the prompt on the first try: "Change <monster> @ <x,y> into what?", expanding to the old prompt if retry is needed. This also allows specifying 'chameleon' when <monster> is a chameleon, 'doppelganger' when it's a doppelganger, and 'sandestin' when it's one of those (but not 'doppelganger' when it's a chameleon or sandestin, and so forth), instead of blanket refusal to accept any non-vampire shapechanger as the choice.
This commit is contained in:
+7
-1
@@ -1,4 +1,4 @@
|
|||||||
$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.52 $ $NHDT-Date: 1560387439 2019/06/13 00:57:19 $
|
$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.53 $ $NHDT-Date: 1560597210 2019/06/15 11:13:30 $
|
||||||
|
|
||||||
This fixes36.3 file is here to capture information about updates in the 3.6.x
|
This fixes36.3 file is here to capture information about updates in the 3.6.x
|
||||||
lineage following the release of 3.6.2 in May 2019. Please note, however,
|
lineage following the release of 3.6.2 in May 2019. Please note, however,
|
||||||
@@ -73,6 +73,9 @@ don't give feedback for monster zapping a wand if a monster plays a fire horn
|
|||||||
if hero knows the number of charges in a wand or magical horn and a monster
|
if hero knows the number of charges in a wand or magical horn and a monster
|
||||||
acquires it and zaps/plays it when not in view, remove the hero's
|
acquires it and zaps/plays it when not in view, remove the hero's
|
||||||
memory of the number of charges
|
memory of the number of charges
|
||||||
|
for wizard mode 'monpolycontrol', allow usually disallowed type 'chameleon',
|
||||||
|
'doppelganger', or 'sandestin' as answer to "change <monster> @ <x,y>
|
||||||
|
into what?" prompt when <monster> is really that type of creature
|
||||||
|
|
||||||
|
|
||||||
Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository
|
Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository
|
||||||
@@ -90,6 +93,9 @@ curses: sometimes the message window would show a blank line after a prompt
|
|||||||
|
|
||||||
Platform- and/or Interface-Specific Fixes or Features
|
Platform- and/or Interface-Specific Fixes or Features
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
|
EDIT_GETLIN: wizard mode 'monpolycontrol' was using the getlin() answer buffer
|
||||||
|
to format the coordinate portion of the "change <monster> @ <x,y> into
|
||||||
|
what kind of monster?" prompt, resulting in "<x,y>" as default answer
|
||||||
curses: very tall menus tried to use selector characters a-z, A-Z, and 0-9,
|
curses: very tall menus tried to use selector characters a-z, A-Z, and 0-9,
|
||||||
but 0-9 should be reserved for counts and if the display was tall
|
but 0-9 should be reserved for counts and if the display was tall
|
||||||
enough for more than 62 entries, arbitrary ASCII punctuation got used
|
enough for more than 62 entries, arbitrary ASCII punctuation got used
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.6 mon.c $NHDT-Date: 1559733390 2019/06/05 11:16:30 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.292 $ */
|
/* NetHack 3.6 mon.c $NHDT-Date: 1560597210 2019/06/15 11:13:30 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.293 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/*-Copyright (c) Derek S. Ray, 2015. */
|
/*-Copyright (c) Derek S. Ray, 2015. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
@@ -24,7 +24,7 @@ STATIC_DCL void FDECL(kill_eggs, (struct obj *));
|
|||||||
STATIC_DCL int FDECL(pickvampshape, (struct monst *));
|
STATIC_DCL int FDECL(pickvampshape, (struct monst *));
|
||||||
STATIC_DCL boolean FDECL(isspecmon, (struct monst *));
|
STATIC_DCL boolean FDECL(isspecmon, (struct monst *));
|
||||||
STATIC_DCL boolean FDECL(validspecmon, (struct monst *, int));
|
STATIC_DCL boolean FDECL(validspecmon, (struct monst *, int));
|
||||||
STATIC_DCL struct permonst *FDECL(accept_newcham_form, (int));
|
STATIC_DCL struct permonst *FDECL(accept_newcham_form, (struct monst *, int));
|
||||||
STATIC_DCL struct obj *FDECL(make_corpse, (struct monst *, unsigned));
|
STATIC_DCL struct obj *FDECL(make_corpse, (struct monst *, unsigned));
|
||||||
STATIC_DCL void FDECL(m_detach, (struct monst *, struct permonst *));
|
STATIC_DCL void FDECL(m_detach, (struct monst *, struct permonst *));
|
||||||
STATIC_DCL void FDECL(lifesaved_monster, (struct monst *));
|
STATIC_DCL void FDECL(lifesaved_monster, (struct monst *));
|
||||||
@@ -3404,7 +3404,7 @@ int mndx;
|
|||||||
if (mndx == NON_PM)
|
if (mndx == NON_PM)
|
||||||
return TRUE; /* caller wants random */
|
return TRUE; /* caller wants random */
|
||||||
|
|
||||||
if (!accept_newcham_form(mndx))
|
if (!accept_newcham_form(mon, mndx))
|
||||||
return FALSE; /* geno'd or !polyok */
|
return FALSE; /* geno'd or !polyok */
|
||||||
|
|
||||||
if (isspecmon(mon)) {
|
if (isspecmon(mon)) {
|
||||||
@@ -3429,17 +3429,17 @@ int *mndx_p, monclass;
|
|||||||
if (!is_vampshifter(mon))
|
if (!is_vampshifter(mon))
|
||||||
return validspecmon(mon, *mndx_p);
|
return validspecmon(mon, *mndx_p);
|
||||||
|
|
||||||
if (*mndx_p == PM_VAMPIRE || *mndx_p == PM_VAMPIRE_LORD
|
|
||||||
|| *mndx_p == PM_VLAD_THE_IMPALER) {
|
|
||||||
/* player picked some type of vampire; use mon's self */
|
|
||||||
*mndx_p = mon->cham;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
if (mon->cham == PM_VLAD_THE_IMPALER && mon_has_special(mon)) {
|
if (mon->cham == PM_VLAD_THE_IMPALER && mon_has_special(mon)) {
|
||||||
/* Vlad with Candelabrum; override choice, then accept it */
|
/* Vlad with Candelabrum; override choice, then accept it */
|
||||||
*mndx_p = PM_VLAD_THE_IMPALER;
|
*mndx_p = PM_VLAD_THE_IMPALER;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
if (*mndx_p >= LOW_PM && is_shapeshifter(&mons[*mndx_p])) {
|
||||||
|
/* player picked some type of shapeshifter; use mon's self
|
||||||
|
(vampire or chameleon) */
|
||||||
|
*mndx_p = mon->cham;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
/* basic vampires can't become wolves; any can become fog or bat
|
/* basic vampires can't become wolves; any can become fog or bat
|
||||||
(we don't enforce upper-case only for rogue level here) */
|
(we don't enforce upper-case only for rogue level here) */
|
||||||
if (*mndx_p == PM_WOLF)
|
if (*mndx_p == PM_WOLF)
|
||||||
@@ -3463,7 +3463,7 @@ int *mndx_p, monclass;
|
|||||||
*mndx_p = PM_WOLF;
|
*mndx_p = PM_WOLF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*FALLTHRU*/
|
/*FALLTHRU*/
|
||||||
default:
|
default:
|
||||||
*mndx_p = NON_PM;
|
*mndx_p = NON_PM;
|
||||||
break;
|
break;
|
||||||
@@ -3526,16 +3526,35 @@ struct monst *mon;
|
|||||||
|
|
||||||
/* for debugging: allow control of polymorphed monster */
|
/* for debugging: allow control of polymorphed monster */
|
||||||
if (wizard && iflags.mon_polycontrol) {
|
if (wizard && iflags.mon_polycontrol) {
|
||||||
char pprompt[BUFSZ], buf[BUFSZ] = DUMMY;
|
char pprompt[BUFSZ], parttwo[QBUFSZ], buf[BUFSZ];
|
||||||
int monclass;
|
int monclass, len;
|
||||||
|
|
||||||
Sprintf(pprompt, "Change %s @ %s into what kind of monster?",
|
/* construct prompt in pieces */
|
||||||
noit_mon_nam(mon),
|
Sprintf(pprompt, "Change %s", noit_mon_nam(mon));
|
||||||
|
Sprintf(parttwo, " @ %s into what?",
|
||||||
coord_desc((int) mon->mx, (int) mon->my, buf,
|
coord_desc((int) mon->mx, (int) mon->my, buf,
|
||||||
(iflags.getpos_coords != GPCOORDS_NONE)
|
(iflags.getpos_coords != GPCOORDS_NONE)
|
||||||
? iflags.getpos_coords : GPCOORDS_MAP));
|
? iflags.getpos_coords : GPCOORDS_MAP));
|
||||||
tryct = 5;
|
/* combine the two parts, not exceeding QBUFSZ-1 in overall length;
|
||||||
|
if combined length is too long it has to be due to monster's
|
||||||
|
name so we'll chop enough of that off to fit the second part */
|
||||||
|
if ((len = (int) strlen(pprompt) + (int) strlen(parttwo)) >= QBUFSZ)
|
||||||
|
/* strlen(parttwo) is less than QBUFSZ/2 so strlen(pprompt) is
|
||||||
|
more than QBUFSZ/2 and excess amount being truncated can't
|
||||||
|
exceed pprompt's length and back up to before &pprompt[0]) */
|
||||||
|
*(eos(pprompt) - (len - (QBUFSZ - 1))) = '\0';
|
||||||
|
Strcat(pprompt, parttwo);
|
||||||
|
|
||||||
|
buf[0] = '\0'; /* clear buffer for EDIT_GETLIN */
|
||||||
|
#define TRYLIMIT 5
|
||||||
|
tryct = TRYLIMIT;
|
||||||
do {
|
do {
|
||||||
|
if (tryct == TRYLIMIT - 1) { /* first retry */
|
||||||
|
/* change "into what?" to "into what kind of monster?" */
|
||||||
|
if (strlen(pprompt) + sizeof " kind of monster" - 1 < QBUFSZ)
|
||||||
|
Strcpy(eos(pprompt) - 1, " kind of monster?");
|
||||||
|
}
|
||||||
|
#undef TRYLIMIT
|
||||||
monclass = 0;
|
monclass = 0;
|
||||||
getlin(pprompt, buf);
|
getlin(pprompt, buf);
|
||||||
mungspaces(buf);
|
mungspaces(buf);
|
||||||
@@ -3543,7 +3562,7 @@ struct monst *mon;
|
|||||||
if (*buf == '\033')
|
if (*buf == '\033')
|
||||||
break;
|
break;
|
||||||
/* for "*", use NON_PM to pick an arbitrary shape below */
|
/* for "*", use NON_PM to pick an arbitrary shape below */
|
||||||
if (!strcmp(buf, "*") || !strcmp(buf, "random")) {
|
if (!strcmp(buf, "*") || !strcmpi(buf, "random")) {
|
||||||
mndx = NON_PM;
|
mndx = NON_PM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -3565,6 +3584,7 @@ struct monst *mon;
|
|||||||
|
|
||||||
pline("It can't become that.");
|
pline("It can't become that.");
|
||||||
} while (--tryct > 0);
|
} while (--tryct > 0);
|
||||||
|
|
||||||
if (!tryct)
|
if (!tryct)
|
||||||
pline1(thats_enough_tries);
|
pline1(thats_enough_tries);
|
||||||
if (is_vampshifter(mon) && !validvamp(mon, &mndx, monclass))
|
if (is_vampshifter(mon) && !validvamp(mon, &mndx, monclass))
|
||||||
@@ -3586,7 +3606,8 @@ struct monst *mon;
|
|||||||
|
|
||||||
/* this used to be inline within newcham() but monpolycontrol needs it too */
|
/* this used to be inline within newcham() but monpolycontrol needs it too */
|
||||||
STATIC_OVL struct permonst *
|
STATIC_OVL struct permonst *
|
||||||
accept_newcham_form(mndx)
|
accept_newcham_form(mon, mndx)
|
||||||
|
struct monst *mon;
|
||||||
int mndx;
|
int mndx;
|
||||||
{
|
{
|
||||||
struct permonst *mdat;
|
struct permonst *mdat;
|
||||||
@@ -3603,6 +3624,11 @@ int mndx;
|
|||||||
polyok() rejects, so we need a special case here */
|
polyok() rejects, so we need a special case here */
|
||||||
if (is_mplayer(mdat))
|
if (is_mplayer(mdat))
|
||||||
return mdat;
|
return mdat;
|
||||||
|
/* shapeshifters are rejected by polyok() but allow a shapeshifter
|
||||||
|
to take on its 'natural' form */
|
||||||
|
if (is_shapeshifter(mdat)
|
||||||
|
&& mon->cham >= LOW_PM && mdat == &mons[mon->cham])
|
||||||
|
return mdat;
|
||||||
/* polyok() rules out M2_PNAME, M2_WERE, and all humans except Kops */
|
/* polyok() rules out M2_PNAME, M2_WERE, and all humans except Kops */
|
||||||
return polyok(mdat) ? mdat : 0;
|
return polyok(mdat) ? mdat : 0;
|
||||||
}
|
}
|
||||||
@@ -3674,7 +3700,7 @@ boolean msg; /* "The oldmon turns into a newmon!" */
|
|||||||
tryct = 20;
|
tryct = 20;
|
||||||
do {
|
do {
|
||||||
mndx = select_newcham_form(mtmp);
|
mndx = select_newcham_form(mtmp);
|
||||||
mdat = accept_newcham_form(mndx);
|
mdat = accept_newcham_form(mtmp, mndx);
|
||||||
/* for the first several tries we require upper-case on
|
/* for the first several tries we require upper-case on
|
||||||
the rogue level (after that, we take whatever we get) */
|
the rogue level (after that, we take whatever we get) */
|
||||||
if (tryct > 15 && Is_rogue_level(&u.uz)
|
if (tryct > 15 && Is_rogue_level(&u.uz)
|
||||||
|
|||||||
Reference in New Issue
Block a user