The air bubbles on the Plane of Water and the clouds on the Plane of
Air were being saved and restored as part of the current level's state
(which is the 'u' struct and invent and such) rather than with the
current level itself. That was ok for normal play, but for wizard
mode's ^V allowing you to return to a previously visited endgame level
after moving to a different one it meant a new set of bubbles for
Water and new set of clouds for Air. Even that was ok since it only
applied to wizard mode, but using #wizmakemap to recreate Water or Air
while you were on it added a new set of bubbles or clouds to the
existing ones. If repeated, eventually there wouldn't be much water
or air left.
Instead of just adding a hack to #wizmakemap, change save/restore to
keep the bubbles/clouds with the level rather than with the state.
That wasn't trivial and now I know why the old odd arrangement was
chosen. Saving hides u.uz by zeroing it out for levels that the hero
isn't on and it is zero during restore so simple checks for whether a
given level is water or air won't work.
This also adds another non-file/non-debugpline() use of DEBUGFILES:
DEBUGFILES=seethru nethack -D
will make water and clouds be transparent instead of opaque. It also
makes fumaroles and other light-blocking gas clouds be transparent
which wasn't really intended, but avoiding it would be extra work that
doesn't accomplish much.
Increments EDITLEVEL for the third time this week....
Noticed when testing the forcefight against obscured furniture fix:
if you attempted forcefight against the edge of the map, you got
feedback about having already moved as far in <direction> as possible
rather than about forcefight failing to attack anything. Have the
can't move out bounds test check for forcefight before deciding to
give to its normal feedback.
against "unknown obstacle"
Pull request #746 by entrez: give better feedback when 'F' prefix
is used toward furniture covered by objects and towards solid rock
terrain on arboreal levels.
Fixes#746
instead of as fake bear traps
Use the new traps and their tiles when confused gold detection finds
trapped doors and trapped chests. (Large boxes can be trapped too;
they use the trapped chest trap and corresponding tile rather than
have their own.)
Usually these pseudo-traps go away when as soon as they are within
line of sight. (While testing, I noticed that seeing a trapped door
from outside its room rather than inside didn't behave that way.
The door was created by wizard mode wishing; I don't know whether
that was a factor.)
I also discovered that secret doors weren't being handled correctly.
They can't be trapped because of their use of both the doormask and
wall_info overlays of levl[][].flags, but I had a secret door be
falsely displayed as a trap. This fixes that.
We should have obj->tknown and rm->D_TRAPKNOWN so that the hero won't
forget about these traps after declining to attempt to untrap them.
But that's more work than I care to tackle.
Issue #745 by k2: when using two-weapon combat, the second attack
would still take place even if the first attack caused the hero to
become paralyzed (hitting a floating eye or g.cube).
Cleaver's up-to-three attacks had the same problem but did stop if
the hero underwent life-saving after some fatally damaging counter-
attack. Two-weapons didn't. Make them both stop early if either
paralysis or life-save occurs.
Multiple attacking monster against monster and against poly'd hero
already deal with paralysis; life-saving doesn't apply.
Fixes#745
Reported directly to devteam: when a Rider revived, its corpse
didn't get used up.
The change to have delobj() never destroy Rider corpses, like it
won't destroy the Amulet or invocation items, didn't take into
account that they should be destroyed when Riders revive from them.
Add delobj_core() to be able to do that without changing existing
delobj() usage.
I'm surprised hardfought players haven't been all over this one.
Reported directly to devteam: changing levels while riding gave an
impossible warning, "no monster to remove".
mon_leaving_level() was trying to take hero's steed off the map but
that isn't on the map in the first place. Only noticable if built
with EXTRA_SANITY_CHECKS enabled. Normally remove_monster(x,y) just
sets level.monsters[x,y] to Null but with extra checks enabled it
first checks whether that is already Null.
Commit 593c3532fc took the 'catchup'
argument away from repair_damage() and calculated it in the routine.
Commit 699a25c00b put the argument
back but neglected to remove calculating and assigning it, making
the passed value be ignored. Take that away, finishing 699a25c00b.
That affected shop repair messages but wasn't enough to prevent a
shop wall repair display glitch. This seems to make things work
properly but is little iffy.
If you have 'fixinv' set to Off and and an inventory of three items,
they'll always be a and b and c. #adjust had you pick 'from' slot
among [abc] and the prompt for 'to' was supposed to show the letter
you picked plus 'd' for 'move to last'. But it was only showing
the 'from' letter itself as likely candidate, omitting the last+1
choice. (Anything after the last letter in use could be picked and
yield the right result, only the list of likely candidate slots in
the prompt wrong.)
Fixed more by trial and error than by understanding why the old code
didn't do what was intended.
Reported by vultur-cadens: slow digestion from wearing white dragon
scales/mail blocked per-turn hunger and didn't cause any hunger,
unlike ring of slow digestion which blocks per-turn hunger but still
causes some hunger as a worn ring itself. If no rings or amulet
were worn, wearing the suit prevented the hero from ever burning any
nutrition.
Change to treat wearing the suit to be quite a bit like wearing a
ring, unless hero is also wearing an actual ring of slow digestion
(then the hunger cost of the suit is 'free').
Wearing a ring of slow digestion and another ring consumes two units
of nutrition every 20 turns, no matter what suit. Wearing white
dragon scales/mail and two non-slow digestion rings now consumes three
units of nutrition every 20 turns. Using the suit to effectively get
an extra ring finger isn't free.
Fixes#742
Issue #729 by argrath points out that one of the checks in
edibility_prompts() couldn't work.
For the next-meal effect after reading a blessed scroll of food
detection, the check whether a corpse was tainted but not dangerous
because the hero had sickness resistance could never be evaluated.
An earlier condition would cause the routine to return before
reaching that check.
Move it sooner, even though doing so violates the "order by most
to least dangerous" guideline. It was either that or eliminate it
altogether.
edibility_prompts() had a lot of repetitive code that has now been
condensed.
Simplify acid blob corpse handling--for all of eating, not just for
edibility_prompts()--by treating that as "never rots" so that the
'rotted' variable always stays 0. Now checks for that variable
being greater than some threshold don't need to include "and not an
acid blob corpse" as an exception. A side-effect of this change is
that not only do they never become tainted, they'll no longer yield
the "you feel sick" outcome when they're old but not old enough to
exceed the tainted threshold.
Bug fix: edibility testing stopped warning about green slimes.
That worked in 3.6.x, but 3.7 changed the 'cadaver' variable to
exclude them so the check for eating a glob of green slime could no
longer be reached.
Fixes#729
Reported by entrez. Don't make 50% of neuter monsters be flagged as
female. It doesn't matter for live monsters but gets inherited by
their corpses, where female and non-female corpses stack separately.
A change made 5 or 6 weeks ago that was meant to enhance tracking of
artifact creation had an unintended side-effect of making every object
obtained via wishing have its dknown flag be set. That made them
behave differenly from items picked up off the floor, so revert to the
old behavior.
hero when hero is [impatiently waiting...] on stairs
My attempts to cherry-pick this failed, so this was done manually.
It is a reimplementation of
NullCGT:feature/monster-item-use:dc2cef0562542fece1732dd2d4c4f0775308faff
] Pets approach the player if they are standing on the stairs.
]
] One of the most frequent complaints I have seen is that pets refuse
] to follow their owners down the stairs. While this can be resolved by
] waiting, most players, especially new ones, are not willing to spend
] multiple dozens of turns waiting for their pets to approach closely
] enough to follow them. This simple commit makes pets react to a player
] standing on stairs as if the player is holding a tripe ration. Simple,
] non-disruptive, and should solve many headaches.
Something I noticed when testing the item-action handling for name and
call; applies to the C/#name command too. You were allowed to call the
real Amulet something and allowed to call fake ones something [else].
If you did that, xname/doname didn't show it but the discoveries list
did, giving away information when the player had access to more than
one unID'd Amulet of Yendor. Rather than messing about with discovery
handling, make real and fake Amulet be ineligible from being given a
type name. (They can still be given individual names.)
Issue #734 reported as "parse function" by Meklon2007: the change
yesterday intended to make ^A work for commands that were preceded
by a prefix was triggering a crash if used after a keystroke that's
not assigned to any command.
'M^A' or '~^A' would segfault by derefencing a null pointer when
checking whether 'M' or '~' was a prefix. This prevents the check
attempt from doing that, but a better fix would be to not put the
invalid command keystroke into the do-again buffer in the first
place.
Fixes#734
Reported by luxidream via the web contact form and also as github
issue #732: using the repeat command after F+direction would take a
step in direction if there was no target to fight.
The direction was being repeated without the F prefix. It wasn't
specific to F; m+dir misbehaved too. This fix seems to work but it
should be replaced with something more robust.
Fixes#732
placed on lava spot on Valkyrie goal level
Reported by k2, arriving at the final level of the Valkyrie quest
can issue a recently added impossible
| mkstairs: placing stairs up on molten lava at <68,13>
The report said it was easy to reproduce, but it took me multiple
tries (so not hard to do, but not a sure thing on any given attempt).
The stairs on that level are placed at specific coordinates that
are outside the pre-mapped area, so there's no guarantee that their
spot will be suitable for stairs. The underlying terrian changes
from lava to stair, but only after the warning about molten lava.
This hack solves that particular level but is not a general solution
for this type of thing. When about to make stairs on a lava spot,
change that spot to normal floor first. Plus 50:50 chance to change
each adjacent lava spot to floor too so that there's decent chance
for some elbow room upon arrival.
Also, turn the no-flip attribute off for that level so that 'fixed'
location of the stairs can occur in four different places.
Fixes#730
after charging causes a ring to explode
Reported by gebulmer: if charging exploded a ring, the ring's memory
got freed but the stale pointer was passed to cap_spe() which accessed
it again. Fix by setting the object pointer to Null after using up
the ring. This was a post-3.6 bug.
Fixes#731
Allow the player to precede q/#quaff or M-d/#dip with the 'm' prefix
to skip asking about fountains, sinks, or pools if one of those
happens to be present, similar to how using it for e/#eat skips food
on the floor and goes straight to inventory.
If you use it and don't have any potions, you'll get "you don't have
anything to drink" or "you don't have anything to dip into", same as
when there is no suitable dungeon feature present combined with no
potions. However, if an applicable dungeon feature is present and
you don't use the prefix but answer 'no' to drink from fountain,&c
and you don't have any potions, "else" will be inserted into the
message: "you don't have anything else to drink".
A big part of the diff is just a change in indentation level for
code that is now inside 'if (!iflags.menu_requested) {' ... '}'.
rhack() normally calls parse(), parse() sets context.move to True
assuming that the player's next action will take game time, then
when it returns, rhack() sets context.move back to False if the
assumption turned out to be incorrect. But when performing actions
after picking something in inventory, rhack() doesn't call parse()
so context.move is left at False.
This was hidden by making the inventory command take game time if
the player picked an item and set up an action to be done with it
even though the action hadn't taken place yet. So time was being
accounted for but if the hero didn't get consecutive moves then
monsters got their turn between the shouldn't-take-time inventory
command and the ought-to-behave-like-normal-command queued action.
My initial attempt to fix this (before figuring out how context.move
works) by stopping inventory from taking time didn't work because
queued item-actions stopped taking time too, or rather the fact that
they took no time became exposed. This second attempt doesn't have
that problem and I think it is correct.
Issue reported by Meklon2007: picking a container from inventory
didn't offer #tip as a possible use of the item.
Implemented in commit 7b351bc20d
but I forgot to close the issue, so this adds a fixes entry for
it in order to do that.
Closes#727
Noticed when adding a 'tip container' choice to item-actions for
context sensitive inventory (update pending). Putting items into a
container with menustyle traditional and then takiing them out with
the #tip command while 'sanity_check' is On would produce warnings
once they were on the floor.
askchain() uses object bypassing to be able to cope with multi-drop
potentially changing invent, and it tried to reset that when done.
But it did so with the original object list (invent in this case)
and that doesn't reset individual objects that have been moved to
any other list. The between-turn resetting of bypass bits wasn't
doing so for container contents. The sanity check wasn't--still
isn't--checking those either, so it wasn't noticeable while items
were still inside the container. But taking them out with #tip
doesn't touch any bypass bits, so between-turn reset isn't triggered
and the items that came out of the container with bypass set
continued to have it set while on floor. sanity_check complained.
Change clear_bypasses() to handle container contents, and change
askchain() to call it instead of just clearing bypasses for whatever
is left of its input chain. (The latter probably isn't necessary
now that the between-turn cleanup deals with contents.)
While testing the new mouse action menus, it was quite annoying
to try and hit some shorter entries. Make all the selectable entries
the same maximum length, and with text left justified.
Stop attempting to catch up for lost time for shop damage repair
when getlev() loads a previousl visited level. Normal shopkeeper
behavior will take care of that.
Also, fixes the display related aspects of shop damage repair
interacting with ball and chain. They don't happen when its done
while the map is being shown.
Reported by entrez, restoring a saved game runs the shop wall/floor
damage repair routine. It was taking place before attached ball
and chain were fully restored so the repair routine treated them as
ordinary objects if they happened to be in a wall gap that gets
fixed on the same turn as restore takes place. They could end up
being moved to a spot that's too far from the hero and then trigger
an impossible "b&c distance".
This restores ball and chain before shop damage repair takes place
so the repair routine deals with them sanely and the impossible won't
occur any more. However, the repair still happens before the current
level's map has been displayed and that looks pretty strange during
the shopkeeper's message. Also, if the hero and the ball start on
opposite sides of the gap, after the gap is repaired the ball will
still be shown as a remembered object at its old spot even though it
ends up being located at the hero's feet.
Closes#726
but more work is needed...
Issue #722 posted by copperwater and commented on by Entrez: both
shk_your() and the() inserted "the" in front of a unique monster's
corpse, yielding "the Lord Surtur's corpse glows iridescently" and
"the Lord Surtur's corpse drops to the floor."
Teach both of those routines to skip "the" when used for monsters
with personal names. It now omits "the" for "Medusa's corpse" but
still gives "the Oracle's corpse".
shk_your() operates on an object and can deal explicitly with corpses
of named monsters. the() operates on text and has to guess whether
it is being used in a similar situation. Right now the guess is just
"is there an apostrophe present?" and might need further refinement.
Fixes#722
Allow selecting an item from inventory and show a menu of actions
applicable for that particular item. Some of the entries might
be slightly spoilerish (eg. it'll reveal that you can read T-shirts),
but the improved usability for new players is more than worth it.
Generally known as "item actions", this was first implemented
in AceHack by Alex Smith.
Pull request from entrez makes object detection of statues that are
actually mimics show the statue's monster type instead of always
depicting tengus.
Fixes#725
detecting monsters when none are present
Give some feedback for monster detection if drinking from a fountain
fails to find any monsters. Potion or spell gives "strange feeling"
feedback in that situation but fountain didn't report anything.
Fixes#724
Implement the suggestion by entrez to avoid "while helpless" in the
reason for the second death if hero gets killed, life-saved, and
killed again at the same time. Life saving sets 'multi' to -1 which
prevents the hero from moving again until next turn and is intended
to make the sequencing of "you survived that attempt on your life"
work if you're being interrupted during some multi-turn activity.
It used to behave differently when the first death occurred while
engaged in some voluntary multi-turn activity. I've removed that
because I couldn't figure out why; it might need to be put back.
menuitem_invert_test() is intended for invert-all/invert-page/
select-all/select-page but was being called for group accelerators.
In the #wizidentify menu, the 'all' choice specifies ^I as a group
accelerator but that stopped working on tty when it recently became
flagged as skip-invert.
Use 'fuzzymatch(,," -",)' when checking whether the name specified
in a player's wish text matches an artifact name so that extra or
omitted spaces and dashes are ignored. Wishing for "firebrand" will
yield "Fire Brand" and "demon bane" will yield "Demonbane".
monster and Elbereth unless there's no other choice.
Suggested by NetSysFire, don't create new monsters on top of scrolls
of scare monster. Not mentioned in the suggestion: unless they are
a type of monster that isn't affected by such scrolls. This extends
it to teleport destination too.
Avoid placing a monster on a scroll of scare monster or on engraved
Elbereth if there are other locations available. Only performed for
callers of goodpos() who explicitly request it, which at the moment
are makemon(), rloc(), and enexto().
Also, propagate 'mmflags_nht' to a bunch of places that were left
using long or unsigned for makemon() and goodpos() flags. I didn't
attempt to be systematic about that though.
Implements #717
while wielding a cockatrice corpse without gloves
Reported by vultur-cadens: if safely wielding a cockatrice corpse
without gloves due to temporary stoning resistance or wearing yellow
dragon scales/mail, having the resistance be lost to timeout or to
taking off the dragon armor should have turned the hero to stone but
didn't.
Extend the handling for taking off gloves to cover these other two
cases too. The feedback for these deaths is usually too verbose to
fit on the tombstone but does show up in logfile.
Fixes#715
Implement the suggestion by NetSysFire that a levitating of flying
hero won't treat pits and holes as off limits when testing potential
destinations during teleport.
Closes#716