nhl_error() was clobbering the stack. I assume that the 'source'
field in the Lua debugging structure is normally a file name, but
nethack loads an entire Lua script into one long string because it
usually comes out of the DLB container, and 'source' contained the
full string. That would overflow the local buffer in nhl_error()
if nethack encountered a Lua problem and tried to report it. (In
my case, the problem was in a level description file modification.)
[Not something under user control unless user can modify dat/*.lua
and put the result into $HACKDIR/nhdat.]
Make wearing a wet towel confer new attribute Half_gas_damage in
addition to the usual blindness. It reduces damage from being inside
a gas cloud region and from being hit by poison gas breath attack.
It also fully blocks breathing of potion vapors.
Might make the Plane of Fire easier although overcoming its blindness
with telepathy won't reveal elementals. Definitely has the potential
to make blind-from-birth conduct easier which wasn't the intent and
probably isn't significant.
Noticed while working on something else: hero kept wearing a towel
after polymorphing into a form without any head. And when not already
wearing one, could put on a blindfold/towel/lenses while in a headless
form.
Move 'implicit_uncursed' and 'mention_walls' from iflags to flags to
make their current setting persist across save/restore. Invalidates
existing save files.
Trying to move into a wall or solid rock fails and doesn't do anything
(unless the 'mention_walls' option is On) and doesn't use a turn, and
trying to move off the edge of the map window also doesn't do anything
(except for 'mention_walls') but that did use a turn. Don't.
pick_role() had a 5 year old copy+paste error where a pair of lines
were cloned multiple times but one of the resulting lines didn't get
the intended revision, preventing OPTIONS=align:!chaotic or !neutral
or !lawful from working as intended when letting the game choose role
randomly. The bad line should have been calling ok_align() but that
routine turned out to have a bug too.
Fixing those lead to other less obvious problems with role selection,
particularly the tty menu version for picking manually. Roles and/or
races which should have been excluded by partial specification weren't
always kept out. Also, if any filtering was specified, trying to
disable all filters (via choosing 'reset filtering' and de-selecting
everything in the menu) was a no-op. Once any filtering was in place
you had to leave at least one role or race or gender or alignment
flagged as not acceptable in order to change any of the filtering.
When that was fixed and it was possible to turn off all filtering,
there was no way to turn it back on because the menu choice to reset
the filters wasn't offered unless there was some filtering in place
(that was intentional but turned out not to be a good idea).
I checked curses and X11; they both offer less versatile selection
capability that don't seem to need the tty-specific fixes.
Give 'novel' a 1 in 1000 chance of being created in place of each
random spellbook (except for hero's initial inventory and NPC
priests' monster inventory and divine reward for prayer--those all
force regular spellbooks; statue contents aren't among the
exceptions--those books can now be novels). Shop inventory (where
first book or scroll shop created is guaranteed one novel) hasn't
been touched. If there is any other special spellbook handling
somewhere, I've overlooked it.
Polymophed into a giant and moving onto a boulder's location could
yield "you easily pick it up" (without actually doing so) followed
by "you see a boulder here". It would happen if autopickup was Off,
or if the 'm' move-without-autopickup prefix was used, while either
boulder was included in pickup_types (including when that is set
for 'all') or hero had thrown that particular boulder and
pickup_thrown was On. The check for whether auto-pick should try
on an object relied on its caller verifying that autopickup was On.
pickup() does that for
pickup() -> autopick() -> autopick_testobj()
but moverock() wasn't doing that for
moverock() -> autopick_testobj()
so the logic controlling moverock's message was subverted.
I first thought that logic itself was incorrect and changed the
message. This keeps the new message even though it turned out not
to be cause of the problem.
Fixes#279
When browsing the map while hallucinating and looking at a pool, a
moat, or 'other' water or at molten lava, report with hallucinatory
liquids rather than the ordinary substance. Likewise when browsing
self on map or using ^X would report "sinking into lava".
Changing data.base lookup to accept leading spaces as an alternative
to the normal leading tab ended up adding an invalid integrity check.
Lines without any leading space or tab were considered to be in error
but empty lines are present so need to be accepted.
The change to make "ouch! you bump into a door" use up a turn didn't
end running, so when it happened while running useless turns took
place and that message was delivered repeatedly until some other
action interrupted the hero. It didn't matter whether autoopen is
enabled.
Fixes#277
Noticed while testing the look-at-self feedback for traps. When
punished and the iron ball gets buried, hero becomes "tethered to a
buried object". It is possible to simply walk away (like from a pit,
bear trap, web, stuck in floor by solidified lava or sinking into
molten lava) but that requires many tries. Once the escape happens,
"you finally wrench the ball free" and are supposed to have it
reattached to a replacement chain. However, buried_ball() wouldn't
look at buried objects if the trap countdown timer was 0 (which is
the case when finally wrenching free). So hero got a new chain to
drag around but it had no heavy iron ball attached.
I didn't turn on sanity checking but that would have complained about
this. Normal dragging didn't care but I wouldn't be surprised if
various actions that checked Punished and picked up the ball in order
to put it down again elsewhere would have had possibly serious trouble.
Use trapname() in several more places. I wasn't systematic about it.
trapname() could generate a random value of 0 and attempt to use
"real trap #0" but 0 is NO_TRAP. So it ended up with "water" from
the preceding block of entries in defsyms[]. Treat 0 as an extra
chance for the actual trap instead of an hallucinatory one.
Add a couple more hallucinatory traps. "Roach Motel" is trademarked
but like Spam and Band-Aid, general usage has trampled over it. I
included "(tm)" anyway. Also, sometimes generate "<role> trap" or
"<rank> trap" on the fly. Why should tourists get all the fun?
globwt() didn't check for wizmode, so unpaid globs would be shown with weight
information even for normal player.
Eliminated globwt() completely and consolidated the output of aum in one place
as we don't really care about the ordering of debug info in wizmode.
Recent object formatting changes for wielded weapon put some pline
arguments in the wrong order.
a - aklys (weapontethered in hand)
or worse, when dual-wielding
a - aklys (wieldedtethered in right hand)
Change back to
a - aklys (tethered weapon in hand)
or
a - aklys (tethered weapon in right hand)
I considered (tethered weapon wielded in right hand) for the two-
weapon case, but I think that's too verbose.
Wizard mode wishing for "Amulet of Yendor" has a 50% chance of
yielding a cheap plastic imitation. Allow asking for "real Amulet
of Yendor" and "fake Amulet of Yendor" to provide precise control.
Asking for "real Amulet of Yendor" in normal play will be accepted
but then overridden with the fake amulet as usual.
Without the prefix, there's still a 50:50 chance for either amulet.
"real fake amulet of yendor" and "fake real amulet of yendor" both
yield a fake one.
When handling "amulet of yendor", any of "cheap", "plastic",
"imitation", "cheap plastic", "cheap imitation", and "plastic
imitation" are now recognized to mean "cheap plastic imitation".
Unlike prefixes such as "blessed rustproof" vs "rustproof blessed",
these two-word ones (or the three-word whole thing) need to be in
specific order and after the general prefixes. Also, any of those
force "fake" even if an explicit "real" prefix came before them.
Apply makes a touch_artifact check on the tool being applied, but
autounlock would pick an unlocking tool to use without doing that.
Noticed while fixing that: autounlock took no time.
Since picking an artifact unlocking tool might now blast the hero,
change the tool selection. First choice: any key except another
role's quest artifact; second: any lock-pick except another role's
quest artifact; third: any credit card except another role's quest
artifact; fourth, fifth, sixth: other roles' quest artifact key,
lock-pick, or credit card. The fifth category (artifact lock-picks)
is empty. Rogues will pick non-cursed Master Key over any other
key (special case for first choice). Tourists will pick a key or
a lock-pick over their PYEC (first and second choices over third).
Jumping, Newton's 3rd Law hurtling, and throwing an iron ball:
attempting to do any of these in such a way that you would diagonally
pass between boulders/walls causes the Luck penalty. However, none of
these actually get you through the diagonal gap, thus they can't be used
to cheat and the penalty doesn't make sense.
Allow wishing for secret doors and secret corridors. It's a bit
more strict about where the wish is performed than wishing for
furniture. Implemented in order to test drum of earthquake effects.
I spent a lot of time figuring out SDOOR details that somebody
already knew at some point but evidently didn't document--you can't
specify D_CLOSED for them or the display code will issue impossible
warnings about wall mode angles.
When a drum of earthquake targets a secret door, reveal it (which
is always followed by collapsing the door), and when it targets a
secret corridor, reveal that corridor. Both situations also place
a pit at the location.
Drum of earthquake can try to destroy fountains, thrones, altars,
sinks, and graves but it wouldn't do so because maketrap() had been
changed to prevent clobbering furniture with traps. So you might get
"the throne falls into a chasm" but the throne would remain intact.
Change furniture to be floor before trying to create a pit. The gist
of the patch is the 'if' after 'do_pit:' and also some changes to the
revealing of hidden monsters. The rest is reformatting.
Don't allow dual-wielding if either wielded or alternate weapon
(or both) is a launcher: bow, crossbow, or sling. (I thought that
this had been addressed ages ago.)
Refine the "can't twoweapon" feedback. The message for having
either or both hands empty is the same, but sentence construction
is different. The not-a-weapon feedback is slightly different, now
mentioning whether it's the wielded or alternate weapon which isn't
allowed. The case where neither are acceptable still just reports
uwep; mentioning both it and uswapwep would be too verbose.
Make more things be described as "(wielded)" instead of "(weapon in
hand)". It was just stacks with quantity more than 1. That's now
joined by ammo and missiles (any stack size, but in reality just 1
since greater was already being caught here) and any quantity of
non-weapon, non-weptool. It's overridden if dual-wielding so that
right/left stay matched.
When dual-wielding, list primary as "(wielded in right hand)" and
secondary as "(wielded in left hand)" instead of "(weapon in hand)"
and "(wielded in other hand)". The vaguer wording was better for
bows since they're held in the off hand but now that they can't be
dual-wielded that doesn't matter. (Single-wielding a bow is still
"(weapon in hand)".)
When not dual-wielding, the item in the alternate weapon slot is
still described as "(alternate weapon; not wielded)" even if it's
not actually a weapon. I couldn't think of better phrasing.
Applying a spellbook allows the player to flip through the pages, providing an
indication of how many reads it has left before turning blank.
Originally from UnNetHack but code almost completely refactored and updated
for post 3.4 changes like deafness and novels.
When GOLDOBJ was activated unconditionally, several texts started referencing
"money" instead of "gold".
As we don't have the intention to introduce a complex coin system with
different denominations, change it back and also some other places that
reference "money".
The test for whether a migrating object generated as plundered
mine-town loot should be delivered to any orc created and then giving
that orc a bandit name was kicking in for orc mummies and orc zombies
as well as for regular orcs.
Also, the loot could include tins or eggs and their species would
get clobbered by the overloading of obj->corpsenm. During delivery
when the overloading was reset they would become giant ant eggs/tins.
(Not seen in actual play.)
Meat rings were causing increased hunger even though they don't do
anything. Not mentioned in the report, but cheap plastic imitation
amulets increased hunger too and they don't do anything either.
Trickier to fix, +0 rings of protection were excluded from hunger
on the grounds that +0 rings don't do anything, but since 3.6.0
+0 protection provides +1 to magic cancellation if protection isn't
coming from anywhere else. Two +0 rings of protection are trickier
still since only one of them provides the MC bonus.
Fixes#272
After the "make 'w' parallel with 'Q'" patch, wielding bare hands
was erroneously treating object id 0 as a split of zeroobj. That
isn't in inventory so seems 'lost'. Fixed by testing for nonzero.
There was another bug: you could wield a partial stack even if your
current weapon was cursed. Fixed by reordering if/else-if/end-if.
Change the composition of worm tooth from none-of-the-above to bone
and crysknife from mineral to bone, same as is used for unicorn horn.
I think the only significant difference will be that worm teeth used
up during polypiling will produce skeletons rather than flesh golems.
Fixes#268
Originally requested by one of the hardfought admins
Adjust all active window ports (tty, curses, win32, Qt, X11) to store
the itemflags that they receive with each item.
Also, make those active window ports understand the new
MENU_ITEMFLAGS_SKIPINVERT flag by skipping any menu items with that
setting during invert_all and invert_page operations.
Build testing and rudimentary functionality testing was carried out
on each of the window ports listed above.
The code was also modified on some non-active window ports (Qt3, gem,
gnome) but it was not tested for build or function there.
The desired functionality expressed was to be able to select a
single object category, and use the @ "invert all" function to
exclude that one and select all the others.
The "invert all" function's behavior of also including things
like "select all" and BUCX menu items made the feature unuseful
for that purpose.
Subtracting one dungeon depth value from another had the subtraction
backwards and that yielded a negative value where a positive one is
expected. If NH_RELEASE_STATUS were to be set to NH_STATUS_RELEASED
then this was at risk of crashing (if the bad subtraction yields -2,
rn2(diff+2) would divide by 0) since rn2()'s argument isn't validated
for released version.
fixes37.0 was confused, listing a couple of things that aren't bugs
in 3.6 as general fixes. I suspect that the DLB one was fixed before
being exposed via git, so shouldn't be there at all.
If you're wielding a stack of N items, issuing the command to quiver
them asks whether you want to quiver N-1 of them (implicitly leaving
one wielded). If you answer no then you're asked whether to quiver
all of them. You could also give a count when picking the item to be
quivered and the stack would be split based on that.
However, if you have a stack of N items quivered, issuing the command
to wield them just did so, leaving the quiver empty. And picking an
item ignored any count, so even explicitly asking for 1 (out of N)
wielded the whole stack. Change 'w' to parallel 'Q'; if you try to
wield a quivered stack, you'll be asked whether to wield just 1 of
them. For no, ask whether to wield the whole stack. Or you can give
an explicit count when picking any stack in inventory to wield.
Both 'w' and 'Q' probably ought to handle the alternate/secondary
weapon similarly when it contains a stack. This doesn't address that.
Bite the bullet and add a special purpose boolean option to control
game behavior for random clairvoyance. When objects or monsters are
discovered, it normally issues "you sense your surroundings" and
performs a getpos() operation which allows the player to browse the
map by moving the cursor around and getting 'autodescribe' feedback.
But there have been complaints that once the hero has the Amulet
(which triggers random clairvoyance even though hero isn't flagged
as having that attribute) the message and pause-to-browse become too
intrusive.
This was initially combined with the 'timed clairvoyance' fix because
they both bump EDITLEVEL to invalidate existing save files, but their
details don't interact so I separated them.
When the hero has random clairvoyance, the code used
| (moves % 15) == 0 && rn2(2) != 0
(where 'moves' is actually the turn number) to decide when it would
kick in and show a portion of the map. If the hero was fast enough
to get an extra move when the turn value met the (moves % 15) == 0
condition then clairvoyance could happen twice (or more if poly'd)
on the same turn.
The changes (one new field, reordering a few others) in 'struct
context' invalidate existing 3.7.0-x save files.
Fixes#266