diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 3e711b77c..c7c3be730 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.51 $ $NHDT-Date: 1560185545 2019/06/10 16:52:25 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.54 $ $NHDT-Date: 1560600663 2019/06/15 12:11:03 $ 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, @@ -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 acquires it and zaps/plays it when not in view, remove the hero's memory of the number of charges +for wizard mode 'monpolycontrol', allow usually disallowed type 'chameleon', + 'doppelganger', or 'sandestin' as answer to "change @ + into what?" prompt when is really that type of creature Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository @@ -86,10 +89,17 @@ using ^G to create "hidden mimic" shouldn't have marked it as undetected since for wizard mode 'wizweight' option, glob weight wasn't shown unless glob had shop price information attached curses: sometimes the message window would show a blank line after a prompt +tty: revert the attempt to fix "message line anomaly: if autodecribe feedback + wrapped to second line, the wrapped portion wasn't erased when a + shorter line was shown or getpos was dismissed" because it disrupted + prompts that spanned more than one line, a more significant issue 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 @ into + what kind of monster?" prompt, resulting in "" as default answer 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 enough for more than 62 entries, arbitrary ASCII punctuation got used diff --git a/src/do_name.c b/src/do_name.c index 7f69ce59e..72f91b40f 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do_name.c $NHDT-Date: 1560161806 2019/06/10 10:16:46 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.147 $ */ +/* NetHack 3.6 do_name.c $NHDT-Date: 1560387831 2019/06/13 01:03:51 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.148 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1116,7 +1116,7 @@ char *monnambuf, *usrbuf; STATIC_OVL void do_mname() { - char buf[BUFSZ] = DUMMY, monnambuf[BUFSZ], qbuf[QBUFSZ]; + char buf[BUFSZ], monnambuf[BUFSZ], qbuf[QBUFSZ]; coord cc; int cx, cy; struct monst *mtmp = 0; @@ -1128,9 +1128,9 @@ do_mname() cc.x = u.ux; cc.y = u.uy; if (getpos(&cc, FALSE, "the monster you want to name") < 0 - || (cx = cc.x) < 0) + || !isok(cc.x, cc.y)) return; - cy = cc.y; + cx = cc.x, cy = cc.y; if (cx == u.ux && cy == u.uy) { if (u.usteed && canspotmon(u.usteed)) { @@ -1155,6 +1155,7 @@ do_mname() /* special case similar to the one in lookat() */ Sprintf(qbuf, "What do you want to call %s?", distant_monnam(mtmp, ARTICLE_THE, monnambuf)); + buf[0] = '\0'; getlin(qbuf, buf); if (!*buf || *buf == '\033') return; diff --git a/src/mon.c b/src/mon.c index 508546e4e..f776c073a 100644 --- a/src/mon.c +++ b/src/mon.c @@ -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) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -22,7 +22,7 @@ STATIC_DCL void FDECL(kill_eggs, (struct obj *)); STATIC_DCL int FDECL(pickvampshape, (struct monst *)); STATIC_DCL boolean FDECL(isspecmon, (struct monst *)); 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 void FDECL(m_detach, (struct monst *, struct permonst *)); STATIC_DCL void FDECL(lifesaved_monster, (struct monst *)); @@ -3399,7 +3399,7 @@ int mndx; if (mndx == NON_PM) return TRUE; /* caller wants random */ - if (!accept_newcham_form(mndx)) + if (!accept_newcham_form(mon, mndx)) return FALSE; /* geno'd or !polyok */ if (isspecmon(mon)) { @@ -3438,17 +3438,17 @@ int *mndx_p, monclass; if (!is_vampshifter(mon)) 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)) { /* Vlad with Candelabrum; override choice, then accept it */ *mndx_p = PM_VLAD_THE_IMPALER; 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 (we don't enforce upper-case only for rogue level here) */ if (*mndx_p == PM_WOLF) @@ -3472,7 +3472,7 @@ int *mndx_p, monclass; *mndx_p = PM_WOLF; break; } - /*FALLTHRU*/ + /*FALLTHRU*/ default: *mndx_p = NON_PM; break; @@ -3535,16 +3535,35 @@ struct monst *mon; /* for debugging: allow control of polymorphed monster */ if (wizard && iflags.mon_polycontrol) { - char pprompt[BUFSZ], buf[BUFSZ] = DUMMY; - int monclass; + char pprompt[BUFSZ], parttwo[QBUFSZ], buf[BUFSZ]; + int monclass, len; - Sprintf(pprompt, "Change %s @ %s into what kind of monster?", - noit_mon_nam(mon), + /* construct prompt in pieces */ + Sprintf(pprompt, "Change %s", noit_mon_nam(mon)); + Sprintf(parttwo, " @ %s into what?", coord_desc((int) mon->mx, (int) mon->my, buf, (iflags.getpos_coords != GPCOORDS_NONE) ? 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 { + 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; getlin(pprompt, buf); mungspaces(buf); @@ -3552,7 +3571,7 @@ struct monst *mon; if (*buf == '\033') break; /* 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; break; } @@ -3574,6 +3593,7 @@ struct monst *mon; pline("It can't become that."); } while (--tryct > 0); + if (!tryct) pline1(thats_enough_tries); if (is_vampshifter(mon) && !validvamp(mon, &mndx, monclass)) @@ -3595,7 +3615,8 @@ struct monst *mon; /* this used to be inline within newcham() but monpolycontrol needs it too */ STATIC_OVL struct permonst * -accept_newcham_form(mndx) +accept_newcham_form(mon, mndx) +struct monst *mon; int mndx; { struct permonst *mdat; @@ -3612,6 +3633,11 @@ int mndx; polyok() rejects, so we need a special case here */ if (is_mplayer(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 */ return polyok(mdat) ? mdat : 0; } @@ -3683,7 +3709,7 @@ boolean msg; /* "The oldmon turns into a newmon!" */ tryct = 20; do { 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 the rogue level (after that, we take whatever we get) */ if (tryct > 15 && Is_rogue_level(&u.uz) diff --git a/win/tty/topl.c b/win/tty/topl.c index b409581a9..6d9f464ff 100644 --- a/win/tty/topl.c +++ b/win/tty/topl.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 topl.c $NHDT-Date: 1549333449 2019/02/05 02:24:09 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.44 $ */ +/* NetHack 3.6 topl.c $NHDT-Date: 1560600658 2019/06/15 12:10:58 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.46 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -155,6 +155,11 @@ const char *str; home(); cl_end(); addtopl(str); + +#if 0 /* this doesn't work as intended; it disrupts multi-line prompts */ + if (ttyDisplay->cury && ttyDisplay->toplin != 3) + more(); +#endif } }