Commit Graph

532 Commits

Author SHA1 Message Date
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
PatR
54aa047ec9 \#wizkill fix
When running #wizkill, if hero was swallowed and you killed the
engulfer and that dropped hero onto a level teleporter, the targetting
loop for selecting the next monster to kill kept going after changing
to another level.  Terminate #wizkill if killing something sends you
to a different level.

Not fixed, and an old bug, or variation of one:  the cursor got
positioned at the coordinates of your spot on the prior level even
though the part of the new level where you actually arrived was
displayed.

The hack.c and trap.c bits are just reformatting.
2022-12-01 15:36:40 -08:00
Pasi Kallinen
47c194fd56 Avoid segfault when null obj passed to water_damage 2022-12-01 13:29:52 +02:00
PatR
7099bf63de more #936 - water vs potions of acid
Pull request #936 took away the destruction of potions of acid ("acid
and water don't mix") if they survived water_damage().  Restore that
by forcing them to not survive.  Exception:  if they're greased and
pass the 50:50 chance of retaining the grease, they aren't destroyed.
2022-11-30 14:49:11 -08:00
Michael Meyer
263e48c6f7 Tell player when water damage removes grease
This was totally silent, which -- at least for me -- has led to quite a
few cases of believing my bag or cloak is still greased when it actually
wore off the last time I took a dip.  I think telling the player that
the grease has worn off would be helpful, and is consistent with other
types of water damage.

The message is printed even if you are blind, since that seems to be
true of all the other messages in water_damage().  I am not sure if that
makes complete sense (especially for ones like a scroll fading -- some
like water getting into a bag could be sensed by touch) but I didn't
change anything there.
2022-11-30 12:54:26 -08: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
nhmall
99a93fe50b some C99 changes
Instead of using index() macro defined to strchr, use C99 strchr.
Instead of using rindex() macro defined to strrchr, use C99 strrchr.

If you want to try building on a platform that doesn't offer those
two functions, these are available:
    define NOT_C99       /* to make some non-C99 code available */
    define NEED_INDEX    /* to define a macro for index()  */
    define NEED_RINDX    /* to define a macro for rindex() */
2022-10-29 10:54:25 -04:00
PatR
61c61f8b04 dgn_bottom() fix
Use the level passed in instead of the hero's location when checking
the dungeon branch.

It probably doesn't make any difference, but use the argument that's
already being provided.
2022-09-22 23:16:19 -07:00
PatR
2d4c5a8e44 refine bottom of Gehennom check
In the quest branch, dbg_bottom() returns a barrier level rather
than actual bottom.  Do things the same way for the gehennom branch.
2022-09-22 16:47:37 -07:00
Michael Meyer
81285b661e Apply dest. limit to monster trap door usage
To prevent monsters from falling past the bottom level or into the
sanctum early, and to maintain consistency between monster and hero hole
usage.
2022-09-22 11:36:48 +03:00
Michael Meyer
9f5b362601 Refine attempt to clamp trap door fall destination
This should prevent anyone from exploiting falling into the sanctum (by
taking advantage of a trap door in a bones file from a differently
laid-out dungeon, as described in the previous commit) to bypass the
invocation, in addition to falling past the actual end of the dungeon.
2022-09-22 11:36:48 +03:00
Michael Meyer
1830b206c7 Prevent hero from falling past end of dungeon
Similar story with saved trap door destinations: if a bones file near
the end of the dungeon came from a longer dungeon (i.e. with a
lower-depth castle) than the one the bones file is loaded into, the
trap door destination could be past the dungeon end.  Clamp the
destination so it won't be lower than the bottom level of the dungeon.
2022-09-22 11:36:48 +03:00
Pasi Kallinen
ccaadaa00e Prevent trapdoors and holes dropping you into Sanctum 2022-09-20 12:07:37 +03: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
PatR
1bdfeb04ab livelog/#chronicle for Sokoban completion
Change "completed sokoban 3" to "completed 3rd Sokoban level".
It doesn't seem like much of an improvement.
2022-08-27 14:00:06 -07:00
Pasi Kallinen
fcf5c1ea50 Monsters see and remember when others trigger traps
No longer will there be a conga line of hill orcs stepping into
the same arrow trap one after another.
2022-08-21 11:51:19 +03:00
Pasi Kallinen
953d43f5ac Monster known traps bit twiddling 2022-08-21 11:36:39 +03: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
Pasi Kallinen
9be2e581b7 Macros for checking is object artifact 2022-08-12 19:37:34 +03:00
Pasi Kallinen
05761bada6 Holes and trapdoors have predetermined exit level
Same hole/trapdoor will always take you to the same level.
2022-07-27 22:51:17 +03:00
Pasi Kallinen
e4cb3f0832 Rangers always succeed in disarming bear traps 2022-07-18 17:22:19 +03:00
Pasi Kallinen
88ec641770 Allow entering a known pit without taking damage 2022-07-18 17:00:20 +03:00
Pasi Kallinen
aa09f3eef5 Use macro unhideable_trap 2022-07-18 13:27:39 +03:00
PatR
ad56ce0d1f type mismatch fix
The new routine to find an adjacent spot expects to be passed a pair
of 'coordxy *' but the code to crawl out of water was passing 'int *'.

While in there, the removal of inline code to pick a spot to crawl to
made in easy to eliminate 'goto crawl'.
2022-07-17 14:24:34 -07:00
Pasi Kallinen
823a6f247b Unify picking crawl goodpos 2022-07-17 21:37:31 +03:00
PatR
f4e38b8b3e fix github issue #820 - clinger vs pit
Issue from youkan700:  a previously undiscovered pit was being made
known before hero poly'd into clinging monster checked whether it was
already known.  So it always gave "you see a pit below you" instead
of "a pit opens up under you!" combined with "you don't fall in!".

(I think those exclamations are excessive but haven't touched them.)
2022-07-15 15:51:01 -07:00
Pasi Kallinen
486ed29077 Blessed potion of polymorph asks user for monster to poly into
... unless there's some other form that would override the choice,
such as a worn dragon armor, lycanthropy, or vampirism.

The polymorph will be in effect for 10-24 turns.
2022-07-14 14:04:27 +03:00
Pasi Kallinen
5c7c9d10ae Rejigger anti-magic traps
My changes were too drastic, so reduce the drain and damage so it
matches all the other traps. Now the anti-magic trap will always
ding your max energy a bit, in addition to the physical damage done
if wearing magic resistance.
2022-07-12 20:24:30 +03:00
Pasi Kallinen
640b6d6ce5 Untrap monster in trap on melting ice
Monster trapped in a trap on melting ice, the monster stayed
trapped even as the trap was removed when the ice melted.
2022-07-06 20:16:24 +03:00
Pasi Kallinen
134363cead Fire trap on ice can indirectly kill a monster via drowning
Make the trap routine claim the trap killed the monster even
though it was drowning that did it, otherwise callers cannot
rely on the trap routine return value.
2022-07-05 12:17:50 +03:00
Pasi Kallinen
361e6a924a Fix segfault with fire trap on ice and monster triggering it
When a monster with innate teleporting stepped on a fire trap on ice,
the ice melted and the monster teleported away before falling
into the pool. If the monster's new location had a trap, the code
tried to access the deleted fire trap.
2022-07-05 10:51:28 +03:00
Michael Meyer
141b568944 Make monsters trigger landmines based on weight
The 1/3 likelihood of a monster setting off a landmine seemed a little
arbitrary to me, especially in that it applied equally to all monsters,
from giants to insects.  Change the flat 33% chance to one based on the
monster's body weight, so that lightweight monsters have little to no
chance of setting off a mine, with the likelihood increasing from there
with the monster's weight.

With a trigger weight of 400, as it is in this commit, a dingo has a 0%
chance of setting off a landmine, a gelatinous cube the same 33% chance
as before, an elf a 50% chance, a human a 72% chance, and something the
size of a dragon (ignoring the reduced likelihood for flying monsters) a
91% chance.
2022-07-02 15:02:32 -07: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
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
0ce9d3a1e9 Merge branch 'pr775' into NetHack-3.7 2022-05-28 19:42:21 -04:00
nhmall
9e6ac144b4 switch to using a flag parameter on newcham() 2022-05-28 19:35:48 -04:00
copperwater
218a6a9d25 Have newcham() give messages when monsters polymorph in more cases
This is a descendent of an earlier patch I wrote. The main idea is still
to clearly communicate to the player *what* something is turning into,
without the need to farlook afterwards, and give them the opportunity to
add MSGTYPE for when something jumps on a polymorph trap and becomes an
arch-lich. If it happens out of sight, the player also might get a whiff
of the monster's smell, giving a bit of advance warning.

There is one new case in here, in normal_shape(), which came about
because I noticed a weird message sequence: "The magic-absorbing blade
cancels the python!  You kill the chameleon!" with no intervening
message indicating the python reverted to a chameleon.
2022-05-27 20:54:47 -04:00
PatR
132e1d433a fix comment (copy/paste victim) 2022-05-07 00:38:44 -07:00
PatR
02207b967a autounlock:untrap
Implement 'untrap' as an 'autounlock' action.  Quite a bit more work
than anticipated.  The new documentation is rather clumsy; too many
if-this and if-not-that clauses have intruded.

I'll be astonished if all the return values are correct....

[A couple of places were checking for (rx != 0 && ry != 0) to decide
whether they were performating an autounlock action at <rx,ry> but
that erroneously excludes the top line of the map if the current
level extends that far.  Just check rx for zero/non-zero.]
2022-05-06 14:44:57 -07:00
PatR
d1217b9f25 add glyphs+tiles for door+chest traps
When trap detection finds trapped doors and trapped chests, it shows
those as bear traps.  When the hero comes within view, they revert to
normal and the detected trap is forgotten.  This doesn't change that,
it is just groundwork to be able to show them distinctly.  Like the
TT_BEARTRAP patch, it increments EDITLEVEL so this seemed like a good
time to put the groudwork in place.

There shouldn't be any visible changes even though internal glyph and
tile values have been renumbered after inserting two new entries.
Adding traps after S_vibrating_square was quite a hassle and suffered
though a couple of off-by-one errors that weren't trivial to find and
fix.
2022-04-27 11:22:12 -07:00
PatR
d194459c7d u.utraptype, TT_BEARTRAP
Add 'FIXME' fix by entrez to change TT_BEARTRAP to non-zero.

Increments EDITLEVEL, invalidating existing save and bones files.
2022-04-27 11:04:12 -07:00
Pasi Kallinen
4cffa9700e Split trap statue creation into separate function 2022-04-26 18:09:36 +03:00
Pasi Kallinen
99efeafec7 Split trap note choosing into separate function 2022-04-26 14:00:09 +03:00
Pasi Kallinen
565a3cf0a9 Reverse the unique requirement 2022-04-03 08:55:09 +03:00
Pasi Kallinen
38a6cee1ab Don't pacify unique monsters when untrapping them from web 2022-04-02 19:38:50 +03:00
PatR
6a2ff5743a items destroyed by exploding chest
From a report by a beta tester 8 years ago:  kicking a chest gave
"THUD!  The chest explodes!" but the chest remained intact.  The
explosion was destroying all floor items at the hero's spot rather
than at the chest's spot.  Fixing that results in the chest being
destroyed because it's one of the items at its own spot.

While fixing that I noticed that delobj() was only protecting the
Amulet and the invocation items from destruction, not Rider corpses.
You could destroy one or more of those by getting a trapped chest's
explosion while using a key at its spot rather than by kicking it
from adjacent.  (Getting the exploding chest result is not easy,
particuarly with positive luck.  I eventually resorted to forcing
it with a debugger.)
2022-03-27 17:55:52 -07:00
SHIRAKATA Kentaro
291d872f62 move null-check on savelev()
Move null-check of ttmp before its first use.
2022-03-24 04:16:16 +09:00
PatR
d53c1a7a67 max HP manipulation
Life-saving has been setting u.uhpmax to max(2 * u.ulevel, 10)
and if it took place during level drain that could make u.uhpmax
increase instead of decrease, confusing healing which gets applied
to a monster who has drained the hero with Stormbringer or the
Staff of Aesculapius.  Change the setting to be max(u.ulevel, 10)
(removing the times two part) and also have level drain force it
to be set back to previous value if/when it gets increased.

Max HP loss due to strength trying to drop below 3 or to fire trap
or to being hit by Death now uses a mininum max HP of u.ulevel
rather than 1.  They don't have the alternate minimum of 10; I'm
uneasy that there are still two different minimum values.

I changed adjattrib() to set the flag to request a status update
before it gave its optional message rather than after so that the
new characteristic value would be visible during the message.  That
resulted in not updating status when eating royal jelly changed HP
or max HP after boosting strength.  But the same missing update
would have occurred--or rather, failed to occur--without the change
in sequencing if the strength boost causes a change in encumbrance.
2022-03-21 12:32:07 -07:00