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.
From a bug report, applying a bullwhip
towards a monster to try to steal its weapon would report that a cursed
cockatrice corpse was welded to the monster's hands even though corpses
wielded by the player never become welded. Code for monsters deciding
what to wield knew that corpses don't weld; everywhere else seems to
assume that they only wield weldable weapons. Add a routine to check
whether a wielded item is welded, similar to what's done for the hero. I
fixed a couple of other spots besides use_whip() but didn't hunt all over.
From a bug report, putting an object with
really long specific and type names into a container with really long
specific and type names caused the program to crash. pline() overflowed
the buffer it formatted into, and even though it was able to send that
for output and trigger a --More-- prompt, eventually a segfault occurred.
Give vpline and vraw_printf a much bigger working buffer, then truncate
the formatted text to BUFSZ - 1 characters so that we don't just push the
long line trouble into the separate interfaces.
From a bug report: if you try to tin a
Rider's corpse and revival fails, you still get the gimicky message about
War not preserving his enemies. Give the suggested alternate message in
that case: The corpse evades your grasp. I hope that we can do better
than that, but I'm too burned out to think of anything.
From a bug report: a shapechanger
which becomes a mimic would always stay as 'm' rather than take on object
or furniture shape. Same applied to monsters which hide in other ways.
The code did that deliberately, but I don't think that it's actually
necessary so this lets them mimic/hide when they're in the right shape.
If they change form to non-mimic/hider while concealed, concealment ends.
It would be fun to have shapechangers-as-mimics actually change their
mimicked shapes periodically, but this doesn't do that. They'd probably
change to non-mimic quicker than they'd mimic something else so it's not
worth the effort.
From a bug report, but
just received: if you choked while eating a cockatrice egg and survived,
the turn-to-stone sequence wouldn't be initiated. For such eggs, turning
to stone starts when the food is finished rather than when it's started,
and fpostfx() wasn't called for food that triggered choking so the egg
went away without actually being finished. Fortune cookies, lumps of
royal jelly, and a few other things suffered from the same situation.
From a bug report, hitting a rust monster with a
fireproof--but not identified as fireproof--weapon caused the rknown bit
to become set, identifying the item as fireproof. That would also happen
for a monster's anything-proof weapon if it hit a rust monster, whether
you could see it happen or not. The code involved is convoluted; I hope
this fix is correct.
From a bug report: you could vomit when polymorphed into a rat but real life
rats can't/don't vomit. The latter was confirmed by <Someone> and <Someone>.
While testing a fix for this, I discovered a couple of other problems.
Healing magic which cured sickness failed to heal Vomiting (potion or
spell; unicorn horn deals with them separately). Enlightenment failed to
report Vomiting (it's not shown on the status line). Most significant was
that vomiting_dialogue() called vomit() twice (also make_confused() and
make_stunned() three times for every once intended). It was dividing the
remaining turns by 3 and then using that value to decide what to do, but
only message display took into account that the same divided value would
occur on 3 consecutive turns (or just 2 for the final countdown to 0,
because dialog routine gets called before timed-property decrement).
From a bug report, but just received:
you can't affix candles to the candelabrum while underwater, because the
underwater check (can't light candles while underwater) is made too soon.
If you somehow managed to get a lit lamp, candle, or candelabrum while
underwater, you wouldn't be able to extinguish it for same reason. The
bug report included a URL for a fix, but I didn't look at that. This
changes use_candle() to rely on use_lamp() for underwater handling, and
changes use_lamp() and use_candelabrum() to check for extinguishing
before making the underwater check.
From a bug report. (Michael forwarded a newsgroup posting about it back
then, but I had trouble reproducing it and didn't figure it out until
trying again now.) If hangup occurred while entering the quest, the magic
portal could be rendered inactive for the hero but still work for monsters.
That's because the hangup save stored the old value of u.uz0 before
goto_level set it to the new u.uz, and a magic portal won't operate when
u.uz0 differs from u.uz (to prevent a pair of portals from getting stuck
sending the hero back and forth). The problem could also occur going from
the quest back to the dungeon, or either direction for Ft.Ludios, but the
--More-- prompt when the quest entry text is being displayed makes hangup
during level change most likely to occur during initial quest entry.
This is just a bandaid, and the SAFERHANGUP config wouldn't be hit
by this situation.
#Q85: Bug: wrest a wand in one turn through engraving
From a bug report: engraving with an empty wand while not levitating, then using
ESC to abort when asked for the text to write, let you attempt to wrest
the last charge without using up a turn. Between the time this report was
sent and received, someone else reported similar issue with levitation,
where no prompting occurs. The fix for it also fixed the original problem.
Somewhat inadvertently though, since you can now no longer write in the
dust with a empty wand. I'm going to leave it this way; all that's needed
is some feedback about failing to engrave.
From a bug report: if you
attempted to engrave with an empty wand while levitating, it wouldn't use
a turn unless you successfully wrested an extra charge out of the wand.
So you could always get such charge in a single elapsed turn of game time
if you didn't care about zapping in any particular direction; extremely
useful for wishing.
Noticed when checking this: when you did wrest the extra charge,
the engraving code accessed freed memory for the wand after it had been
used up.
Lastly, wands producing certain effects always become discovered,
even when you don't yet know what they look like. (This part of the patch
is trunk-only since it utilizes the routine which fixes similar case for
zapping.)
From a bug report: if you
were at one of the map edges and kicked away from map center while blind,
you'd get impossible("show_glyph: bad pos ..."). That was due to calling
feel_location() for the out of bounds location, which occurred after the
kick code had made use of invalid data so other problems might occur too.
Now you kick "nothing" as if it was something (hence possibly wounding
your leg, taking some damage, potentially dying). I didn't want to try to
classify the surrounding terrain as rock or air or whatever, and the thing
being kicked only shows up if the kick is fatal.
From the newsgroup: if polymorphed into a metallivore, you could eat
artifacts that you couldn't touch with your hands. Now you can't eat ones
which evade your grasp, and you take some damage from other touchy items
on--actually, prior to--the first bite. (Those still "taste delicious" if
you survive; I'm not sure whether this ought to be changed.)
From the newsgroup: slash'em lychanthrope character could throw
while in wolf form. That came straight from nethack; any animal capable
of manipulating an object--possibly with its mouth--could throw things.
Now hands are required. This doesn't require free hands, although it
probably should; it's kind of tough to imagine making a competent throw
while your hands are stuck to a cursed two-handed weapon.
From a bug report: shopkeeper
wouldn't move to block his doorway if there was a grave at that location.
Nothing supernatural; shopkeeper and temple priest movement was too
specific about what sort of terrain might be present and didn't know that
room floor might be replaced by a grave.
A recent change to force gold in inventory (during multi-item Drop or
applying/looting containers) to have '$' for its inventory letter for the
!GOLDOBJ configuration has revealed a bug which 3.4.3 has for the GOLDOBJ
configuration. Specifying a count followed by '$' to use a subset of
carried gold didn't work under tty; the $ was treated as a group accelator
and overrode the count, so full stack was always used. (The code a few
lines above this which counts the occurrences of group accelators already
includes this same fix: ignore an item's group accelator when it matches
the selector.)
I wouldn't be surprised if other interfaces are subject to the same
problem; since I can't test those I'm not attempting to fix them blindly.
Someone in the newsgroup claims to have reported this in mid-October,
but he uses a fake address in news and maybe he did so with his mail too,
resulting it not being delivered. Anyway, arming a land mine on the Plane
of Air, then setting it off, produced a pit in the air. This fixes that
directly, in case someone manages to do it again, and it also prevents
land mines and bear traps from being armed in midair in the first place.
Ditto for Plane of Water; water/pool locations were already covered (can't
arm there), and the bubbles ought to be treated similarly to Plane of Air.
When testing this, I managed to get a crash while restoring a saved
game. I had worn a blindfold and armed a land mine on the water level
(with just the no-pit part of the patch in place), then saved. When
restoring, I got a crash in restore_waterlevel() at one or the other of
these lines (traceback pointed at the first, but it has to have actually
been the second; an access violation from an address derived by applying
a small offset to a null pointer):
ebubbles = b;
b->next = (struct bubble *)0;
After that, I couldn't reproduce it with a wished-for trap and couldn't
stay in one place long enough again to successfully arm a trap object.
So there may be a nasty bug still present, perhaps now hidden by no longer
being able to create a new trap on that level.
Reading the comments in the previous patch, I realized that keeping
the old behavior for monsters who are shooting multiple missiles was
leaving an obscure but potentially serious bug. I haven't attempted to
trigger it but 3.4.3 is bound to be vulnerable.
From the newsgroup: ``Something is engraved here on the water.''
An engraving written on a lowered drawbridge would be transfered to the
underlying terrain when the bridge was raised. The coverse was also true;
if you plugged the moat and then engraved on the ground, that engraving
would remain visible--and touchable if blind--when the bridge was lowered
to cover its spot. Rather than try to handle two different engravings at
the same coordinates (with one of those two changing locations when the
bridge is raised or lowered), this just wipes out any engraving at both
span and portcullis locations whenever the bridge state changes, like is
done for traps.
Typing a response at the "Who are you?" prompt didn't allow digits in
the character's name under Unix and VMS; something like "arc15" came out
as "arc__". This allows them to be used anywhere except for the first
character. "arc15" now works; "15arc" ends up as "_5arc" so that there
still won't be a leading digit abutting the uid value when they're joined
to form the save file name.
Also from the newsgroup (2nd from "Three bugfixes for Xorns" [I got
the subject wrong on the previous spell of protection patch]): when
phazing through walls or rock you could engrave as if it was ordinary
floor. Again I didn't use the user's patch; it left closed doors, raised
drawbridge, and iron bars as locations where engraving was still feasible
and said "you can't write in solid rock" even if you were inside a tree.
[The 3rd of "3 xorn fixes" was for misleading feedback when attempting to
engrave while underwater; we've already fixed that one.]
There was a suggestion that you should be able to engrave within solid
rock if you use a wand of digging, and that seems like a pretty good idea,
but the check for location comes before the check for writing instrument so
would be tricky to implement.
From the newsgroup (subject: "3 xorn fixes"): casting spell of
protection would report "the air around you begins to shimmer" even when
you were embedded in rock or swallowed. It included a pointer to a patch;
I looked at that but ended up not using it.
From a bug report: if swallowed and blind
and in quantum mechanic form, hitting the engulfer would yield "the <mon>
disappears" even though you were still swallowed by <mon>. The pre-teleport
criteria for whether you knew the target was there were different from the
post-teleport ones. Make them match; swallower will remain sensed by touch
and won't be described as disappearing.
From a bug report: entering lava cures sliming,
but if you got [re-]afflicted by green slime after becoming stuck in lava,
#sit failed to cure it. Fix that, and have sinking farther into lava cure
it too (although not necessarily right away).
Also, suppress leaving the corpse in a bones file for death caused by
being dissolved in lava. Lastly, suppress the "you rise from the dead as
a <monster>" message during bones creation when the game ends due to being
turned into green slime since you transformed rather than died (and sliming
timeout gives "you have become green slime" just prior to that).
Something's wrong with the way lava was being handled in moveloop().
If you were trapped in lava (ie, moved into some but didn't die on the
spot thanks to fire resistance), you could sink and ultimately die without
ever taking another actual turn (typing ``i<space>'' repeatedly is an easy
way to reproduce). [`didmove' was only being checked for the sinking
deeper case and not for the decrement which ultimately leads to the fully
sunk case.] On the other hand, if you could manage to start an occupation
and avoid being interrupted, you would never sink while it was in progress.
[Lava handling followed ``if (multi && occupation) { ...; continue; }''.]
While testing some other code (lava vs slime, coming shortly) I ended
up with the cursor sitting on the status line while the game was waiting
for me to enter my next move. I don't really understand what's going on
there, and moving the lava handling before bot() might have hidden that
particular problem now by changing the point at which Slime will get taken
off the status line, but this attempts to fix it anyway.
From a bug report: zapping a wand of striking or locking or spell of
force bolt or wizard lock up or down when standing at an open drawbridge's
portcullis didn't affect the bridge if the portcullis was positioned north
of the open span. One of the two drawbridges on the Valkyrie quest goal
level has that orientation. is_drawbridge_wall()'s name is somewhat
misleading; it isn't boolean and returns -1 rather than 0 for "no".
Noticed when examining resists_magm() while working on anti-magic
traps: if you were polymorphed, you would be granted magic resistance by
keeping a cloak of same or gray dragon scales/mail in your quiver slot,
your alternate weapon slot, or main weapon slot (ie, by wielding it). And
you obtained light-based blindness resistance regardless of whether you
were polymorphed if you carried a potion of blindness in any of those slots.
High resistance made the Riders unlikely to be polymorphed, but
they were susceptible to being turned into green slime (and then never
reviving if killed in that state). Now they'll be immune to both types
of transformation.
Eliminate the somewhat redundant "You die..." following "You turned
to stone..." when becoming petrified by touching a cockatrice (reported
by <email deleted> for kicking, but occurs for weaponless hitting too).
Also, if a cockatrice killed you with normal damage, your tombstone would
erroneously report petrification and presumeably there'd be a statue
instead of a ghost in the resulting bones file. This fixes both things.
[I can't get access to my mail at present, but `cvs update' shows
that there aren't any patch notification messages pending for me.]
Extend a pre-3.4.3 fix--for objects picked up in an untended shop--
to container contents. Without it, dropping a bag or box in a tended shop
and declining to sell it, then picking it back up after the shop has become
untended (shk killed or evicted) would leave the contents with no_charge
set. After that it could be sold in another tended shop, picked back up
for free, then kept or sold a second time. (Picking it back up in the
tended shop would clear the bit; afterwards it behaved normally. And it's
not something prone to abuse; if you can make a tended shop become untended
you really don't need to sell stuff twice. But it'd be noticeably wrong if
anyone ever stumbled across it.)
Prevent getobj() from overflowing its inventory letter collection
buffer if someone figures out some new way to fill up their inventory with
a huge number of # entries. Inventory manipulation might become crippled
at that stage but at least it shouldn't be able to trigger a crash.
Also, the !fixinv configuration was never taught about # and did
strange things if you had more than 52 items, both for inventory display
and object selection with getobj.
The reassign()/getobj() situation is definitely confused regarding
gold, using GOLD_SYM in some places and def_oc_syms[COIN_CLASS] in
others, and it's schizophrenic about whether the GOLDOBJ configuration
keeps gold in a letter slot or specially named $ slot. I'm sure there
are some problems there but I'm not planning to try to figure them out.
Prevent heroes in giant form from picking up boulders once they run
out of available inventory slots to avoid an uncontrolled number of '#'
entries. There is an exception: if not already carrying any boulders,
they can put one into the '#' slot. Loadstones are treated the same way,
although since they stack and are rare to begin with, someone would have
to have gone far out of their way to have gotten many # entries with them.
Assuming that you can get something other than a boulder or loadstone
into the # slot (which is definitely possible, I just can't remember how),
you could relatively easily get three total # entries by picking up a
loadstone and polying into a giant and picking up a boulder. But I don't
think there's anything wrong with that.
According to a newsgroup followup, a hidden pet summoned via magic
whistle could produce the same effect as the level change case (where
sometimes the glyph for unseen monster would appear unexpectedly). I was
unable to reproduce this one, but I don't see anything in the code to deal
with the situation, so I suspect that the monster is moving immediately
and being revealed before I have a chance to notice anything odd.
I assume that other situations where hidden monsters get teleported
are being handled as attacks which expose them. At least I hope so.
From the newsgroup: if a pet was hiding under an object next to you
when you changed levels, it could arrive hidden at the destination if there
was something available to hide under there too, and sometimes you'd start
the new level with a hidden monster glyph at its location. I was able to
reproduce that once with current trunk code, but while trying to figure
out what is actually happening I've been unable to make it happen again.
However, it doesn't make sense for a monster to be able to remain in hiding
during the level change in the first place, so this patch prevents that.
(I'd still like to know how/why map_invisible() is sometimes getting called.
[The test character was a level 1 tourist without auto-search capability.]
I'm reasonably sure that it won't happen any more once this fix in place.)
This also brings adjacent pets out of hiding when they accompany you
during ascension or dungeon escape, but it seems that that wasn't actually
necessary. The end of game disclosure already lists such by name rather
than as "it", contrary to my expectations. (I had forgotten that end-of-
game forces true names so that blindness and hallucination don't interfere
with disclosure; obviously that ends up handling hidden monsters too.)
Fido grows up into a large dog.
The soldier becomes a sargeant.
Similar feedback was previously given only when the monster was going to be
killed off due to its new form having been genocided.
From a bug report: you could end up with
gravestone/logfile result of "burned by burning" or "drowned in a drowning".
If you get life-saved when drowning in water or burning in lava, the game
tries to teleport you to safety. If the teleport fails for some reason--
such as lack of unoccupied non-water or non-lava locations--you drown or
burn again. But life-saving was resetting the killer reason and the repeat
drowning/burning wasn't setting it up again, so the default got used and
produced a silly result.
<Someone> wrote:
> I can' t find this bug in the known bug list. If I missed I do apologize.
> It occurs on the standard windows nethack.exe. Just wield a cream pie
> and then apply it. Press x to switch weapons. Program in disorder.
> s - 1752440940 glorkum 32 26485 101's named ? (alternate weapon; not wielded).
> Greetings, <Someone>
It crashed with an access violation for me.
Recently reported to the list, a fireproof container dropped in lava would
catch fire and burn. Add the missing check; this looks an oversight when
the idea of fireproof was added, since other fireproof objects get handled
later in the cascading if().
<Someone> reported the longstanding behavior that when dragging, the chain
does not always remain directly between the player and the ball. This occurs
when the player zigzags. Added a check to the simple drag code to try to
keep the chain directly between the player and the ball. But, don't do this
if the player is walking thru rock or if it would move the chain into rock.
Pat recently forwarded a discussion that Elbereth was ignored unless there
was an object on its location. Mostly. It was also respected if the hero
was Displaced, no matter where the hero was. No one commented on his
message, which I took for assent to address this. Removed the qualifiers, so
now Elbereth is always respected, just like a scroll of scare monster.
<Someone> noticed that when a monster escaped upladder in the wizard
tower, it ended up outside the tower. This is due to the "wander" code in
monster migration. Rather than add code to try to keep the monster from
crossing the undiggable wall, just add REGIONs on the tower levels within the
area, which then utilizes the existing in-a-room constraint behavior of
monster migration. Of course, one can still fill a tower level with fodder,
and then when another monster climbs the ladder, it will still end up
outside the tower.
stinking clouds extend their timers, causing the "ttl == 0" check in
visible_region_at to be inappropriate; technically it was never quite
right, since the ttl is set to 0 one turn before removal is considered. But
with the Eyes on, this caused a visible change in the region although the
region still existed. Introduced a new -2L value to designate that the
region is being removed (-1L means it's permanent), which is what
visible_region_at was really trying to test.
<Someone> wrote:
>>comments:
>>When you commit suicide with a potion of oil (lit), sometimes nethack
>>reports an `obj_is_local' error just after disclosing all the game
>>variables. This has been found in-game (don't ask) and reproduced in
>>wizard mode and in-game (start-scumming).
>
> 0) a neutral human wizard (the scrolls/spellbooks burning, potions boiling ;))
> 1) wish up 3 potions of oil (so that the 2 remaining will definitely kill you)
> 2) a'pply one of them
> 3) stand 1 square away from a wall, like "| @"
> 4) throw the lit potion into the wall (`h' in this case)
> 5) answer `yes' on all prompts.
The thrown potion of oil, which was extracted from any chain
during the throw, still had its timers attached when the call to
splatter_burning_oil() was made. If that killed the hero, a
panic would result during bones file creation (saving timers)
because (obj->where == OBJ_FREE) on the potion.
Remove the timer prior to splattering the oil inside.