diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 7fa058915..ddad2f371 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -370,6 +370,14 @@ g.cubes would eat globs of green slime without harm; engulf those instead fix up true rumor about rock moles vs boots Bell of Opening could trigger segfault attempting to open some types of traps if hero was mounted +automatic #overview annotation for quest summons wasn't shown if the quest + entry portal was on same level as bigroom or rogue level +gaining or losing strength while wearing gauntlets of power could give + misleading message about already being as strong or weak as possible +levitation vs encumbrance message sequencing issues: putting on boots of + levitation reported reduction of encumbrance before finish-wearing + and float-up messages, taking off such boots didn't report increase + of encumbrance until player took another action Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository @@ -403,6 +411,13 @@ DUMPLOG: RIP tombstone was printed for characters who survived (ascended, artifact creation violated illiterate conduct when artifact name was assigned, behavior intended only for creating Sting or Orcrist via naming tty: revert to pline() for issuing prompts (override MSGTYPE=hide differently) +previous tty-revert fix had the override test backwards, breaking MSGTYPE +save 'autodescribe' option value prior to detection or #terrain display and + restore it after rather than leave it forced on +humanoid pet could become hostile but still remain tame if it observed hero + attacking a peaceful creature +minor ^X/enlightenment bugs: grammar when poly'd into '1 hit dice' critter, + missing punctuation for "You entered the dungeon N turns ago" Platform- and/or Interface-Specific Fixes diff --git a/include/extern.h b/include/extern.h index 511d20858..0ad6935c4 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1490908458 2017/03/30 21:14:18 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.585 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1494107197 2017/05/06 21:46:37 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.587 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -439,6 +439,7 @@ E int NDECL(Armor_off); E int NDECL(Armor_gone); E int NDECL(Helmet_off); E int NDECL(Gloves_off); +E int NDECL(Boots_on); E int NDECL(Boots_off); E int NDECL(Cloak_off); E int NDECL(Shield_off); @@ -1424,6 +1425,7 @@ E int FDECL(pronoun_gender, (struct monst *)); E boolean FDECL(levl_follower, (struct monst *)); E int FDECL(little_to_big, (int)); E int FDECL(big_to_little, (int)); +E boolean FDECL(big_little_match, (int, int)); E const char *FDECL(locomotion, (const struct permonst *, const char *)); E const char *FDECL(stagger, (const struct permonst *, const char *)); E const char *FDECL(on_fire, (struct permonst *, struct attack *)); diff --git a/src/attrib.c b/src/attrib.c index c87afb683..e0021632f 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 attrib.c $NHDT-Date: 1455357587 2016/02/13 09:59:47 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.55 $ */ +/* NetHack 3.6 attrib.c $NHDT-Date: 1494034337 2017/05/06 01:32:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.62 $ */ /* Copyright 1988, 1989, 1990, 1992, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ @@ -14,6 +14,10 @@ static const char *const minusattr[] = { "weak", "stupid", "foolish", "clumsy", "fragile", "repulsive" }; +/* also used by enlightenment for non-abbreviated status info */ +const char + *const attrname[] = { "strength", "intelligence", "wisdom", + "dexterity", "constitution", "charisma" }; static const struct innate { schar ulevel; @@ -111,7 +115,7 @@ adjattrib(ndx, incr, msgflg) int ndx, incr; int msgflg; /* positive => no message, zero => message, and */ { /* negative => conditional (msg if change made) */ - int old_acurr; + int old_acurr, old_abase; boolean abonflg; const char *attrstr; @@ -125,6 +129,7 @@ int msgflg; /* positive => no message, zero => message, and */ } old_acurr = ACURR(ndx); + old_abase = ABASE(ndx); if (incr > 0) { ABASE(ndx) += incr; if (ABASE(ndx) > AMAX(ndx)) { @@ -149,9 +154,14 @@ int msgflg; /* positive => no message, zero => message, and */ abonflg = (ABON(ndx) > 0); } if (ACURR(ndx) == old_acurr) { - if (msgflg == 0 && flags.verbose) - pline("You're %s as %s as you can get.", - abonflg ? "currently" : "already", attrstr); + if (msgflg == 0 && flags.verbose) { + if (ABASE(ndx) == old_abase) + pline("You're %s as %s as you can get.", + abonflg ? "currently" : "already", attrstr); + else /* current stayed the same but base value changed */ + Your("innate %s has %s.", attrname[ndx], + (incr > 0) ? "improved" : "declined"); + } return FALSE; } @@ -223,16 +233,28 @@ int typ; /* which attribute */ boolean exclaim; /* emphasis */ { void VDECL((*func), (const char *, ...)) = poiseff[typ].delivery_func; + const char *msg_txt = poiseff[typ].effect_msg; - (*func)("%s%c", poiseff[typ].effect_msg, exclaim ? '!' : '.'); + /* + * "You feel weaker" or "you feel very sick" aren't appropriate when + * wearing or wielding something (gauntlets of power, Ogresmasher) + * which forces the attribute to maintain its maximum value. + * Phrasing for other attributes which might have fixed values + * (dunce cap) is such that we don't need message fixups for them. + */ + if (typ == A_STR && ACURR(A_STR) == STR19(25)) + msg_txt = "innately weaker"; + else if (typ == A_CON && ACURR(A_CON) == 25) + msg_txt = "sick inside"; + + (*func)("%s%c", msg_txt, exclaim ? '!' : '.'); } -/* called when an attack or trap has poisoned the hero (used to be in mon.c) - */ +/* called when an attack or trap has poisoned hero (used to be in mon.c) */ void poisoned(reason, typ, pkiller, fatal, thrown_weapon) const char *reason, /* controls what messages we display */ - *pkiller; /* for score+log file if fatal */ + *pkiller; /* for score+log file if fatal */ int typ, fatal; /* if fatal is 0, limit damage to adjattrib */ boolean thrown_weapon; /* thrown weapons are less deadly */ { @@ -671,7 +693,9 @@ int r; { 0, 0 } }; int i; - for (i = 0; roleabils[i].abil && roleabils[i].role != r; i++); + + for (i = 0; roleabils[i].abil && roleabils[i].role != r; i++) + continue; return roleabils[i].abil; } @@ -996,7 +1020,7 @@ int x; #ifdef WIN32_BUG return (x = ((tmp <= 3) ? 3 : tmp)); #else - return (schar) ((tmp <= 3) ? 3 : tmp); + return (schar) ((tmp <= 3) ? 3 : tmp); #endif } else if (x == A_CHA) { if (tmp < 18 diff --git a/src/cmd.c b/src/cmd.c index f9473e6a7..048fc5bbd 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 cmd.c $NHDT-Date: 1457207033 2016/03/05 19:43:53 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.220 $ */ +/* NetHack 3.6 cmd.c $NHDT-Date: 1494034344 2017/05/06 01:32:24 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.256 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1586,7 +1586,10 @@ int final; } } -/* characteristics: expanded version of bottom line strength, dexterity, &c */ +/* characteristics: expanded version of bottom line strength, dexterity, &c; + [3.6.1: now includes all status info (except things already shown in the + 'background' section), primarily so that blind players can suppress the + status line(s) altogether and use ^X feedback on demand to view HP, &c] */ STATIC_OVL void characteristics_enlightenment(mode, final) int mode; @@ -1612,22 +1615,39 @@ int final; enl_msg("Your armor class ", "is ", "was ", buf, ""); if (Upolyd) { - Sprintf(buf, "%d hit dice", mons[u.umonnum].mlevel); + switch (mons[u.umonnum].mlevel) { + case 0: + /* status line currently being explained shows "HD:0" */ + Strcpy(buf, "0 hit dice (actually 1/2)"); + break; + case 1: + Strcpy(buf, "1 hit die"); + break; + default: + Sprintf(buf, "%d hit dice", mons[u.umonnum].mlevel); + break; + } } else { /* flags.showexp does not matter */ /* experience level is already shown in the Background section */ Sprintf(buf, "%-1ld experience point%s", - u.uexp, u.uexp == 1 ? "" : "s"); + u.uexp, plur(u.uexp)); } you_have(buf, ""); - Sprintf(buf, " You entered the dungeon %ld turn%s ago", - moves, moves == 1 ? "" : "s"); - putstr(en_win, 0, buf); + /* this is shown even if the 'time' option is off */ + Sprintf(buf, "the dungeon %ld turn%s ago", moves, plur(moves)); + /* same phrasing at end of game: "entered" is unconditional */ + enlght_line(You_, "entered ", buf, ""); #ifdef SCORE_ON_BOTL - Sprintf(buf, "%ld", botl_score()); - enl_msg("Your score ", "is ", "was ", buf, ""); + if (flags.showscore) { + /* describes what's shown on status line, which is an approximation; + only show it here if player has the 'showscore' option enabled */ + Sprintf(buf, "%ld%s", botl_score(), + !final ? "" : " before end-of-game adjustments"); + enl_msg("Your score ", "is ", "was ", buf, ""); + } #endif /* bottom line order */ @@ -1644,9 +1664,10 @@ STATIC_OVL void one_characteristic(mode, final, attrindx) int mode, final, attrindx; { + extern const char *const attrname[]; /* attrib.c */ boolean hide_innate_value = FALSE, interesting_alimit; int acurrent, abase, apeak, alimit; - const char *attrname, *paren_pfx; + const char *paren_pfx; char subjbuf[BUFSZ], valubuf[BUFSZ], valstring[32]; /* being polymorphed or wearing certain cursed items prevents @@ -1664,30 +1685,24 @@ int mode, final, attrindx; } switch (attrindx) { case A_STR: - attrname = "strength"; if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER && uarmg->cursed) hide_innate_value = TRUE; break; case A_DEX: - attrname = "dexterity"; break; case A_CON: - attrname = "constitution"; if (uwep && uwep->oartifact == ART_OGRESMASHER && uwep->cursed) hide_innate_value = TRUE; break; case A_INT: - attrname = "intelligence"; if (uarmh && uarmh->otyp == DUNCE_CAP && uarmh->cursed) hide_innate_value = TRUE; break; case A_WIS: - attrname = "wisdom"; if (uarmh && uarmh->otyp == DUNCE_CAP && uarmh->cursed) hide_innate_value = TRUE; break; case A_CHA: - attrname = "charisma"; break; default: return; /* impossible */ @@ -1698,7 +1713,7 @@ int mode, final, attrindx; acurrent = ACURR(attrindx); (void) attrval(attrindx, acurrent, valubuf); /* Sprintf(valubuf,"%d",) */ - Sprintf(subjbuf, "Your %s ", attrname); + Sprintf(subjbuf, "Your %s ", attrname[attrindx]); if (!hide_innate_value) { /* show abase, amax, and/or attrmax if acurr doesn't match abase diff --git a/src/detect.c b/src/detect.c index a46cf47f9..def22469e 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 detect.c $NHDT-Date: 1463191981 2016/05/14 02:13:01 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.70 $ */ +/* NetHack 3.6 detect.c $NHDT-Date: 1491705573 2017/04/09 02:39:33 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.76 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -59,13 +59,15 @@ int ter_typ; const char *ter_explain; { coord dummy_pos; /* don't care whether player actually picks a spot */ + boolean save_autodescribe; dummy_pos.x = u.ux, dummy_pos.y = u.uy; /* starting spot for getpos() */ + save_autodescribe = iflags.autodescribe; iflags.autodescribe = TRUE; iflags.terrainmode = ter_typ; getpos(&dummy_pos, FALSE, ter_explain); iflags.terrainmode = 0; - /* leave iflags.autodescribe 'on' even if previously 'off' */ + iflags.autodescribe = save_autodescribe; } /* extracted from monster_detection() so can be shared by do_vicinity_map() */ diff --git a/src/do_name.c b/src/do_name.c index 98293152e..34a853159 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -412,9 +412,10 @@ int cx, cy; cc.y = cy; if (do_screen_description(cc, TRUE, sym, tmpbuf, &firstmatch)) { (void) coord_desc(cx, cy, tmpbuf, iflags.getpos_coords); - pline("%s%s%s%s", firstmatch, *tmpbuf ? " " : "", tmpbuf, - (iflags.getloc_travelmode && !is_valid_travelpt(cx,cy)) - ? " (no travel path)" : ""); + custompline(SUPPRESS_HISTORY, + "%s%s%s%s", firstmatch, *tmpbuf ? " " : "", tmpbuf, + (iflags.getloc_travelmode && !is_valid_travelpt(cx, cy)) + ? " (no travel path)" : ""); curs(WIN_MAP, cx, cy); flush_screen(0); } diff --git a/src/do_wear.c b/src/do_wear.c index 15f00bbee..f0c1038dc 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do_wear.c $NHDT-Date: 1455667557 2016/02/17 00:05:57 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.90 $ */ +/* NetHack 3.6 do_wear.c $NHDT-Date: 1494107204 2017/05/06 21:46:44 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.94 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -23,7 +23,7 @@ STATIC_DCL void FDECL(on_msg, (struct obj *)); STATIC_DCL void FDECL(toggle_stealth, (struct obj *, long, BOOLEAN_P)); STATIC_DCL void FDECL(toggle_displacement, (struct obj *, long, BOOLEAN_P)); STATIC_PTR int NDECL(Armor_on); -STATIC_PTR int NDECL(Boots_on); +/* int NDECL(Boots_on); -- moved to extern.h */ STATIC_PTR int NDECL(Cloak_on); STATIC_PTR int NDECL(Helmet_on); STATIC_PTR int NDECL(Gloves_on); @@ -148,7 +148,6 @@ boolean on; * [Blindf_on() is an exception and calls setworn() itself.] */ -STATIC_PTR int Boots_on(VOID_ARGS) { @@ -1274,7 +1273,7 @@ cancel_don() context.takeoff.cancelled_don = (afternmv == Boots_on || afternmv == Helmet_on || afternmv == Gloves_on || afternmv == Armor_on); - afternmv = 0; + afternmv = (int NDECL((*))) 0; nomovemsg = (char *) 0; multi = 0; context.takeoff.delay = 0; diff --git a/src/dungeon.c b/src/dungeon.c index d3b603143..5b5e7c369 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dungeon.c $NHDT-Date: 1470275509 2016/08/04 01:51:49 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.76 $ */ +/* NetHack 3.6 dungeon.c $NHDT-Date: 1491958681 2017/04/12 00:58:01 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.79 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2951,8 +2951,6 @@ boolean printdun; Sprintf(buf, "%sA very big room.", PREFIX); } else if (mptr->flags.roguelevel) { Sprintf(buf, "%sA primitive area.", PREFIX); - } else if (mptr->flags.quest_summons) { - Sprintf(buf, "%sSummoned by %s.", PREFIX, ldrname()); } else if (on_level(&mptr->lev, &qstart_level)) { Sprintf(buf, "%sHome%s.", PREFIX, mptr->flags.unreachable ? " (no way back...)" : ""); @@ -2974,6 +2972,11 @@ boolean printdun; } if (*buf) putstr(win, 0, buf); + /* quest entrance is not mutually-exclusive with bigroom or rogue level */ + if (mptr->flags.quest_summons) { + Sprintf(buf, "%sSummoned by %s.", PREFIX, ldrname()); + putstr(win, 0, buf); + } /* print out branches */ if (mptr->br) { diff --git a/src/hack.c b/src/hack.c index 1c7e44804..a250d86de 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 hack.c $NHDT-Date: 1464485934 2016/05/29 01:38:54 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.168 $ */ +/* NetHack 3.6 hack.c $NHDT-Date: 1494107206 2017/05/06 21:46:46 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.174 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -552,10 +552,10 @@ dosinkfall() /* * Interrupt multi-turn putting on/taking off of armor (in which * case we reached the sink due to being teleported while busy; - * in 3.4.3, Boots_on()/Boots_off() [called via (*aftermv)() when + * in 3.4.3, Boots_on()/Boots_off() [called via (*afternmv)() when * 'multi' reaches 0] triggered a crash if we were donning/doffing * levitation boots [because the Boots_off() below causes 'uarmf' - * to be null by the time 'aftermv' gets called]). + * to be null by the time 'afternmv' gets called]). * * Interrupt donning/doffing if we fall onto the sink, or if the * code below is going to remove levitation boots even when we @@ -2766,9 +2766,13 @@ const char *msg_override; nomovemsg = 0; u.usleep = 0; multi_reason = NULL; - if (afternmv) - (*afternmv)(); - afternmv = 0; + if (afternmv) { + int NDECL((*f)) = afternmv; + /* clear afternmv before calling it (to override the + encumbrance hack for levitation--see weight_cap()) */ + afternmv = (int NDECL((*))) 0; + (void) (*f)(); + } } STATIC_OVL void @@ -2843,7 +2847,16 @@ boolean k_format; int weight_cap() { - register long carrcap; + long carrcap, save_ELev = ELevitation; + + /* boots take multiple turns to wear but any properties they + confer are enabled at the start rather than the end; that + causes message sequencing issues for boots of levitation + so defer their encumbrance benefit until they're fully worn */ + if (afternmv == Boots_on && (ELevitation & W_ARMF) != 0L) { + ELevitation &= ~W_ARMF; + float_vs_flight(); /* in case Levitation is blocking Flying */ + } carrcap = 25 * (ACURRSTR + ACURR(A_CON)) + 50; if (Upolyd) { @@ -2873,6 +2886,12 @@ weight_cap() if (carrcap < 0) carrcap = 0; } + + if (ELevitation != save_ELev) { + ELevitation = save_ELev; + float_vs_flight(); + } + return (int) carrcap; } diff --git a/src/mon.c b/src/mon.c index ebb680780..8276d4792 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mon.c $NHDT-Date: 1466289475 2016/06/18 22:37:55 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.227 $ */ +/* NetHack 3.6 mon.c $NHDT-Date: 1492733171 2017/04/21 00:06:11 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.237 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2606,9 +2606,9 @@ struct monst *mtmp; /* Called whenever the player attacks mtmp; also called in other situations where mtmp gets annoyed at the player. Handles mtmp getting annoyed at the - attack and any ramifications that might have. Useful also in situations where - mtmp was already hostile; it checks for situations where the player shouldn't - be attacking and any ramifications /that/ might have. */ + attack and any ramifications that might have. Useful also in situations + where mtmp was already hostile; it checks for situations where the player + shouldn't be attacking and any ramifications /that/ might have. */ void setmangry(mtmp, via_attack) struct monst *mtmp; @@ -2616,13 +2616,13 @@ boolean via_attack; { if (via_attack && sengr_at("Elbereth", u.ux, u.uy, TRUE)) { You_feel("like a hypocrite."); - /* AIS: Yes, I know alignment penalties and bonuses aren't balanced at - the moment. This is about correct relative to other "small" - penalties; it should be fairly large, as attacking while standing on - an Elbereth means that you're requesting peace and then violating - your own request. I know 5 isn't actually large, but it's - intentionally larger than the 1s and 2s that are normally given for - this sort of thing. */ + /* AIS: Yes, I know alignment penalties and bonuses aren't balanced + at the moment. This is about correct relative to other "small" + penalties; it should be fairly large, as attacking while standing + on an Elbereth means that you're requesting peace and then + violating your own request. I know 5 isn't actually large, but + it's intentionally larger than the 1s and 2s that are normally + given for this sort of thing. */ adjalign(-5); if (!Blind) @@ -2668,20 +2668,30 @@ boolean via_attack; ++got_mad; } } - if (got_mad && !Hallucination) - pline_The("%s appear%s to be angry too...", - got_mad == 1 ? q_guardian->mname - : makeplural(q_guardian->mname), - got_mad == 1 ? "s" : ""); + if (got_mad && !Hallucination) { + const char *who = q_guardian->mname; + + if (got_mad > 1) + who = makeplural(who); + pline_The("%s %s to be angry too...", + who, vtense(who, "appear")); + } } /* make other peaceful monsters react */ if (!context.mon_moving) { + static const char *const Exclam[] = { + "Gasp!", "Uh-oh.", "Oh my!", "What?", "Why?", + }; struct monst *mon; + int mndx = monsndx(mtmp->data); for (mon = fmon; mon; mon = mon->nmon) { if (DEADMONSTER(mon)) continue; + if (mon == mtmp) /* the mpeaceful test catches this since mtmp */ + continue; /* is no longer peaceful, but be explicit... */ + if (!mindless(mon->data) && mon->mpeaceful && couldsee(mon->mx, mon->my) && !mon->msleeping && mon->mcansee && m_canseeu(mon)) { @@ -2692,32 +2702,38 @@ boolean via_attack; verbalize("Halt! You're under arrest!"); (void) angry_guards(!!Deaf); } else { - const char *exclam[] = { - "Gasp!", "Uh-oh.", "Oh my!", "What?", "Why?" - }; if (!rn2(5)) { - verbalize("%s", exclam[mon->m_id % SIZE(exclam)]); + verbalize("%s", Exclam[mon->m_id % SIZE(Exclam)]); exclaimed = TRUE; } - if (!mon->isshk && !mon->ispriest - && (mon->data->mlevel < rn2(10))) { - monflee(mon, rn2(50)+25, TRUE, !exclaimed); + /* shopkeepers and temple priests might gasp in + surprise, but they won't become angry here */ + if (mon->isshk || mon->ispriest) + continue; + + if (mon->data->mlevel < rn2(10)) { + monflee(mon, rn2(50) + 25, TRUE, !exclaimed); exclaimed = TRUE; } - if (!mon->isshk && !mon->ispriest) { + if (mon->mtame) { + /* mustn't set mpeaceful to 0 as below; + perhaps reduce tameness? */ + } else { mon->mpeaceful = 0; adjalign(-1); if (!exclaimed) pline("%s gets angry!", Monnam(mon)); } } - } else if ((mtmp->data == mon->data) && !rn2(3)) { + } else if (mon->data->mlet == mtmp->data->mlet + && big_little_match(mndx, monsndx(mon->data)) + && !rn2(3)) { if (!rn2(4)) { growl(mon); exclaimed = TRUE; } if (rn2(6)) - monflee(mon, rn2(25)+15, TRUE, !exclaimed); + monflee(mon, rn2(25) + 15, TRUE, !exclaimed); } } } diff --git a/src/mondata.c b/src/mondata.c index a9d054f4c..32ea5bccc 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mondata.c $NHDT-Date: 1470966820 2016/08/12 01:53:40 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.61 $ */ +/* NetHack 3.6 mondata.c $NHDT-Date: 1492733172 2017/04/21 00:06:12 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.62 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1009,6 +1009,32 @@ int montype; return montype; } +/* determine whether two permonst indices are part of the same progression; + existence of progressions with more than one step makes it a bit tricky */ +boolean +big_little_match(montyp1, montyp2) +int montyp1, montyp2; +{ + int l, b; + + /* simplest case: both are same pm */ + if (montyp1 == montyp2) + return TRUE; + /* assume it isn't possible to grow from one class letter to another */ + if (mons[montyp1].mlet != mons[montyp2].mlet) + return FALSE; + /* check whether montyp1 can grow up into montyp2 */ + for (l = montyp1; (b = little_to_big(l)) != l; l = b) + if (b == montyp2) + return TRUE; + /* check whether montyp2 can grow up into montyp1 */ + for (l = montyp2; (b = little_to_big(l)) != l; l = b) + if (b == montyp1) + return TRUE; + /* neither grows up to become the other; no match */ + return FALSE; +} + /* * Return the permonst ptr for the race of the monster. * Returns correct pointer for non-polymorphed and polymorphed diff --git a/src/pline.c b/src/pline.c index 118ed82ee..2c174e672 100644 --- a/src/pline.c +++ b/src/pline.c @@ -145,7 +145,7 @@ VA_DECL(const char *, line) if ((pline_flags & SUPPRESS_HISTORY) == 0) dumplogmsg(line); #endif - if ((pline_flags & OVERRIDE_MSGTYPE) != 0) { + if ((pline_flags & OVERRIDE_MSGTYPE) == 0) { msgtyp = msgtype_type(line, no_repeat); if (msgtyp == MSGTYP_NOSHOW || (msgtyp == MSGTYP_NOREP && !strcmp(line, prevmsg))) diff --git a/src/timeout.c b/src/timeout.c index 430784e5a..e5187e93b 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 timeout.c $NHDT-Date: 1456526165 2016/02/26 22:36:05 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.65 $ */ +/* NetHack 3.6 timeout.c $NHDT-Date: 1493510119 2017/04/29 23:55:19 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.70 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -249,7 +249,7 @@ nh_timeout() baseluck -= 1; if (u.uluck != baseluck - && moves % (u.uhave.amulet || u.ugangr ? 300 : 600) == 0) { + && moves % ((u.uhave.amulet || u.ugangr) ? 300 : 600) == 0) { /* Cursed luckstones stop bad luck from timing out; blessed luckstones * stop good luck from timing out; normal luckstones stop both; * neither is stopped if you don't have a luckstone. diff --git a/src/trap.c b/src/trap.c index 2c9b4e511..ddf065a0c 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 trap.c $NHDT-Date: 1489745987 2017/03/17 10:19:47 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.277 $ */ +/* NetHack 3.6 trap.c $NHDT-Date: 1494107206 2017/05/06 21:46:46 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.278 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2794,6 +2794,9 @@ float_up() if (Flying) You("are no longer able to control your flight."); BFlying |= I_SPECIAL; + /* levitation gives maximum carrying capacity, so encumbrance + state might be reduced */ + (void) encumber_msg(); return; } @@ -2837,12 +2840,14 @@ long hmask, emask; /* might cancel timeout */ BFlying &= ~I_SPECIAL; if (Flying) { You("have stopped levitating and are now flying."); + (void) encumber_msg(); /* carrying capacity might have changed */ return 1; } } if (u.uswallow) { You("float down, but you are still %s.", is_animal(u.ustuck->data) ? "swallowed" : "engulfed"); + (void) encumber_msg(); return 1; } @@ -2924,6 +2929,11 @@ long hmask, emask; /* might cancel timeout */ } } + /* levitation gives maximum carrying capacity, so having it end + potentially triggers greater encumbrance; do this after + 'come down' messages, before trap activation or autopickup */ + (void) encumber_msg(); + /* can't rely on u.uz0 for detecting trap door-induced level change; it gets changed to reflect the new level before we can check it */ assign_level(¤t_dungeon_level, &u.uz); diff --git a/src/worn.c b/src/worn.c index 947f367b9..a99d1336d 100644 --- a/src/worn.c +++ b/src/worn.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 worn.c $NHDT-Date: 1446887541 2015/11/07 09:12:21 $ $NHDT-Branch: master $:$NHDT-Revision: 1.47 $ */ +/* NetHack 3.6 worn.c $NHDT-Date: 1493510127 2017/04/29 23:55:27 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.48 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -31,11 +31,11 @@ const struct worn { { 0, 0 } }; /* This only allows for one blocking item per property */ -#define w_blocks(o, m) \ - ((o->otyp == MUMMY_WRAPPING && ((m) &W_ARMC)) \ - ? INVIS \ - : (o->otyp == CORNUTHAUM && ((m) &W_ARMH) && !Role_if(PM_WIZARD)) \ - ? CLAIRVOYANT \ +#define w_blocks(o, m) \ + ((o->otyp == MUMMY_WRAPPING && ((m) & W_ARMC)) \ + ? INVIS \ + : (o->otyp == CORNUTHAUM && ((m) & W_ARMH) && !Role_if(PM_WIZARD)) \ + ? CLAIRVOYANT \ : 0) /* note: monsters don't have clairvoyance, so your role has no significant effect on their use of w_blocks() */