Commit Graph

297 Commits

Author SHA1 Message Date
nhmall
0a13d759a3 more bot() tinkering 2023-11-17 09:47:39 -05: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
nhmall
d064ac2cda more cast style consistency 2023-11-13 20:31:02 -05:00
Pasi Kallinen
dd5ca5b058 Change menu_headings to accept color and attribute
Instead of just accepting an attribute, it's now possible to
use a color, or both color and attribute, for example:

OPTIONS=menu_headings:inverse
OPTIONS=menu_headings:red
OPTIONS=menu_headings:red&underline

Default is still just inverse.
This lets the player change the menu heading color without
needing to use menu colors for them.

Also makes it so the core uses NO_COLOR instead of 0, for all
the menu lines which don't have any prefedefined color.

Tested for tty, curses, x11, qt, and win32
2023-11-13 07:33:56 +02:00
PatR
ac57c070be simplified menu_headings fix
Reported by entrez, some putstr() to text window got changed to
add_menu_str().  I didn't test with curses; with tty some headers
ended up in limbo:  "Artifacts" header for '` a y' (wizard mode show
artifacts, something I had forgotten even existed) and also monster
class headers for 'm #vanquished by-class' (available to everyone).
Qt lost them too, but at least it didn't panic.

Not due to over-simplification:  end of game disclosure suppresses
header line highlighting, except when disclosing final inventory.
Change it to do so, although it would be simpler overall to just not
bother with any menu_headings highlight suppression.
2023-11-05 23:50:12 -08:00
nhkeni
33d85bfe08 CRASHREPORT cleanup
make deprecation warning suppression unconditional
formatting/whitespace
2023-09-07 20:55:07 -04:00
Michael Meyer
1dab134fce Fix: rising from the grave as a zombie
When the hero is killed by a zombie, she is supposed to arise from the
grave as a zombie of a type matching her race.  Commit 580c5a6 broke
this inadvertently -- done_in_by was passing gy.youmonst.data to
zombie_form() and relying on the old behavior where it attempted to
include the hero's race in is_elf, is_orc, etc if the permonst matched
the hero's role.  Because this no longer works, zombie_form was only
returning PM_HUMAN_ZOMBIE when passed the role permonst of an
unpolymorphed hero.  Use gu.urace.zombienum instead.  This would have to
be a little more sophisticated (falling back to zombie_form() if Upolyd)
if a polymorphed hero with unchanging could die via done_in_by but
that's not currently possible as far as I can tell.
2023-09-07 05:35:51 -07:00
nhkeni
ee2510eb2f blind attempt to fix Windows build 2023-09-06 13:55:06 -04:00
nhkeni
8c095b009a Add CRASHREPORT, show contact form on panic/impossible
When calling panic() or impossible(), create the option
of opening a browser window with most of the fields
already populated.  Code for MacOS and linux is included;
other ports are affected by argument change to early_init
which are done but not tested.

To enable, define CRASHREPORT in config.h and set
CRASHREPORTURL in sysconf to (for the moment at least)
http[s]://www.nethack.org/common/contactcr.html

Adds --grep-defined option to makedefs for Makefiles.

Adds "bid" (binary identifier), an MD4 of the main nethack
binary.  This is ONLY for helping (in the future) contact.html
to set the "NetHack from" field automatically for our own
binaries.  This can be faked, but the user can lie so nothing
lost.  There's nothing magic about MD4; other ports can use
anything that prodcues a long apparently random string we can
match against.

- new option --bidshow for us to get the MD4 of a
  released binary so I can add it to the website.
  Only available in wizard mode and not in nethack.6.
- typo macos -> macosx in hints file

No support for packaging builds as I'm not sure what that
would look like.

Adds a javascript helper for MacOS.
Adds a lua helper for linux (and builds and installs
 nhlua).
2023-09-06 12:27:13 -04:00
PatR
ee27ec97d1 tutorial tweaks
Replace tests against tutorial_dnum with 'In_tutorial()' predicate.

Give a message when entering the tutorial (via level change mechanism).

Likewise, give a message when resuming regular play.

If player uses #quit or ^C in the tutorial, ask whether to cut the
tutorial short and resume regular play; skip "Really quit?" if the
answer is yes.  Behavior is a bit odd for ^C + yes; it just sits there
until player types something.
2023-06-04 00:22:14 -07:00
nhmall
4761bf190e OpenVMS update follow-up 2023-05-22 20:50:35 -04:00
nhmall
68b8e84aa3 changes to build with VSI C compiler
The changes from past OpenVMS compilers are #ifdef'd VMS9
2023-05-22 14:43:10 -04:00
PatR
845e813e86 fuzzer vs repeat deaths, take IV
A limit of 20 deaths on the same move before having the fuzzer give up
was not enough.  Bump that to 100.  No effect at all on normal play.
2023-05-09 22:38:53 -07:00
PatR
210387c176 break fuzzer out of life-save loop, take II
When being burned up by lava, die 20 times before giving up the
attempt at life-saving (was unlimited).  Giving up leads to the hero
standing on lava rather than dying.  Normally moveloop() dunks the
hero again on next turn but fuzzer life-saving now has a chance to
confer temporary fire resistance.  So hero might have an opportunity
to level teleport or use ranged attacks that free up spots so have
somewhere available to teleport to safety if/when dunked again.

The recent code to give up on trying to resurrect the dying hero
after 15 deaths on the same move is extended to 20.  They apply to
each of the 20 lava resurrect attempts but still doesn't guarantee
that the hero will eventually get free before done() gives up.
2023-05-08 01:35:21 -07:00
PatR
ca02bc4898 fix #K3917 - fuzzer stuck in endless lifesave loop
Life-saving from being burned up in lava attempts to teleport the
hero to safely.  If that fails, hero immediately burns up again.
For fuzz testing, that results in an infinite loop.

While implementing a fix (in done(), not just lava-specific), I
noticed that hangup while running interactively in explore or
wizard mode could be subject to similar effect.

For the fuzzer, if hero dies 15 times without advancing the move
count (not 'moves', the turn count), don't life-save again.  With
hangup, don't prompt for "Die?" more than once.

Normal interactive declining to die still works.  The more exotic
situations aren't tested.
2023-05-06 16:51:59 -07:00
nhmall
de79240dea some comment spelling fixes 2023-03-16 22:27:01 -04:00
PatR
b3d5158e64 git issue #994 - killed by a touch of death
Issue reported by vultur-cadens:  cause of death reason for touch
of death and death due to loss of strength only showed the cause,
not the monster spellcaster who was responsible.

This changes
|Killed by a touch of death.
to
|Killed by the touch of death inflicted by the Wizard of Yendor.
and
|Killed by terminal fraility.
to
|Killed by strength loss inflicted by a chameleon imitating an arch-lich.
(The 'imitating' part doesn't fit on the tombstone but will be present
in logfile/xlogfile.)

Noticed while implemented this:  touch of death was modifying u.uhpmax
and basing death vs damage on that even when hero was polymorphed.
It now rehumanizes the hero in that situation.

Closes #994
2023-03-05 15:11:25 -08:00
nhmall
fd3057483f fix an issue when HANGUPHANDLING isn't defined
This is a contrived issue since HANGUPHANDLING is probably
defined for UNIX
2023-03-01 10:54:04 -05:00
PatR
0e761836ca fix misplaced parenthesis in end.c 2023-01-23 23:45:19 -08:00
PatR
c5aad9fe56 reimplement pull request #944 - grave contents
Pull request from entrez:  if bones left dead hero's corpse on top
of a new grave, don't find a corpse or summon a zombie when digging
the grave up.  It also removed the chance that a ghoul might be
summoned when engraving on a headstone, switching to zombie or mummy
instead.

Rather than adopting the pull request, this retains summoning a
ghoul via engraving and adds the possibly of doing so when kicking
a headstone.  Having a ghoul prowl around the grave is independent
of whether there is a corpse or zombie inside the grave.  To achieve
this, another flag in 'struct rm' is needed; the single bit for
'disturbed' isn't sufficient.  The bigger 'flags' field wasn't in
use for graves so commandeer that for new 'emptygrave'.  'disturbed'
still uses the 'horizontal' bit in order to have engraving and/or
kicking summon at most one ghoul.

Closes #944
2023-01-23 11:38:15 -08:00
nhmall
3803a711bd place the sound_exit_nhsound() calls 2023-01-22 19:02:37 -05:00
PatR
9dca76bb50 end.c bit - unnecessary 'else' 2023-01-21 01:56:07 -08:00
nhmall
6e136c6f7d more ATTNORETURN
A recent commit to alloc.c by Keni drew attention to the fact that
there are extern prototypes scattered around in various .c files.
Those can make use of ATTRNORETURN (non-gcc compilers and C23) the
same way the prototypes in extern.h can, and they were overlooked
when ATTRNORETURN was first added.
2023-01-12 15:38:15 -05:00
Pasi Kallinen
030fc0036a Remove NO_VSNPRINTF
Affects only ancient VMS where vsnprintf wasn't available.
2023-01-06 15:53:06 +02:00
PatR
ddd358aa03 miscellaneous objects[] macros
Replace FIRST_GEM and LAST_GEM with FIRST_REAL_GEM, LAST_REAL_GEM,
FIRST_GLASS_GEM, and LAST_GLASS_GEM and define those along with
objects[] rather than separately.  Do the latter for FIRST_AMULET
and LAST_AMULET too.  Also new FIRST_SPELL and LAST_SPELL used to
compute MAXSPELLS.  (That value looks wrong to me, but this defines
it with the same value as before.  If it gets fixed, EDITLEVEL will
need to be incremented.)

This started as just proof of concept that extra information could
be collected as objects[] gets initialized at compile time.
2022-12-28 01:50:24 -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
nhmall
4b04b1e6ac expand support for noreturn declarations
Although gcc specifies support for declaring a function as
noreturn after the function name and parameters, other compilers
do so via an attribute at the start of the declaration. Add some
macro support for the attribute-at-the-beginning method:
  o MS Visual Studio compiler
  o Upcoming C23 standard (untested at this point)
2022-11-24 00:51:42 -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
nhmall
99a93fe50b some C99 changes
Instead of using index() macro defined to strchr, use C99 strchr.
Instead of using rindex() macro defined to strrchr, use C99 strrchr.

If you want to try building on a platform that doesn't offer those
two functions, these are available:
    define NOT_C99       /* to make some non-C99 code available */
    define NEED_INDEX    /* to define a macro for index()  */
    define NEED_RINDX    /* to define a macro for rindex() */
2022-10-29 10:54:25 -04:00
PatR
e121eee867 end-of-game disclosure for gold in invent on tty
Reported by entrez:  disclosing inventory at end of game did not show
gold.  Not mentioned:  only for tty.

It was using the same window as gets used for perm_invent (although
not shown _as_ perm_invent because end of game turns that off) and the
default for whether to show gold is different for tty than for other
interfaces due use of experimental TTYINV from player's environment.

Force the end of game inventory disclosure to work the same as the
dumplog inventory listing and use a different window, by falsely
telling display_inventory() that a response is requested.  Works but
the whole inventory mechanism has become quite convoluted.
2022-10-27 17:25:14 -07:00
nhmall
6151623cce Revert "NEED_VARARGS bit for end.c and files.c"
This reverts commit af71163d99.
2022-09-17 15:58:05 -04:00
nhmall
af71163d99 NEED_VARARGS bit for end.c and files.c
avoid build failure in the event that NEED_VARARGS is already defined
on the compiler command line.
2022-09-17 12:31:26 -04:00
Michael Meyer
fe04b4a632 Move 'major events' section in dumplog
The sections of the dumplog can be broadly organized into two
categories: 'current state' and 'game overview'.  Current state includes
information about what exactly was happening when the game ended: the
map, recent messages, current inventory, and current attributes.  Game
overview is more like a history of the game up to that point: vanquished
monsters, extinct species, conducts, and dungeon overview.

All the current state sections are listed first, followed by the game
overview sections -- I'm not sure if this was a deliberate move to break
the dumplog into two distinct 'chapters', but it's convenient for
readers who may only want to know the circumstances of a death without
seeing the nitty-gritty details of the entire game up to that point.

The one section that wasn't ordered with its category was major events,
which was positioned near the top of the 'current state' group, above
the inventory listing.  This commit moves it into the 'game overview'
group.  I put it at the top, since it can serve as a sort of summary of
the game for those who are interested but don't care about some of the
details of monsters killed, etc.
2022-08-28 14:32:47 -07:00
Pasi Kallinen
fd9745f9c6 Command repeating by using cmd queues
This replaces the old pushq/saveq arrays (which were used to save
the keys pressed by the user for repeating a previous command)
with a new command queue.  This means there's no hard-coded limit
to the saved keys, and it can repeat extended commands which are
not bound to any key.
2022-08-09 11:54:45 +03:00
Pasi Kallinen
09cf464816 Potions of healing, extra healing, and lifesaved heal amount
Make potions of healing and extra healing more useful in the early
game, by upping the average amount of health restored.

Make amulet of life saving restore between 60 and 170 health,
depending on constitution. Previously life saving was the best way
to heal back up to full, even if you had thousands of hp.
2022-08-02 01:11:14 +03:00
nhmall
a518d82c54 no quotes in WINDOWPORT macro invocation 2022-06-29 22:13:28 -04:00
nhmall
a8f0e91ddf replace leading tabs in several files 2022-05-30 12:09:35 -04:00
nhmall
fe5cb1011f buf sizes in version.c
there were some 'sizeof buf' on a passed pointer variable buf.
pass the actual buffer size in a second argument.
2022-05-12 19:38:50 -04:00
PatR
47cef18a9b life-saved, while helpless
Implement the suggestion by entrez to avoid "while helpless" in the
reason for the second death if hero gets killed, life-saved, and
killed again at the same time.  Life saving sets 'multi' to -1 which
prevents the hero from moving again until next turn and is intended
to make the sequencing of "you survived that attempt on your life"
work if you're being interrupted during some multi-turn activity.

It used to behave differently when the first death occurred while
engaged in some voluntary multi-turn activity.  I've removed that
because I couldn't figure out why; it might need to be put back.
2022-04-04 10:20:28 -07:00
PatR
eea362249c wishing for artifacts
Use 'fuzzymatch(,," -",)' when checking whether the name specified
in a player's wish text matches an artifact name so that extra or
omitted spaces and dashes are ignored.  Wishing for "firebrand" will
yield "Fire Brand" and "demon bane" will yield "Demonbane".
2022-04-02 00:28:48 -07:00
PatR
d53c1a7a67 max HP manipulation
Life-saving has been setting u.uhpmax to max(2 * u.ulevel, 10)
and if it took place during level drain that could make u.uhpmax
increase instead of decrease, confusing healing which gets applied
to a monster who has drained the hero with Stormbringer or the
Staff of Aesculapius.  Change the setting to be max(u.ulevel, 10)
(removing the times two part) and also have level drain force it
to be set back to previous value if/when it gets increased.

Max HP loss due to strength trying to drop below 3 or to fire trap
or to being hit by Death now uses a mininum max HP of u.ulevel
rather than 1.  They don't have the alternate minimum of 10; I'm
uneasy that there are still two different minimum values.

I changed adjattrib() to set the flag to request a status update
before it gave its optional message rather than after so that the
new characteristic value would be visible during the message.  That
resulted in not updating status when eating royal jelly changed HP
or max HP after boosting strength.  But the same missing update
would have occurred--or rather, failed to occur--without the change
in sequencing if the strength boost causes a change in encumbrance.
2022-03-21 12:32:07 -07:00
nhkeni
ff1289e828 Add Strlen(), a strlen(3) that panics if string is stupid long and returns unsigned.
First batch of changes to use it to suppress warnings.
2022-03-16 21:34:21 -04:00
nhkeni
81b014977d Some easy loss-of-precision fixes. 2022-03-16 17:49:29 -04:00
PatR
93928640c6 github issue #688 - end of game livelog event
Requested by k21971 (hardfought admin):  classify the gameover event
as something other than achievement so that live-logging can exclude
it in order to use the xlogfile end-of-game entry instead.

It had been classified as an achievement because that was the only
category being treated as 'major' so written to final dumplog.  Give
is a new classification 'dump' which is distinct from achievement
and intended to explicitly request that an event go into dumplog.
The gameover event is the only one in that category, at least for now.

Add a bunch of other classifications besides achievement and dump to
be treated as 'major' for dumplog.  The new list is
  wish, achieve, umonst (death of unique monster), divinegift,
  lifesave (via amulet, not explore-/wizard-mode decline to die),
  artifact, genocide, dump
and may still need further tuning.  Currently excluded are
  conduct (first violation of any conduct), killedpet, alignment
  (changed, either via helmet or conversion), minorac (minor
  achievement such as level gain or entering the mines), and spoiler
  (currently only applies to finding Mines' End luckstone which is
  also 'achieve' so will be in dumplog).

This doesn't remove the reference to unimplemented LLC_TURNS that is
mentioned in the template sysconf.

Closes #688
2022-03-03 07:47:56 -08:00
PatR
77bd50fd77 fix github issue #687 - logging of major events
Reported by k21971, the dumplog section labeled "major events" showed
all logged events rather than just the ones classified as major.
Filter out the non-major ones when writing dumplog.

At the moment only a couple of ones other than achievements are major.
Probably various other types should be too.

The #chronicle command still lists all logged events unless they're
flagged as 'spoiler'.  So far the mines' end luckstone is the only
one flagged that way.  Unfortunately a player with access to live
logging could still learn whether or not the gray stone that has just
been picked up on the last mines level is the target luckstone by
viewing the log from outside of the game.

The #chronicle command would be more useful if it gathered all the
categories of events present and put up a menu allowing the player to
choose which ones to view.  I haven't attempted to implement that.

Closes #687
2022-03-01 04:15:55 -08:00
PatR
0ac3b08825 livelog revisions
Some changes to fix things I noticed in the dumplog referenced by
github issue #687 about showing all logged events under the header
"major events".  (This doesn't address that.  I figured it was
intentional while #chronicle is having any bugs worked out.)

Sequencing:  show the event corresponding to an achievement for
entering a dungeon branch before the livelog-specific event of
entering a level for the first time.  You enter the branch before
arriving at the new level.

Missing feedback:  the you-won achievement didn't produce any
"ascended" event.  That turned out to be a side-effect to suppressing
achievements that take place after the gameover flag has been set
(so blind-from-birth and/or nudist when applicable plus duplicate
obtained-amulet and ascended due to manipulation to reposition the
amulet achievement to be right before ascended so that the alternate
wording it has in the achievements listing looks better).  Instead of
just forcing the ascended achievement to produce an ascended event,
this adds a more general game-over event.

While in there, change the classification of attaining level 14 from
minor livelog event to major since questing keys off of it.
2022-02-28 13:46:59 -08:00
PatR
8c447e6ad5 formatting bits in end.c 2022-02-26 00:24:17 -08:00
PatR
ca97f4f3dd more thrown object cleanup
Handle thrown or kicked object that's in transit for hangup save and
panic save in addition to normal end of game.  Affects ball and chain
placement too, if they've been temporarily taken off the map.
2022-02-25 07:10:30 -08:00
PatR
3ea4b00879 memory management
MONITOR_HEAP+heaputil pointed out some unreleased memory.  The livelog
stuff wasn't being freed.  Not surpringly the data used for collecting
and formatting build-options that just got changed from strdup() to
dupstr() wasn't being freed.  And a couple of date/version bits.
2022-02-10 12:14:27 -08:00
Pasi Kallinen
1e90f89203 Chronicle of major events, and livelog
Log game events, such as entering a new dungeon level, breaking
a conduct, or killing a unique monster, in a new "Major events"
chronicle. The entries record the turn when the event happened.
The log can be viewed with #chronicle -command, and the entries
also show up in the end-of-game dump, if that is available.

This feature is on by default, but can be disabled by
defining NO_CHRONICLE compile-time option.

This also contains "live logging", writing the events as they
happen into a single livelog-file. This is mostly useful for
public servers. The livelog is off by default, and must be
compiled in with LIVELOG, and then turned on in sysconf.

Mostly this a version of livelogging from the Hardfought server,
with some changes.
2022-02-09 22:49:25 +02:00