Commit Graph

182 Commits

Author SHA1 Message Date
Pasi Kallinen
15ced6f1ff Fix pet apport value
Fuzzer encountered a case where a pet apport ended up being zero:
the reviving tame troll already had edog structure, so it was not reset.
2025-05-23 17:21:27 +03:00
PatR
3aecc90b2d commit 46b98bab5b951c16f3c6766f23acb22c3046608c
Author: PatR <rankin@nethack.org>
Date:   Mon Apr 7 13:58:28 2025 -0700

    fix issue #1404 - re-tamed feral pet starves

    Issue reported by k21971:  changes in 'struct edog' initialization
    resulted in re-taming of a feral former pet producing a tame monst
    that immediately dies of starvation.

    I didn't look at the earlier behavior, just forced hunger to be
    initialized separately from other edog fields.

    Fixes #1404
2025-04-07 14:11:58 -07:00
copperwater
71e562def8 Livelog when a player breaks petless conduct
If a player initially goes petless then later obtains a pet, it's absent
from the game chronicle. Fix that by adding a livelog for it.

This required a bit of restructuring in create_familiar() that I wanted
to do anyway: removing the kludge of decrementing u.uconduct.pets when a
figurine has been deployed but isn't actually going to come out tame.
Calling initedog() /after/ deciding whether it's needed or not prevents
a first-pet livelog being produced for a figurine that didn't come out
tame.

The guardian angel code, which avoids calling initedog(), can never be
the hero's first pet anyway because it only appears tame when the hero
has already broken petless conduct. But while checking, I noticed a
duplicate comment, so I removed that.
2025-03-04 18:41:02 +02:00
nhmall
679094ff93 keep tameness at or above its existing level
Resolves #1380
2025-02-16 07:30:22 -05:00
nhmall
a68bc3b3fb fix tamed pet issue #1379
fixes #1379
2025-02-12 23:26:03 -05:00
nhmall
d74624abbd add mexta field to simplify detection of overwrite
Because this invalidates existing save and bones files,
an increment of EDITLEVEL will accompany this.
2025-02-02 08:30:48 -05:00
nhmall
ed44da351e more follow-up, less hiding of illegal values
Catch it prior to the rn2() call instead. We need to
be aware of the issue.
2025-01-24 18:26:56 -05:00
nhmall
02102de396 attempt to resolve issue #1368
Resolve #1368
2025-01-24 17:06:17 -05:00
nhmall
61f969e88b follow-up for put_saddle_on_mon()
Commit 1acc2727 helped ensure that the which_armor(mtmp, W_SADDLE)
test at the top of put_saddle_on_mon() wouldn't lead to an obj
leak.

This commit covers off the adjacent can_saddle() test in
put_saddle_on_mon(), because if that failed, it could also lead
to a memory leak of the saddle obj passed by the caller.

- have put_saddle_on_mon() create and use its own saddle obj
  if a NULL saddle obj is passed, instead of having to do that
  in the caller.
- where an existing saddle obj needs to be passed from the caller,
  ensure that the caller has done its own can_saddle(mon) check prior
  to calling put_saddle_on_mon(), so that the can_saddle() test
  in put_saddle_on_mon() won't fail.
- lastly, add an impossible() to put_saddle_on_mon() to catch
  a failure when a saddle obj is passed from the caller and either
  test has failed, just in case. That should not happen with any of
  the existing cases now, but it will provide some bullet-proofing
  for new code, new callers.
2025-01-20 14:37:46 -05:00
PatR
1acc272718 fix memory leak for knight's starting pony
makemon() has a 1% chance to bestow a worn saddle when creating any
rideable monster.  If that chance kicked in on a knight's starting
pony, an extra saddle would end up being created but not worn nor
in inventory nor on floor so not be freed when the game ended.

That 1% chance also overrode saddle suppression for pauper knights.
There wouldn't be any extra saddle but their pony could start with
one, against intent.

Have makedog() (which is only used for starting pet) tell makemon()
to suppress inventory when creating the initial pet.
2025-01-20 10:24:12 -08:00
PatR
9e2d862ba9 static analyzer fix for dog.c
The missing break meant that executation fell through to the default
case and reset xlocale and ylocale to 0.  The comment states that
this is for the fuzzer; I have no idea whether this fix matters to it.
2025-01-18 20:04:26 -08:00
Pasi Kallinen
6df83cb677 Fix pet data being reset when charm monster was cast
Casting charm monster with pets nearby could reset the edog struct.
If the pet ate a mimic corpse and was pretending to be something else
when that edog reset happened, the sanity checking would issue an impossible.
The error happened because meating was reset, but the pet appearance was not,
but the edog struct reset is the part being wrong.  Lets not do that.

To reproduce, turn on sanity checking, create a tame dog, give it a mimic corpse
to eat, #wizcast charm monster next to it.
2025-01-17 17:07:07 +02: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
7fa38eb7b3 Use pline_mon instead of pline_xy
Forgot about this function. Whoops.
2024-12-14 15:20:17 +02:00
Pasi Kallinen
4f37795f96 Accessibility: pet message locations 2024-12-14 15:00:46 +02:00
nhmall
c897f3a950 a comment for the obj side of discard_migrations() 2024-12-09 22:59:56 -05:00
nhmall
d99a24843b deal with light sources in discard_migrations()
Otherwise, when discard_migrations() purges monsters,
their stale monster pointers can be left inside the light source data
structure.
2024-12-09 21:41:26 -05:00
PatR
13b8725ac2 combine taming of already tame monsters
Merge the recent change in the effect of blessed scroll of taming on
already tame monsters with the earlier change of any taming on already
tame monsters.  Non-blessed has a chance of boosting monst->mtame by 1
when it is less than 10, more likely the lower the current value is.
For blessed, boost by 2 after that, so possibly by 3 if it is very low.

Make spell of charm monster when skilled or expert in enchantment
spells behave the same as blessed scroll of taming.  [I'm not too sure
about this; it may make the spell too powerful.]
2024-12-07 19:38:01 -08:00
nhmall
9f33d1cf7a Merge branch 'newsym_worm' of https://github.com/entrez/NetHack into NetHack-3.7 2024-11-30 20:14:40 -05:00
Michael Meyer
92d931f190 Refresh worm segments when (un)taming
Because newsym() would be called only on the head position of the worm,
if hilite_pet was on, the segments and head of a long worm would have
mismatched highlighting in the immediate aftermath of taming or
untaming.
2024-11-30 17:30:52 -05: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
cbc93a0555 github issue #1312 - prot from shape changers
Issue reported by youkan700:  shape change anomalies.  Shapechangers
could change shape despite active protection-from-shape-changers if
hero wore two rings of protection from shape changers and took one
off.  Shapechangers who migrated to a not-yet-visited level that
eventually got visited with protection from shape changers in effect
would be stuck in their current shape, even if the PfSC attribute
got toggled off and back on.

The issue included suggested fixes and those are what I've used.  I
noticed a third case that only applies to wizard mode:  if player
used #wizintrinsic to set a timed value for PfSC, monsters wouldn't
resume changing shape after it timed out, unless/until it got toggled
on and back off via a PfSC ring or hero left the level and returned.

Fixes #1312
2024-11-28 11:33:26 -08:00
PatR
35cf713988 fix part of #S11588 - mons eating poisoned items
Prevent non-poison resistant monsters that eat items from eating
poisoned items.
2024-10-12 14:39:48 -07:00
nhmall
bf1af7c471 Merge branch 'NetHack-3.7' of https://github.com/klorpa/NetHack into NetHack-3.7 2024-09-14 09:17:48 -04:00
PatR
aa043f0ddf some reformatting (2 of 4) 2024-09-05 14:51:21 -07:00
PatR
96787441e9 pauper tweaks
For 'pauper', most roles start without any skills.  However, strong
fighter types were starting with basic bare-handed combat/marital arts,
giving them a big advantage.  Knights were starting with basic riding,
which is probably useless now that they have to acquire a saddle to
use it (see below).  Take those initial skills away, producing an even
playing field.

Non-paupers get their initial skills without needing to spend any skill
credits (aka slots) on those.  Give paupers 2 starting credits that
they'll be able to use once they acquire suitable weapons or spells
and train them up, so that once they're reasonably developed they won't
lag in skills compared to non-paupers.

Pauper knights were still starting with a saddled pony.  Suppress the
saddle when the knight is a pauper.

Wizards start knowing a lot of spellbooks.  Pauper wizards shouldn't.

Give most roles advance knowledge of one low level spell or other item.
It won't benefit them unless/until they find the corresponding item.
2024-09-01 15:11:28 -07:00
klorpa
02c4147893 Typos 2024-08-31 15:28:42 -05:00
Michael Meyer
b363b702d7 Make pets unwilling to eat all polyfood() corpses
The previous is_shapeshifter() test meant that pets were still perfectly
willing to eat genetic engineer corpses and be polymorphed.  Use
polyfood() instead.

Fixes #1183.
2024-07-15 23:42:29 -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
Pasi Kallinen
2bec685bae Pyrolisk eggs explode when broken 2024-06-02 10:50:58 +03:00
Pasi Kallinen
f131942dd2 Another tamedog message
Give a different message when a peaceful creature was tamed.
Allow suppressing this and the previous message, when the caller
handles messaging.
2024-03-24 10:48:29 +02:00
Pasi Kallinen
4d206c1c40 Make tamedog give a message
People seemed to be confused when a monster next to them was tame
after stepping on a magic trap; this is also an accessibility issue.
2024-03-23 18:37:12 +02:00
nhkeni
9c0ed8ae63 NOSTATICFN for src/* 2024-03-14 17:41:51 -04:00
nhmall
688ac6ffbe remove register from variable declarations 2024-02-19 16:30:07 -05:00
nhmall
594eead50d pick_familiar_pm follow-up 2024-01-29 12:09:14 -05:00
Pasi Kallinen
97678379dc Split picking familiar permonst type 2024-01-29 19:00:25 +02:00
nhmall
2fa996eb19 comment update/clarification 2024-01-11 14:19:28 -05:00
nhmall
25a8c258e6 replace x >= LOW_PM with ismnum(x) shorthand macro 2024-01-11 14:01:10 -05:00
PatR
83bdf71932 pull request #1175 - obj->corpsenm fixes
Pull request by mkuoppal:  some objects which use the corpsenm field
to access the mons[] array can have a corpsenm value of NON_PM (-1)
and weren't avoiding array access in those cases.

In addition to a fixes entry for it, this makes some revisions to the
commited code, handling a few of the cases differently.

Closes #1175
2024-01-06 15:13:31 -08:00
Mika Kuoppala
5cfa4cd9f6 src/dog: Fix TIN or EGG based corpsenm
TIN or EGG can have the corpsenm not assigned into a
proper monster and instead have an value of -1.

Take this into account in assigning the monster (fptr)
pointer to only point into >= LOW_PM monste entries.
2024-01-06 12:06:54 -08:00
nhmall
c5a5b55c15 nonnull for some static functions during recent analysis 2023-12-16 10:51:59 -05:00
Michael Meyer
fe8710532e Fix: latent bug with finish_meating on catchup
Some players of 3.6 recently noticed that sometimes, mimics in shops
seemed to have moved around even before the player had entered the shop
or done anything to uncloak them.  I found that this was because
finish_meating was being called for all non-eating monsters when
restoring a level (monsters that weren't eating anything would have
meating == 0 so always pass the 'imv > meating' check).  This would
uncloak mimics -- but not all the time, because the 'mappearance != 0'
test meant mimics disguised as strange objects weren't uncloaked.  I
think that was meant to be an additional check to confirm the monster
really did have a disguise, but in reality it meant that M_AP_OBJECT
"strange object", M_AP_MONSTER "giant ant", etc disguises wouldn't be
removed by finish_meating.

As it turns out, this was mostly fixed by coincidence in 221e4a7, which
fixed the "exclude actual mimics" check in finish_meating.  So at this
point in 3.7 it's largely a latent bug, but it still had the potential
to improperly uncloak non-mimics who can disguise themselves (like the
Wizard of Yendor, maybe?), and could cause other problems if
finish_meating were updated to have additional effects, or if some
monster types were made to disguise themselves as a strange object when
eating a mimic.
2023-11-30 18:05:34 -08:00
Pasi Kallinen
94d44e433b Fix sanity error when pet ate a mimic corpse
When a pet ate a mimic corpse and started mimicking a monster,
and the user then used #wizmakemap, the sanity checker complained
about "non-mimic posing as foo" - the code was clearing the
pet eating counter, but didn't clear the appearance.
2023-11-29 12:15:08 +02:00
PatR
d748dbaa12 more menu headings
Simplify suppression of highlighting for menu header lines during end
of game disclosure.  Didn't actually affect as many things as I was
expecting.

Plus a bit left out of the optfn_dogname() parsing commit.
2023-11-14 17:51:27 -08:00
PatR
bc93ee5d04 pet petrified by eating Medusa's corpse
From a reddit thread:  a tame mind flayer ate Medusa's corpse and was
turned to stone.  Pets won't eat cockatrice corpses unless stoning
resistant but would eat Medusa's corpse if merely poison resistant.
Mind flayers aren't normally poison resistant but could be if wearing
green dragon scales/mail.

Augment the touch_petrifies() test when classifying food for pets.
2023-08-30 13:38:08 -07:00
PatR
ab0de251cd fix #K3938 - sleeping monster tamed by thrown food
Player reported that a cat which was asleep in a treasure zoo would
catch and eat thrown food, becoming tamed in the process, without
waking up.

Temporary sleep was handled (via checking for !mon->mcanmove) but
indefinite sleep wasn't.  Make a monster hit by taming effect (either
magic or thrown food) wake up from indefinite sleep.  For temporary
sleep, the remaining duration is cut in half.  The timeout isn't
dropped all the way to 0 because a monster with mon->mfrozen set
isn't necessarily asleep.  That timeout is shared by timed sleep,
timed paralysis, and busy time when donning armor.
2023-06-27 08:51:29 -07:00
Pasi Kallinen
8b32ae98e9 Add petless conduct
Breaks saves.
2023-04-11 14:21:06 +03:00
Pasi Kallinen
5ca4e166b1 More fuzzer branch teleporting 2023-03-18 10:46:10 +02:00
Pasi Kallinen
e37428d5cd Fix fuzzer teleporting out of Fort Ludios 2023-03-18 08:51:37 +02:00
nhmall
de79240dea some comment spelling fixes 2023-03-16 22:27:01 -04:00