Commit Graph

406 Commits

Author SHA1 Message Date
PatR
0e761c3e30 talking artifact inconsistency
To get the Magic Mirror of Merlin to speak, you could apply it in
any direction (or wield it).  To get the Master Key of Thievery to
speak, you had to apply it toward an adjacent doorway or down while
on a container (or wield it).  Make the key behave like the mirror.
2023-03-18 21:47:34 -07:00
nhmall
de79240dea some comment spelling fixes 2023-03-16 22:27:01 -04:00
nhmall
ecf74d5308 some pline()-like function usage 2023-03-08 19:12:52 -05:00
nhmall
da71e22fac suppress some warnings if SND_SPEECH is not defined
apply.c:1413:27: warning: unused variable 'shkp' [-Wunused-variable]
            struct monst *shkp = shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE));
                          ^
apply.c:1570:27: warning: unused variable 'shkp' [-Wunused-variable]
            struct monst *shkp = shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE));
                          ^
apply.c:1650:31: warning: unused variable 'shkp' [-Wunused-variable]
                struct monst *shkp = shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE));
                              ^
apply.c:1697:23: warning: unused variable 'shkp' [-Wunused-variable]
        struct monst *shkp = shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE));
                      ^
apply.c:2157:31: warning: unused variable 'shkp' [-Wunused-variable]
                struct monst *shkp = shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE));
                              ^
apply.c:2165:31: warning: unused variable 'shkp' [-Wunused-variable]
                struct monst *shkp = shop_keeper(*in_rooms(corpse->ox,
2023-02-08 12:44:14 -05:00
nhmall
fbd9a7bae8 another update to the soundlib interface
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.
2023-02-07 00:44:36 -05:00
Pasi Kallinen
7aeba46690 Pickaxing or whipping a liquid wall 2023-02-07 07:36:51 +02:00
nhmall
84b9af9151 add a few missing Soundeffects to apply.c 2023-01-24 13:36:33 -05:00
nhmall
3d908c49ef take initial stab at macsound interface
Use macOS AppKit framework routines for a first cut at a
macsound soundlib interface.

Requires WANT_MACSOUND=1 on build.

Nothing has been done to move the stock sounds into the resources
of a bundle, so after building, if you want to try the stock sounds
out:
	cp sound/wav/*.wav ~/Library/Sounds

Because the NSSound macOS routines always do the search, supposedly
the following locations are searched in this order:
   1. the application’s main bundle
   2. ~/Library/Sounds
   3. /Library/Sounds
   4. /Network/Library/Sounds
   5. /System/Library/Sounds

Although not specifically implemented as of yet, it may be pretty
close to being able to put soundeffects wav files (by se_ name)
into ~/Library/Sounds working for the SND_SOUNDEFFECTS_AUTOMAP feature.

Feedback is welcome. Contributions for improving it are even more
welcome.

The new soundlib supporting file is named
sound/macsound/macsound.m since it's got objective C in it.

Known bugs and glitches:

The Hero_playnotes on a set of 5 notes goes too fast, so there
needs to be a slight delay added between the note of a multi-note
play.
2023-01-23 23:50:43 -05:00
PatR
1f9cb8250b feedback bit
Handle the candle vs underwater message that just had its punctation
fixed slightly differently.
2023-01-21 11:24:52 -08:00
Michael Meyer
891a20f569 Fix: underwater vision update frequency
Underwater vision was updated only once per turn, so if the hero had
more than one move per turn it could cause some spots to be left behind
on the map.  For example, after moving around underwater while very fast
for a while:

            }
          }}}
          }}}}
       }  }}@}
      }    }}}

Not only does the radius of vision appear to "smear" temporarily, but if
the hero moves fast enough, isolated spots can be left entirely behind
(since the normal underwater vision update only clears nearby spots, not
the entire map).  Both these effects are visible in the example above.

The fix in this commit is to update the frequency of underwater vision
updates to "once-per-time-taken" rather than "once-per-turn", so that it
updates with every move.  I'm not sure if it needs to happen more
frequently than that (i.e. in the "once-per-input" section) but I might
be overlooking something.

Also add missing punctuation to the message for applying a lamp
underwater.
2023-01-21 11:02:05 -08:00
nhmall
28cd188259 resolve 5 analyzer warnings if no SND_LIB_* define 2023-01-20 17:32:55 -05:00
nhmall
8bbe9282aa add soundeffects hooks to core
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.
2023-01-20 14:20:08 -05:00
nhmall
ba5356603a yn()
A number of C compiler suites have a math.h library that includes a yn()
function name that conflicts with NetHack's yn() macro:
"The y0(), y1(), and yn() functions are Bessel functions of the second kind,
for orders 0, 1, and n, respectively. The argument x must be positive. The
argument n should be greater than or equal to zero. If n is less than zero,
there will be a negative exponent in the result."

At one point, isaac64.h included math.h, although that has since been removed.

Some libraries used in NetHack (Qt for one) do include math.h and that required
build work-arounds to avoid the conflict.

Rename the NetHack macro from yn() to y_n() and avoid the math.h conflict
altogether, eliminating the need for that particular work-around.
2023-01-12 16:04:40 -05:00
nhmall
02a48aa8cf split g into multiple structures
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
     ^ ^
2022-11-29 21:53:21 -05:00
Michael Meyer
619781dbb8 Add 'mdistu' macro
Short for distu(mtmp->mx, mtmp->my) (i.e. the distance between the hero
and the specified monster), which is a very common use of distu().  The
idea is that this would be a convenient shorthand for it; I actually
thought it (or something very similar) existed already, but couldn't
find it when I tried to use it earlier.  Based on the number of uses of
fully-spelled-out 'distu(mtmp->mx, mtmp->my)' replaced in this commit
I'm guessing I just imagined it.
2022-11-18 23:42:47 -08:00
PatR
fc0f05398e getpos() reformatting
Some miscellaneous reformatting done while looking over getpos() usage
rather than reformatting of getpos() itself.
2022-10-20 10:33:38 -07:00
PatR
c2a9343367 horn_of_plenty-to-container #tip
For tipping purposes, a horn of plenty is treated like a container.
But using one as the source container in a container-to-container tip
wasn't supported.  Implement that.

Also, #tip was offering carried bags of tricks as candidate containers
to tip some other carried container into.  Only do that for ones which
aren't known to be bags of tricks (so when type not discovered yet, or
specific bag not seen yet due to blindness).
2022-09-14 15:54:24 -07:00
PatR
7ae4efb07c fix issue #872 - container-to-container #tip
Reported by k2:  tipping one container's contents directly into
another container allowed transferring a wand of cancellation (not
mentioned:  or a bag of holding or a bag of tricks) into a bag of
holding without blowing it up.

That's now fixed.  There are other issues that this doesn't touch:

I think it's odd that you can transfer stuff from one carried
container to another but not from a carried container to a floor
container nor from one floor container to another one at same spot.

I didn't test shop billing so an not sure what happens when #tip
blows up a bag of holding and there are some unpaid items involved.

Using #tip on horn of plenty treats it like a container, but doing
that when it's carried doesn't offer the chance to tip its contents
directly into a carried container.

Tipping a carried container does not require free hands or even
limbs (for playability) but tipping such into another container
should require at least one free hand.

Fixes #872
2022-09-12 14:17:22 -07:00
nhmall
c548fff9e4 some spelling corrections
The pull request included some changes that were neither accidental nor
unintentional, so only a subset of the changes from pull request #869
submitted by klorpa were manually applied.

behaviour  -> behavior
speach     -> speech
knowlege   -> knowledge
incrments  -> increments
stethscope -> stethoscope
staiway    -> stairway
arifact    -> artifact
extracing  -> extracting

The uses of "iff" were left alone.

Close #869
2022-09-08 10:54:11 -04:00
Pasi Kallinen
e952f67f2c Add #wizcast command to cast any spell
Wizard-mode command to cast any spell without checks that would
prevent casting, and with no energy use.

Mainly to allow the fuzzer to exercise the spell code paths.
2022-09-06 22:58:28 +03:00
nhmall
0086e01967 return legal indexes for some display.h macros
Some static analyzers flagged the last-resort values as
out of bounds (which they were).

There's a small number of other complaint-suppression items in here too,
but nothing drastic.
2022-09-06 10:00:07 -04:00
nhmall
ef6fde88ea redundant code warning line 400 src/apply.c
if (odummy->otyp == SLIME_MOLD
400 ->                    && has_mcorpsenm(mtmp) && MCORPSENM(mtmp) != NON_PM)

The definition of has_mcorpsenm macro is:
include/mextra.h:#define has_mcorpsenm(mon) ((mon)->mextra && MCORPSENM(mon) != NON_PM)

Remove the redundant code.
2022-08-17 21:16:23 -04:00
PatR
b07fe59b3c attack/damage by trapper and lurker above
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.
2022-08-15 04:14:36 -07:00
PatR
1a6456ad82 fix github issue #842 - lamp/lantern feedback
Issue reported by GorillaSapiens:  you get notified if a lamp burns
out even if you're blind at the time.

That is intended behavior; you can feel the heat or lack of heat
from a lamp or candle.  But the comment from copperwater pointed out
that you shouldn't be able to feel that for a brass lantern.

This suppresses the "power has run out" feedback if blind at the
time.  However, applying a lantern to turn it on or off still gives
the on/off feedback on the assumption that there's a switch and you
can feel its position.  When hero is blind and lantern is out of
power, trying to turn it on yields "nothing seems to happen".  It's
not completely consistent since you would feel the switch in its On
position but claiming that the lantern is on would be a lie.

The basic on and off messages referred to "lamp" even when using a
brass lantern.  I thought that that had been fixed a long time ago.

Fixes #842
2022-08-13 15:55:10 -07:00
Pasi Kallinen
fd9745f9c6 Command repeating by using cmd queues
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.
2022-08-09 11:54:45 +03:00
Pasi Kallinen
cb9044c23f Make failed polearming or jumping return correct value 2022-07-28 22:10:08 +03:00
Pasi Kallinen
bae221d0c3 Grappling location feedback 2022-07-28 13:50:57 +03:00
Michael Meyer
ac0d6a98ce Prevent amorphous mon from carrying hero into door
An amorphous engulfer like a fog cloud could engulf the hero, then carry
him into a closed door.  If it was killed or decided to spit out the
hero, he would be left occupying the same spot as a closed/locked door.
Make an amorphous monster unable to move into a door if currently
engulfing the hero.

Something more complicated could be done along the lines of allowing the
move if the hero is himself in an amorphous polyform, but that verges on
being a little too silly, maybe.

I also included fixes to a couple miscellaneous, unrelated formatting
issues that I noticed recently.
2022-07-22 14:38:14 -07:00
Pasi Kallinen
6fe0f7c132 Unify impaired movement direction checks 2022-07-17 12:23:49 +03:00
Pasi Kallinen
81d54f15ce Applying a cursed lamp can make your hands slippery 2022-07-12 22:12:52 +03:00
nhmall
3004cf2d34 be more consistent with coordinates 2022-07-02 09:10:03 -04:00
nhmall
30b557f7d5 change xchar to other typedefs
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
2022-06-30 23:48:18 -04:00
nhmall
2770223d10 interface groundwork for core-side color decisions
(user-side decisions really, but as it stands right now
user-side decisions/options are made and processed by the core)

add a parameter to add_menu so color can be passed
2022-06-25 13:21:51 -04:00
PatR
5e09a86766 yet more magic whistle
'optr' was accidentally left around from an intermediate revision.
There's no reason to keep it as a comment.
2022-06-19 02:39:43 -07:00
nhmall
c3fcf9dbd6 silence three compile warnings
apply.c:495:22: warning: variable 'optr' set but not used [-Wunused-but-set-variable]
    struct permonst *optr;
                     ^
1 warning generated.
cmd.c:4577:26: warning: variable 'how' set but not used [-Wunused-but-set-variable]
    const char *dothat, *how;
                         ^
cmd.c:4578:29: warning: variable 'viawindow' set but not used [-Wunused-but-set-variable]
    boolean prefixhandling, viawindow;
                            ^
2 warnings generated.
2022-06-19 04:56:48 -04:00
PatR
e6a5ef8e59 magic whistle followup 2022-06-19 01:40:07 -07:00
PatR
e5180d1587 magic whistle bandage
Reported by entrez:  if magic whistle summoned a pet onto a trap, the
messages produced could be in the wrong sequence or contradictory.
The code was collecting counts and name-of-first for shift (was seen
before whistling, seen at different spot after), for appear (wasn't
seen before, now is), and for disappear (was seen before, now isn't)
before dealing with a trap at arrival location.  The trap could issue
a message (including pet killed, pet sent away--teleport trap, hole,
&c--or pet changed shape--which occurred after its name/old shape was
saved for use when it was the only one in its category), and finally
the summary message was issued.

Change the code to handle arriving in a trap before the collection
into the three categories that provide feedback, and skip the latter
if any message was given during mintrap().  That handles the most
glaring anomalies like killed followed by shifted location or takes
on new shape followed by old shape shifted or appeared.  But it no
longer gives specific shift/appear/disappear feedback for those cases.
Pets that don't land on traps or who land on ones that don't issue
any feedback aren't affected.

The accessibility aspect of this--message feedback in order to avoid
tedious screen reading of the map--will need to be satisfied by the
trap feedback unless/until someone comes up with a better solution.
One possibility is an option to allow player to have rloc() always
issue its vanish and appear messages.  Right now it does so when magic
whistle hasn't been discovered yet, then avoids that hyper-verbosity
(if hero has multiple pets) once it has.  Or the whistle code could
count the number of pets first, then behave as if such an option is in
effect when the count is small and only resort to the current summary
method if the count is larger than some threshold.
2022-06-17 14:58:02 -07:00
nhmall
be76727265 granular verbose message suppression mechanics
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).
2022-06-09 13:53:20 -04:00
nhmall
d486270ec9 warning fix 2022-05-10 21:10:02 -04:00
PatR
97d884585c redo magic whistle feedback
Give more information when magic whistle is already discovered and
applying it affects multiple pets, without much increase in verbosity.
For each of the three categories
 1) was already in view and moves to another spot still in view,
 2) was out of view and arrives at a spot within view,
 3) was in view but gets sent to a spot out of view,
show the pet by name (which might be "your <monst>" if it hasn't been
named) when there is just one, or "two creatures", "three...", "four...",
"several...", or "many..." when there are more than one.  The first
category with more than 1 says "creatures".  When there are additional
categories with more than 1, their part of the message says "others" if
prior part(s) already mention "creatures", or it says "other creatures"
if the prior part(s) only list pets by name.

For example
|Three creatures appear.
|Fido shifts location and Fang appears.
|Your pony shifts location and two other creatures appear.
|Many creatures shift locations, several others appear, and two others
disappear.
|Two creatures appear and two others disappear.
2022-05-10 15:53:24 -07:00
PatR
da83c9324a magic whistle fix
Restore old behavior of magic whistle causing pets to be moved to
different locations even when already adjacent to the hero.

This lets rloc() give its relatively new, more verbose messages if
a magic whistle isn't discovered yet but suppresses those when
already discovered in order to issue its own message.  For a single
pet that starts within view and arrives elsewhere within view it says
"shifts location" rather than "vanishes and reappears".  For multiple
pets, it gives one summary message instead of a separate one for each
pet affected by whistling.
2022-05-09 03:21:53 -07:00
Pasi Kallinen
f10cdc2d9c Use get_mleash to find the leash attached to monster 2022-04-26 08:46:55 +03:00
Pasi Kallinen
4a01c8fbd7 Monster list iterator
Add some basic functions to iterate through the monster list,
ignoring dead monsters. Mainly just to allow splitting up code
into discrete functions.

Not quite happy with the get_iter_mons_xy - should probably have
a pointer to iterator data struct, which gets passed through instead,
but this works for now.
2022-04-24 13:03:47 +03:00
SHIRAKATA Kentaro
367ea0e6d6 add initializer on use_tinning_kit()
If poly_when_stoned() is true, an uninitialized buffer kbuf[] is passed to instapetrify().
Although instapetrify() doesn't access it in that situation for now,
it should be initialized anyway for readability.
2022-03-25 15:47:51 +09:00
Pasi Kallinen
006ae67029 Fix autowielding tools taking no time
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
2022-03-15 11:34:48 +02:00
PatR
e3490743e0 divine gift of spell knowledge
Remove the conduct-specific aspect of receiving spells as prayer boon.
Anyone now has a 25% chance of having the spell directly implanted
into their head, not just characters who have maintained illiterate
conduct.  It can now also restore a forgotten spell or refresh one
that is nearly forgotten.  It still tries to choose a spell which
isn't already known (new: or was known but has been forgotten) but if
it picks one that is known and doesn't need refreshing, a redundant
book will be given, same as the behavior in earlier versions.

The chance for receiving a blank spellbook is higher when that item
is undiscovered.  When given as a prayer reward, make it become
discovered even if hero doesn't read it so that it will be less likely
to be given again.  There's a 1% chance for that auto-discovery to
happen with other bestowed books.  Unlike blank boots, having the book
be discovered doesn't lessen their chance of being repeat gifts.

Minor bug fix:  for a spell implanted from scratch, the book remains
unknown.  That's ok; it's actually more interesting than discovering
a book you haven't seen yet.  But after acquiring and reading the book
you could get "you know <spell> quite well already" and the book would
stay undiscovered even though you were just told what spell it's for.
2022-03-09 07:06:37 -08:00
Pasi Kallinen
d0f349cbd1 Use find_mid finding the leashed mon 2022-02-26 22:42:37 +02:00
Pasi Kallinen
2777f45bd5 Get rid of force_mintrap, allow passing flags to mintrap
It uses the same flags as dotrap, so simulate force_mintrap
by passing FORCETRAP flag.
2022-02-24 17:13:23 +02:00
Pasi Kallinen
8e91320d2f Use u_at macro 2022-02-23 20:28:55 +02:00
Pasi Kallinen
e0a83630e1 Some spell code reorg
Keep the internal spell array index inside spell.c,
and refer to spells outside of it with the otyp id.
2022-02-23 10:52:10 +02:00