From the newsgroup: hangup save while picking up gold from the
floor in a shop would duplicate that gold in the save file. First the
gold amount was being added to hero's gold, then two messages were given
[pline() or prinv() about pickup followed by one from costly_gold() about
shop credit], and lastly the floor gold would be removed. The second
message could trigger --More-- and provide a controllable interruption
point between giving the gold to the hero and removing it from the floor.
Change this to do the removal step before feedback.
Fix the problem From a bug report. His system has a logical name "DATA" pointing at some disk, and
when the dlb utility tried to open "data" for inclusion in the library
being built at install time, it attempted to access the wrong thing and
failed. He then attempted to fix it in a manner which let dlb finish, by
modifying dlb_main.c to append "." to file names that lack a dot, but
then nethack couldn't access "dungeon" in the library because string
comparison didn't match the altered dlb directory entry of "dungeon.".
NetHack was working around this unintended interaction with the
environment issue in fopen_datafile(), and dlb was doing so for fopen()
but not open(). This moves nethack's fixup out of src/files.c and into
sys/vms/vmsfiles.c, adds another routine there so that both open() and
fopen() are covered, and updates the vms Makefiles so that the various
utility programs all link with vmsfiles. (The build script vmsbuild.com
puts object files into a library and gets that last bit for free.)
Reported a month ago by <email deleted>, putting on
a cloak of invisibility while blind and then using ';' or '/' to examine
yourself revealed that you had become invisible. This fix just changes
the lookat() output when you can't see that you can't see yourself. :-)
Probing and stethoscope still reveal invisibility, as will any message
which uses x_monnam() to identify the hero. (First part is intentional;
last part seems not worth bothering about--I'm not even sure that the
player can arrange to trigger it.)
From a bug report, if you're swallowed
while in a vault and the guard arrives, he'll ask your name even though
you're hidden within the engulfer. This makes him give a message and
then leave, as is already done if you're mimicking an object or unable to
speak.
This also suppresses his repeated "Move along!" message if you're
swallowed or held since it's silly to keep telling you to move when you
obviously can't.
From a bug report, a monster which
died by moving into a trap which was next to the hero standing on Elbereth
resulted in "The <mon> is killed! The <mon> turns to flee!". An earlier
change made monflee() return if it's given a dead monster, so the fleeing
message is no longer given. This fixes the place where monflee() was
inappropriately being called for a dead monster in the reported situation.
Fix the crash From a bug report, where
having the hit that cuts a long worm into two also take the original down
to 1 HP would result in clone_mon() returning null and nethack crashing due
to a segmentation fault or access violation. The same thing could happen
if there's been enough long worms created to get them flagged as extinct.
This bug was only present in 3.4.3. Prior to that, cut_worm() did
its own monster creation inline instead of calling clone_mon(), ignoring
extinction and too-low hit points.
From the newsgroup: you could get "suddenly you cannot see the <mon>"
even though it remained visible. Cited case was for an orc who drank a
potion of invisibility while being observed by a hero wielding Sting, which
causes orcs to be displayed even when they're invisible. But it could also
happen when non-blind telepathy or extended monster detection is in effect.
Another entry in $cvsroot/shared/bugs/buglist, this one reported by
<email deleted>: if the Wizard had the Amulet and used
his "double trouble" spell, his clone would attack him in order to try to
get the Amulet. This prevents any monster who's after the Amulet from
attacking the Wizard to get it.
From an entry in $cvsroot/shared/bugs/buglist From a bug report:
when item weights were all scaled up by a factor of 10 for 3.1.0, the
code controlling random item drops by monsters still limited small ones
to dropping things of 3 weight units of less. Scale that up to 30.
While testing something, I noticed that my last remaining discovery
would never be forgotten. The formula
count = ((count * percent) + 50) / 100
always yields 0 with count==1 and percent==25 (the value used for mind
flayer attacks). Not likely to come up in actual play very often....
From a bug report: nymphs could steal
boulders even though they aren't allowed to pick those up. It happened
becuase can_carry() is only called for monkeys (consequently, they don't
have this problem), not for nymphs.
From the newsgroup: Conflict caused tame engulfer to swallow hero.
To try to get out, player hit it (with Magicbane, but that's not relevant
other than to provide an alternate "you hit it" message).
The magic-absorbing blade probes the invisible Audrey!
You get regurgitated!
placing defunct monster onto map?
Program in disorder, &c
[some look_here() feedback]
You kill poor invisible Audrey!
The problem was caused by hmon_hitmon(): it subtracted damage from the
target's hit points, did some bookkeeping and message delivery, then
called killed(). One bit of bookkeeping was to call abuse_pet() and
monflee() when the target is tame, regardless of whether the damage was
fatal. monflee() -> release_hero() -> expels() puts the hero and the
engulfer back onto the map, and that warning was triggered because the
former engulfer had no hit points left.
From a bug report, getting the "you kick at
empty space" result doesn't use any turns but can have side-effects like
waking up monsters and negatively exercising hero's stats. It should take
a turn even though nothing gets kicked.
splatter_burning_oil() is called when a lit potion of oil gets
broken, and it can dish out fatal damage to the hero. An earlier fix
to prevent a light-source panic (thrown item is not on any of the object
lists) during bones creation didn't address leaving that lit potion
intact if it was on the floor (which can happen if the breakage is caused
by striking or force bolt rather than its being thrown or kicked). Use
the existing obj->in_use mechanism as a more general fix, after teaching
bones code that it applies to other things besides the hero's inventory.
Reverse the previous patch. It made other artifacts like Fire Brand
also do full damage against shades, which wasn't inteded. Back to the
drawing board....
From the newsgroup: Sunsword is ineffective against shades. It
gets a special bonus of double damage vs undead, but since it's not made
of silver it was only doing 1 point of damage against shades. Make the
bonus-vs-undead attribute override the silver-required criterion. (If
there's ever a whip or other flimsy weapon which gets a bonus against
some type(s) of thick-skinned monster, its attack will override the skin
thickness in similar fashion.)
A change a couple of weeks ago to have player's chosen ammo be auto-
quivered when using the 'f' command while quiver is empty was excluding
objects with quantity 1. That was on the basis that it was in the process
of being thrown so there was no point in putting it into the quiver slot
first. But if it was a boomerang, or Mjollnir under suitable conditions,
there was a chance for it to be available for another throw, so there is
a point to quivering it. Also, player can hit ESC at the direction prompt
and end up not throwing it after all. So, put even quantity 1 items into
the quiver when 'f' command is used with empty quiver.
I found a copy of a news posting from 1996 which suggested that
using a[pply] to break a wand which has 0 charges should have a chance of
wresting out one extra charge, like zapping. That way the player can't
destroy spent wands with impunity, and it makes the two wand actions be
more consistent. Also, it's trivial to implement. :-)
From the newsgroup: attempting to #chat to a gnome elicited "the
gnome grunts" (because gnomes have MS_ORC sound, and MS_ORC is just a
synonym for MS_GRUNT) even when the hero was a gnome. This patch makes
MS_ORC (orcs, gnomes, kobolds, a couple of named demons) or MS_GRUNT
(ogres, ettins, trolls, gargoyles) behave as MS_HUMANOID when the hero
has same race. That by itself wasn't quite enough; hostile MS_HUMANOID
monsters other than fake players wouldn't respond, so this gives those
a generic message (threatening the hero). In a somewhat similar case,
peaceful MS_CUSS monsters wouldn't respond; now they say something too.
There was a suggestion in the newsgroup that if you use the 'f'
command when your quiver is empty, that whatever missile you supply to the
"what do you want to throw?" prompt be automatically put into the quiver.
This implements that, and separates most of the common code from dothrow()
and dofire() into a separate routine. A post-3.4.3 change to dothrow() to
require hands for throwing wasn't propagated to dofire(). With the common
routine, they're much less likely to get out of sync like that.
This is going into the branch as well as the trunk because the hands
checking mismatch was added there too.
Reported--more or less--by <email deleted>:
chargeable rings don't show up as likely candidates in the "what do you
want to charge?" prompt. They're supposed to be there once the type has
been discovered but it was using the wrong field so basing that on whether
the player had assigned a name to the type instead. (Picking a chargeable
ring's letter even though it wasn't listed did work correctly though.)
Noticed while looking at something else: zapping a wand of opening
or spell of knock downwards while riding causes your steed's saddle to
fall off, which in turn causes the hero to fall and take some damage.
If that damage was fatal, the saddle would be left worn in bones data.
This reorganizes mdrop_obj() to defer until last the part that ultimately
makes the hero fall off, and changes bhitm() to call that instead of
handling saddle removal inline, also gives new saddle-off feedback there.
Reported in Dec'04 by <email deleted>, an
unpoly'd hero or a hero poly'd into monster form which lacks a kick
attack both get bonus from rings of increase damage when kicking, but
a hero poly'd into monster form which has a kick attack did not.
Back port the trunk fix that prevents stone-to-flesh on self when
wielding a figurine from leaving stale worn object pointer and eventually
triggering a panic or crash. Branch only except for fixes34.4 update.
From a bug report, walk_path() was
favoring orthogonal steps at beginning of the path and diagonal ones at
end, when intermixing diagonal and orthoganal produced a more accurate
representation of the real path. Only mattered for long distance jumps
3x2 or 3x1 steps away; hurtling always moves in a straight line and short
(2x1 knight) jumps aren't affected by the patch supplied with the report.
From the newsgroup: player chatted with leader and was ejected for
not being high enough level, then when he came back later there was no
leader to be found, but there was a polymorph trap on quest home level.
This makes quest leaders and nemesis be aware of all trap types--rather
than just having leaders be aware of magic portals--so they'll be able to
avoid polymorph traps. It also makes chatting with a polymorphed leader
work as long as the new form is able to speak (use same criteria as with
poly'd shopkeepers: can't be in a form that's limited to animal sounds).
I had intended to put the Hate_silver patch into the branch as well
as the trunk, but hit too much nonmatching context. When switching it to
be trunk only, I neglected to put the fixes entry into the proper file.
Monster werecritters are vulnerable to silver when in human form as
well as when in beast form, but hero inflicted with lycanthropy was only
vulnerable while in beast form. Add pseudo-property Hate_silver to handle
that correctly. Also, add silver vulnerability to enlightenment feedback.
Lastly, hero vulnerable to silver had Con abused if hit by silver missile
but not when hit hand-to-hand; add an exercise() call to the latter.
Many (most?) non-weapon artifacts show up in inventory and messages
as "the <foo> of <bar>" even when their underlying object type hasn't been
discovered yet. For types which don't use the `known' bit, obj->known is
forced to 1; obj_is_pname() checked that but not the oc_name_known flag
for the type. So you'd see things like "the Heart of Ahriman" instead of
"a luckstone named <the H of A>" or "a gray stone named <the H of A>" even
though it hadn't been identified yet, unintentionally hiding the artifact's
object type from the player.
While testing the figurine timer patch, I observed
The goblin wields a crude dagger.
You see a goblin drop out of your pack!
Rather than try to get the sequencing right, just prevent monsters made
by figurine activation or by the create familiar spell start without any
inventory. This will have a side effect of making wishes for a blessed
figurine of an archon be less powerful, because the subsequent pet A won't
come equipped with a shield of reflection and an artifact--or at least
rustproof--long sword anymore.
From a bug report: having a lit
candle or potion of oil be wielded or "worn" as alternate weapon or quiver
at the time it finished burning up would leave a stale worn object pointer
which could trigger a panic or crash. Need to call useup() instead of
obj_extract_self()+obfree() for objects in inventory, similar to the way
hatching eggs are handled.
From a bug report: attempting to apply
a towel which is currently "worn" in the weapon, alternate weapon, or
quiver slot fails with "you cannot use it while you're wearing it". The
message sounds odd when the towel is wielded, and there's no reason why
you shouldn't be able to use it when it's in any of those weapon slots.
Compare it with current blindfold rather than checking its owornmask.
<email deleted>, escaping from being stuck
by lava via jumping--or simply walking--got you out of the lava while being
at the same location. You could then stay there for as long as you liked
without falling back in. This makes a lava and water check on turns where
time passes but hero hasn't moved, performing a subset of spoteffects().
I think the water case only matters when using wizard mode to wish for a
pool or moat, which gets created at hero's feet without making him fall in
(unlike wishing for lava, where hero does immediately fall in).
Guard against buffer overflows when reading in score entries, in case
`record' has become corrupted or been maliciously modified. This addresses
the part of "#Q101: Security bug in nethack 3.4.3" that we have control
over. A Gentoo bug tracking discussion pointed out to us by <email deleted>, describes how that particular Linux
distribution makes users be members of the games group, allowing them to
modify files in nethack's playground directory when it has been set up in
the usual ``setgid games'' manner, thus making score processing in that
environment be vulnerable to buffer overrun exploits.
There was a report recently about "<pet> is still eating" coming out
on the console at end of game for player using X11 or Qt. That happened
because the end-of-game pet handling takes place after the message window
has been closed. It won't happen with the dev code any more because eating
no longer prevents pets from accompanying on final ascent or escape. But
a pet carrying the Amulet should still fail to tag along and yield similar
result. However, levl_follower() was changed (probably by me...) to have
pets not attempt to follow when they carried the Amulet, rendering code
in keepdogs()--which reported them as being confused--unreachable. This
reverts levl_follower() to have Amulet-carrying monsters other than the
Wizard try to accompany the hero during level changes (and keepdogs still
prevents them from succeeding). It also reorganizes keepdogs() a bit,
giving trapped followers an extra chance to escape from their trap and
preventing those who fail that chance from tagging along (previously,
non-pets ignored being trapped).
After doing that, I got tty to behave similarly to the X11/Qt report:
a message behaved strangely. In my case, it was delivered between a pair
of clearings of the screen and only visible by using terminal emulator's
scrolling buffer. I think there's a wait_synch() missing somewhere, but
haven't tried to figure out where. Instead, this makes the end-of-game
call to keepdogs() take place sooner, while pline() still works normally.
Dying at a shop doorway, or at the free spot one step in, while not
owing the shopkeeper anything would yield "<shk> gratefully inherites all
your possessions" but leave those possesions where the next hero could
just pick them up for free. Move them all the way inside the shop, as
happens when the hero dies while owing the shk. Also, if hero has gold
left after shopkeeper takes any payment owed, force it to go into shk's
inventory instead of having it end up in the pile of other stuff.
finish_paybill() duplicated much of drop_upon_death(), but not the
two-weapon hack to avoid curse() causing hero's secondary weapon to be
dropped while in the midst of removing it from inventory (but unlike the
old 3.4.1 panic for that, this one just triggered a warning about nonzero
worn mask). It also lacked the named fruit fixup, whatever that does.
Make finish_paybill() call drop_upon_death() instead of copying it.
Noticed while looking at the dipping code: #dip at a pool location
gives the chance to dip into the pool, and dipping a potion of acid into
such causes the acid to explode, causing damage and posibly killing the
hero. Use-up handling was being done after the dip had finished, so the
potion would remain in final inventory during disclosure and end up in
the resulting bones file if there was one.
From a bug report: zapping wand
of speed monster (or slow monster) at an immobile monster would give the
usual '<mon> is moving faster" (or slower) message even though the monster
couldn't move at all. This fixes that for monsters who can never move
and also for monsters who are temporarily paralyzed or asleep, although I
wonder whether speed change magic ought to also snap the latter out of it.
You can't begin or resume locking or unlocking a chest on the floor
while swallowed by a monster, but you could lock or unlock an adjacent
door in that situation.
From a bug report: you could end up
standing on water/lava if you survived being on an open drawbridge while
it was destroyed. This fixes the bridge destruction case; opening and
closing are handled differently and I left them alone.
Trunk and branch, noticed while working on an interface enhancement:
you could use #force to break the lock of a chest that's on the floor
while you're engulfed, also while levitating or mounted w/o riding skill.
Trunk only: refine an earlier fix that bills for breaking the lock
of a shop-owned chest. The item which the hero is forced to buy showed
up in the bill as unlockable, which is accurate after the fact but didn't
reflect the shop's item. Fix by billing for chest before altering it.
Simplify <Someone>'s patch (the part for the secondary weapon wasn't and
still isn't needed since dual-wielding can only occur when both primary
and alternate weapon slots contain weapons or weapon-tools, but we might
as well keep it). There was at least one other case where wielded in-use
leash could be removed from inventory without becoming unleashed first:
a bullwhip-wielding monster could snatch it away.
That lead to some other whip issues: monsters who select disarming
via bullwhip as miscellaneous strategy had 80% chance of not using it on
any given turn, but had no chance to select another misc strategy on such
turns--they always resorted to ordinary nonMUSE behavior and usually just
attacked. The adjacency check missed diagonal locations, also would aim
the disarm attempt accurately even when displacement or invisibility made
the hero's precise location unknown. [I took the easy way out here and
only let them try to disarm when they know the hero's location. It's
tempting to aim at the guessed location and sometimes accidentally disarm
a nearby monster, but disarming is an action which targets a particular
weapon rather than just a location.] Lastly, disarming always targetted
hero's primary weapon, never a dual-wielder's secondary one.
From a bug report, if you polymorph into
something, like a killer bee, that causes you to drop your weapon, but the
weapon is a wielded, in-use leash, the leash would be dropped but retain
it's in-use state. However, the leash was tied to you, so it seems it
should remain attached, just unwielded, just as it would if it hadn't been
wielded. I've changed the behavior to do this. I wonder whether one
should be able to wield an in-use leash.
From a bug report: gelatinous cubes
could engulf Rider corpses, allowing g.cube and cargo to be teleported
away without triggering corpse revival, or to be hit with theft attack by
poly'd hero to get the corpse into inventory so it could then be put into
a container in order to prevent revival (or to be destroyed via bag of
holding explosion or cursed access).
Noticed while checking out the report that you can #jump when riding
a sleeping steed: hero's sleep resistance or magical breathing prevented
sleeping gas traps from hitting steed. "You are enveloped in a cloud of
gas" but your steed is untouched? That didn't make sense.