From a bug report, the "you stagger"
message when a trapped chest releases a cloud of gas shouldn't include the
inaccurate phrase "and your vision blurs" if hallucination is blocked by
Grayswandir. Suppress it in that case.
From a bug report, you'd get the message
"the corridor disappears" whenever a vault guard was killed, even if the
temporary vault corridor was already gone due to leaving its vicinity. This
fix seems to work ok, but I don't pretend to understand how the convoluted
vault code actually works.
Spotted when fixing the Rogue level digging/phasing bug: pet movement
was setting up the wrong flag for pets who happened to be carrying a key.
This wasn't particularly noticeable because they tended to drop keys right
after picking them up. And apparently the checks elsewhere in movement
prevented that wrong flag from having any effect; once I changed it so that
pets would hang on to keys, I never saw them break a door down with one.
Now they'll keep keys, similar to unicorn horns and pick-axes, and use them
properly. The door unlocking message needed a tweak because it assumed
that the opener was on the far side trying to reach you and looked quite
odd when you could see the action taking place.
I've put this into the fixes file as a new feature rather than a fix.
From a bug report, 2003: a
pet who normally would dig could pass through walls and solid rock on the
Rogue level without leaving a tunnel in its wake. Monsters are explicitly
prohibited from digging on the Rogue level, but pet movement ignored that
and specified that locations accessible via digging were valid destinations;
actual movement bypassed the digging step so it acted like passthru.
From a bug report, the probing/stethoscope code assumed that all Angels
(the specific monster type, not the whole 'A' class) used the epri extension
to hold alignment, but that's not true for randomly generated ones. So
monster status feedback gave erroneous results, and it would vary based on
pet behavior if the random Angel had been tamed. Also, touch_artifact()
didn't know about special alignment handling for Angels and aligned priests
so always used their default alignment.
There are other problems with Angels--such as whether they should even
be allowed to be generated randomly in the first place--that this doesn't
attempt to address. The patch for that was starting to sprawl all over the
place so I pulled this simpler bit out for a first cut. Probing now shows
the Wizard of Yendor as unaligned instead of lumping him in with chaotics.
Another Makefile update needed: pline.[c,o] no longer needs epri.h.
Fix the problems From a bug report. So having
OPTIONS=IBMgraphcs
OPTIONS=noDECgraphics
would yield an ASCII display instead of showing IBMgraphics, but IBMgraphics
flag in the Options list would falsely show as on. Manually toggling it off
put things back into sync.
Avoiding the false setting is completely trivial. And fixing the
inappropriate override turns out to be easy too, unless I've bungled this.
One thing it does not do is try to warn about attempts to set conflicting
options like
OPTIONS=IBMgraphcs
OPTIONS=DECgraphics
Fixing that seems to be too messy to bother with, particularly since the
game runs ok (leaving the setting handled last in place).
From a bug report, applying a
mirror at sleeping Medusa yielded "too tired to look at your mirror" even
even though the item being used was listed in inventory as "looking glass".
Several other messages and any target monster would produce similar things.
Perhaps they should auto-ID when applied, but I changed messages to use
the description if real name isn't known.
This also treats incubi identically to succubi regarding mirrors:
they like to see their own image and will take the mirror away when one is
applied at them.
From the newsgroup three or four weeks ago: sleeping or pararlyzed
unicorns would catch thrown gems despite being unable to move. Now they'll
magically dodge instead--in other words, thrown gems will always simply
miss the target (and land at its feet) when a unicorn is unable to move.
The unicorn won't be angered or awakened by the attempt.
From a bug report. Pushing one
boulder from a location which had more than one would open up line of sight
at that spot as if all boulders there were gone.
From a bug report: #M30: 3.4.2 bugs and ideas); describe
flyers (poly'd hero or riding flying steed) as flying when they use ladders
or jump down holes. This also gives feedback when using the stairs in the
ordinary up or down case, where no message was previously given.
From a bug report, player's character inflicted
with lycanthropy doesn't gain level drain resistance when in normal form
even though lycanthrope monsters do have it when in their human form. The
report claimed that the character didn't gain it when in beast form either,
but the code--and testing--suggests otherwise.
The same resist_drli() call used for monsters is used for the hero,
but the is_were() check there isn't able to recognize a lychanthrope hero
since youmonst->data doesn't track that when in human/normal form. This
adds another more specific check to handle that case.
Fix the crash caused by division by zero (attempt to compute rn2(0))
when deciding prayer boon for a character whose Luck went negative during
the course of the prayer. <email deleted> triggered it
by killing a shopkeeper with the ongoing damage from a scroll of stinking
cloud; his non-chaotic character was branded a murderer and lost two points
of Luck after the prayer was already in progress. (Prayers fail when Luck
is already negative, so the code to pick a boon expects non-negative values;
the fact that is always adds at least +2 leads to me to suspect that someone
already realized that luck timeout on Friday 13th could result in Luck of -1
at the end of a successful prayer--that value doesn't trigger this crash.)
For "the hair on the back of your neck stands up" or "the hair on
your head seems to stand up" make subject and verb agree when poly'd into
forms where "hair" is replaced by something explicitly plural like "scales"
or "cilia".
Fix the problem From a bug report. Presumeably the corpse exclusion at <u.ux,u.uy>
was intended to be for killing your way out of an engulfer, but there wasn't
any comment to that effect. The exclusion still applies if you were inside
the monster when it died; ridden steed is the only other way I can think of
to have a monster die at your location, so it should be the only case which
gets affected. Neither steed nor engulfer is allowed to generate a random
item when upon death; you already know what was carried in those cases.
The bulk of the diff is from reorganizing the relevant `if' and
subsequent indentation changes.
When lit due to being wielded by a monster, Sunsword continued to emit
light after that monster was killed. This was fixed by <Someone> in 3.4.1 but a
change I made for 3.4.3 broke that fix. When mdrop_obj() was split out of
relobj(), relevant unwielding code ended up only being executed for monsters
who were still alive.
Fix the reported bug about an inappropriate space in the message
"For you, scum ; only N zorkmids for that foo."
when an angry shopkeeper quotes a price for an item which has just been
picked up. Also, suppress "only" in that case; just include it when the shk
isn't angry. And the word "zorkmids" was actually missing, so I added it.
I think the semi-colon should actually be a comma, but I've left that as is.
From <Someone>, half a year or so ago:
> When you've already entered the Castle, I think your God shouldn't be
> giving you the two Castle-related messages anymore.
>
> This might be difficult to track, I realise that.
It already suppressed the tune delivery feedback if you had opened the
drawbridge with music or if that drawbridge had been destroyed. And if
you've entered the castle by the back door or via wand of opening/spell of
knock, learning the tune could still be useful, so I didn't try to extend
dungeon tracking to the point of "entered the castle". However, if you've
already passed beyond the valley below then you most likely no longer have
much interest in the drawbridge, so add a check for that to the prayer
feedback suppression.
<Someone>'s real concern was probably more about the message phrasing
than the "useless" prayer boon (since it says "to enter the castle" rather
than "to open the castle drawbridge"), and that does make the god sound a
bit silly if you've already entered the building. It would make sense to
skip the first of the two messages if you make it inside without opening or
destroying the bridge, but this patch doesn't attempt to address that.
When you first attempt to walk down the stairs from the Valley of the
Dead to the second level of the Gehennom branch, the game prompts you about
whether you really want to proceed. But if wasn't keeping track of whether
you had previously level teleported past that point (which is possible when
starting from the Valley rather than from higher up), so would still issue
that once-only prompt if you used the stairs later. Mark the prompt as if
it has already given whenever you reach a Gehennom level beyond the Valley.
From a bug report: the invulnerability conferred
during the multi-turn delay for a successful prayer was not protecting
against damage inflicted by hostile mind flayer's "wave of mental energy".
I think being asleep or unconscious ought to override vision the way
that being blinded does, but that's a more ambitious change than I care to
tackle. This replaces You("see ...") with You_see("..."), comparable to
You_hear(). It catches the reported door case and several variations of
light sources burning out while on the floor rather than in inventory, but
it probably misses some other cases. zap_over_floor() in particular is
highly suspect.
From a bug report. <Someone> as slashem-Bugs-883643 on 1/24/2004. To avoid
using the possibly invalid object pointer after calling bhit(), changed as
suggested to add another level of indirection allowing bhit to null the
object pointer before returning. Callers that are affected update their
object pointers after bhit returns.
From a bug report: zapping force
bolt broke an adjacent potion of blindness (possibly carried by the monster
he was attacking) which caused "it suddently gets dark" but further course
of the bolt resulted in now blinded hero recieving "a door appears in the
wall". make_blinded() was deferring vision recalculation until next pass
through moveloop() (or until next pline()--if the "gets dark" message had
been delivered after the call to make_blinded() instead of before, this
wouldn't have been noticeable). Fix is trivial: just recalculate vision
immediately when temporary blindness is toggled. [It might also be needed
for involuntary blindfold removal, although I suspect that that is always
accompanied by corresponding pline() which gets vision back into synch.]
<Someone> recently reported that after lieutenants had been genocided,
he saw a sergeant drink a potion of gain level and then vanish, leaving
behind its gear but no corpse. The message about growing into a lieutenant
and subsequently dropping dead would only be given if the monster could
be sensed via telepathy, not when it occurred in plain sight. I'm not
absolutely sure that this was unintentional, since sensing the dying
monster's mind might be giving additional information about what was
happening. But there was no comment stating that and I think such behavior
violates the principal of least surprise, so seeing it happen will now give
the message too.
Because the description seen by the player is "you have never changed
form" rather than "you have never polymorphed yourself", make death by fully
turning into green slime (even if that death is avoided via lifesaving)
violate the conduct. Suggested by <Someone> 9-Dec-2004. Likewise, eating
a mimic corpse and temporarily turning yourself into a pile of gold also
violates that conduct. Mentioned by someone--probably <Someone>, or possibly in
the newsgroup--a long time ago.
<email deleted>, attempting to #chat
with quest leader who was raised from the dead yielded "impossible: invalid
quest character". The code attempted to handle that but the conditional
logic for preserving the m_id field was backwards. 3.4.3 only dealt with
the corpse revival case; dev code tried to support it for statue animation
too but still had the same problem.
Several apparent bugs remain: if the leader is angry (perhaps hero
killed him before reviving him) he won't give an angry response if the
player initiates #chat rather than wait for adjacent leader to do so. If
it's an archeologist reviving the statue of petrified Lord Carnarvon, hero
gets a rather ironic message about feeling guilty for destroying historic
statue. Lastly, shouldn't there be a comparable quest_status.nemesis_m_id
so that if one player lugs the corpse or statue of his quest nemesis back
into the main dungeon and another one revives that, it won't start behaving
like 2nd player's nemesis? Live nemesis is explicitly kept out of bones
but I don't think the corpse or statue of one is blocked and its monster
behavior after revival is based on mon->data->msound==MS_NEMESIS rather
than on m_id of current game's active nemesis monster.
1) in the autopickup exception sub-menu from 'O', change the selector for
"exit" from 'e' to 'x' so that the entries occur in alphabetical order.
Also frees up 'e' for some hypothetical future "edit" entry (I'm not
planning on attempting to implement anything along those lines though).
-1) I wanted to make 'x' start out preselected to show that it's the default
choice, but that doesn't work correctly--at least for the tty interface.
PICK_ONE menus don't know how to deal with having a preselected item and
in this case it ended up returning 'x' no matter what choice I made.
Even if that aspect gets fixed, it might have trouble with explicitly
picking the preselected entry since that would probably be toggled off
in the process. So the preselection bit of this menu is commented out.
2) at the prompt for adding new exceptions, quit adding instead of giving
"invalid syntax" warning if user enters empty input.
3) allow <ESC> in the "list" or "remove" submenu to quit all the way out of
the upper menu too.
4) simplify the way magic numbers are used for action_titles[] menu setup.
5) greatly simplify return value of special_handling().
6) avoid a potential for getlin() or strcat() buffer overflow if getlin()
were ever to be changed to return BUFSZ-1 characters instead of COLNO or
whatever its narrower current limit is.
I'm pretty sure that I've run into the issue of being unable to have a
preselected entry in a PICK_ONE menu before, but I can't recall if I ever
mentioned it. Fixing that looks like it'd be pretty messy and would need
to be done for all the interfaces. Ick.
> clear stale prompt
[...]
> Can someone who understands the relevant windowing code fix ^R in getpos()?
I still don't understand why it wasn't working as expected, but moving
the existing cursor positioning after flush_screen() instead of before now
makes ^R work ok during getpos(). It doesn't restore the top line text so
isn't a transparent redraw but it now displays a prompt string there instead.
Likewise after typing '?' for help so that it should be move evident that
nethack is still waiting for you to move the cursor somewhere.
Also add support for ^L in numpad mode. I almost never use that and
didn't think of it the first time around.
From the newsgroup: applying various types of tools (example was a
mirror; figurine is another case) and then typing <ESC> at the "In what
direction?" prompt would leave the prompt displayed. User complained that
he tried to answer the no longer valid prompt--even though the cursor had
correctly moved back to the '@' on his map--and ended up walking into lava
instead. Suggested fix in the newsgroup was to use pline("Never mind.")
the way many commands already do, but it's simpler and more robust to clear
the message window before getdir() returns. Callers can issue Never_mind
feedback on a case by case basis as before; I haven't added any here.
Perhaps getpos() should get passed an extra argument telling it to issue
that message; then a dozen or so pline(Never_mind) calls could be removed.
I also was annoyed that ^R gave me the command assist display instead
of redrawing the screen with the prompt intact. This fixes it for getdir().
The corresponding fix for getpos() doesn't work correctly; it successfully
redraws the screen but leaves the cursor at the end of the 2nd status line,
despite the fact that it is followed by an existing cursor position call.
Can someone who understands the relevant windowing code fix ^R in getpos()?
(Easiest test case is probably just ^T in wizard mode.) I have't added an
entry for ^R to the fixes file since it isn't fixed yet. And I didn't look
to see whether yn_function() ought to handle ^R too; it might be used in
contexts where map redraws don't make sense.
This uses Michael's suggestion for keeping the display up to date when
removing a djinni or water demon in advance of granting a wish (so that it
won't be present in a bones file if the wish is fatal--problem with earlier
fix was that player could notice monster was already gone while responding
to the wish prompt). It's not quite as straightforward as I was hoping for
and would get a lot messier if it needed to cope with Warning & Warn_of_mon.
Fix the problem From a bug report, so finding it in a bones file yielded a fully functional magic
lamp. Fix as user suggested: convert the lamp first.
It also left the djinni who would normally have disappeared right after
the wish. Water demons from fountains have that problem too. Unfortunately
my fix is a bit buggy: when removing the monster before granting the wish,
the player can notice. Is there a straightforward way to display a monster
where none is present on the map? Or do we need something comparable to the
obj->in_use flag for monsters, so that the bones code can discard particular
ones?
Pointed out by <Someone>: engraving with a cursed wand should pose a
risk of having it explode just like zapping does. [At the moment when one
explodes, any existing engraving doesn't get changed.] Suggested by someone
(<Someone>?) some time back: explosion due to recharging could be consolidated
with explosion due to zapping cursed wands. And noted by <Someone> in the
newsgroup: '+' in an engraving--perhaps written by someone trying to leave
bones file notes--should have a chance of being partially rubbed out to '-'.
From a bug report, using stone to flesh to
reanimate a petrified monster who was carrying gold (in his case, it was
a shopkeeper) resulted in gold in the monster's inventory. Somehow it was
also being duplicated in the mgold field--I didn't try to figure that part
out--so killing the monster produced double gold. More significantly,
probing such a monster prior to killing it caused a panic when the monster
inventory was being massaged for formatting.
Fix is trivial: use a routine which knows about special handling for
gold when transferring statue contents to resurrected monster. Both aspects
of the problem only occurred for the !GOLDOBJ configuration (which is our
default). However, any objects which confer something special when simply
being carried would have also been misbehaving--automagic animation of
cursed figurines is the only applicable situation; too rare for anyone to
have noticed.
Implement the suggestion that Fire Brand avoids damage from rust traps
by boiling away the water. Rather than making this be trap-specific, it
applies to all types of erosion which go through erode_obj(). That includes
hitting rust monsters but not dipping into potions or fountains, nor falling
into moats. And it doesn't provide 100% protection, just a high chance of
avoiding rust damage. Also, Frost Brand gets similar protection by freezing.
The message handling needed some rewriting for the branch version.
That compiles ok but hasn't been tested. It would have been simpler just to
move Yobjnam2() over even if nothing else was changed to use it yet....
While wearing EotO, ";" and selecting a monster behind a wall would display
"normal vision" as well as "astral vision". This is because cansee() gets
set for things seen via astral vision. However, couldsee() is only set for
things that could be seen normally, so check both values.
When confused remove curse acts upon an object to randomly bless or
curse it, clear the bknown flag. Do this for all objects which get subjected
to the effect, even ones which are already blessed or cursed and hence don't
change state.
<Someone> reported that when levitating and blind, he was getting
"You float over the hole" without it showing up on the map. Easiest way
to reproduce: zap a wand of digging downwards while levitating blind,
move off the spot and back over it.
Make sure that all traps created by the player are mapped. For other
traps, it was about 50:50 whether the trap triggering message yields enough
information to warrant forcibly mapping the trap when blind.
A few weeks ago someone in the newsgroup posted how he got an intrinsic
value for increased damage up to something like +74 via eating rings (on his
way to killing the Riders a zillion times for maximum score--he wanted to be
sure to kill them in a single hit each time so that his use of keystroke
macros wouldn't get out of sync by extended combat). Make it moderately
difficult to get beyond +20 and impossible to get past +40 for corresponding
attribute when eating rings of increase damage, increase accuracy, and
protection. Since you could also wear a pair of +7 rings you can still get
an awfully high total, but it won't be unlimited any more and most people
willing and able to go to such extreme lengths would undoubtedly prefer to
be wearing other types of rings.
From the newsgroup: non-cursed dunce cap or helm of opposite alignment
which would glow black and become cursed if worn by the hero wasn't doing
the same when worn by a monster. Fixing this gives players a new way to
recognize bad hats--drop on altar, then drop in front of approaching goblin
or other wimpy monster capable of wearing armor--but I think that's fair.
Since helms of opposite alignment are usually already cursed it won't make
much difference for them; most players seem to avoid all conical hats so it
won't make much difference for dunce caps either.
When 3.4.0 added the shop price to inventory display of unpaid items,
it resulted in showing that price twice if you used the `I u' command while
carrying just one unpaid object.
k - a potion of object detection (unpaid, 150 zorkmids) 150 zorkmids
With two or more unpaid objects it uses a menu style display and explicitly
suppresses "(unpaid, N zorkmids)" from the inventory formatting. Do the
same suppression when there's one item.
k - a potion of object detection 150 zorkmids
Various actions (potion dilution, igniting candles or oil, dulling a
weapon by engraving) on an unpaid object can modify it in such a way that
a shopkeeper will force the hero to buy it. bill_dummy_object() is used
to make a copy for the shop bill; play continues with the modified item
now owned by the player. bill_dummy_object() was setting the no_charge
flag unconditionally on the modified object but the flag shouldn't be set
for items in inventory. It was possible to drop the object and sell it,
pick it back up for free due to that flag setting, then drop it and sell
it again. One easy way to reproduce is to zap yourself with a wand of
cancellation while carrying unpaid positively enchanted armor or weapon.
The no_charge flag gets cleared when you pick something up off the
floor or take it out of a container, so this sell-it-again case would only
repeat once. Selling a dropped item ought to clear the flag, but my head
is still spinning after looking at the shop code to see about implementing
that. This fix just prevents bill_dummy_object() from mis-setting the
flag in the first place; sellobj() still can't fix it up after the fact.
From a bug report, it is possible for the hero to
appear embedded in the wall after destroying the drawbridge. This is because
The variable "lev1", which was the entity's location, was being referenced
after e_died, but e_died can change the entity's location. So, as <Someone>
suggested, refer to the current location directly.
While auditing nomul() I noticed unconscious() treats (multi < 0 && !nomovemsg)
as unconscious. This explains the behavior in M29 (unconscious message
while performing #turn). I checked all the places with this combination,
and found a few that did not appear to fall under the "unconscious" category.
Most I changed to use You_can_move_again to ensure the same display w/o the
unconscious behavior. Also:
- found another string that unconscious() should have considered
- vomit() now sets nomovemsg, one caller was also doing this redundantly
- vomiting_dialogue() was calling stop_occupation() after vomit(), which can
reset multi. I reversed the order and removed a doubly-redundant nomul call.
tele() still has a problem: some cases where multi < 0 should probably take
a branch like the unconscious() branch but with a different message.
doturn()'s behavior - turn then wait - is also less than perfect, but I
think this is a known problem.
Finally apply the patch sent by <Someone> in 11/2003 for slashem-Bugs-799278,
updated to match the current code and handle additional cases. The fix
is brute force: always ensure nomovemsg is set when nomul is called with
a negative value. I also scanned the code for places manually setting
multi negative, they all set nomovemsg. It would be nice to have a function
that did the right thing, but there are several special cases and I was
not feeling creative.
From the newsgroup: player offered the Amulet with a pet adjacent
to his character, and instead of getting "You and Fido ascended" he got
"Fido is still eating" followed by "You ascended". Make all adjacent pets
eligible to accompany an ascension even when they're in circumstances where
they'd be prevented from coming along on a normal level change.
When testing drawbridge stuff recently I ended up with an unseen
monster who evidently cast the aggravation spell repeatedly, yielding a
steady stream of "you feel that monsters are aware of your presence"
messages. This patch makes monsters tend to avoid repeating that spell
once everyone on the level has already been woken up. It also extends
the spell effect so that it will wake monsters like quest nemesis and the
Wizard who ordinarily wait until you get close before they become active.