Commit Graph

215 Commits

Author SHA1 Message Date
Pasi Kallinen
2ebbd13f79 Fix boulder over a hole or a pit dug by a monster
When a monster digs down and creates a pit or a hole,
drop the boulder at the location into it.
2024-05-28 19:10:36 +03:00
PatR
c8b8f8767e MUSE wand of striking
Some code to stop a monster's zap of a wand of striking short if it
gets destroyed by hitting and destroying a drawbridge is no longer
needed with the new deferred obj deletion.
2024-05-07 12:14:54 -07:00
Pasi Kallinen
a6c5d967d2 Fix bhit/mbhit hitting destroyed objects
A monster zapped a wand of striking, hitting a burning potion
of oil, which destroyed items in the same square, and the ray was
checking destroyed item.  Similar thing with a ray done by hero.

The code currently stops checking the objects in the location
if a next object in the chain was destroyed - an improvement
would be to gather all the objects into an array and iterate
over that instead of relying on the nexthere pointer.
2024-05-07 16:05:00 +03:00
nhkeni
22d64456a6 staticfn followup 2024-03-29 13:45:27 -04:00
nhkeni
54c3dd35ac Merge branch 'keni-staticfn' into NetHack-3.7 2024-03-16 09:38:21 -04:00
nhkeni
9c0ed8ae63 NOSTATICFN for src/* 2024-03-14 17:41:51 -04:00
PatR
9ee55d87eb fix pull request #1223 - wand of striking by monst
Pull request by elunna with assistance by entrez tried to fix up
wand of striking discovery when the wand is zapped by a monster.

The fix didn't match the intended behavior (which may or may not be
the desired behavior...), so this skips the code in the pull request.
[I can't post comments on github anymore since I declined to switch
to their 2-factor authentication.  But I can still read submissions
without logging in.]

This also tries to fix a couple of inconsistencies between zapping
by the hero versus by a monster.  If the zap "boinged" :-) due to
target's magic resistance, zap by hero didn't discover the wand but
zap by monster did.  Conversely, a zap by the hero that reached a
target and missed did discover it but one by a monster did not.

Now a zap of not-yet-discovered wand of striking by the hero which
hits, whether or not the hit gets resisted, will become discovered
provided that the spot where target is hit can be seen (the target
itself need not be), and one which misses or which can't be seen
hitting something will no longer be.

Supersedes #1223
Closes #1223
2024-03-13 13:28:05 -07:00
nhmall
688ac6ffbe remove register from variable declarations 2024-02-19 16:30:07 -05:00
Pasi Kallinen
57747535af Add m_next2u, analogous to m_next2m and next2u 2024-01-19 21:53:25 +02:00
Pasi Kallinen
679c312d4d Message location for monster hurling a potion 2024-01-14 17:21:48 +02:00
nhmall
97e4c0f34a another comment bit 2024-01-11 14:44:58 -05:00
nhmall
25a8c258e6 replace x >= LOW_PM with ismnum(x) shorthand macro 2024-01-11 14:01:10 -05:00
Pasi Kallinen
58031920dc Fix monsters using escape items unnecessarily
Monsters were using escape items when they couldn't move due to
being surrounded by other monsters.  This was most evident in
Fort Ludios, where the alarm woke up all the monsters and they
would then read all the teleport scrolls.

Usually this doesn't matter, as special rooms full of monsters
are asleep.

Hardcode this fix for the Ludios only, otherwise you could trap
two monsters next to each other in a boulder fort, and they
would be happy to stay in there...
2024-01-11 19:31:37 +02:00
Mika Kuoppala
c4d3ca00ce src/muse: Avoid touch_petrifies check if bad corpsenm
EGGs can have non permanent monster based corpsenm assigned
(-1). Before doing the touch_petrifies check, make sure
that we have valid corpsenm.
2024-01-06 12:06:55 -08:00
Pasi Kallinen
0a8f919ff3 Make monsters not use camera when hero resists blindness 2023-12-16 23:34:16 +02:00
PatR
dc02eb3e4f more MUSE WAND_STRING (should be WAND_STRIKING)
Reverse part of commit 8b5e9eadb1.
Shouldn't use get_obj_location(obj,...) to try to figure out if obj
has been deleted.  That routine uses obj->where rather than scanning
the various object lists and doing that when obj has been deleted
would access stale memory.
2023-12-12 20:15:50 -08:00
PatR
8b5e9eadb1 more drawbridge destruction - MUSE WAN_STRING
A zap from a wand of striking shouldn't hit a drawbridge if it is
just passing over the span's spot when the bridge is closed.  This
change matches the 3.7 behavior when the zap is performed by the hero.
It does hit if passing over that same spot when the bridge is open or
if it hits the portcullis spot whether open or closed.

Also, simplify the handling for the wand's destruction.  It still
ends the zap early if that happens even though logically the rest of
the zap range should still be targetted.
2023-12-12 16:07:36 -08:00
PatR
c9ef210378 fix #K4061 - wand with "interesting effect"
Report was for an impossible "What an interesting effect (%d)" which
the fuzzer turned into a panic.  Monster on the drawbridge zapped
toward the open portcullis, destroying the bridge and killing itself.
Wand was made of wood and burned up in lava under the fallen span.
Freeing the object zeroed it rather than leaving stale data, and the
zap continued while referencing freed memory that looked like it had
type STRANGE_OBJECT, triggering the impossible.

This will make a monster-induced zap stop early if a drawbridge
incident destroys the wand.  That isn't the best possible fix
because the zap should continue despite the wand's destruction, but
at least it will now avoid triggering "intestsing effect".
2023-12-11 21:04:12 -08:00
PatR
6c38bfeba2 fix #K4042 - visible but unreachable teleport trap
If a monster fled from the hero by intentionally jumping into a vault
teleporter located in a niche which was still hidden and the hero
saw it happen, the trap would be mapped but the niche would remain as
a secret corridor spot.  The hero couldn't move onto the trap until
searching or wall kicking or other map disclosing activity converted
the spot into regular corridor.

Trap doors in hidden niches did already change the secret corridor
into normal corridor to unhide the trap's spot, but only if the hero
saw it happen.  Now the terrain change occurs even if hero doesn't
see it; only mapping the trap depends on that.

While testing the fix, I noticed that a monster jumping onto a vault
teleporter was teleporting randomly rather than being sent to the
vault, unlike when triggering such a trap by accident.  The code has
changed for 3.7 but this bug was already present in earlier versions.
2023-12-02 15:05:45 -08:00
PatR
97238fc01a github issue #1157 - wand of striking
Issue reported by elunna:  hero witnessing a wand of striking being
zapped by a monster didn't have that type of wand become discovered.
Monsters observing hero resisting--or failing to resist--the effect
on hero didn't learn about target's current resistance capability.

Barely tested.

Fixes #1157
2023-11-30 16:37:07 -08:00
SHIRAKATA Kentaro
5f6535728d remove unnecessary condition on use_offensive()
`otmp` here is always non-null, otherwise it leads segv at earlier code.
2023-11-29 11:27:20 -08:00
nhmall
04082a2033 Remove TEXTCOLOR build option 2023-11-22 16:01:58 -05:00
nhmall
76d328d86a gi.invalid_obj -> hands_obj 2023-11-11 19:49:38 -05:00
nhmall
314a2a9489 use gi.invalid_obj instead of cg.zeroobj
cg.zeroobj was originally added (under its previous unprefixed name)
for providing a one-line way to zero out the fields of a struct obj.

    struct obj tempobj;
    tempobj = cg.zeroobj;

    initfn(struct obj *otmp)
    {
        if (otmp)
            *otmp = cg.zeroobj;
    }

More recently, the address of cg.zeroobj began to be used as a return
flag to indicate some things, but the 'const struct obj zeroobj' wasn't
an ideal fit for the purpose and required a number of casts, including
casting away const.

Provide a better fitting variable (gi.invalid_obj) and eliminate a
number of casts.
2023-11-10 11:07:49 -05:00
Pasi Kallinen
491cc9933f Unhide a water monster using a polymorph trap 2023-08-08 16:49:03 +03:00
PatR
450f060132 github issue #1060 - crystal helmet
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
2023-06-14 06:13:11 -07:00
PatR
9079250cfc testing for Vlad
Redo the check for whether a monster is Vlad when deciding whether to
keep it out of a bones file.  Use the new check in find_defensive()
where Vlad won't waste a turn attempting to use a wand of digging when
in his undiggable own tower.  (Failing to check for vampshifted Vlad
in the latter case wasn't actually a bug because if/when shifted,
he's unable to use items so couldn't attempt to use wand of digging.
Switch to the new check anyway.)
2023-06-09 16:09:26 -07:00
PatR
7e4be52a6c fix issue #1046 - unseen monster reading scroll
Reported by copperwater "on behalf of Maud":  when hero hears an
unseen monster read a not-yet-discovered scroll of create monster
and doesn't see any new monster appear, the player is given a chance
to call the scroll something.  When hearing an unseen monster read
a not-yet-discovered scroll of teleportation, the label is revealed
but no such 'call it' opportunity is offered, so the player could
deduce which of the two scroll types it was for either case.

Provide an opportunity to supply a 'called' name for scrolls of
teleportation when heard being read, same as with create monster.
Surprisingly complicated to achieve.

Eliminated a couple of goto's in the process.

Fixes #1046
2023-06-04 16:22:38 -07:00
PatR
1c94bdac89 blindness overhaul
I was working on this at the time 3.6.0 was released and set it aside
until later.  Later has finally arrived.  Redo the Blind, Blinded,
Blindfolded,&c macros to make more complete use of intrinsic property
handling.  Blinded was being treated as a number which could be added
to or subtracted from; now that has to be done via TIMEOUT mask
because it has FROMOUTSIDE (OPTIONS:blind) and FROMFORM (poly'd into
!haseyes() form) bits included.  Object definitions for blindfold and
towel now specify the BLINDED property; overriding blindness via the
Eyes of the Overworld is accomplished via props[BLINDED].blocked.

Code generated for the scores of Blind and !Blind tests throughout
the program should be smaller.

One bug that has been fixed is that putting on the Eyes of the
Overworld cured permanent blindness (from OPTIONS:blind).  The
u.uroleplay.blind flag was cleared and stayed so after taking them
off.  Putting the Eyes on still breaks blind-from-birth conduct but
now blindness will resume when they are removed.

This was untested at the time it was set aside and is only lightly
tested now.  A large number of the changes here are just to switch
from Blinded to BlindedTimeout for current timed value and to call
set_itimeout() for setting a new value.
2023-04-27 14:53:28 -07:00
PatR
85a002c157 hearing an unseen monster read a scroll
Heroes recognized unseen same-race monsters by voice, but it yielded
an unexpected result if the monster was unique.  Change it so that
hero will recognize any type of monster by its voice if that monster
has been seen and limit unseen same-race ones to non-unique monsters.
Treats shopkeepers as unique since they have distinct names.

This adds a new flag to struct monst in order to track whether each
specific monster has ever been seen or sensed.
2023-04-22 02:00:04 -07:00
Pasi Kallinen
9340197c4c Remove extra full stop 2023-03-18 09:11:18 +02:00
nhmall
de79240dea some comment spelling fixes 2023-03-16 22:27:01 -04:00
nhmall
d9b43ce357 adjust wording preceding "Being confused,..." 2023-03-08 19:09:15 -05:00
nhmall
22b3525f0b scroll labeling while blind #986
Adjust the wording a little as discussed in #986.

Close #986.
2023-03-08 13:07:47 -05:00
PatR
4021a63bcf wand/spell/breath killer reason
Extend "killed by the touch of death inflicted by <monster>" to buzz().
"Killed by a bolt of cold" becomes "killed by a bolt of cold zapped by
<monster>" or "killed by a blast of cold" becomes "killed by a blast
of cold exhaled by <monster>" and so forth.

More work than expected; the zap code isn't passed enough context.

BZ_M_WAND() was producing the wrong value for wands zapped by monsters.
2023-03-07 02:47:42 -08: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
PatR
5d5445d85b fix github issue #972 - moving while trapped
Reported by elunna:  a monster trapped in a pit or web that was
adjacent to a polymorph trap could enter that trap to change shape.
It would remain flagged as trapped but there's no way to escape
from a polymorph trap so it would be stuck.

Fix supplied by entrez:  when a monster is picking MUSE strategy,
don't allow it choose "enter polymorph trap" if it is currently
trapped.

I entered the changes from the diff manually and added a bunch of
minor formatting bits.

Fixes #972
2023-02-06 15:50:39 -08:00
Pasi Kallinen
734dcfdabe Don't let monsters loot Schroedinger's box 2023-01-28 20:27:36 +02: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
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
PatR
8836b32128 github issue #935 - disarming swallowed hero
Issue reported by AndrioCelos:  bullwhip using monster was able to
snatch hero's weapon when hero was engulfed.

Fix is trivial:  when a monster is choosing an item to use, don't
pick bullwhip if hero is engulfed.  Regular attack attempts already
skip engulfed hero.

Fixes #935
2022-11-28 02:08:49 -08:00
PatR
223818ff41 github issue #934 - hearing unseem mon read scroll
Issue reported by Melon2007:  when non-deaf hero heard an unseen
monster read a scroll, the monster's type was identified accurately
(unless distorted by hallucination).  That was intentional but it
doesn't seem plausible for the hero's hearing to be that acute.
Change it to report the monster type accurately if not hallucinating
and monster is the same species as the hero (as the current form if
hero is poly'd), otherwise report it as "someone" when it's humanoid,
otherwise as "something".

Also, if the monster is heard at a spot that would be visible if
hero could see, draw a "remembered, unseen monster" glyph there.

Fixes #934
2022-11-28 01:44:19 -08: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
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
4a84fb5b9d Monsters can blind you with a camera 2022-08-22 13:32:12 +03:00
Pasi Kallinen
953d43f5ac Monster known traps bit twiddling 2022-08-21 11:36:39 +03:00
Pasi Kallinen
b0f3371147 Monsters try to escape from boulder forts
If a monster cannot move, for example because it's being
blocked off by boulders or walls, it will try to escape by some
method - such as a wand or scroll of teleportation.
2022-08-20 21:49:55 +03:00
Pasi Kallinen
7ab1ac0a19 Split soldier-finding into separate function 2022-08-20 19:33:53 +03:00
Pasi Kallinen
1900a30323 Return early from mon_has_friends 2022-08-16 14:49:25 +03:00
Pasi Kallinen
d7d4ed3dfe Monsters using wands of teleportation more
Previously monsters used wands of teleportation at hero, if hero was
standing on top of stairs, or on a scary thing (eg. Elbereth or
scroll of scare monster).

Allow monsters to recognize when hero is behind a chokepoint and
monster has friends with them, hopefully teleporting the hero
out of the chokepoint.
2022-08-16 12:17:58 +03:00