From c429cf55849a89a33db39781945dcc8316f1888f Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 19 Dec 2018 14:52:23 -0800 Subject: [PATCH 1/9] fix github issue #169 - monst vs vibrating square Fixes #169 Monsters should not be afraid of stepping on the vibrating square since it's only a trap for display purposes. [Perhaps they should deliberately avoid it if the hero hasn't seen it yet, but I didn't implement that.] "You see a strange vibration beneath ." was strange when was a wolf's "rear paws" or horse's "rear hooves"--was the vibration magically skipping the front ones? And it sounded naughty when it was a snake's "rear regions". If the creature has no limbs or is floating or flying, just say "beneath "; otherwise, if the part is "rear ", omit "rear ". The message was weird in another way. Caller removes the monster from it's old location and places it on the new one, calls newsym() for the old location to show lack of monster, but then calls mintrap() before newsym() for monster's new location (the trap's location). If pline messages cause buffered map output to be flushed, the monster will be missing during the time the messages are delivered. I fixed that for vibrating square [seetrap()->newsym() before pline() rather than after] but it should probably be fixed in the caller instead. --- doc/fixes36.2 | 1 + src/mon.c | 3 ++- src/trap.c | 32 ++++++++++++++++++++++++-------- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index d7348a2ee..598527047 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -289,6 +289,7 @@ diluted potion of oil is less effective when filling lamps (adds less fuel) apply fix from grunthack to prevent panic "fakecorr overflow" when vault guard couldn't figure out how to lead the hero from vault to civilization; fixes longstanding bug C343-23 +vibrating square is not really a trap so monsters don't need to avoid it Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository diff --git a/src/mon.c b/src/mon.c index de037e42b..88aaf3dce 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mon.c $NHDT-Date: 1544658160 2018/12/12 23:42:40 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.274 $ */ +/* NetHack 3.6 mon.c $NHDT-Date: 1545259929 2018/12/19 22:52:09 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.275 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1476,6 +1476,7 @@ nexttry: /* eels prefer the water, but if there is no water nearby, if ((ttmp->ttyp != RUST_TRAP || mdat == &mons[PM_IRON_GOLEM]) && ttmp->ttyp != STATUE_TRAP + && ttmp->ttyp != VIBRATING_SQUARE && ((!is_pit(ttmp->ttyp) && !is_hole(ttmp->ttyp)) || (!is_flyer(mdat) && !is_floater(mdat) && !is_clinger(mdat)) || Sokoban) diff --git a/src/trap.c b/src/trap.c index d8d4018e7..965c9347e 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 trap.c $NHDT-Date: 1543515862 2018/11/29 18:24:22 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.312 $ */ +/* NetHack 3.6 trap.c $NHDT-Date: 1545259936 2018/12/19 22:52:16 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.313 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2691,13 +2691,29 @@ register struct monst *mtmp; break; case VIBRATING_SQUARE: if (see_it && !Blind) { - if (in_sight) - pline("You see a strange vibration beneath %s %s.", - s_suffix(mon_nam(mtmp)), - makeplural(mbodypart(mtmp, FOOT))); - else - pline("You see the ground vibrate in the distance."); - seetrap(trap); + seetrap(trap); /* before messages */ + if (in_sight) { + char buf[BUFSZ], *p, *monnm = mon_nam(mtmp); + + if (nolimbs(mtmp->data) + || is_floater(mtmp->data) || is_flyer(mtmp->data)) { + /* just "beneath " */ + Strcpy(buf, monnm); + } else { + Strcpy(buf, s_suffix(monnm)); + p = eos(strcat(buf, " ")); + Strcpy(p, makeplural(mbodypart(mtmp, FOOT))); + /* avoid "beneath 'rear paws'" or 'rear hooves' */ + (void) strsubst(p, "rear ", ""); + } + You_see("a strange vibration beneath %s.", buf); + } else { + /* notice something (hearing uses a larger threshold + for 'nearby') */ + You_see("the ground vibrate %s.", + (distu(mtmp->mx, mtmp->my) <= 2 * 2) + ? "nearby" : "in the distance"); + } } break; default: From 34b4d80d6babe9896a269f145b01e07f16a0ed08 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 19 Dec 2018 17:36:14 -0800 Subject: [PATCH 2/9] fix #H2582 - seemingly angry peaceful vault guard Another one from nearly 7 years ago. Hero kicked embedded gold out of a wall while following the guard away from the vault and got "The guard calms down and picks up the gold." and player thought it was odd because the guard was peaceful. It is odd, but guards have an agitation state (0..7) when peaceful and it is always non-zero when this event occurs. Suppress the "calms down" part unless the agitation is close to making the guard turn hostile. [Agitation is set to 5 after that event, so it isn't very calming.] Also, the guard was picking up gold from underneath the hero while two steps away. Move him adjacent (although it doesn't knock other monsters out of the way if there's no room) prior to the message, then back again after. That's how if works for gold that's not at the guard's location and not at the hero's location, although that case does knock another monster out of the way if one is on the gold. --- doc/fixes36.2 | 3 ++ src/vault.c | 129 ++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 102 insertions(+), 30 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index 598527047..b4437d63a 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -290,6 +290,9 @@ apply fix from grunthack to prevent panic "fakecorr overflow" when vault guard couldn't figure out how to lead the hero from vault to civilization; fixes longstanding bug C343-23 vibrating square is not really a trap so monsters don't need to avoid it +if hero kicks some embedded gold out of a wall while following vault gaurd + away from vault, don't report "the guard _calms_down_and_ picks up + the gold" unless he's on brink of going ballistic Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository diff --git a/src/vault.c b/src/vault.c index c23f55595..3945f215d 100644 --- a/src/vault.c +++ b/src/vault.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 vault.c $NHDT-Date: 1545217597 2018/12/19 11:06:37 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.58 $ */ +/* NetHack 3.6 vault.c $NHDT-Date: 1545269451 2018/12/20 01:30:51 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.59 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -15,6 +15,7 @@ STATIC_DCL boolean FDECL(find_guard_dest, (struct monst *, xchar *, xchar *)); STATIC_DCL void FDECL(move_gold, (struct obj *, int)); STATIC_DCL void FDECL(wallify_vault, (struct monst *)); STATIC_DCL void FDECL(gd_mv_monaway, (struct monst *, int, int)); +STATIC_OVL void FDECL(gd_pick_corridor_gold, (struct monst *, int, int)); void newegd(mtmp) @@ -604,9 +605,9 @@ struct monst *grd; } STATIC_OVL void -gd_mv_monaway(grd, nx,ny) +gd_mv_monaway(grd, nx, ny) register struct monst *grd; -int nx,ny; +int nx, ny; { if (MON_AT(nx, ny) && !(nx == grd->mx && ny == grd->my)) { if (!Deaf) @@ -616,6 +617,97 @@ int nx,ny; } } +/* have guard pick gold off the floor, possibly moving to the gold's + position before message and back to his current spot after */ +STATIC_OVL void +gd_pick_corridor_gold(grd, goldx, goldy) +struct monst *grd; +int goldx, goldy; /* ox, gold->oy> */ +{ + struct obj *gold; + coord newcc, bestcc; + int gdelta, newdelta, bestdelta, tryct, + guardx = grd->mx, guardy = grd->my; + boolean under_u = (goldx == u.ux && goldy == u.uy), + see_it = cansee(goldx, goldy); + + if (under_u) { + /* Grab the gold from between the hero's feet. + If guard is two or more steps away; bring him closer first. */ + gold = g_at(goldx, goldy); + if (!gold) { + impossible("vault guard: no gold at hero's feet?"); + return; + } + gdelta = distu(guardx, guardy); + if (gdelta > 2 && see_it) { /* skip if player won't see it */ + bestdelta = gdelta; + bestcc.x = (xchar) guardx, bestcc.y = (xchar) guardy; + tryct = 9; + do { + /* pick an available spot nearest the hero and also try + to find the one meeting that criterium which is nearest + the guard's current location */ + if (enexto(&newcc, goldx, goldy, grd->data)) { + if ((newdelta = distu(newcc.x, newcc.y)) < bestdelta + || (newdelta == bestdelta + && dist2(newcc.x, newcc.y, guardx, guardy) + < dist2(bestcc.x, bestcc.y, guardx, guardy))) { + bestdelta = newdelta; + bestcc = newcc; + } + } + } while (--tryct >= 0); + + if (bestdelta < gdelta) { + remove_monster(guardx, guardy); + newsym(guardx, guardy); + place_monster(grd, (int) bestcc.x, (int) bestcc.y); + newsym(grd->mx, grd->my); + } + } + obj_extract_self(gold); + add_to_minv(grd, gold); + newsym(goldx, goldy); + + /* guard is already at gold's location */ + } else if (goldx == guardx && goldy == guardy) { + mpickgold(grd); /* does a newsym */ + + /* gold is at some third spot, neither guard's nor hero's */ + } else { + /* just for insurance... */ + gd_mv_monaway(grd, goldx, goldy); /* make room for guard */ + if (see_it) { /* skip if player won't see the message */ + remove_monster(grd->mx, grd->my); + newsym(grd->mx, grd->my); + place_monster(grd, goldx, goldy); /* sets mx, grd->my> */ + } + mpickgold(grd); /* does a newsym */ + } + + if (see_it) { /* cansee(goldx, goldy) */ + char monnambuf[BUFSZ]; + + Strcpy(monnambuf, Monnam(grd)); + if (!strcmpi(monnambuf, "It")) + Strcpy(monnambuf, "Someone"); + pline("%s%s picks up the gold%s.", monnambuf, + (grd->mpeaceful && EGD(grd)->warncnt > 5) + ? " calms down and" : "", + under_u ? " from beneath you" : ""); + } + + /* if guard was moved to get the gold, move him back */ + if (grd->mx != guardx || grd->my != guardy) { + remove_monster(grd->mx, grd->my); + newsym(grd->mx, grd->my); + place_monster(grd, guardx, guardy); + newsym(guardx, guardy); + } + return; +} + /* * return 1: guard moved, 0: guard didn't, -1: let m_move do it, -2: died */ @@ -774,35 +866,12 @@ register struct monst *grd; m = egrd->fakecorr[fci].fx; n = egrd->fakecorr[fci].fy; goldincorridor = TRUE; + break; } + /* new gold can appear if it was embedded in stone and hero kicks it + (on even via wish and drop) so don't assume hero has been warned */ if (goldincorridor && !egrd->gddone) { - x = grd->mx; - y = grd->my; - if (m == u.ux && n == u.uy) { - struct obj *gold = g_at(m, n); - /* Grab the gold from between the hero's feet. */ - obj_extract_self(gold); - add_to_minv(grd, gold); - newsym(m, n); - } else if (m == x && n == y) { - mpickgold(grd); /* does a newsym */ - } else { - /* just for insurance... */ - gd_mv_monaway(grd, m,n); - remove_monster(grd->mx, grd->my); - newsym(grd->mx, grd->my); - place_monster(grd, m, n); - mpickgold(grd); /* does a newsym */ - } - if (cansee(m, n)) - pline("%s%s picks up the gold.", Monnam(grd), - grd->mpeaceful ? " calms down and" : ""); - if (x != grd->mx || y != grd->my) { - remove_monster(grd->mx, grd->my); - newsym(grd->mx, grd->my); - place_monster(grd, x, y); - newsym(x, y); - } + gd_pick_corridor_gold(grd, m, n); if (!grd->mpeaceful) return -1; egrd->warncnt = 5; From f7dd3b8215b683bbca713ced65aa6aee21015e7b Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 19 Dec 2018 17:52:49 -0800 Subject: [PATCH 3/9] clang on OSX The Unix Makefile.{src,utl} use the compiler name 'gcc' by default on OSX, and that invokes clang which defines __GNUC__ to deal with gcc extensions. But when invoked via the Xcode IDE, it evidently uses its own name instead, and wasn't defining __GNUC__. tradstdc.h started down the road of duplicating gcc features; switch to pretending to be gcc instead. --- include/tradstdc.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/include/tradstdc.h b/include/tradstdc.h index e6a8f3e8f..468ebdea8 100644 --- a/include/tradstdc.h +++ b/include/tradstdc.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 tradstdc.h $NHDT-Date: 1543371689 2018/11/28 02:21:29 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.32 $ */ +/* NetHack 3.6 tradstdc.h $NHDT-Date: 1545270756 2018/12/20 01:52:36 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.34 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -390,8 +390,10 @@ typedef genericptr genericptr_t; /* (void *) or (char *) */ #endif #ifdef __clang__ -#define UNUSED __attribute__((unused)) -#define NORETURN __attribute__((noreturn)) +/* clang's gcc emulation is sufficient for nethack's usage */ +#ifndef __GNUC__ +#define __GNUC__ 4 +#endif #endif /* From de1861aa0f486f797a5e0a4342e05288a1d5f8ee Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 20 Dec 2018 18:28:57 -0800 Subject: [PATCH 4/9] fix #H6189 - Eyes of the Overworld database entry The phrasing of the data.base entry for the Eyes of the Overworld reads as if it is continuing some passage in a reference book, but that comes off strange when using '/' to see it. Rephrase it. data.base could stand to have an entry for 'lenses'.... --- dat/data.base | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/dat/data.base b/dat/data.base index ebb781af7..410912710 100644 --- a/dat/data.base +++ b/dat/data.base @@ -1,5 +1,5 @@ # NetHack 3.6 data.base -# $NHDT-Date: 1524683801 2018/04/25 19:16:41 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.84 $ +# $NHDT-Date: 1545359287 2018/12/21 02:28:07 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.87 $ # Copyright (c) 1994, 1995, 1996 by the NetHack Development Team # Copyright (c) 1994 by Boudewijn Wayers # NetHack may be freely redistributed. See license for details. @@ -1629,9 +1629,19 @@ eye of the aethiopica the power to instantly open a portal to any other area of the dungeon, allowing its invoker to travel quickly between areas. +# note: The Eyes of the Overworld is the title of Jack Vance's sequel +# to The Dying Earth and in it the 'Eyes' were separate "cusps" that +# needed to be worn like contact lenses, one on each eyeball. Wearing +# just one and attempting to look with both eyes caused instant stun. +# And when wearing two you couldn't see normal world, only a projection +# of it that had similar topology but where everything was "better". +# NetHack simplifies things: a pair of lenses is a single item like +# spectacles (eyeglasses), and the effect of wearing these lenses has +# been changed to be useful to game play (Xray vision). [The quote is +# not derived from the book.] eyes of the overworld - ... and finally there is "the Eyes of the Overworld". This - obscure artifact pushes the wearer's view sense into the + The Eyes of the Overworld is a rather obscure artifact. + These magical lenses push the wearer's view sense into the "overworld" -- another name for a segment of the Astral Plane. Usually, there is nothing to be seen. However, the wearer is also able to look back and see the area around herself, From 4e1eecc7fa20472fbecaced78a8e4687d1d432c0 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 20 Dec 2018 18:58:44 -0800 Subject: [PATCH 5/9] data.base lookup bit When testing the change to the Eyes of the Overworld wording and asking for information about inventory item k - a pair of lenses named The Eyes of the Overworld I got "I don't have any information on those things". Not because that item wasn't identified, but because the lookup was for "pair of lenses" (finding nothing) and then for "The Eyes of the Overworld" (and not finding it due to "The" which is stripped from the first attempt but wasn't from the second nor present in the data.base key). --- doc/fixes36.2 | 2 ++ src/pager.c | 12 +++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index b4437d63a..b080b417d 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -293,6 +293,8 @@ vibrating square is not really a trap so monsters don't need to avoid it if hero kicks some embedded gold out of a wall while following vault gaurd away from vault, don't report "the guard _calms_down_and_ picks up the gold" unless he's on brink of going ballistic +for '/?' information lookup, "item named The Artifact" failed to find info + about "Artifact" due to presence of "The" Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository diff --git a/src/pager.c b/src/pager.c index 6982860c9..f15c40f59 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pager.c $NHDT-Date: 1545129848 2018/12/18 10:44:08 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.142 $ */ +/* NetHack 3.6 pager.c $NHDT-Date: 1545361111 2018/12/21 02:58:31 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.143 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -576,6 +576,8 @@ char *supplemental_name; if (*dbase_str == ' ') ++dbase_str; } + if (!strncmp(dbase_str, "pair of ", 8)) + dbase_str += 8; if (!strncmp(dbase_str, "tame ", 5)) dbase_str += 5; else if (!strncmp(dbase_str, "peaceful ", 9)) @@ -640,6 +642,14 @@ char *supplemental_name; ep = strstri(dbase_str, ", "); if (ep && ep > dbase_str) *ep = '\0'; + /* remove article from 'alt' name ("a pair of lenses named + The Eyes of the Overworld" simplified above to "lenses named + The Eyes of the Overworld", now reduced to "The Eyes of the + Overworld", skip "The" as with base name processing) */ + if (!strncmpi(alt, "a ", 2) + || !strncmpi(alt, "an ", 3) + || !strncmpi(alt, "the ", 4)) + alt = index(alt, ' ') + 1; /* remove charges or "(lit)" or wizmode "(N aum)" */ if ((ep = strstri(dbase_str, " (")) != 0 && ep > dbase_str) *ep = '\0'; From 0e583161094b417eb64e5c3b02fb91f854fe7ebb Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 21 Dec 2018 01:14:45 -0800 Subject: [PATCH 6/9] fix #H2680 - IDing unpaid gem should adjust price Another one from 6.5 years ago, identifying a type of gem should give a new price for any unpaid gems of that type and adjust shopping bill accordingly. Report was for rubbing with touchstone and learning worthless glass with price not changing until the learned 'gem' was dropped. Fix works for that and also other forms of identification (and for amnesia, raising prices of forgotten gems); no dropping is required for the price to change. Theoretically could apply to any type of item, but prices of gems are by far the most sensitive to whether or not they're identified. --- doc/fixes36.2 | 2 ++ include/extern.h | 3 ++- src/o_init.c | 10 ++++++++-- src/shk.c | 41 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index b080b417d..e9484a622 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -295,6 +295,8 @@ if hero kicks some embedded gold out of a wall while following vault gaurd the gold" unless he's on brink of going ballistic for '/?' information lookup, "item named The Artifact" failed to find info about "Artifact" due to presence of "The" +identifying or forgetting gem types now adjusts prices for gems already on + shopping bill Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index bd0255c2a..78c7647da 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1545182146 2018/12/19 01:15:46 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.674 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1545383614 2018/12/21 09:13:34 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.675 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2220,6 +2220,7 @@ E long FDECL(contained_cost, (struct obj *, struct monst *, long, BOOLEAN_P, BOOLEAN_P)); E long FDECL(contained_gold, (struct obj *)); E void FDECL(picked_container, (struct obj *)); +E void FDECL(gem_learned, (int)); E void FDECL(alter_cost, (struct obj *, long)); E long FDECL(unpaid_cost, (struct obj *, BOOLEAN_P)); E boolean FDECL(billable, (struct monst **, struct obj *, CHAR_P, BOOLEAN_P)); diff --git a/src/o_init.c b/src/o_init.c index b4fc440ee..b2d28f50e 100644 --- a/src/o_init.c +++ b/src/o_init.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 o_init.c $NHDT-Date: 1528332336 2018/06/07 00:45:36 $ $NHDT-Branch: NetHack-3.6.2 $:$NHDT-Revision: 1.24 $ */ +/* NetHack 3.6 o_init.c $NHDT-Date: 1545383615 2018/12/21 09:13:35 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.25 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -362,8 +362,11 @@ boolean credit_hero; exercise(A_WIS, TRUE); } /* moves==1L => initial inventory, gameover => final disclosure */ - if (moves > 1L && !program_state.gameover) + if (moves > 1L && !program_state.gameover) { + if (objects[oindx].oc_class == GEM_CLASS) + gem_learned(oindx); /* could affect price of unpaid gems */ update_inventory(); + } } } @@ -390,6 +393,9 @@ register int oindx; disco[dindx - 1] = 0; else impossible("named object not in disco"); + + if (objects[oindx].oc_class == GEM_CLASS) + gem_learned(oindx); /* ok, it's actually been unlearned */ update_inventory(); } } diff --git a/src/shk.c b/src/shk.c index 1a50616e9..315de4c1d 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 shk.c $NHDT-Date: 1545036290 2018/12/17 08:44:50 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.143 $ */ +/* NetHack 3.6 shk.c $NHDT-Date: 1545383616 2018/12/21 09:13:36 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.144 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2278,6 +2278,45 @@ register struct monst *shkp; return tmp; } +/* unlike alter_cost() which operates on a specific item, identifying or + forgetting a gem causes all unpaid gems of its type to change value */ +void +gem_learned(oindx) +int oindx; +{ + struct obj *obj; + struct monst *shkp; + struct bill_x *bp; + int ct; + + /* + * Unfortunately, shop bill doesn't have object type included, + * just obj->oid for each unpaid stack, so we have to go through + * every bill and every item on that bill and match up against + * every unpaid stack on the level.... + * + * Fortunately, there's no need to catch up when changing dungeon + * levels even if we ID'd or forget some gems while gone from a + * level. There won't be any shop bills when arriving; they were + * either paid before leaving or got treated as robbery and it's + * too late to adjust pricing. + */ + for (shkp = next_shkp(fmon, TRUE); shkp; + shkp = next_shkp(shkp->nmon, TRUE)) { + ct = ESHK(shkp)->billct; + bp = ESHK(shkp)->bill; + while (--ct >= 0) { + obj = find_oid(bp->bo_id); + if (!obj) /* shouldn't happen */ + continue; + if ((oindx != STRANGE_OBJECT) ? (obj->otyp == oindx) + : (obj->oclass == GEM_CLASS)) + bp->price = get_cost(obj, shkp); + ++bp; + } + } +} + /* called when an item's value has been enhanced; if it happens to be on any shop bill, update that bill to reflect the new higher price [if the new price drops for some reason, keep the old one in place] */ From d3682dd5ca549daf2971db6655d7cef9213417ac Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 21 Dec 2018 14:36:55 -0800 Subject: [PATCH 7/9] monsters on melting ice Reported seven years ago, when ice melts underneath a monster, it hovers there until its next move, then falls in and drowns. Dunk it immediately, and give hero credit/blame if it happens during the hero's turn (so presumably the melting was caused by the hero). Also, let monster with teleport capability who gets dunked teleport away from the water before getting wet, the way hero does. --- doc/fixes36.2 | 2 ++ src/mon.c | 36 +++++++++++++++++++++++++++++++----- src/zap.c | 15 +++++++++++++-- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index e9484a622..68894447e 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -297,6 +297,8 @@ for '/?' information lookup, "item named The Artifact" failed to find info about "Artifact" due to presence of "The" identifying or forgetting gem types now adjusts prices for gems already on shopping bill +when fire converts an ice location into a water location, dunk any monster on + that spot immediately instead of waiting until its next move Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository diff --git a/src/mon.c b/src/mon.c index 88aaf3dce..73df0bcd8 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mon.c $NHDT-Date: 1545259929 2018/12/19 22:52:09 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.275 $ */ +/* NetHack 3.6 mon.c $NHDT-Date: 1545430257 2018/12/21 22:10:57 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.276 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -541,6 +541,12 @@ register struct monst *mtmp; * themselves --ALI */ if (!is_clinger(mtmp->data) && !likes_lava(mtmp->data)) { + /* not fair...? hero doesn't automatically teleport away + from lava, just from water */ + if (can_teleport(mtmp->data) && !tele_restrict(mtmp)) { + if (rloc(mtmp, TRUE)) + return 0; + } if (!resists_fire(mtmp)) { if (cansee(mtmp->mx, mtmp->my)) { struct attack *dummy = &mtmp->data->mattk[0]; @@ -551,7 +557,14 @@ register struct monst *mtmp; : !strcmp(how, "melting") ? "melts away" : "burns to a crisp"); } - mondead(mtmp); + /* unlike fire -> melt ice -> pool, there's no way for the + hero to create lava beneath a monster, so the !mon_moving + case is not expected to happen (and we haven't made a + player-against-monster variation of the message above) */ + if (context.mon_moving) + mondead(mtmp); + else + xkilled(mtmp, XKILL_NOMSG); } else { mtmp->mhp -= 1; if (DEADMONSTER(mtmp)) { @@ -576,16 +589,29 @@ register struct monst *mtmp; */ if (!is_clinger(mtmp->data) && !is_swimmer(mtmp->data) && !amphibious(mtmp->data)) { + /* like hero with teleport intrinsic or spell, teleport away + if possible */ + if (can_teleport(mtmp->data) && !tele_restrict(mtmp)) { + if (rloc(mtmp, TRUE)) + return 0; + } if (cansee(mtmp->mx, mtmp->my)) { - pline("%s drowns.", Monnam(mtmp)); + if (context.mon_moving) + pline("%s drowns.", Monnam(mtmp)); + else + /* hero used fire to melt ice that monster was on */ + You("drown %s.", mon_nam(mtmp)); } if (u.ustuck && u.uswallow && u.ustuck == mtmp) { /* This can happen after a purple worm plucks you off a - flying steed while you are over water. */ + flying steed while you are over water. */ pline("%s sinks as %s rushes in and flushes you out.", Monnam(mtmp), hliquid("water")); } - mondead(mtmp); + if (context.mon_moving) + mondead(mtmp); + else + xkilled(mtmp, XKILL_NOMSG); if (!DEADMONSTER(mtmp)) { water_damage_chain(mtmp->minvent, FALSE); (void) rloc(mtmp, FALSE); diff --git a/src/zap.c b/src/zap.c index 6907880e4..eb61a261c 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 zap.c $NHDT-Date: 1544442714 2018/12/10 11:51:54 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.302 $ */ +/* NetHack 3.6 zap.c $NHDT-Date: 1545431660 2018/12/21 22:34:20 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.303 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -4040,8 +4040,12 @@ boolean say; /* Announce out of sight hit/miss events if true */ /* hit() and miss() need bhitpos to match the target */ bhitpos.x = sx, bhitpos.y = sy; /* Fireballs only damage when they explode */ - if (type != ZT_SPELL(ZT_FIRE)) + if (type != ZT_SPELL(ZT_FIRE)) { range += zap_over_floor(sx, sy, type, &shopdamage, 0); + /* zap with fire -> melt ice -> drown monster, so monster + found and cached above might not be here any more */ + mon = m_at(sx, sy); + } if (mon) { if (type == ZT_SPELL(ZT_FIRE)) @@ -4244,6 +4248,7 @@ const char *msg; { struct rm *lev = &levl[x][y]; struct obj *otmp; + struct monst *mtmp; if (!msg) msg = "The ice crackles and melts."; @@ -4281,6 +4286,8 @@ const char *msg; } if (x == u.ux && y == u.uy) spoteffects(TRUE); /* possibly drown, notice objects */ + else if (is_pool(x, y) && (mtmp = m_at(x, y)) != 0) + (void) minliquid(mtmp); } #define MIN_ICE_TIME 50 @@ -4327,11 +4334,15 @@ long timeout UNUSED; { xchar x, y; long where = arg->a_long; + boolean save_mon_moving = context.mon_moving; /* will be False */ + /* melt_ice -> minliquid -> mondead|xkilled shouldn't credit/blame hero */ + context.mon_moving = TRUE; /* hero isn't causing this ice to melt */ y = (xchar) (where & 0xFFFF); x = (xchar) ((where >> 16) & 0xFFFF); /* melt_ice does newsym when appropriate */ melt_ice(x, y, "Some ice melts away."); + context.mon_moving = save_mon_moving; } /* Burn floor scrolls, evaporate pools, etc... in a single square. From 4159dd985aa94e55c07ddb7e5280b83237a2a085 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 21 Dec 2018 16:59:01 -0800 Subject: [PATCH 8/9] fix #2468 - killer bees without a queen Seven year old suggestion was to have a killer bee eat royal jelly if there was no queen around, then after a short delay it would become a queen. This does that, with "no queen around" being "no queen bee on current dungeon level" and the transformation happening immediately with the "short delay" taking place after. Pet killer bees will target nearby royal jelly if there's no queen, hostile killer bees will only eat it if they happen to walk on the same spot as one. Both types accept either tame or hostile queen bee as an existing queen. Killer bees eating royal jelly will drop dead if queen bees have been genocided, and aren't smart enough to avoid the instinct to eat such if/when that happens to be the situation. --- doc/fixes37.0 | 2 ++ include/extern.h | 3 ++- src/dog.c | 17 ++++++++++++- src/dogmove.c | 18 +++++++++----- src/makemon.c | 8 ++++--- src/monmove.c | 62 +++++++++++++++++++++++++++++++++++++++++++----- 6 files changed, 93 insertions(+), 17 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index c83af6c37..465eef81d 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -14,6 +14,8 @@ Platform- and/or Interface-Specific Fixes General New Features -------------------- +if a killer bee encounters a lump of royal jelly and there is no queen bee on + the level, the bee will eat the jelly and become a new queen Platform- and/or Interface-Specific New Features diff --git a/include/extern.h b/include/extern.h index 78c7647da..10d7335d5 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1545383614 2018/12/21 09:13:34 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.675 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1545439142 2018/12/22 00:39:02 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.676 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1487,6 +1487,7 @@ E boolean FDECL(monhaskey, (struct monst *, BOOLEAN_P)); E void FDECL(mon_regen, (struct monst *, BOOLEAN_P)); E int FDECL(dochugw, (struct monst *)); E boolean FDECL(onscary, (int, int, struct monst *)); +E int FDECL(bee_eat_jelly, (struct monst *, struct obj *)); E void FDECL(monflee, (struct monst *, int, BOOLEAN_P, BOOLEAN_P)); E void FDECL(mon_yells, (struct monst *, const char *)); E int FDECL(dochug, (struct monst *)); diff --git a/src/dog.c b/src/dog.c index 93a33716e..051a46f26 100644 --- a/src/dog.c +++ b/src/dog.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dog.c $NHDT-Date: 1543052701 2018/11/24 09:45:01 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.84 $ */ +/* NetHack 3.6 dog.c $NHDT-Date: 1545439150 2018/12/22 00:39:10 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.85 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -757,6 +757,21 @@ register struct obj *obj; if ((obj->otyp == CORPSE || obj->otyp == EGG) && touch_petrifies(fptr) && !resists_ston(mon)) return POISON; + if (obj->otyp == LUMP_OF_ROYAL_JELLY + && mon->data == &mons[PM_KILLER_BEE]) { + struct monst *mtmp = 0; + + /* if there's a queen bee on the level, don't eat royal jelly; + if there isn't, do eat it and grow into a queen */ + if ((mvitals[PM_QUEEN_BEE].mvflags & G_GENOD) == 0) + for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { + if (DEADMONSTER(mtmp)) + continue; + if (mtmp->data == &mons[PM_QUEEN_BEE]) + break; + } + return !mtmp ? DOGFOOD : TABU; + } if (!carni && !herbi) return obj->cursed ? UNDEF : APPORT; diff --git a/src/dogmove.c b/src/dogmove.c index 1c8f4dd79..8a3cd1b04 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dogmove.c $NHDT-Date: 1502753407 2017/08/14 23:30:07 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.63 $ */ +/* NetHack 3.6 dogmove.c $NHDT-Date: 1545439152 2018/12/22 00:39:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.72 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -211,7 +211,7 @@ boolean devour; { register struct edog *edog = EDOG(mtmp); boolean poly, grow, heal, eyes, slimer, deadmimic; - int nutrit; + int nutrit, res; long oprice; char objnambuf[BUFSZ]; @@ -250,6 +250,11 @@ boolean devour; newsym(x, y); newsym(mtmp->mx, mtmp->my); } + if (mtmp->data == &mons[PM_KILLER_BEE] + && obj->otyp == LUMP_OF_ROYAL_JELLY + && (res = bee_eat_jelly(mtmp, obj)) >= 0) + /* bypass most of dog_eat(), including apport update */ + return (res + 1); /* 1 -> 2, 0 -> 1; -1, keep going */ /* food items are eaten one at a time; entire stack for other stuff */ if (obj->quan > 1L && obj->oclass == FOOD_CLASS) @@ -379,8 +384,9 @@ struct edog *edog; else You_feel("worried about %s.", y_monnam(mtmp)); stop_occupation(); - } else if (monstermoves > edog->hungrytime + 750 || DEADMONSTER(mtmp)) { - dog_died: + } else if (monstermoves > edog->hungrytime + 750 + || DEADMONSTER(mtmp)) { + dog_died: if (mtmp->mleashed && mtmp != u.usteed) Your("leash goes slack."); else if (cansee(mtmp->mx, mtmp->my)) @@ -1184,7 +1190,7 @@ int after; /* this is extra fast monster movement */ } } -newdogpos: + newdogpos: if (nix != omx || niy != omy) { boolean wasseen; @@ -1256,7 +1262,7 @@ newdogpos: } cc.x = mtmp->mx; cc.y = mtmp->my; - dognext: + dognext: if (!m_in_out_region(mtmp, nix, niy)) return 1; remove_monster(mtmp->mx, mtmp->my); diff --git a/src/makemon.c b/src/makemon.c index d78363130..9c6bd6b43 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 makemon.c $NHDT-Date: 1544998885 2018/12/16 22:21:25 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.131 $ */ +/* NetHack 3.6 makemon.c $NHDT-Date: 1545439153 2018/12/22 00:39:13 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.132 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1801,9 +1801,11 @@ struct monst *mtmp, *victim; return (struct permonst *) 0; /* note: none of the monsters with special hit point calculations - have both little and big forms */ + have both little and big forms (killer bee can't grow into queen + bee by just killing things, so isn't in the little_to_big list) */ oldtype = monsndx(ptr); - newtype = little_to_big(oldtype); + newtype = (oldtype == PM_KILLER_BEE && !victim) ? PM_QUEEN_BEE + : little_to_big(oldtype); if (newtype == PM_PRIEST && mtmp->female) newtype = PM_PRIESTESS; diff --git a/src/monmove.c b/src/monmove.c index fbc2d419d..a59963aec 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 monmove.c $NHDT-Date: 1544442712 2018/12/10 11:51:52 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.109 $ */ +/* NetHack 3.6 monmove.c $NHDT-Date: 1545439153 2018/12/22 00:39:13 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.110 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -254,6 +254,48 @@ struct monst *mon; } } +/* killer bee 'mon' is on a spot containing lump of royal jelly 'obj' and + will eat it if there is no queen bee on the level; return 1: mon died, + 0: mon ate jelly and lived; -1: mon didn't eat jelly to use its move */ +int +bee_eat_jelly(mon, obj) +struct monst *mon; +struct obj *obj; +{ + int m_delay; + struct monst *mtmp = 0; + + /* find a queen bee */ + if ((mvitals[PM_QUEEN_BEE].mvflags & G_GENOD) == 0) + for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { + if (DEADMONSTER(mtmp)) + continue; + if (mtmp->data == &mons[PM_QUEEN_BEE]) + break; + } + /* if there's no queen on the level, eat the royal jelly and become one */ + if (!mtmp) { + m_delay = obj->blessed ? 3 : !obj->cursed ? 5 : 7; + if (obj->quan > 1L) + obj = splitobj(obj, 1L); + if (canseemon(mon)) + pline("%s eats %s.", Monnam(mon), an(xname(obj))); + delobj(obj); + + if ((int) mon->m_lev < mons[PM_QUEEN_BEE].mlevel - 1) + mon->m_lev = (uchar) (mons[PM_QUEEN_BEE].mlevel - 1); + /* there should be delay after eating, but that's too much + hassle; transform immediately, then have a short delay */ + (void) grow_up(mon, (struct monst *) 0); + + if (DEADMONSTER(mon)) + return 1; /* dead; apparently queen bees have been genocided */ + mon->mfrozen = m_delay, mon->mcanmove = 0; + return 0; /* bee used its move */ + } + return -1; /* a queen is already present; ordinary bee hasn't moved yet */ +} + #define flees_light(mon) ((mon)->data == &mons[PM_GREMLIN] \ && (uwep && artifact_light(uwep) && uwep->lamplit)) /* we could include this in the above macro, but probably overkill/overhead */ @@ -371,7 +413,8 @@ register struct monst *mtmp; { register struct permonst *mdat; register int tmp = 0; - int inrange, nearby, scared; + int inrange, nearby, scared, res; + struct obj *otmp; /* Pre-movement adjustments */ @@ -379,11 +422,10 @@ register struct monst *mtmp; mdat = mtmp->data; if (mtmp->mstrategy & STRAT_ARRIVE) { - int res = m_arrival(mtmp); + res = m_arrival(mtmp); if (res >= 0) return res; } - /* check for waitmask status change */ if ((mtmp->mstrategy & STRAT_WAITFORU) && (m_canseeu(mtmp) || mtmp->mhp < mtmp->mhpmax)) @@ -541,9 +583,9 @@ register struct monst *mtmp; } } } -toofar: + toofar: - /* If monster is nearby you, and has to wield a weapon, do so. This + /* If monster is nearby you, and has to wield a weapon, do so. This * costs the monster a move, of course. */ if ((!mtmp->mpeaceful || Conflict) && inrange @@ -571,6 +613,14 @@ toofar: /* Now the actual movement phase */ + if (mdat == &mons[PM_KILLER_BEE] + /* could be smarter and deliberately move to royal jelly, but + then we'd need to scan the level for queen bee in advance; + avoid that overhead and rely on serendipity... */ + && (otmp = sobj_at(LUMP_OF_ROYAL_JELLY, mtmp->mx, mtmp->my)) != 0 + && (res = bee_eat_jelly(mtmp, otmp)) >= 0) + return res; + if (!nearby || mtmp->mflee || scared || mtmp->mconf || mtmp->mstun || (mtmp->minvis && !rn2(3)) || (mdat->mlet == S_LEPRECHAUN && !findgold(invent) From 8dfc10d8c62e94c42f0f35a9e43d4f20464579af Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 21 Dec 2018 17:11:22 -0800 Subject: [PATCH 9/9] fix #H2709 - exercise_steed() for riding skill Code appears to intend that riding for 100 turns be treated like a successful weapon hit as far as skill training goes, but it was actually requiring 101 turns each time. It's conceivable that that was intentional, but unlikely. --- doc/fixes36.2 | 1 + src/steed.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index 68894447e..d891d6e63 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -299,6 +299,7 @@ identifying or forgetting gem types now adjusts prices for gems already on shopping bill when fire converts an ice location into a water location, dunk any monster on that spot immediately instead of waiting until its next move +training riding skill had an off-by-one bug when counting turns riding Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository diff --git a/src/steed.c b/src/steed.c index a90a0ce86..feede89c5 100644 --- a/src/steed.c +++ b/src/steed.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 steed.c $NHDT-Date: 1544666049 2018/12/13 01:54:09 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.61 $ */ +/* NetHack 3.6 steed.c $NHDT-Date: 1545441042 2018/12/22 01:10:42 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.62 $ */ /* Copyright (c) Kevin Hugo, 1998-1999. */ /* NetHack may be freely redistributed. See license for details. */ @@ -366,7 +366,7 @@ exercise_steed() return; /* It takes many turns of riding to exercise skill */ - if (u.urideturns++ >= 100) { + if (++u.urideturns >= 100) { u.urideturns = 0; use_skill(P_RIDING, 1); }