Noticed when trying all the extended commands. #wizbury didn't have
any feedback (other than clearing the adjacent floor if any objects
were present).
Also, prevent #wizbury from burying boulders.
In 3.6.2 parts of the wakeup code were merged together, and this
caused pets consider any noise made by the hero - such as hitting
iron bars or digging - as whistling for them to come to the hero.
Change it to only consider actual whistling and ringing a bell.
Reported almost 9 years ago: if an adjacent statue was in a pit,
you could use a pick-axe to break it even though if you managed to
move to the pit location without falling in, you wouldn't be able
to reach objects there including the statue.
Allow a pick to reach if hero is in a conjoined pit, or if it is a
mattock rather than an ordinary pick-axe. Otherwise you'll get the
"you swing at thin air" result. Similarly when hero is in a pit and
and adjacent statue or boulder is on the floor: mattock will work
but pick-axe now yields "you can't reach".
Issue reported by mkuoppal: drum of earthquake triggers a sanity
check warning which the fuzzer escalated to panic.
Analysis by entrez. If a pit gets created next to a pool or moat or
lava, liquid might flow there and replace the pit. But the drum of
earthquake code assumed that the pit was still there. If there was a
monster there and it wasn't levitating or flying and it wasn't killed
by the liquid, it got marked as trapped even though the pit was gone.
'sanity_check' noticed.
With difficulty I was able to reproduce the impossible warning before
the fix, but the are a bunch of random factors at play. After the
fix I can't reproduce it again, but that's not a guarantee that it's
actually fixed. The analysis seems correct though and the fix is
based on dealing with that.
Closes#1170
Merge some nearly-duplicate code for the two trap types. Also include
alignment name when referring to an altar's destruction, since it
provides some context for the immediate follow-up by its god.
This is for completely destroying an altar with extra-powerful magical
digging -- the normal altar_wrath() punishment didn't seem sufficient
for such an outrage to me, so skip straight to slinging the lightning
bolts. Destroying an altar is unlikely to happen by accident (though
it's possible with poorly timed usage of a drum of earthquake).
b_trapped was treating 0 as a null value for its bodypart parameter, but
0 is actually the value of ARM, so b_trapped(..., ARM) would be treated
as intending no A_CON abuse. Add NO_PART = -1 to the bodypart_types
enum, and use that instead of 0 as the "no body part" value in
b_trapped, so that ARM can be passed to it without any ambiguity.
aosdict identified this issue in xNetHack and handled it differently; he
added NO_PART with a value of 0, incremented the existing bodypart_types
values, and padded the body part arrays so the actual body parts would
start at index 1. I think using NO_PART = -1 is simpler, but that's an
alternative approach that can be used instead -- it is advantageous in
that it automatically fixes any other places where 0 is assumed to be a
non-body-part value that I may have overlooked.
Especially powerful magic is meant to be able to destroy altars
(breaking a wand of digging or using a drum of earthquake), but it was
being blocked by a check added to maketrap() in a7f6460 designed to
prevent wizard-mode trap wishing from overwriting stairs. The check was
refined in 6a3d82c to add an exception for digging up graves, but
continued to prevent the destruction of other types of
previously-destructible terrain.
Since this block was a side effect of an attempt to add some guard rails
to wizmode terrain wishes, and the code to explicitly permit the
destruction of other furniture with especially powerful magic is still
present, it doesn't seem like it was actually intended. Open up terrain
destruction by digging magic a bit more by excluding only
non-destructible terrain, not all furniture other than graves, from
being overwritten by pits and holes.
Also, use AM_SANCTUM to more precisely identify non-destructible high
altars in dig_check() rather than checking whether the hero is on the
Astral or Sanctum levels.
Issue reported by vultur-cadens: changing helm of brilliance to
crystal made it stop being classified as "hard helmet" so it gave
less protection against things falling onto the hero's head.
Change the is_metallic() tests used on helmets to new hard_helmet().
Unlike when thrown, crystal helmets don't break when objects fall
on them.
Fixes#1060
sound_verbal(char *text, int32_t gender, int32_t tone, int32_t vol,
int32_t moreinfo);
-- NetHack will call this function when it wants to pass text of
spoken language by a character or creature within the game.
-- text is a transcript of what has been spoken.
-- gender indicates MALE or FEMALE sounding voice.
-- tone indicates the tone of the voice.
-- vol is the volume (1% - 100%) for the sound.
-- moreinfo is used to provide additional information to the soundlib.
-- there may be some accessibility uses for this function.
It may be useful for accessibility purposes too.
A preliminary implementation has been attempted for macsound to test
the interface on macOS. No tinkering of the voices has been done.
Use of the test implementation requires the following at build time with make.
WANT_SPEECH=1
That needs to be included on the make command line to enable the test code,
otherwise just the interface update is compiled in.
I don't know for certain when AVSpeechSynthesizer went into macOS, but older versions
likely don't support it, and would just leave off the WANT_SPEECH=1.
If built with WANT_SPEECH=1, the 'voices' NetHack option needs to be enabled.
It was a bit strange, when I first started up the test, to hear Asidonhopo,
the shopkeeper, talking to me as I entered his shop and interacted with him.
When a monster triggered a rolling boulder trap which buried
a shop item in a pit, the shopkeeper would bill the hero.
(Or get mad at hero, if they were out of the shop)
The fix might not be quite right - should the shopkeeper get
mad at hero when monster triggers a trap created by hero?
Or when an item is buried in a pit created by a hero?
Pull request from entrez: if bones left dead hero's corpse on top
of a new grave, don't find a corpse or summon a zombie when digging
the grave up. It also removed the chance that a ghoul might be
summoned when engraving on a headstone, switching to zombie or mummy
instead.
Rather than adopting the pull request, this retains summoning a
ghoul via engraving and adds the possibly of doing so when kicking
a headstone. Having a ghoul prowl around the grave is independent
of whether there is a corpse or zombie inside the grave. To achieve
this, another flag in 'struct rm' is needed; the single bit for
'disturbed' isn't sufficient. The bigger 'flags' field wasn't in
use for graves so commandeer that for new 'emptygrave'. 'disturbed'
still uses the 'horizontal' bit in order to have engraving and/or
kicking summon at most one ghoul.
Closes#944
Insert the calls to trigger a number of potential soundeffects
into the core.
If no additional soundlib support is integrated into the
build, then the Soundeffect macro (sndprocs.h) expands to nothing:
[#define Soundeffect(seid, vol)
]
If, however, at least one additional soundlib support is integrated
into the build, then the Soundeffect macro gets defined as this
in sndprocs.h:
[#define Soundeffect(seid, vol) \
do { \
if (!Deaf && soundprocs.sound_soundeffect \
&& ((soundprocs.sndcap & SNDCAP_SOUNDEFFECTS) != 0)) \
(*soundprocs.sound_soundeffect)(emptystr, (seid), (vol)); \
} while(0)
]
That macro definition checks for the hero not being Deaf; it checks
to ensure that the active soundlib interface has a non-null
sound_soundeffect() function pointer; and it checks to ensure
that the active soundlib interface has declared that it supports
soundeffects by setting the SNDCAP_SOUNDEFFECTS bit in its sndcap
entry. That just means that the interface routines are prepared to
accept and deal with the calls from the core, whether or not it
actually produces the desired soundeffect.
The consolidation of global variables from scattered source
files into decl.c and declared in decl.h was begun in 3.7.0.
Their placement in common files was done for centralized
initialization and potential re-initialization during a
"play again" scenario.
It wasn't really necessary for all of them to be housed in a
single huge structure to meet the "play again" requirement,
and the single huge structure has been a little unwieldy when
it comes to maintenance.
Following this commit, instead of one single extremely large structure
named 'g' to house all of the relocated global variables, they
are distributed into several ga through gz.
To make things easy for the developer, each variable is placed
into the struct corresponding to the starting letter of the variable.
That way, no lookup is required in order to know which struct houses
a particular variable, it is a simple match to the starting letter
for all the centralized global variables.
A global variable named 'amulets', would be found in ga.
ga.amulets
^ ^
A global varable named 'move', would be found in gm.
gm.moves
^ ^
A global variable named 'val_for_n_or_more' would be found in gv.
gv.val_for_n_or_more
^ ^
A global variable named 'youmonst' would be found in gy.
gy.youmonst
^ ^
Change trappers and lurkers above to remove digestion damage. They
fold themselves around rather than swallow the victim. There were
are lot of places that assumed that an engulfer which is an animal
would swallow and digest the victim. In hindsight, it might have
been simpler to take the M1_ANIMAL flag off of trappers and lurkers
above.
This adds a new digests() predicate for creatures with AT_ENGL+AD_DGST
(purple worm) and also enfolds() for AT_ENGL+AD_WRAP (both 't'-class
critters).
There are several minor fixes mixed in with this. I didn't record
them as I went along but the two I remember are
1) if poly'd into a holder and holding on to a monster, the '<' and
'>' commands refursed to work; release the held creature first
and then treat those commands as normal;
2) throwing a non-weapon while engulfed by an ochre jelly reported
"the <item> vanishes into the ochre jelly's /currents/".
This needs a lot more testing. I found and fixed multiple minor
details before my own testing burned out.
This replaces the old pushq/saveq arrays (which were used to save
the keys pressed by the user for repeating a previous command)
with a new command queue. This means there's no hard-coded limit
to the saved keys, and it can repeat extended commands which are
not bound to any key.
One of the drivers of this change was that screen coordinates require a
type that can hold values greater than 127. Parameters to the window
port routines require a large type in order to be able to have values
a fair bit larger than COLNO and ROWNO passed to them, particularly for
their use to the right of the map window.
This splits the uses of xchar into 3 different situations, and adjusts
their type and size:
xchar
|
-----------------------
| | |
coordxy xint16 xint8
coordxy: Actual x or y coordinates for various things (moved to 16-bits).
xint16: Same data size as coordxy, but for non-coordinate use (16-bits).
xint8: There are only a few use cases initially, where it was very
plain to see that the variable could remain as 8-bits, rather
than be bumped to 16-bits. There are probably more such cases
that could be changed after additional review.
Note: This first changed all xchar variables to coordxy. Some were
reviewed and got changed to xint16 or xint8 when it became apparent that
their usage was not for coordinates.
This increments EDITLEVEL in patchlevel.h
Switch to using a macro invocation Verbos(n, s) in place of the
flags.verbose checks.
Provide the mechanics for individual suppression of any of the
existing messages that were considered verbose.
Mechanics only - this code update does not provide any means of
setting the suppression bits.
iflags.verbose = 0
is still a master suppression of all the verbose messages.
iflags.verbose = 1
turns on the verbose messages only for those whose suppression
bit is 0 (not set).
When applying some tools (whips, polearms, grapples), or rubbing
a lamp, or when fireassist is on and you fire something without
wielded launcher, the automatic wielding should take as much time
as wielding the item normally does.
Fixes#696
Hidden monster might be forced to move to a location where it
can't hide, perhaps because it's mostly surrounded by other monsters.
Hidden monster in a pit under items, getting hit by a rolling boulder,
the boulder will fill the pit burying the items, making the monster
unable to hide there.
If you want to declare a pointer which the address pointed to is constant,
you should declare it as like `static const char *const var = "...";`.
This commit supplies missing `const` and prevents some programming
error in the future.