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.
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.
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.
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.
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
^ ^
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.
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() */
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.
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.
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.
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
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.
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'.
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.)
... 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.
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.
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.
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.
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.
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).
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.
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.]
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.
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.)
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.