Commit Graph

273 Commits

Author SHA1 Message Date
Pasi Kallinen
e2b80cd886 Monsters trapped in pits cannot kick 2025-07-04 17:39:08 +03:00
PatR
45f751989a fix #K4331 - sticking from distance
Stop attacking if target isn't there anymore.  Already handled for
two-weapon in normal form, not for multi-attacks in poly'd form and
for multi-attack monster vs hero or monster vs other monster.

I didn't attempt to reproduce the reported problem.  This fix is
based on code inspection.

Also prevent monsters that have hug or engulf attacks from knocking
target back with other attacks since that prohibits the grab/engulf
from being able to hit.
2025-06-03 22:13:22 -07:00
Pasi Kallinen
ab4f70b448 Monsters were bashing with Snickersnee
Side effect of allowing Snickersnee to attack like a polearm,
monsters were bashing with it in melee.
2025-05-20 19:59:28 +03:00
Alex Smith
97e0e934e8 Use a common funcion for all monster healing
Previously, the code for monster healing was repeated every time it
was needed; this commit sends it all through a common function, which
will make it easier to make changes to how monster healing works in
the future.

This is just a code reorganisation and won't have any gameplay
effect unless I made a mistake.
2025-01-12 18:20:13 +00:00
Pasi Kallinen
055c0d5954 Accessibility: more message locations pt 2 2024-12-14 15:30:12 +02:00
Pasi Kallinen
fd23463941 Sparkle shield effect and accessibility
When sparkle is turned off, there are some places where
a monster resisting the effect did not give any message.

This fixes some of those.
2024-12-14 14:34:22 +02:00
PatR
9768677f91 comment tweak 2024-12-11 20:53:08 -08:00
PatR
aedb24d343 partly fix issue #1336 - pets vs floating eyes
Issue reported by ars3niy:  pets with reflection or ranged attacks
would only attack floating eyes when rolling the 10% random chance
that other pets have even though they could have always safely
attacked.

This fixes the situation for melee attacks by pets who have
reflection.

dog_move() is too complicated for my feeble brain to cope with the
ranged attack aspect.  Pets still won't use ranged attacks against
floating eyes.

With the fix for reflection, I discovered that silver dragons
would be subjected to floating eyes' passive paralysis even when
their breath attack was suppressed.  (It wouldn't impact them, due
to reflection, but the message about the floating eye being hit by
its reflected gaze was being delivered without being preceded by
any message since no attack had taken place yet.)  This fixes that.

\#1336 is still open
2024-12-11 12:38:28 -08:00
nhmall
0792e5fe9e expand implicit fallthrough detection to non-gcc compilers
gcc has recognized various "magic comments" for white-listing
occurrences of implicit fallthrough in switch statements for
a long time:

    The range and shape of "falls through" comments accepted are
    contingent upon the level of the warning. (The default level is =3.)

    -Wimplicit-fallthrough=0 disables the warning altogether.
    -Wimplicit-fallthrough=1 treats any kind of comment as a "falls through" comment.
    -Wimplicit-fallthrough=2 essentially accepts any comment that contains something
     that matches (case insensitively) "falls?[ \t-]*thr(ough|u)" regular expression.
    -Wimplicit-fallthrough=3 case sensitively matches a wide range of regular
     expressions, listed in the GCC manual. E.g., all of these are accepted:
        /* Falls through. */
        /* fall-thru */
        /* Else falls through. */
        /* FALLTHRU */
        /* ... falls through ... */
       etc.
    -Wimplicit-fallthrough=4 also, case sensitively matches a range of regular
     expressions but is much more strict than level =3.
    -Wimplicit-fallthrough=5 doesn't recognize any comments.

Plenty of other compilers did not recognize the gcc comment convention,
and up until now the compiler warning for detecting unintended
fallthrough had to be suppressed on other compilers. That's because the code
in NetHack has been relying on the gcc approach, and only the gcc approach.

The C23 standard introduces an attribute [[fallthrough]] for the
functionality, when implicit fallthrough warnings have been enabled.

Several popular compilers already support that, or a very similar attribute
style approach, today, even ahead of their C23 support:

       C compiler                       whitelist approach
       ---------------------------   -------------------------------------
       C23 conforming compilers         [[fallthrough]]

       clang versions supporting
       standards prior to
       C23                              __attribute__((__fallthrough__))

       Microsoft Visual Studio
       since VS 2022 17.4.
       The warning C5262 controls
       whether the implict
       fallthrough is detected and
       warned about with
       /std:clatest.                    [[fallthrough]]

This adds support to NetHack for the attribute approach by inserting a
macro FALLTHROUGH to the existing cases that require white-listing, so
other compilers can analyze things too.

The definition of the FALLTHROUGH macro is controlled in include/tradstdc.h.

The gcc comment approach has also been left in place at this time.
2024-11-30 14:16:27 -05:00
PatR
149cb96020 github issue #1299 - sleeping mimics
Issue reported by elunna:  sleeping mimics can grab the hero, and
zapping a concealed mimic with a wand of sleep describes the target
as a mimic but doesn't bring it out of concealment.

The grab-when-asleep case is reasonable.  It's a reflexive counter-
attack by a magical creature.  And the mimic wakes up in the process.
But the mimic wasn't being brought out of concealment.  Do that.

Unconceal mimics hit by wand of sleep unless already sleeping.

Fixes #1299
2024-11-29 23:30:04 -08:00
nhmall
1dbba0f63b rename IS_ROCK() macro to IS_OBSTRUCTED()
It has included trees since they were added, so give it a
more fitting name.
2024-11-09 11:12:42 -05:00
PatR
cc1066b1ff some reformatting (3 of 4) 2024-09-05 15:55:24 -07:00
nhmall
6c0ae092c6 distinguish global variables that get written to savefile
The g? structs had a mix of variables that were written to
the savefile, and those that were not.

For better clarity and to distinguish those that end up in
the savefile, relocate some g? variables that get written
directly to the savefile into different structs.

This updates EDITLEVEL, although technically it probably
didn't need to, since savefile contents are not changing.

Details:

    gb.bases            -> svb.bases
    gb.bbubbles         -> svb.bbubbles
    gb.branches         -> svb.branches
    gc.context          -> svc.context
    gd.disco            -> svd.disco
    gd.dndest           -> svd.dndest
    gd.doors            -> svd.doors
    gd.doors_alloc      -> svd.doors_alloc
    gd.dungeon_topology -> svd.dungeon_topology
    gd.dungeons         -> svd.dungeons
    ge.exclusion_zones  -> sve.exclusion_zones
    gh.hackpid          -> svh.hackpid
    gi.inv_pos          -> svi.inv_pos
    gk.killer           -> svk.killer
    gl.lastseentyp      -> svl.lastseentyp
    gl.level            -> svl.level
    gl.level_info       -> svl.level_info
    gm.mapseenchn       -> svm.mapseenchn
    gm.moves            -> svm.moves
    gm.mvitals          -> svm.mvitals
    gn.n_dgns           -> svn.n_dgns
    gn.n_regions        -> svn.n_regions
    gn.nroom            -> svn.nroom
    go.oracle_cnt       -> svo.oracle_cnt
    gp.pl_character     -> svp.pl_character
    gp.pl_fruit         -> svp.pl_fruit
    gp.plname           -> svp.plname
    gp.program_state    -> svp.program_state
    gq.quest_status     -> svq.quest_status
    gr.rooms            -> svr.rooms
    gs.sp_levchn        -> svs.sp_levchn
    gs.spl_book         -> svs.spl_book
    gt.timer_id         -> svt.timer_id
    gt.tune             -> svt.tune
    gu.updest           -> svu.updest
    gx.xmax             -> svx.xmax
    gx.xmin             -> svx.xmin
    gy.ymax             -> svy.ymax
    gy.ymin             -> svy.ymin

Related note:
There are some pointer variables that are heads of chains that were not
moved from 'g?' to 'sv?', because they are not actually written to the
savefile directly, but the objects/monst/trap/lightsource/timer in the
chains they point to are. That can be changed, if desired.
Examples: gi.invent, gm.migrating_objs, gb.billobjs, gm.migrating_mons,
          gf.ftrap, gl.light_base, gt.timer_base
2024-07-13 14:57:50 -04:00
nhkeni
9c0ed8ae63 NOSTATICFN for src/* 2024-03-14 17:41:51 -04:00
RainRat
a3658f85ac fix typos 2024-02-28 20:15:56 -08:00
nhmall
688ac6ffbe remove register from variable declarations 2024-02-19 16:30:07 -05:00
nhmall
25a8c258e6 replace x >= LOW_PM with ismnum(x) shorthand macro 2024-01-11 14:01:10 -05:00
Michael Meyer
a69ff06e85 Make mstate flag checks more mutually consistent
Various places checking for whether a monster was on the map based on
mstate flags were inconsistent about which ones they checked (and then
place_monster() was additionally inconsistent with all of them about
which bits were cleared when placing a monster onto the map).  I think
some places were also more convoluted than is now necessary because they
date back to mstate being an alias for mspare1, which it shared with
migflags before those became two separate dedicated fields (MSTATE_MASK
also dates back to this and is no longer used, so I removed it).

I tried to go through all the MON_foo mstate bits, understand when/why
they are set, and make the various functions I noticed more consistent
(with each other, and with my understanding of how the bits work) about
how they are treated.  I don't know for a fact that I understood
everything right -- some diagnostic bits that aren't used for much of
anything, like MON_OBLITERATE, had me mystified until I read the 5ee78c5
commit message -- but this patch hasn't caused any new problems (sanity
check or otherwise) with the fuzzer in my testing so far.  All the same,
it could probably use review by someone who has a good sense of what the
mstate bits mean.
2023-11-08 10:41:40 -08:00
PatR
c1045cc18a sanity check: avoid "you over monster" impossible
I did this several months ago to avoid a sanity check warning (and
consequent fuzzer panic) when an engulfer expels the hero on a full
level.  I was hoping to refine it but never went back; install it
now before forgetting about it entirely.

If a chameleon changes from wall-phazer to engulfer while in a spot
the hero can't move onto and engulfs him/her, expelling the hero
after the engulfer has taken the hero's spot might be forced to put
the hero on top of the engulfer or another monster when unable to
use the engulfer's former spot.  Rather than try to figure out all
the possible ways this might happen and attempt to deal with each
of them, just prevent an engulf attack from succeeding if the hero
wouldn't be able to move to the engulfer's spot.  (Does not prevent
an air elemental over water from engulfing the hero.)
2023-11-02 09:12:37 -07:00
nhmall
6cbefc7c2d Revert "granular verbose message suppression mechanics"
This reverts commit be76727265.
2023-10-29 20:39:07 -04:00
Pasi Kallinen
79496b079a Fix splitting monster being killed twice
Fuzzer encountered "m_detach: monster already detached?"

A monster hit a black pudding that split. The clone was
created on top of a rolling boulder trap, which triggered,
the boulder hit the original black pudding, and killed it.
The dead pudding then retaliated (as the code didn't check
if it was dead) and a passive attack of the other monster
tried to kill the already dead pudding.

I think one of these checks would be enough, but adding the
DEADMONSTER check just in case.
2023-10-21 19:49:49 +03:00
Pasi Kallinen
69a4853851 Fix "no monster to remove" when tame nymph attacked
A tame nymph attacked another monster, stole an item and teleported
away, but dog_move() wasn't passed the information that the nymph
was done, and tried to move the nymph from the old location.

Same with a tame leprechaun.
2023-10-21 16:05:15 +03:00
PatR
bbba8b82d2 fix issue #1062 - monster hiding messages
Reported by Umbire:  if a statue of a hider-under was activated by
a statue trap, it would hide underneath its own statue.  Also, the
hero saw a snake hide under unseen submerged kelp.

Both of those things were exposed by new "you see <monster> hide"
message rather than caused by it.  It also led to the [re-]discovery
that an existing monster hiding under a statue that was a not-yet-
triggered trap prevented the trap from producing a monster.

This redoes yesterday's can't-hide-under-statue change:  hiders can
hide under statues again, but they can't hide under anything at trap
locations.  [Pits containing one or more objects are an exception,
although it seems silly that a hero is prevented from falling into
one by the presence of a tiny creepy-crawly hiding under a ring or
dart in there.]  So, hider-underers won't be able to interfere with
statue traps by being present at the trap location.  [Trappers and
lurkers-above probably need a similar restriction; I didn't look.
They avoid trap spots rather than get lured to such by objects.]

It also prevents newly created hider-underers from becoming hidden
as part of the their creation (except when that creation is part
of level creation) whether their creation uses up an object (statue
activation, egg hatching) or there are simply other items present.
That will prevent statue of a hider producing a monster that hides
under the activated statue (which was happening due to the sequence
create monster, transfer any statue contents to monster inventory,
destroy statue).

The can't-hide-under-statues code has been repurposed to prevent
hiding under gold pieces unless there are at least 10 (arbitrary
threshold) of those or they're in a pile with some other object(s).

Sea monsters hide in water regardless of the presence of objects.
Prevent other swimmers from hiding under objects at water locations.
Such creatures don't have gills and shouldn't be able to stay
submerged in hiding for an arbitrary length of time.  [No exception
is made for non-breathers.  The overlap between swimmers and hider-
underers is limited to small snakes, even though it is feasible for
a creature wearing an amulet of magical breathing to polymorph into
one.  Heros don't spend enough time underwater to worry about snakes
hiding under kelp or thrown junk.]

Lastly, alter the "suddenly, you notice a <monster>" message if
monster-vs-monster activity causes one you've just seen going into
hiding comes back out again without any intervening messages.  [I'm
not sure whether something similar is needed for the "Wait.  There's
something there" message in the you-vs-monster case.]

Fixes #1062
2023-06-16 21:19:43 -07:00
PatR
9052bd5099 fix #K3925 - u.ustuck of long worm tail
Don't allow stick/wrap/engulf attacks directed at long worm tails
to succeed.  Achieved by making sure that 'notonhead' is up do date
in a bunch of places and utilizing the fairly recent can't-{stick,wrap,
engulf}-unsolid-monsters code.

Should prevent a 'sanity_check' warning about being too far from
u.ustuck that would happen when holding the tail while the head was
not adjacent to the hero.

Also don't let pet ranged attacks from choosing a long worm's tail
as target.  They'll still be able to target long worms provided that
the head is lined up and not shielded by tail segment(s).
2023-05-20 15:34:32 -07:00
Pasi Kallinen
9ca1c5fb56 Fix dmonsfree warning caused by knockback
When a monster being attacked was knocked back into a level
teleport trap, the attacker could still hit the defender.
If the second hit then killed the defender, this could result
in dmonsfree warning.
2023-05-07 22:12:56 +03:00
Pasi Kallinen
e18548c821 Fix knockback impossible
When monster attacked another monster, and the retaliation attack
knocked back the attacking monster, the variables holding the
attacking monster coordinates were out of sync and caused
"no monster to remove" warning.

Propagate back the knockback hit, so the current monster cannot
do anything further.
2023-05-07 12:57:09 +03:00
PatR
1a2d844a22 fix #K3902 - hug attacks against unsolid targets
Prevent hug attacks (owlbear, python, pit fiend, several others),
attacks for wrap damage (eel and kraken, trapper and lurker above),
attacks for stick-to damage (mimic, lichen), and attacks for digestion
damage (purple worm) from succeeding against unsolid monsters (ghosts,
lights, vortices, most elementals).

Polymorph of an engulf or hold target into unsolid form has been
addressed by a couple of previous updates.
2023-04-14 13:27:33 -07:00
nhmall
5f69dc6228 make attack result macros more distinguishable from makemon macros
Use the MM_ prefix only for the makemon macros, and change these five as follows:

 MM_MISS 0x0     -> M_ATTK_MISS      /* aggressor missed */
 MM_HIT 0x1      -> M_ATTK_HIT       /* aggressor hit defender */
 MM_DEF_DIED 0x2 -> M_ATTK_DEF_DIED  /* defender died */
 MM_AGR_DIED 0x4 -> M_ATTK_AGR_DIED  /* aggressor died */
 MM_AGR_DONE 0x8 -> M_ATTK_AGR_DONE  /* aggressor is done with their turn */

include/hack.h:#define NO_MM_FLAGS     0x000000L /* use this rather than plain 0 */
include/hack.h:#define MM_NOWAIT       0x000002L /* don't set STRAT_WAITMASK flags */
include/hack.h:#define MM_NOCOUNTBIRTH 0x000004L /* don't increment born count (for revival) */
include/hack.h:#define MM_IGNOREWATER  0x000008L /* ignore water when positioning */
include/hack.h:#define MM_ADJACENTOK   0x000010L /* acceptable to use adjacent coordinates */
include/hack.h:#define MM_ANGRY        0x000020L /* monster is created angry */
include/hack.h:#define MM_NONAME       0x000040L /* monster is not christened */
include/hack.h:#define MM_EGD          0x000100L /* add egd structure */
include/hack.h:#define MM_EPRI         0x000200L /* add epri structure */
include/hack.h:#define MM_ESHK         0x000400L /* add eshk structure */
include/hack.h:#define MM_EMIN         0x000800L /* add emin structure */
include/hack.h:#define MM_EDOG         0x001000L /* add edog structure */
include/hack.h:#define MM_ASLEEP       0x002000L /* monsters should be generated asleep */
include/hack.h:#define MM_NOGRP        0x004000L /* suppress creation of monster groups */
include/hack.h:#define MM_NOTAIL       0x008000L /* if a long worm, don't give it a tail */
include/hack.h:#define MM_MALE         0x010000L /* male variation */
include/hack.h:#define MM_FEMALE       0x020000L /* female variation */
include/hack.h:#define MM_NOMSG        0x040000L /* no appear message */

include/hack.h:#define MM_NOEXCLAM     0x400000L /* more sedate "<mon> appears." mesg for ^G */
include/hack.h:#define MM_IGNORELAVA   0x800000L /* ignore lava when positioning */
2023-03-19 12:19:34 -04:00
PatR
1c24f208f3 genetic engineer attacks
When a genetic engineer polymorphs someone it normally teleports away.
Also set mspec_used so that it can't polymorph someone [else] on its
next turn, it case of a no-teleport level or it happens to randomly
land adjacent to the target.
2023-03-17 16:00:44 -07:00
nhmall
de79240dea some comment spelling fixes 2023-03-16 22:27:01 -04:00
PatR
01af084f43 non-digest engulfing
Be more consistent with the engulf attack feedback by creatures who
fold themselves around the victim (trapper, lurker above) rather than
swallow or directly engulf.

Replace an instance of a non-literal format string and the warnings
manipulation it needed with a literal one.
2023-03-13 12:49:22 -07:00
PatR
923249085a fixes entry for PR #978 - suppress monster's name
for <new form> portion of messages "<old form> turns into <new form>"
to avoid named vampires yielding "Dracula turns into Dracula".

Pull request from entrez:  a couple of engulf messages used regular
monster naming for vamp-shifters transforming rather than dying.
3.6.1 had fixes for this for basic monster death but didn't handle
engulfing.

Fixes #978
2023-02-20 13:04:44 -08:00
Michael Meyer
3be8e9447e Avoid "It turns into [Name]" on vamp engulf
Apply a similar fix as a791b4b and f441696 ended up settling on for
normal vampire transformation to the vampire transformation that happens
when their shapeshifted form is engulfed.
2023-02-20 12:44:43 -08:00
PatR
5fd6c02170 pyrolisk feedback
From a report 9 years ago, a pet pyrolisk was repeatedly gazing at a
grey-elf and nothing happened.  It turned out that the elf was wearing
an elven cloak which was negating damage some of the time (most of the
time back then) but with no indication that that's what was happening.

This makes many types of damage that are negated by MC say so.
Probably other types of damage should do likewise.
2023-02-17 14:40: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
SHIRAKATA Kentaro
0d441b0c2f remove the code to silence lint
Warning facilities on recent compilers are incredibly improved,
so the code to silence "good-old" lint is much less sense.
2022-11-19 00:49:11 -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
e2bd3b6b55 warning fix
mhitm.c: In function 'hitmm':
mhitm.c:583:30: warning: '%s' directive writing between 8 and 9 bytes into a region of size between 0 and 255 [-Wformat-overflow=]
  583 |             Sprintf(buf, "%s %s", magr_name,
      |                              ^~
In file included from ../include/config.h:671,
                 from ../include/hack.h:10,
                 from mhitm.c:6:
../include/global.h:279:24: note: 'sprintf' output between 10 and 266 bytes into a destination of size 256
  279 | #define Sprintf (void) sprintf
mhitm.c:583:13: note: in expansion of macro 'Sprintf'
  583 |             Sprintf(buf, "%s %s", magr_name,
      |             ^~~~~~~
2022-10-24 09:14:35 -04:00
PatR
39560aac49 fix github issue #907 - bad shade logic
Issue reported by vultur-cadens:  one of the checks for whether a
shade would be harmed by an attack was erroneously inside a block
of code that only executed when you could see the attack.  Basic
physical damage wasn't affected but some monster (or poly'd hero)
damage types that shouldn't affect shades didn't when seen but did
when unseen.

Could also get "attack passes harmlessly through the shade" when
an unseen attack for physical damage hit and failed to deal damage.

fixes #907
2022-10-23 01:11:14 -07:00
Michael Meyer
34aabca74b Describe engulf attacks a bit more consistently
Use verbiage for mon vs mon and hero (mostly hero) engulf attacks that
matches recent changes to monster vs hero engulf attacks more closely
(e.g. "swallows whole" instead of "engulfs" for purple worm, other
changes in b07fe59...).  Also ensure non-AD_DGST engulf attacks
(e.g. from revamped trapper or lurker above polyforms) aren't treated as
"eating" (or as involving "debris").

Also change the enfolds and digests macros so they produce booleans
rather than attack pointers (I got a compiler warning about casting
struct attack * to boolean when I did 'boolean b = digests(ptr);').
2022-09-20 16:54:23 -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
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
e9ec89a903 fix issue #836 - engulfing mounter hero
Reported by copperwater:  if an engulfer swallowed a mounted hero,
odd things could happen if the hero dismounted.  The steed would be
silently expelled and float-down flooreffects were attempted.

It turns out that if the engulfer is classified as an animal (so
purple worm, lurker above, trapper), the hero got "plucked from
<steed>'s saddle" and was forcibly dismounted prior to completing
the engulf operation, but non-animals (vortices, air elemental,
ocher jelly, Juiblex) swallowed the hero+steed intact.  The most
straightforward fix to dismounting-while-engulfed issues is to change
engulfing to always pluck the hero from the saddle even when the
engulfer isn't an animal.

If there's no room on the level to place the former steed, it gets
killed off.  I looked at changing that to put the steed into limbo,
waiting to migrate back to the current level if hero leaves and
subsequently returns, but that breaks movemon()'s assumption that
when monsters are in the process of moving, only the currently moving
one can be taken off the fmon list to be placed on migrating_mons.

[The recently added monster knockback code violates that assumption
too when knocking the victim into a level changer trap.  It needs to
be fixed in one fashion or another.]
2022-08-09 16:22:50 -07:00
Pasi Kallinen
810744a27d Fix knockbacked monster migrating or killed
Fix a case where a monster knocked back another monster into a trap,
and the trap either killed or migrated the monster, then the actual
damage dealing later could try to detach the already detached monster.

If the monster migrated, the monster is gone before the damage from
the hit is dealt to the monster.
2022-07-26 23:20:54 +03:00
Pasi Kallinen
0bca93be87 Large monster can knock back smaller ones
When a monster at least two sizes larger hits another one,
there's a chance the smaller defender will be knocked back.

This applies also to hero, attacking when polymorphed to
a large monster, or defending from a large monster.

Most of the monsters that can knock back are giants and dragons.

Idea and some of the code from EvilHack.
2022-07-18 23:01:11 +03:00
PatR
66dc16b61f gulpmm "placing <mon> over itself"
Reported direclty to devteam by a hardfought player:
|placing tame fire vortex <56,18> over itself at <56,18>, [...]

An old map fixup when an engulfer and its victim temporarily share
the same map location got impacted by changes made a month or two
back for removing dead or migrated monsters from the map.  The old
fixup (for putting the engulfer back after removing the victim also
removed it) was no longer needed and using it resulted in a warning
from place_monster() about putting a monster on top of itself.
2022-07-14 16:13:47 -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
96f6c52082 Trapped monster cannot move to swallow another
The swallower kept their trapped-state, but could be moved to
another location. Just deal with it by not letting a trapped monster
swallow.
2022-07-08 10:47:14 +03: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
PatR
b25961fb13 pull request #792 - pet w/ engulf+digest \
can gain intrinsics by swallowing monsters whole

Pull request #792 from entrez:  monsters can gain instrinsics now but
the case for an engulfer digesting a live monster was overlooked.

Add the same for non-pet monsters digesting other monsters, likely
under the influence of conflict but possibly counter-attacking a pet.

Closes #792
2022-06-29 18:08:50 -07:00