Commit Graph

521 Commits

Author SHA1 Message Date
Pasi Kallinen
5f1163c11a Change the tips internal data struct
Previously adding any new tips invalidated saves; now you can have
up to the number of bits in a long without change in savefile.

Invalidates saves.
2026-04-04 15:39:46 +03:00
nhmall
fcd9f5468c some coordxy follow-up
Return a couple of variables that actually held a direction back
to int from coordxy.

bhit() takes int params instead of coordxy.

boomhit() takes int params instead of coordxy.

xytod() renamed to xytodir(), and takes int params (promotion will handle
coordxy params).

dtoxy(coord *, int) renamed to dirtocoord(coord *, int).
2026-02-11 09:40:25 -05:00
Pasi Kallinen
91cc3e3f12 Replace a weight magic number 2025-12-14 20:23:22 +02:00
Alex Smith
4d55e1de79 Make saving grace also work against repeated damage sources
For example, being hit by the bounce of a wand of fire means that
the main character could take damage twice in a turn, which would
kill even through saving grace; and scrolls and potions could burn
up after that and finish off the last HP, even if the wand only hit
once. This commit changes it to track all damage done during the
turn, and prevent HP dropping below 1 from damage until the next
player action or the next turn boundary, whichever comes first.
2025-11-26 05:45:45 +00:00
PatR
93f8e5b3b3 fix #S14702 - travel to covered vibrating square
Targeting '~' when vibrating square has been discovered would report
"Can't find dungeon feature '~'" if it was covered by an object or a
monster.

That's normal behavior for a trap but the vibrating square is only
one of those for display purposes.
2025-11-20 15:02:54 -08:00
nhmall
c0686d1795 clear pair of warnings re: not initialized 2025-09-30 12:41:55 -04:00
nhmall
bbc8578375 get rid of a visual studio build warning
lnt-arithmetic-overflow	A sub-expression may overflow before being assigned to a wider type
2025-09-30 12:35:18 -04:00
PatR
81e72dd0cc notice_all_mons()
Process monsters more consistently.
2025-04-24 11:19:20 -07:00
PatR
0ecd573152 escape_from_sticky_mon()
Reorganized a 'switch' statement in order to eliminate a 'goto'.
There should be no changed in behavior.
2025-04-03 15:26:05 -07:00
PatR
d7f107eaf9 still more 'nethack --dumpweights'
After updating the --dumpweights code in hack.c to insert "pair of"
for gloves and boots and "set of" for dragon scales, I've switched
it to use simple_typename() instead.

Turns out that that routine also lacked handling for 'pair|set of'.
And it was generating "coin of gold piece".  Fix those.

Roughly half of the gems are "<gem>" and the others "<gem> stone",
so the --dumpweights output is different by more than just pair/set.
2025-03-19 17:30:56 -07:00
PatR
b237337806 streamline domove_core()
Split handling for paranoid_confirm:Trap out of domove_core() into
a separate routine.  There should be no change in behavior.
2025-03-19 14:33:13 -07:00
nhmall
a943c4c10b replace some weight-related magic numbers
adds a header file include/nhconst.h  (I'm open to a better name)
2025-03-19 13:29:58 -04:00
PatR
ef9734f1c1 another 'nethack --dumpweights' tweak
Don't suppress slime mold.
2025-03-19 01:39:01 -07:00
PatR
ec6632352f 'nethack --dumpweights' tweak
In the generated comments accompanying weights, show /* a novel */
rather than /* a spellbook of novel */.
2025-03-18 11:53:58 -07:00
nhmall
e164ce0af4 rings were missed in --dumpweights text 2025-03-16 08:41:08 -04:00
nhmall
ef6ca6c5fa follow-up for --dumpweights
Use a string compare for the sort and encode the weight
at the beginning of the string
2025-03-15 23:18:01 -04:00
nhmall
b169b79d36 dump monster and obj weights using --dumpweights 2025-03-15 19:55:49 -04:00
nhmall
57825b170d pull request #1397 by copperwater
Closes #1397
2025-03-14 10:00:35 -04:00
PatR
719166f9ec fix issue #1377 - Forcefight vs displacer beasts
Issue reported by elunna:  Using the 'F' prefix against a displacer
beast prevented swapping places.

This doesn't use the suggested fix.  It is quite short but there is
a large diff due to change in indentation and reformatting several
comments because of that.

Attacking a displacer beast either with or without 'F' might miss,
hit, or swap places.  It won't "harmlessly attack thin air."

Fixes #1377
2025-03-10 09:17:41 -07:00
copperwater
49b43f760f Fix: a number of unblock_points shouldn't unblock unconditionally
Initially diagnosed in an xnethack fuzzer crash - unblock_point
shouldn't be called when a closed door becomes non-closed, because it's
possible that there's a gas cloud on the space which means it still
blocks vision. These always need to be recalc_block_point. A number of
them were fixed, but when I went through all the xnethack ones, I found
some that were unchanged from upstream NetHack. I reproduced the sanity
check impossibles usually by breathing gas at a door as an iron golem
and then opening or destroying the door to trigger the unblock_point
call.

The use of recalc_block_point in wizterrainwish was not triggering this
bug, but the previous code there basically duplicated
recalc_block_point.
2025-03-08 07:53:57 -05:00
nhmall
10e5d2121c fix typo reported in b9ff8068 from Sept 2024 2025-02-09 10:52:21 -05:00
PatR
41f6582690 analyzer lint for hack.c 2025-01-19 23:06:38 -08:00
PatR
a490ce5759 remove trailing spaces from src/*.c, include/*.h 2025-01-10 01:30:49 -08:00
PatR
7982c72e8b fix github issue #1360 - autounlock=Kick
Issue reported by ostrosablin:  having Kick enabled as one of the
values for the 'autounlock' option succeeded it prompting "kick it?"
when walking into a locked closed door, but answering "yes" behaved
the same as answering "no".

There's bound to be a better way of fixing this, but this works.

Fixes #1360
2025-01-04 13:59:06 -08:00
Pasi Kallinen
faf2267aba Use correct variables, not where we are trying to go 2024-12-18 10:35:54 +02:00
Pasi Kallinen
20c456cbbb Avoid using doopen return value in test_move
We can't rely on doopen_indir return value to
check whether hero moved and opened a door.
Instead, explicitly check whether the door is still
closed, and whether hero moved.
2024-12-17 20:58:02 +02:00
Pasi Kallinen
0381e61624 Fix out-of-bounds in test_move
Hero was on the top-left of an open map at (1,0), and
a monster was trying to knock them back to (0,-1).
2024-12-17 18:23:01 +02:00
PatR
b2b9b685c5 fix issue #1305 - failed #untrap from doorway
Issue reported by loggersviii:  attempting #untrap from an adjacent
doorway can move the hero diagonally out of the doorway.

A followup comment by elunna pointed out that a monster's attack that
results in knockback can produce similar result.

Fixes #1305
2024-12-13 22:48:32 -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
c255dc4bc4 paranoid_confirm:trap when flying or levitating
Avoid asking the player whether to _step_ on a trap when flying or
levitating.  locomotion() isn't the right routine for handling that.
2024-11-27 10:37:55 -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
SHIRAKATA Kentaro
bb401fcb38 split a message of a rock disappearing into a separate function
... to prepare further refactoring
2024-10-27 00:48:01 +09:00
nhmall
79c889502c follow-up: remove trailing whitespace 2024-10-24 08:40:44 -04:00
SHIRAKATA Kentaro
666b053c09 split "dopush" on moverock_core() into a separate function 2024-10-09 23:00:16 +09:00
SHIRAKATA Kentaro
387b23f633 split "nopushmsg" on moverock_core() into a separate function 2024-09-28 04:47:25 +09:00
SHIRAKATA Kentaro
f98f7d0bba split "cannot_push" on moverock_done() into a separate function 2024-09-16 16:03:20 +09:00
PatR
5bb4adace0 'tips' fix and enhancement
When 'tips' are enabled, the farlook tip displays some text at the
start of getpos().  But it clobbered the initial prompt, leaving
the screen in an ambiguous state (seemingly a normal map display,
but it is actually waiting for player to move the cursor) after
removing the tip's popup window.

Reissue the prompt.  farlook's short but misleading prompt of
"Pick an object" is changed to "Pick a monster, object or location".
I would normally include a comma before "or" but omitting it makes
the longer text seem slightly less cluttered.

The other tips are all one-line, delivered via pline().  Prefix
all of their messages with "Tip:" (which the farlook one already
uses) as a hint for using OPTIONS=!tips to shut them off.
2024-09-14 12:53:48 -07:00
nhmall
a2ec46a640 Merge branch 'moverock_core' of https://github.com/argrath/NetHack into NetHack-3.7 2024-09-14 10:25:08 -04:00
PatR
933330a0df move saving-grace back behind the curtain
If hero survives a killing blow via saving-grace, report that to
livelog but hide it from player's own #chronicle.

Only reveal whether saving-grace was used up during end-of-game
disclosure.  Omit that during enlightenment unless running in
explore mode (or wizard mode).
2024-09-13 13:31:12 -07:00
SHIRAKATA Kentaro
f1626f48ea split moverock_core() into a separate function
... to force a call to moverock_done() at the end.
2024-09-13 02:51:11 +09:00
PatR
b9ff8068b4 extending u.usaving_grace
Issue a livelog/#chronicle message if saving-grace saves the hero.
Right now it's classified as conduct for livelog filtering, because
I didn't want to implement a new category (needs update of global.h
and also the template 'sysconf') and conduct felt like the best fit
of the existing classifications.

Report whether saving-grace is available or already used, among
the attributes of magical enlightenment or end-of-game disclosure.

And move the fixes entry for it from the fixes section to the new
features section of fixes3-7-0.txt.

It seems likely that someone will want to turn not using saving-
grace into a tracked conduct.  That seems like overkill to me, not
to mention inflating the N for "N conduct games".
2024-09-06 15:32:26 -07:00
PatR
045d60848b hero health manipulation
I've been investigating issue #1252 (while the fuzzer was running,
sanity_check complained that hero's current health was greater
than maximum health) off and on for three months and haven't found
the cause.

I've checked all the places that lower maximum HP that I've managed
to find, but not spent much time looking for places that raise
current HP.

These changes might provide some more information.  They don't rely
on sanity_check being enabled.

Issue #1252 is still open.
2024-09-06 13:35:00 -07:00
PatR
aa043f0ddf some reformatting (2 of 4) 2024-09-05 14:51:21 -07:00
PatR
cd19f84721 boulder pushing comment
Replace wondering whether something is possible with a description of
how it can happen.
2024-09-05 01:14:20 -07:00
PatR
bd10bf36ec address #K4246 - pushing shop boulder out of shop
The report is for 3.6.7:  pushing a boulder into a general store adds
it to shop's inventory, but pushing it back out lets player remove it
for free.  3.7 has already fixed this; update its comments though.
2024-09-04 03:00:57 -07:00
SHIRAKATA Kentaro
7bb1d4a827 unify moverock() to "early return" style
... to prepare further refactorings.
2024-09-03 23:46:21 -07:00
SHIRAKATA Kentaro
01910d2998 split "moverock_done" into a separate function 2024-08-17 18:13:35 -07:00
PatR
c63b493904 tweak paranoid_confirm:trap vs regions
It is possible to have a known trap be at the same location as a gas
cloud region.  When paranoid_confirm:trap is set, ask for confirmation
about entering the region before confirmation about entering the trap
since the map will be showing the region rather than the trap.

Dual confirmations will be annoying but not new.  Before this change,
it would ask about entering the trap, and if the answer was yes, it
would ask about entering the region.  The situation seems to be too
rare to warrant implementing a single combined confirmation, and the
code to accomplish that would likely be messy.
2024-08-13 13:53:41 -07:00
PatR
0eb8896301 paranoid_confirm:Trap vs vapor+gas cloud regions
Extend paranoid_confirm:trap to also ask for confirmation when
attempting to enter a gas cloud region (scroll of stinking cloud,
breath from green dragons or iron golems, steam clouds from boiling
water, vapor left by fog cloud movement, no doubt several others).

Like with traps, can be overridden for a given move by using the
'm' prefix.  Unlike traps, doesn't try to guess whether moving into
a region will be harmless.

Doesn't affect movement into cloud terrain (Plane of Air).

Update the Guidebook to describe the revised behavior of
paranoid_confirm:trap and to mention how #terrain deals with regions.

'any_visible_region()' got mixed in with this but isn't used yet.
Affects extern.h and region.c.
2024-08-11 14:59:57 -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