Commit Graph

9550 Commits

Author SHA1 Message Date
PatR
1532a052c0 spellbook of blank paper named Making Money
Reported directly to devteam, polymorphing a spellbook could produce
a blank spellbook with a Discworld novel's title attached.
2024-02-27 11:27:02 -08:00
nhmall
334535e7b0 Fix makemon() trying to generate a monster on top of another monster
When makemon was called with all-zero arguments (e.g. for random
monster generation over time), ptr==NULL means "a random monster".
This was being forwarded to mon==NULL in makemon_rnd_goodpos, and
then mtmp==NULL in goodpos, which means "an object, not a monster".
Because objects can be generated under monsters, this meant that an
attempt to create a random monster could end up choosing a location
that already had a monster, which would then cause the monster
generation to fail.

This mostly wasn't noticeable in normal play: it effectively
reduced the monster generation rate depending on how many locations
outside LOS happened to contain a monster. Normally that's a very
small proportion, so the bug had no obvious effects: but when there
are very few locations outside LOS (i.e. the player can see almost
every location on the level), the bug effectively caused monster
generation to stop once those locations became occupied by
non-moving (e.g. hiding) monsters, something that became observable
in games where the player decided to dig out and light almost an
entire level.

This commit fixes the problem by adding a new flag to goodpos that
requests that it not choose a position that already has a monster.

This bug was diagnosed, and this fix committed, by ais523; but
nhmall wrote almost all of the code implementing the fix.
2024-02-27 19:04:35 +00:00
PatR
1d26f80ccf more nhmd4.c formatting
Insert a space between cast operator and target.

For 'x | y' expression spanning multiple lines, split with bitwise OR
operator at the beginning of second line instead at the end of first.

I changed a macro that was expanding to 'expr_1; expr_2' into
'(expr_1, expr_2)'.  Both expressions modify arg 'a' which would be
a no-no within a single expression, but the comma operator provides a
sequence point that guarantees that the first expression will be fully
evaluated with side-effects--assignment to 'a'--completed before the
second one starts, making both assignments be well defined.
2024-02-26 11:46:03 -08:00
PatR
5acb82640d update a getpos() comment
Not a typo this time; the highlight-valid-position callback interface
was simplified.
2024-02-25 12:36:19 -08:00
PatR
53f16f9e8c reformat nhmd4.{c,h} 2024-02-24 13:49:51 -08:00
Pasi Kallinen
dd37c5326a Accessibility: showdamage option
Add a new boolean option showdamage, if on, outputs a message
like "[HP -2, 14 left]" - several variants have something similar,
but I chose the message based on how eSpeak said it, while keeping
it short.
2024-02-24 17:38:46 +02:00
PatR
9927e264b5 hacklib.c NONNULL functions
A bunch of routines return a pointer which is never Null but weren't
telling the compiler that such was the case.  A couple (strsubst(),
stripchars()) were accepting Null output argument and then returning
Null, but callers had no reason to use them that way, so they've been
changed.  (upstart() could have been changed similarly; I've already
forgotten why I left it as-is.)
2024-02-23 20:02:01 -08:00
nhkeni
5f64dd3f1b Make initoptions() call initoptions_init() if that hasn't already happened. 2024-02-23 20:14:03 -05:00
nhkeni
eadebf0132 Use local md4 implementation instead of libcrypto for linux.
NB: "make depend" needs to be rerun
2024-02-23 17:08:49 -05:00
nhkeni
61f4d972bb Add local md4 implementation and drop libcrypto for linux. 2024-02-23 17:05:45 -05:00
PatR
cba7e6eb43 umpteenth comment typo fix
plus bonus fix:  change a recent fixes entry to past tense.
2024-02-22 11:01:53 -08:00
PatR
9f7fffc823 rolling boulder trap fix
The recent "trap.c reformatting" commit included a non-formatting
change switching from gb.bhitpos.x,.y to local x,y in the rolling
boudler trap routine.  The part of that routine used when a rolling
boulder hits another boulder and transfers its remaining momentum
to that other one got switched to wrong x,y and the first boulder
basically kept going, possibly hitting itself at each new position.
2024-02-22 11:00:18 -08:00
nhkeni
7e08ce3e9e Merge branch 'keni-crdumplog' into NetHack-3.7 2024-02-21 16:27:52 -05:00
Pasi Kallinen
c7e2ebe83c Check inventory protection only when hero is carrying it
TODO and better fix would be to have similar check for
monster inventory.
2024-02-21 11:28:49 +02:00
Pasi Kallinen
391295cfdc Move comment 2024-02-21 08:18:40 +02:00
nhkeni
3f5d1d3a36 split DUMPLOG
DUMPLOG requests the DUMPLOG feature as it does now
DUMPLOG_CORE requests the internal buffering only (used for CRASHREPORT)

This allows CRASHREPORT to access recent messages without performing
any file I/O.
2024-02-20 21:42:05 -05:00
Pasi Kallinen
e76ab9558f remove register that snuck in 2024-02-20 22:13:31 +02:00
Pasi Kallinen
ea38ddcb13 Fix mplayer weapon weight 2024-02-20 22:11:42 +02:00
Erik Lunna
eb22a81088 Refactor, unify, and nerf item destruction
Note: Original change is from xNetHack by copperwater <aosdict@gmail.com>,
      but this commit comes from HACKEM-MUCHE by Erik Lunna, with
      some minor code formatting.

From xNetHack commit a0a6103bea:

'The original goal: nerf item destruction using a method I initially
 proposed for SpliceHack, in which the number of items subject to
 damage from any single source is limited by the amount of damage the
 effect caused. The intent was to be more fair all around and prevent
 aggravating situations where, for instance, a chest shock trap zaps
 you for 4 damage and immediately ten of your rings and wands blow up.

 Problem 1: no easy way to limit the items destroyed without biasing
 heavily towards the start of the invent chain. The old code was able
 to get away without bias by just indiscriminately destroying
 everything eligible with a 1/3 chance. Here, I had to introduce
 reservoir sampling in a somewhat more complex form than I've applied
 it elsewhere, since there are a pool of potential items.

 Problem 2: destroy_item no longer worked remotely like destroy_mitem,
 which still destroyed 1/3 of items indiscriminately. Commence the
 process of squishing them into one function that handles both the
 player and monsters. (Which required making a lot of adjustments to
 destroy_one_item, now named maybe_destroy_item, on nits such as
 messaging and when to negate damage. An annoying consequence of the
 merge is that in the player case, their HP is deducted and they can
 be killed directly, but for monsters they need to add up the
 destruction damage and return it.)

 Unifying destroy_item and destroy_mitem has some advantages: in
 addition to the obvious code duplication removal, it ensures monsters
 now take the same damage as players for destruction (previously they
 took a piddly 1 damage per destroyed item). Now when you hit
 something with Mjollnir and their coveted wand of death breaks apart
 and explodes, you at least get the satisfaction of knowing they took
 the standard amount of damage from it.  Monsters also now get
 symmetry with players in having extrinsic elemental resistance
 protect them from item destruction, and damage negation from item
 destruction if they were appropriately resistant.

 Problem 3: a lot of callers didn't preserve the "amount of incoming
 damage" that this refactor relies on. E.g. if the defender resisted
 that element, the local dmg variable would be set to 0. So I had to
 do some wrangling with callers to save that original damage
 value. The rule of thumb is: all *incoming* damage counts. So that
 includes the player's spellcasting bonus if applicable, but not
 things like half damage, negation due to resistance, or extra damage
 due to being vulnerable to cold/fire.

 Then I figured, while I'm here let's get rid of all those silly cases
 where destroy_items is called multiple times for various different
 object classes, and cut the object class parameter out of it. This
 has a few minor effects:

 - Places where different object classes previously rolled
   independently for destruction to happen at all now roll
   once. (Which, by my calculation, generally means less incidences of
   destruction - a fire attack now won't have three separate chances
   to hit your scrolls, potions, and spellbooks. On the flip side, a
   lucky roll will no longer save an entire object class in your
   inventory.)

 - Callers can no longer specify different probabilities for
   destroying different object classes. The only place this was really
   used was to call destroy_item with a slightly lower probability on
   SPBOOK_CLASS.  With the nerf in this commit, less of them ought to
   be destroyed anyway.

 - A very edge case of where explosion-vs-monster damage was totted up
   differently for golems, which could result in differences of a hit
   point here or there.

 - All object classes being processed in one go means that less items
   are destroyed than would be if they were still processed
   independently.  This is not really visible compared to the old
   baseline of just destroying 33% of everything, but would be a
   marked difference versus a copy of the game that still called
   destroy_items separately for different object classes. To
   compensate, I adjusted my planned damage-to-destruction-limit
   scaling factor down from 8 to 5.

 Not done: merging in ignite_items(), though that would probably be
 really easy now.'

Notes from porting from xNetHack:

- It might be necessary to reexamine at all the conditional checks for
calling destroy_items. Because item destruction is much more
restrained and uses the actual damage from an effect, we might now
need to check 'if (!rn2(3))' and similar in all the places item
destruction occurs.
2024-02-20 22:03:54 +02:00
nhmall
b4f578495c more pointer style consistency 2024-02-20 13:04:32 -05:00
nhmall
0a985459f0 make style consistent for function ptr arguments 2024-02-19 17:21:04 -05:00
nhmall
688ac6ffbe remove register from variable declarations 2024-02-19 16:30:07 -05:00
PatR
6f569f0a27 beating dead horses
Extend a joke that no one has ever seen in actual play.
Clears out an old entry from 'git stash'.
2024-02-19 11:30:00 -08:00
PatR
c84dc79610 trap.c reformatting
Monstly changing '<type>* <var>' to '<type> *<var>'.  Wrap or shorten
a few wide lines.

One of the rolling boulder routines accessed gb.bhitpos.x,y many times;
change that to use local x,y instead.
2024-02-19 11:11:23 -08:00
PatR
4c7259a1d4 another comment typo 2024-02-19 00:42:27 -08:00
PatR
44de195718 theft against punished hero with empty inventory
If a punished hero's inventory is empty, have a nymph usually take
off the attached chain and indirectly fix punishment.  If hero is
trapped by being chained to a buried iron ball, sometimes take off
the implicit chain and indirectly release hero from the trap.

Monkeys won't do this and nymphs will only do so if there is no
inventory (aside from gold and/or embedded dragon scales which they
aren't allowed to target).

It's a lot simpler than I was expecting when I wrote the TODO about
it recently.
2024-02-18 11:24:21 -08:00
PatR
d688309012 openholdingtrap() message sequencing
If a trap is blocking levitation or flight and you use wand of opening
or spell of knock to get out, you'd get things like
|You start to float in the air!
|You are released from the bear trap.

Give the release message before the actual untrapping.
2024-02-18 11:18:48 -08:00
Pasi Kallinen
2952bdab63 No secret doors or corridors on the early levels
New players often get stuck on the first level when they can't
find the secret door or corridor.  Make the first two levels
have no such features.
2024-02-18 11:47:02 +02:00
PatR
d253e947da more getpos() highlighting plus jumping in place
Simplify the valid-position highlighting via '$' by combining the
tmp_at(start) and tmp_at(populate) steps.

Add highlighting for a couple of targetting operations that would
give valid/invalid feedback via autodescribe but weren't displaying
highlight markers for $.

I made several jumping changes, most of them dealing with picking
hero's own spot.
2024-02-16 15:36:17 -08:00
PatR
1d5f45aa78 getpos() highlighting of valid positions
Redo getpos() highlighting.  If bgcolors is Off, '$' toggles between
no highlighting and showing dollar signs at valid spots.  ^R removes
those if they're present.  When bgcolors is On, '$' cycles among
three settings:  highlighting via background color, no highlighting,
and highlighting by drawing dollar sign characters.  ^R switches to
background color mode.

This doesn't directly solve the problem of background color causing
conflict with the foreground color of some objects or monsters, but
being able to get rid of the background with a keystroke should be an
improvement.

'bgcolors' defaults to On, which was a problem for tty when 'color'
was Off.  Turn it Off (in the core) for text map if color is Off and
bgcolors hasn't been explicitly set.  Conversely, Qt was leaving
color Off and then using color with abandon.  Turn in On (in the core)
for tiled map if it hasn't been given an explicit value.  Those two
changes should cope with most situations and still let the player
override.
2024-02-16 14:56:20 -08:00
nhmall
437a403286 follow-up - avoid onefile issues 2024-02-15 21:56:47 -05:00
nhmall
48c01b4ac1 quiet some new warnings
end.c:177:16: warning: unused parameter 'why' [-Wunused-parameter]
  177 | NH_abort(char *why)
      |          ~~~~~~^~~
end.c: At top level:
end.c:1191:1: warning: 'get_saved_pline' defined but not used [-Wunused-function]
 1191 | get_saved_pline(int lineno){
      | ^~~~~~~~~~~~~~~
options.c:1263:1: warning: 'optfn_crash_urlmax' defined but not used [-Wunused-function]
 1263 | optfn_crash_urlmax(int optidx UNUSED, int req, boolean negated UNUSED, char *opts, char *op)
      | ^~~~~~~~~~~~~~~~~~
options.c:1240:1: warning: 'optfn_crash_name' defined but not used [-Wunused-function]
 1240 | optfn_crash_name(int optidx UNUSED, int req, boolean negated UNUSED, char *opts, char *op)
      | ^~~~~~~~~~~~~~~~
options.c:1217:1: warning: 'optfn_crash_email' defined but not used [-Wunused-function]
 1217 | optfn_crash_email(int optidx UNUSED, int req, boolean negated UNUSED, char *opts, char *op)
      | ^~~~~~~~~~~~~~~~~
2024-02-15 21:25:22 -05:00
nhkeni
e378b782fc Yes, apparently there are configurations that still need the NH_abort() macro 2024-02-15 19:00:08 -05:00
nhkeni
3d3ce2369c Merge branch 'keni-wincw2' into NetHack-3.7
Lots of manually resolved conflicts.
2024-02-15 16:25:12 -05:00
PatR
bf8a634760 nethack --version:dump
Add the 'dump' argument to the existing '--version' command-line
option to display the magic numbers used when validating save and
bones files for compatibility.

Nothing exciting, just a line of 5 hex values.  I was going to also
list the values for however many save and bones files are specified
on the command line but it seems to need more effort than I care to
expend.  And I hadn't made up my mind whether that should be done by
nethack, recover, or some new standalone program.  [Single line of
relatively raw output is so that they could be compared more easily.]

nethack --version:bad-argument was writing a message to stdout and
then starting play--which immediately overwrites stdout.  Have it
quit instead.  Player wasn't trying to start a game and quitting is
what it does with --version:good-argument.
2024-02-13 15:58:10 -08:00
Pasi Kallinen
d511944dda Add missing initializer for field w_what 2024-02-12 12:57:50 +02:00
nhmall
f2b1150950 include MAXOCLASSES in --dumpenums 2024-02-11 00:10:17 -05:00
PatR
2d82528920 uskin sanity check
'uskin' isn't part of worn[] so wasn't being checked with the other
slot pointers.  Add that, although it'll be excluded by default and
need to have EXTRA_SANITY_CHECKS defined to include it.
2024-02-10 18:04:10 -08:00
nhmall
cc7618438c Windows Install.windows and nhsetup.bat updates 2024-02-10 12:39:49 -05:00
PatR
e2a3c98aac worn/wielded pointer sanity checks
Check the various uarm, uwep, and so forth pointers to make sure that
they point to items in hero's inventory and that those items have the
corresponding W_ARM, W_WEP, &c bit set in their owornmask field.
Also check whether any other items in inventory have the same bit set.
[Some of this is already handled by sanity_check_worn() in mkobj.c.]

Also validate two-weapon combat mode.  I don't recall ever seeing any
problems reported about it though.

Does not validate ball and chain.  Those should have their own sanity
checks that validate a bunch of other stuff besides just worn slots.
They already get some checking by the normal object tests.

This works ok with 'sanity_check' set and items worn and wielded
normally.  The only insane situation tested was by reverting the
confused-looting-with-quivered-gold fix from earlier today.  I haven't
used a debugger to force other such problems so this isn't very
thoroughly tested.
2024-02-09 23:32:16 -08:00
PatR
c490265e35 Q enhancement
Noticed while testing confused #loot:  when using 'Q' to populate
quiver, or 'f' when quiver is empty, don't bother asking what to
ready/fire if inventory is empty.

And when inventory isn't empty, don't list '-' as a likely candidate
if quiver is already empty.

'w' behaves differently.  '-' is treated as a likely candidate when
already not wielding anything, and even when inventory is completely
empty.
2024-02-09 16:46:22 -08:00
PatR
9326f80ecc lava_effects() bit
lava_effects() item destrunction had the logic for handling Book of
the Dead wrong.  (However, that didn't matter since the obj_resists()
check earlier would prevent it from being burned up.  Fix it anyway.)
2024-02-09 15:52:17 -08:00
PatR
381851348b fix #K4103 - crash after confused #loot of throne
If gold is moved into throne's coffer chest (or added to exchequer
monster's minvent) while quivered by the hero, it wasn't being unworn
to remove it from quiver slot.  That could lead to a crash.  Example
was segfault during 'f' command.

freeinv() expects caller to unwear item being removed from inventory;
reverse_loot() wasn't doing so.
2024-02-09 15:48:47 -08:00
PatR
bffa88b04e regions vs long worm tails
If any part of a long worm is within a posion gas cloud region,
include it just once no matter how many segments are inside.  The
tail will take harm from poison gas, but only once rather than for
repeated for every segment inside the region.

Unlike with detection, show long worm tail if hero is adjacent to
it in a gas cloud region and would see that tail segment if the
region wasn't inhibiting visibility.
2024-02-08 23:44:22 -08:00
PatR
ad8bcc6b3f comment typo of the day
I have no idea how this got in.  It's not just a typo; what's beyond
thinko?
2024-02-08 12:32:43 -08:00
PatR
fd5526db7c fix for #H9430 and github issue #1207 - gas clouds
Reported yesterday as issue #1207 by elunna and over four years ago
in #H9430:  monsters in gas clouds that should be shown by Warning
aren't.  And in some discussion of #H9430 back then:  monsters
adjacent to the hero while in gas clouds aren't shown on the map,
but combat and other interaction describes them as if they were.
There have been changes since then--to prevent seeing things on the
far side of gas clouds as if there were no clouds in the way--but
the basic problems with warning and adjacency weren't addressed.

This is a band-aid (tm) that probably makes things livable.  Don't
allow gas region display to override monsters that are sensed via
warning or when the hero is next to them.  That part doesn't work
correctly if the hero isn't blind and is inside the cloud while the
monster is adjacent but outside.  I think it will take more than a
band-aid to deal with that sensibly.

Closes #1207
2024-02-08 07:04:15 -08:00
PatR
5212e4b3db fix github issue #1204 - reflected poison gas
Reported by elunna:  a poison gas breath attack that was reflected
by the target still left that target enveloped in a poison gas cloud.

This makes the gas trail not extend to the target if the attack hits
and is reflected.  But if the attack misses then the cloud does reach
the target, which seems weird to me.  However, being in the cloud is
a separate event that isn't deterred by reflection.

Closes #1204
2024-02-07 11:58:12 -08:00
Pasi Kallinen
6b9f411a32 Accessibility: mon_movement
Adds a new boolean option, mon_movement. When hero notices monster
movement, give a message. Use with spot_monsters and accessiblemsg.
2024-02-07 19:50:38 +02:00
nhkeni
dbe5c98dca add CRASHREPORT directly to browser
add CRASHREPORT for Windows
add ^P info to report (via DUMPLOG)

new options: crash_email, crash_name, crash_urlmax
new game command: #bugreport
new config option: CRASHREPORT_EXEC_NOSTDERR
new command line option: --bidshow

deleted helper scripts:
    NetHackCrashReport.Javascript
    nhcrashreport.lua

misc:
    update CRASHREPORTURL (will need to be updated before release)
    update bitrot in winchain
    winchain for Windows
    add missing synch_wait for NetHackW --showpaths
    add PANICTRACE (and CRASHREPORT) in mdlib.c:build_opts

missing:
    packaging (Windows needs the pdb file)
    no testing with MSVC command line build

port status:
    linux: working, but glibc's backtrace doesn't show static functions
    Windows VS: working.  pdb file is large - looking into options
    MacOS: working
    msdos: not supported
    VMS: not supported
    MSVC: planned, but not attempted
    MSYS2: working, but libbacktrace not showing symbols (yet?)
2024-02-06 18:33:59 -05:00
nhmall
1f255dcd03 comment bit 2024-02-06 15:03:59 -05:00