diff --git a/Files b/Files index f2bb266aa..0e6674eec 100644 --- a/Files +++ b/Files @@ -226,11 +226,24 @@ mdgrep.pl panic.c recover.c dgn_comp.l dgn_comp.y lev_comp.l lev_comp.y win/Qt: -(files for the Qt widget library - X11, Windows, Mac OS X, or Qtopia) +(files for the Qt 3 widget library - X11, Windows, Mac OS X, or Qtopia) Info.plist Install.Qt knethack.lnk knh-mini.xpm knh.xpm nhicns.uu nhsplash.xpm qt_clust.cpp qt_win.cpp qttableview.cpp tileedit.cpp tileedit.h qpe-nethack.control +win/Qt4: +(files for the Qt 4 widget library - X11, Windows, Mac OS X) +qt4bind.cpp qt4bind.h qt4click.cpp qt4click.h qt4clust.cpp +qt4clust.h qt4delay.cpp qt4delay.h qt4glyph.cpp qt4glyph.h +qt4icon.cpp qt4icon.h qt4inv.cpp qt4inv.h qt4kde0.h +qt4key.cpp qt4key.h qt4line.cpp qt4line.h qt4main.cpp +qt4main.h qt4map.cpp qt4map.h qt4menu.cpp qt4menu.h +qt4msg.cpp qt4msg.h qt4plsel.cpp qt4plsel.h qt4rip.cpp +qt4rip.h qt4set.cpp qt4set.h qt4stat.cpp qt4stat.h +qt4str.cpp qt4streq.cpp qt4streq.h qt4str.h qt4svsel.cpp +qt4svsel.h qt4win.cpp qt4win.h qt4xcmd.cpp qt4xcmd.h +qt4yndlg.cpp qt4yndlg.h + win/X11: (files for X versions) Install.X11 NetHack.ad Window.c dialogs.c ibm.bdf @@ -287,7 +300,7 @@ tiles.mak winMS.h winhack.c winhack.rc win/win32/vs2015: (files for Visual Studio 2015 Express Edition builds) -afterdgncomp.proj afterdlb.proj afterlevcomp.proj aftermakedefs.proj +afterdgncomp.proj afterdlb.proj afterlevcomp.proj aftermakedefs.proj afternethack.proj afterrecover.proj aftertile2bmp.proj aftertilemap.proj afteruudecode.proj build.bat common.props config.props console.props default.props default_dll.props dgncomp.vcxproj @@ -389,7 +402,7 @@ uudecode.exe DEVEL: (files for people developing changes to NetHack) -code_features.txt code_style.txt Developer.txt git_recipes.txt +code_features.txt code_style.txt Developer.txt git_recipes.txt nhgitset.pl DEVEL/DOTGIT: diff --git a/doc/fixes36.1 b/doc/fixes36.1 index bb8c17505..f48947ce9 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -521,6 +521,17 @@ prayer boon of 'fix all troubles' could get stuck in an infinite loop for TROUBLE_STUCK_IN_WALL if there was no spot to teleport into available It shouldn't be considered hypocrisy if you speed up your pet while standing on Elbereth +fix 'object lost' panic if hero with lycanthropy but in human form is wielding + a potion of unholy water which gets boiled/exploded by fire, causing + were-transformation and drop of wielded weapon +prevent segfault if pline() is called recursively (which could happen if the + interface code issues a debugpline() while processing putstr()) +open at yourself is the same as #loot +when #force reports that a chest's lock is already broken or already unlocked, + force it to be described as "a chest", even when its lock state is + already known, rather than as "a broken chest" or "an unlocked chest" +honor wish for "locked", "unlocked", or "broken" chest or box +honor wish for "empty" container including statue, bag-o-tricks, horn-o-plenty Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository @@ -602,6 +613,7 @@ when clairvoyance lets you move the cursor to examine the map (if it occurs monster), the "for instructions type '?'" prompt could be confusing prevent Mjollnir from being auto-quivered if it's been thrown without return and then picked back up while quiver slot is empty +plural of "fox" is not "foxen" Platform- and/or Interface-Specific Fixes @@ -735,7 +747,7 @@ swallowers can't re-engulf hero immediately after spitting him/her out werejackals can summon foxes and coyotes; werewolves can summon wargs allow taming monkeys and apes with bananas GENERICUSERS is now a sysconf statement instead of compile-time option -fountains are bright blue +fountains are bright blue, graves are white ray bounceback chance depends on the wall type undead #turning takes less time at higher experience level peacefuls may react when you attack other peacefuls diff --git a/src/drawing.c b/src/drawing.c index 88bc26750..d81ffa2c9 100644 --- a/src/drawing.c +++ b/src/drawing.c @@ -166,7 +166,7 @@ const struct symdef defsyms[MAXPCHARS] = { { '<', "ladder up", C(CLR_BROWN) }, /* upladder */ { '>', "ladder down", C(CLR_BROWN) }, /* dnladder */ { '_', "altar", C(CLR_GRAY) }, /* altar */ - { '|', "grave", C(CLR_GRAY) }, /* grave */ + { '|', "grave", C(CLR_WHITE) }, /* grave */ { '\\', "opulent throne", C(HI_GOLD) }, /* throne */ /*30*/ { '#', "sink", C(CLR_GRAY) }, /* sink */ { '{', "fountain", C(CLR_BRIGHT_BLUE) }, /* fountain */ diff --git a/src/end.c b/src/end.c index 427f4501c..322ab4636 100644 --- a/src/end.c +++ b/src/end.c @@ -1301,7 +1301,8 @@ int how; for normal end of game, genocide doesn't either */ if (how <= GENOCIDED) { dump_redirect(TRUE); - genl_outrip(0, how, endtime); + if (iflags.in_dumplog) + genl_outrip(0, how, endtime); dump_redirect(FALSE); } #endif @@ -1382,7 +1383,8 @@ int how; artifact_score(invent, FALSE, endwin); /* list artifacts */ #ifdef DUMPLOG dump_redirect(TRUE); - artifact_score(invent, FALSE, 0); + if (iflags.in_dumplog) + artifact_score(invent, FALSE, 0); dump_redirect(FALSE); #endif diff --git a/src/lock.c b/src/lock.c index 426e8a35f..9de1e29c5 100644 --- a/src/lock.c +++ b/src/lock.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 lock.c $NHDT-Date: 1446955300 2015/11/08 04:01:40 $ $NHDT-Branch: master $:$NHDT-Revision: 1.67 $ */ +/* NetHack 3.6 lock.c $NHDT-Date: 1521499715 2018/03/19 22:48:35 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.80 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -549,8 +549,13 @@ doforce() for (otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere) if (Is_box(otmp)) { if (otmp->obroken || !otmp->olocked) { - There("is %s here, but its lock is already %s.", doname(otmp), - otmp->obroken ? "broken" : "unlocked"); + /* force doname() to omit known "broken" or "unlocked" + prefix so that the message isn't worded redundantly; + since we're about to set lknown, there's no need to + remember and then reset its current value */ + otmp->lknown = 0; + There("is %s here, but its lock is already %s.", + doname(otmp), otmp->obroken ? "broken" : "unlocked"); otmp->lknown = 1; continue; } @@ -630,8 +635,9 @@ int x, y; } else if (!get_adjacent_loc((char *) 0, (char *) 0, u.ux, u.uy, &cc)) return 0; + /* open at yourself/up/down */ if ((cc.x == u.ux) && (cc.y == u.uy)) - return 0; + return doloot(); if (stumble_on_door_mimic(cc.x, cc.y)) return 1; diff --git a/src/objnam.c b/src/objnam.c index 90c96e156..5eb969e42 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 objnam.c $NHDT-Date: 1471112245 2016/08/13 18:17:25 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.178 $ */ +/* NetHack 3.6 objnam.c $NHDT-Date: 1521507553 2018/03/20 00:59:13 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.199 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -22,6 +22,7 @@ STATIC_DCL boolean FDECL(singplur_lookup, (char *, char *, BOOLEAN_P, const char *const *)); STATIC_DCL char *FDECL(singplur_compound, (char *)); STATIC_DCL char *FDECL(xname_flags, (struct obj *, unsigned)); +STATIC_DCL boolean FDECL(badman, (const char *, BOOLEAN_P)); struct Jitem { int item; @@ -2042,10 +2043,11 @@ static struct sing_plur one_off[] = { { "nemesis", "nemeses" }, { "ovum", "ova" }, { "ox", "oxen" }, + { "passerby", "passersby" }, { "rtex", "rtices" }, /* vortex */ - { "tooth", "teeth" }, { "serum", "sera" }, { "staff", "staves" }, + { "tooth", "teeth" }, { 0, 0 } }; @@ -2054,19 +2056,18 @@ static const char *const as_is[] = { "boots", "shoes", "gloves", "lenses", "scales", "eyes", "gauntlets", "iron bars", /* both singular and plural are spelled the same */ - "deer", "elk", "fish", "tuna", "yaki", - "-hai", "krill", "manes", "moose", "ninja", - "sheep", "ronin", "roshi", "shito", "tengu", - "ki-rin", "Nazgul", "gunyoki", "piranha", "samurai", - "shuriken", 0, + "bison", "deer", "elk", "fish", "fowl", + "tuna", "yaki", "-hai", "krill", "manes", + "moose", "ninja", "sheep", "ronin", "roshi", + "shito", "tengu", "ki-rin", "Nazgul", "gunyoki", + "piranha", "samurai", "shuriken", 0, /* Note: "fish" and "piranha" are collective plurals, suitable for "wiped out all ". For "3 ", they should be "fishes" and "piranhas" instead. We settle for collective variant instead of attempting to support both. */ }; -/* singularize/pluralize decisions common to both makesingular & makeplural - */ +/* singularize/pluralize decisions common to both makesingular & makeplural */ STATIC_OVL boolean singplur_lookup(basestr, endstring, to_plural, alt_as_is) char *basestr, *endstring; /* base string, pointer to eos(string) */ @@ -2090,16 +2091,35 @@ const char *const *alt_as_is; /* another set like as_is[] */ } } - /* avoid false hit on one_off[].plur == "lice"; + /* avoid false hit on one_off[].plur == "lice" or .sing == "goose"; if more of these turn up, one_off[] entries will need to flagged as to which are whole words and which are matchable as suffices then matching in the loop below will end up becoming more complex */ if (!strcmpi(basestr, "slice") || !strcmpi(basestr, "mongoose")) { if (to_plural) - (void) strkitten(basestr, 's'); + Strcasecpy(endstring, "s"); return TRUE; } + /* skip "ox" -> "oxen" entry when pluralizing "ox" + unless it is muskox */ + if (to_plural && strlen(basestr) > 2 && !strcmpi(endstring - 2, "ox") + && strcmpi(endstring - 6, "muskox")) { + /* "fox" -> "foxes" */ + Strcasecpy(endstring, "es"); + return TRUE; + } + if (to_plural) { + if (!strcmpi(endstring - 3, "man") + && badman(basestr, to_plural)) { + Strcasecpy(endstring, "s"); + return TRUE; + } + } else { + if (!strcmpi(endstring - 3, "men") + && badman(basestr, to_plural)) + return TRUE; + } for (sp = one_off; sp->sing; sp++) { /* check whether endstring already matches */ same = to_plural ? sp->plur : sp->sing; @@ -2209,7 +2229,7 @@ const char *oldstr; spot--; while (spot > str && *spot == ' ') spot--; /* Strip blanks from end */ - *(spot + 1) = 0; + *(spot + 1) = '\0'; /* Now spot is the last character of the string */ len = strlen(str); @@ -2224,7 +2244,6 @@ const char *oldstr; { static const char *const already_plural[] = { "ae", /* algae, larvae, &c */ - "men", /* also catches women, watchmen */ "matzot", 0, }; @@ -2240,9 +2259,8 @@ const char *oldstr; /* man/men ("Wiped out all cavemen.") */ if (len >= 3 && !strcmpi(spot - 2, "man") - /* exclude shamans and humans */ - && (len < 6 || strcmpi(spot - 5, "shaman")) - && (len < 5 || strcmpi(spot - 4, "human"))) { + /* exclude shamans and humans etc */ + && !badman(str, TRUE)) { Strcasecpy(spot - 1, "en"); goto bottom; } @@ -2417,7 +2435,8 @@ const char *oldstr; } else { /* input doesn't end in 's' */ - if (!BSTRCMPI(bp, p - 3, "men")) { + if (!BSTRCMPI(bp, p - 3, "men") + && !badman(bp, FALSE)) { Strcasecpy(p - 2, "an"); goto bottom; } @@ -2444,6 +2463,54 @@ bottom: return bp; } +boolean +badman(basestr, to_plural) +const char *basestr; +boolean to_plural; /* true => makeplural, false => makesingular */ +{ + int i, al; + char *endstr, *spot; + /* these are all the prefixes for *man that don't have a *men plural */ + const char *no_men[] = { + "albu", "antihu", "anti", "ata", "auto", "bildungsro", "cai", "cay", + "ceru", "corner", "decu", "des", "dura", "fir", "hanu", "het", + "infrahu", "inhu", "nonhu", "otto", "out", "prehu", "protohu", + "subhu", "superhu", "talis", "unhu", "sha", + "hu", "un", "le", "re", "so", "to", "at", "a", + }; + /* these are all the prefixes for *men that don't have a *man singular */ + const char *no_man[] = { + "abdo", "acu", "agno", "ceru", "cogno", "cycla", "fleh", "grava", + "hegu", "preno", "sonar", "speci", "dai", "exa", "fla", "sta", "teg", + "tegu", "vela", "da", "hy", "lu", "no", "nu", "ra", "ru", "se", "vi", "ya", + "o", "a", + }; + + if (!basestr || strlen(basestr) < 4) + return FALSE; + + endstr = eos((char *)basestr); + + if (to_plural) { + for (i = 0; i < SIZE(no_men); i++) { + al = (int) strlen(no_men[i]); + spot = endstr - (al + 3); + if (!BSTRNCMPI(basestr, spot, no_men[i], al) + && (spot == basestr || *(spot - 1) == ' ')) + return TRUE; + } + } else { + for (i = 0; i < SIZE(no_man); i++) { + al = (int) strlen(no_man[i]); + spot = endstr - (al + 3); + if (!BSTRNCMPI(basestr, spot, no_man[i], al) + && (spot == basestr || *(spot - 1) == ' ')) + return TRUE; + } + } + return FALSE; +} + /* compare user string against object name string using fuzzy matching */ STATIC_OVL boolean wishymatch(u_str, o_str, retry_inverted) @@ -2603,6 +2670,8 @@ struct alt_spellings { { "grapnel", GRAPPLING_HOOK }, { "grapple", GRAPPLING_HOOK }, { "protection from shape shifters", RIN_PROTECTION_FROM_SHAPE_CHAN }, + /* if we ever add other sizes, move this to o_ranges[] with "bag" */ + { "box", LARGE_BOX }, /* normally we wouldn't have to worry about unnecessary , but " stone" will get stripped off, preventing a wishymatch; that actually lets "flint stone" be a match, so we also accept bogus "flintstone" */ @@ -2696,7 +2765,7 @@ struct obj *no_wish; register struct obj *otmp; int cnt, spe, spesgn, typ, very, rechrg; int blessed, uncursed, iscursed, ispoisoned, isgreased; - int eroded, eroded2, erodeproof; + int eroded, eroded2, erodeproof, locked, unlocked, broken; int halfeaten, mntmp, contents; int islit, unlabeled, ishistoric, isdiluted, trapped; int tmp, tinv, tvariety; @@ -2722,9 +2791,11 @@ struct obj *no_wish; char *un, *dn, *actualn, *origbp = bp; const char *name = 0; - cnt = spe = spesgn = typ = very = rechrg = blessed = uncursed = iscursed = - ispoisoned = isgreased = eroded = eroded2 = erodeproof = halfeaten = - islit = unlabeled = ishistoric = isdiluted = trapped = 0; + cnt = spe = spesgn = typ = 0; + very = rechrg = blessed = uncursed = iscursed = ispoisoned = + isgreased = eroded = eroded2 = erodeproof = halfeaten = + islit = unlabeled = ishistoric = isdiluted = trapped = + locked = unlocked = broken = 0; tvariety = RANDOM_TIN; mntmp = NON_PM; #define UNDEFINED 0 @@ -2812,6 +2883,13 @@ struct obj *no_wish; trapped = 1; } else if (!strncmpi(bp, "untrapped ", l = 10)) { trapped = 2; /* not trapped */ + /* locked, unlocked, broken: box/chest lock states */ + } else if (!strncmpi(bp, "locked ", l = 7)) { + locked = 1, unlocked = broken = 0; + } else if (!strncmpi(bp, "unlocked ", l = 9)) { + unlocked = 1, locked = broken = 0; + } else if (!strncmpi(bp, "broken ", l = 7)) { + broken = 1, locked = unlocked = 0; } else if (!strncmpi(bp, "greased ", l = 8)) { isgreased = 1; } else if (!strncmpi(bp, "very ", l = 5)) { @@ -3217,7 +3295,10 @@ retry: ; /* avoid false hit on "* glass" */ } else if (!BSTRCMPI(bp, p - 6, " glass") || !strcmpi(bp, "glass")) { register char *g = bp; - if (strstri(g, "broken")) + + /* treat "broken glass" as a non-existent item; since "broken" is + also a chest/box prefix it might have been stripped off above */ + if (broken || strstri(g, "broken")) return (struct obj *) 0; if (!strncmpi(g, "worthless ", 10)) g += 10; @@ -3737,6 +3818,28 @@ typfnd: if (Is_box(otmp) || typ == TIN) otmp->otrapped = (trapped == 1); } + /* empty for containers rather than for tins */ + if (contents == EMPTY) { + if (otmp->otyp == BAG_OF_TRICKS || otmp->otyp == HORN_OF_PLENTY) { + if (otmp->spe > 0) + otmp->spe = 0; + } else if (Has_contents(otmp)) { + /* this assumes that artifacts can't be randomly generated + inside containers */ + delete_contents(otmp); + otmp->owt = weight(otmp); + } + } + /* set locked/unlocked/broken */ + if (Is_box(otmp)) { + if (locked) { + otmp->olocked = 1, otmp->obroken = 0; + } else if (unlocked) { + otmp->olocked = 0, otmp->obroken = 0; + } else if (broken) { + otmp->olocked = 0, otmp->obroken = 1; + } + } if (isgreased) otmp->greased = 1; diff --git a/src/pline.c b/src/pline.c index 319f13946..745bd7d22 100644 --- a/src/pline.c +++ b/src/pline.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pline.c $NHDT-Date: 1519183957 2018/02/21 03:32:37 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.65 $ */ +/* NetHack 3.6 pline.c $NHDT-Date: 1520964541 2018/03/13 18:09:01 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.66 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -96,6 +96,7 @@ void pline VA_DECL(const char *, line) #endif /* USE_STDARG | USE_VARARG */ { /* start of vpline() or of nested block in USE_OLDARG's pline() */ + static int in_pline = 0; char pbuf[3 * BUFSZ]; int ln; int msgtyp; @@ -138,11 +139,14 @@ VA_DECL(const char *, line) if ((pline_flags & SUPPRESS_HISTORY) == 0) dumplogmsg(line); #endif - - if (!iflags.window_inited) { + /* use raw_print() if we're called too early (or perhaps too late + during shutdown) or if we're being called recursively (probably + via debugpline() in the interface code) */ + if (in_pline++ || !iflags.window_inited) { + /* [we should probably be using raw_printf("\n%s", line) here] */ raw_print(line); iflags.last_msg = PLNMSG_UNKNOWN; - return; + goto pline_done; } msgtyp = MSGTYP_NORMAL; @@ -158,7 +162,7 @@ VA_DECL(const char *, line) * doing so out of context and probably end up seeming silly. * (Not an issue for no-repeat but matters for no-show.) */ - return; + goto pline_done; } if (vision_full_recalc) @@ -178,6 +182,10 @@ VA_DECL(const char *, line) if (msgtyp == MSGTYP_STOP) display_nhwindow(WIN_MESSAGE, TRUE); /* --more-- */ + pline_done: + --in_pline; + return; + #if !(defined(USE_STDARG) || defined(USE_VARARGS)) /* provide closing brace for the nested block which immediately follows USE_OLDARGS's VA_DECL() */ diff --git a/src/polyself.c b/src/polyself.c index d79f01f44..227b7d7f7 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 polyself.c $NHDT-Date: 1513298347 2017/12/15 00:39:07 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.116 $ */ +/* NetHack 3.6 polyself.c $NHDT-Date: 1520797126 2018/03/11 19:38:46 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.117 $ */ /* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ @@ -964,7 +964,7 @@ int alone; { struct obj *otmp; const char *what, *which, *whichtoo; - boolean candropwep, candropswapwep; + boolean candropwep, candropswapwep, updateinv = TRUE; if (uwep) { /* !alone check below is currently superfluous but in the @@ -989,17 +989,26 @@ int alone; You("find you must %s %s %s!", what, the_your[!!strncmp(which, "corpse", 6)], which); } + /* if either uwep or wielded uswapwep is flagged as 'in_use' + then don't drop it or explicitly update inventory; leave + those actions to caller (or caller's caller, &c) */ if (u.twoweap) { otmp = uswapwep; uswapwepgone(); - if (candropswapwep) + if (otmp->in_use) + updateinv = FALSE; + else if (candropswapwep) dropx(otmp); } otmp = uwep; uwepgone(); - if (candropwep) + if (otmp->in_use) + updateinv = FALSE; + else if (candropwep) dropx(otmp); - update_inventory(); + + if (updateinv) + update_inventory(); } else if (!could_twoweap(youmonst.data)) { untwoweapon(); } diff --git a/src/potion.c b/src/potion.c index 5daa9fbcc..fc9de1d76 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 potion.c $NHDT-Date: 1502753790 2017/08/14 23:36:30 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.138 $ */ +/* NetHack 3.6 potion.c $NHDT-Date: 1520797133 2018/03/11 19:38:53 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.144 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1563,6 +1563,11 @@ register struct obj *obj; int i, ii, isdone, kn = 0; boolean cureblind = FALSE; + /* potion of unholy water might be wielded; prevent + you_were() -> drop_weapon() from dropping it so that it + remains in inventory where our caller expects it to be */ + obj->in_use = 1; + switch (obj->otyp) { case POT_RESTORE_ABILITY: case POT_GAIN_ABILITY: @@ -1714,7 +1719,7 @@ register struct obj *obj; break; */ } - /* note: no obfree() */ + /* note: no obfree() -- that's our caller's responsibility */ if (obj->dknown) { if (kn) makeknown(obj->otyp); diff --git a/src/rip.c b/src/rip.c index b8ef7f594..ce3c8d6e7 100644 --- a/src/rip.c +++ b/src/rip.c @@ -143,7 +143,7 @@ time_t when; #ifdef DUMPLOG if (tmpwin == 0) - dump_forward_putstr(0, 0, "Gave over:", TRUE); + dump_forward_putstr(0, 0, "Game over:", TRUE); else #endif putstr(tmpwin, 0, ""); diff --git a/src/uhitm.c b/src/uhitm.c index bfc103e0a..8f9e3a0b9 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 uhitm.c $NHDT-Date: 1520043553 2018/03/03 02:19:13 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.175 $ */ +/* NetHack 3.6 uhitm.c $NHDT-Date: 1521684760 2018/03/22 02:12:40 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.176 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -513,14 +513,10 @@ struct attack *uattk; /* ... but we don't enforce that here; Null works ok */ u.dx, u.dy, u.dz); return TRUE; /* target hasn't been killed */ } - clockwise = !clockwise; /* alternate */ /* adjust direction by two so that loop's increment (for clockwise) or decrement (for counter-clockwise) will point at the spot next to primary target */ - if (clockwise) - i = (i + 6) % 8; - else - i = (i + 2) % 8; + i = (i + (clockwise ? 6 : 2)) % 8; umort = u.umortality; /* used to detect life-saving */ /* @@ -535,10 +531,8 @@ struct attack *uattk; /* ... but we don't enforce that here; Null works ok */ struct monst *mtmp; int tx, ty, tmp, dieroll, mhit, attknum, armorpenalty; - if (clockwise) - i = (i + 1) % 8; /* ++i, wrap 8 to i=0 */ - else - i = (i + 7) % 8; /* --i, wrap -1 to i=7 */ + /* ++i, wrap 8 to i=0 /or/ --i, wrap -1 to i=7 */ + i = (i + (clockwise ? 1 : 7)) % 8; tx = x + xdir[i], ty = y + ydir[i]; /* current target location */ if (!isok(tx, ty)) @@ -563,6 +557,8 @@ struct attack *uattk; /* ... but we don't enforce that here; Null works ok */ if (!uwep || u.umortality > umort) break; } + /* set up for next time */ + clockwise = !clockwise; /* alternate */ /* return False if primary target died, True otherwise; note: if 'target' was nonNull upon entry then it's still nonNull even if *target died */ @@ -583,8 +579,8 @@ struct attack *uattk; int dieroll = rnd(20); int mhit = (tmp > dieroll || u.uswallow); - /* Cleaver attacks three spots, one on either side of 'mon'; - it can't we part of dual-wielding but we guard against that anyway; + /* Cleaver attacks three spots, 'mon' and one on either side of 'mon'; + it can't be part of dual-wielding but we guard against that anyway; cleave return value reflects status of primary target ('mon') */ if (uwep && uwep->oartifact == ART_CLEAVER && !u.twoweap && !u.uswallow && !u.ustuck && !NODIAG(u.umonnum)) diff --git a/sys/unix/gitinfo.sh b/sys/unix/gitinfo.sh index 5cdb34715..770943e25 100755 --- a/sys/unix/gitinfo.sh +++ b/sys/unix/gitinfo.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.6 gitinfo.sh $NHDT-Date: 1520201830 2018/03/04 22:17:10 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.0 $ +# NetHack 3.6 gitinfo.sh $NHDT-Date: 1521185933 2018/03/16 07:38:53 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.1 $ # bring dat/gitinfo.txt up to date; called from Makefile.src @@ -10,16 +10,18 @@ # this script to be skipped or to run but fail to generate dat/gitinfo.txt. # -always=0 -if [[ $1 -eq 1 || $1 == "force" || $1 == "always" ]]; then always=1; fi - # try to figure out where we are: top, one level down (expected), or sys/unix prefix=. if [ -f ../sys/unix/gitinfo.sh ]; then prefix=..; fi if [ -f ../../sys/unix/gitinfo.sh ]; then prefix=../..; fi +rungit=0 +if [ $1 -eq 1 ]; then rungit=1; fi +if [ $1 = "force" ]; then rungit=1; fi +if [ ! -f $prefix/dat/gitinfo.txt ]; then rungit=1; fi + # try to run a perl script which is part of nethack's git repository -if [[ $always -eq 1 || ! -f $prefix/dat/gitinfo.txt ]]; then +if [ $rungit -eq 1 ]; then ( cd $prefix; \ perl -IDEVEL/hooksdir -MNHgithook -e '&NHgithook::nhversioning' \ 2> /dev/null ) \ diff --git a/sys/unix/hints/linux-qt4 b/sys/unix/hints/linux-qt4 index ae3911939..34c8863d5 100644 --- a/sys/unix/hints/linux-qt4 +++ b/sys/unix/hints/linux-qt4 @@ -1,5 +1,5 @@ # -# NetHack 3.6 linux-x11 $NHDT-Date: 1432512814 2015/05/25 00:13:34 $ $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ +# NetHack 3.6 linux-qt4 $NHDT-Date: 1432512814 2015/05/25 00:13:34 $ $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 585f8c29a..4abb7a6c5 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -1,4 +1,4 @@ -# NetHack 3.6 Makefile.msc $NHDT-Date: 1520177858 2018/03/04 15:37:38 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.111 $ */ +# NetHack 3.6 Makefile.msc $NHDT-Date: 1520858848 2018/03/12 12:47:28 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.112 $ */ # Copyright (c) NetHack PC Development Team 1993-2018 # #============================================================================== @@ -1239,6 +1239,7 @@ spotless: clean if exist $(O)gamedir.tag del $(O)gamedir.tag if exist $(O)nh*key.lib del $(O)nh*key.lib if exist $(O)nh*key.exp del $(O)nh*key.exp + if exist $(INCL)\win32api.h del $(INCL)\win32api.h if exist $(MSWIN)\mnsel.bmp del $(MSWIN)\mnsel.bmp if exist $(MSWIN)\mnselcnt.bmp del $(MSWIN)\mnselcnt.bmp if exist $(MSWIN)\mnunsel.bmp del $(MSWIN)\mnunsel.bmp diff --git a/sys/winnt/nttty.c b/sys/winnt/nttty.c index 3ac469ea8..1d2d8c89f 100644 --- a/sys/winnt/nttty.c +++ b/sys/winnt/nttty.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 nttty.c $NHDT-Date: 1454381842 2016/02/02 02:57:22 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.67 $ */ +/* NetHack 3.6 nttty.c $NHDT-Date: 1520825872 2018/03/12 03:37:52 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.70 $ */ /* Copyright (c) NetHack PC Development Team 1993 */ /* NetHack may be freely redistributed. See license for details. */ @@ -366,11 +366,16 @@ nttty_kbhit() void get_scr_size() { + int lines, cols; + GetConsoleScreenBufferInfo(hConOut, &csbi); + + lines = csbi.srWindow.Bottom - (csbi.srWindow.Top + 1); + cols = csbi.srWindow.Right - (csbi.srWindow.Left + 1); - LI = csbi.srWindow.Bottom - (csbi.srWindow.Top + 1); - CO = csbi.srWindow.Right - (csbi.srWindow.Left + 1); - + LI = lines; + CO = min(cols, 80); + if ((LI < 25) || (CO < 80)) { COORD newcoord; diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 32dc6b3c5..0ad6d2aa6 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 wintty.c $NHDT-Date: 1506908980 2017/10/02 01:49:40 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.140 $ */ +/* NetHack 3.6 wintty.c $NHDT-Date: 1520825319 2018/03/12 03:28:39 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.142 $ */ /* Copyright (c) David Cohrs, 1991 */ /* NetHack may be freely redistributed. See license for details. */ @@ -2365,7 +2365,13 @@ register int x, y; /* not xchar: perhaps xchar is unsigned and } debugpline4("bad curs positioning win %d %s (%d,%d)", window, s, x, y); - return; + /* This return statement caused a functional difference between DEBUG and + non-DEBUG operation, so it is being commented out. It caused tty_curs() + to fail to move the cursor to the location it needed to be if the x,y + range checks failed, leaving the next piece of output to be displayed + at whatever random location the cursor happened to be at prior. */ + + /* return; */ } #endif x += cw->offx; diff --git a/win/win32/mhmenu.c b/win/win32/mhmenu.c index 6bdea0a2f..b541af305 100644 --- a/win/win32/mhmenu.c +++ b/win/win32/mhmenu.c @@ -160,10 +160,11 @@ mswin_menu_window_select_menu(HWND hWnd, int how, MENU_ITEM_P **_selected, ap = data->menu.gacc; for (i = 0; i < data->menu.size; i++) { if (data->menu.items[i].accelerator != 0) { - next_char = (char) (data->menu.items[i].accelerator + 1); + if (isalpha(data->menu.items[i].accelerator)) { + next_char = (char)(data->menu.items[i].accelerator + 1); + } } else if (NHMENU_IS_SELECTABLE(data->menu.items[i])) { - if ((next_char >= 'a' && next_char <= 'z') - || (next_char >= 'A' && next_char <= 'Z')) { + if (isalpha(next_char)) { data->menu.items[i].accelerator = next_char; } else { if (next_char > 'z') diff --git a/win/win32/mhstatus.c b/win/win32/mhstatus.c index a362c60bd..52d24621a 100644 --- a/win/win32/mhstatus.c +++ b/win/win32/mhstatus.c @@ -2,6 +2,7 @@ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ +#include #include "winMS.h" #include "mhstatus.h" #include "mhmsg.h" @@ -352,16 +353,21 @@ onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam) : status_fg_color)); nBg = status_bg_color; - GetTextExtentPoint32(hdc, wbuf, vlen, &sz); + sz.cy = -1; if (*f == BL_TITLE && iflags.wc2_hitpointbar) { HBRUSH back_brush = CreateSolidBrush(nhcolor_to_RGB(hpbar_color)); RECT barrect; - /* first draw title normally */ + /* prepare for drawing */ SelectObject(hdc, fnt); SetBkMode(hdc, OPAQUE); SetBkColor(hdc, status_bg_color); SetTextColor(hdc, nhcolor_to_RGB(hpbar_color)); + + /* get bounding rectangle */ + GetTextExtentPoint32(hdc, wbuf, vlen, &sz); + + /* first draw title normally */ DrawText(hdc, wbuf, vlen, &rt, DT_LEFT); /* calc bar length */ @@ -386,12 +392,20 @@ onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam) nFg = nBg; nBg = tmp; } + + /* prepare for drawing */ SelectObject(hdc, fnt); SetBkMode(hdc, OPAQUE); SetBkColor(hdc, nBg); SetTextColor(hdc, nFg); + + /* get bounding rectangle */ + GetTextExtentPoint32(hdc, wbuf, vlen, &sz); + + /* draw */ DrawText(hdc, wbuf, vlen, &rt, DT_LEFT); } + assert(sz.cy >= 0); rt.left += sz.cx; cy = max(cy, sz.cy);