Commit Graph

296 Commits

Author SHA1 Message Date
Pasi Kallinen
e407af4477 Allow defining random-teleport exclusion zones in lua
Adds a new lua command

  des.exclusion({ type = "teleport", region = { x1,y1, x2,y2 } });

which allows defining "exclusion zones" in the level, areas where
random teleports (or falling into the level) will never place the hero.
Does not prevent targeted teleportation into the area.

Breaks saves and bones.
2023-08-24 18:38:39 +03:00
PatR
60c1956850 revamp 'special' combat
This is a re-creation of a project that was lost years ago while not
quite finished.  The old version included some instrumentation to
measure how many hits it takes to kill things during actual play; that
wasn't ready for prime time and this hasn't attempted to redo it.

Changes:
1) improves martial arts and bare-handed combat:  they now have a
   chance to hit twice when skill is better than 'basic'; 20% chance
   for second hit at skilled, 40% at expert, 60% at master, and 80% at
   grandmaster; when attacking more than once, strength bonus is
   handled as in #2;
2) nerfs two-weapon combat a bit:  hitting twice uses only 3/4 strength
   bonus on each hit, but when both attacks hit that's 3/2 bonus from
   strength which is still more than you get for one hit at a time;
3) beefs up two-handed weapons:  hitting via melee with a two-handed
   weapon uses 3/2 of stength bonus to reflect the increased influence
   of strength; isn't done for applied polearms though.

The reduction in strength bonus for two-weapon has far less impact
than it might sound, due to rounding up with the low values involved.
| full   3/4
|  +1 -> +1
|  +2 -> +2
|  +3 -> +2
|  +4 -> +3
|  +5 -> +4
|  +6 -> +5
The small reduction also doesn't matter if/when current hit happens to
deal a killing blow anyway.

Rings of increase damage apply at full value to every hit, same as
before.

When hitting bare-handed (#1 without gloves), a silver ring on either
hand continues to give a damage bonus against silver haters when you
make an ordinary single attack.  However if you attack twice, a silver
ring only applies on the first hit when it is worn on the right hand
and only applies on the second hit when worn on the left hand.  (Two
hits with a silver ring on each hand will give silver bonus for both.)

We might conceivably need to add support for a count prefix of 1 to
let player explicitly avoid a second bare-handed/martial-arts hit
attempt (similar to how throw and fire accept a count to limit missile
volley amount).

Kicking has been ignored.
2023-07-30 14:08:30 -07: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
1bd966f826 fix issue #1061 - dipping container into water
Issue reported by loggersviii:  dipping a container into an uncursed
potion of water mentions water getting into the container.  That
happens even when that type of potion hasn't been discovered yet.

Make POT_WATER become discovered if this occurs.  Doesn't apply when
hallucinating where a random liquid is mentioned instead of water.

Fixes #1061
2023-06-15 02:29:51 -07:00
PatR
fb0509a6b3 fix #3841 - steed and engulfer on same map spot
Reported five months ago, a save was performed while a mounted hero
was engulfed.  Restore issued a warning about the engulfer being
placed on top of the steed (who shouldn't have been on the map).

The report arrived at about the same time as engulfing a riding
hero was changed to force a dismount instead of engulfing both hero
and steed so nothing further was done about it.  This changes
restore to not put a steed on the map and then take it off again.
It also attempts to simplify usteed and ustuck handling during save
and restore.

Testing so far indicates that things are still working correctly.
Keep makeplural(body_part(FINGER)) crossed.

Existing save and bones files are invalidated.
2023-06-14 00:04: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
Pasi Kallinen
0ac9309e1e Simple options menu shows help for each entry 2023-04-17 15:47:50 +03:00
nhmall
2185d325c4 header file changes hack.h, decl.h/.c, system.h, wintty.h
- Move secondary preprocessor defines down further in config.h
so that they can be overridden via [platform]conf.h which is
included from global.h, specifically:
    LIVELOGFILE when LIVELOG is defined
    DUMPLOG_FILE when DUMPLOG is defined

- Minimize platform-specific, or compiler-specific code in hack.h and decl.h.

- reorganize src/decl.c to align with include/decl.h.

- a new header file cstd.h added, containing calls to C99
standard header files.

- hack.h, decl.h, and decl.c have been cleaned up and had code
moved so that things line up as follows:

     hack.h     defines values that are available to all
                NetHack source files, contains enums for use in all
                NetHack source files, and contains a number of
                struct definitions for use in all NetHack source files.
                It does not contain variable declarations or variable
                definitions.

     decl.h     contains the extern declarations for variables that
                are defined in decl.c. These variables are global and
                available to all NetHack source files. The location of
                the variables within decl.h was random, so give it some
                order for now.

     decl.c     contains the definition of the variables declared in
                decl.h, and initializes them where appropriate. The
                variable definitions are laid out in much the
                same order as their declarations in decl.h.

- wintty.h: There were some varying terminal-related prototypes in
system.h, and that was the only thing left that demanded that
system.h be included. Those have been replaced by an #include
<term.h> in include/wintty.h to get the more current (and hopefully
more correct) prototypes, rather than hardcoding them in NetHack
sources.

For edge-case platform compatiblity, there is no #include <term.h>
if the build defines NO_TERMCAP_HEADERS. In that case one set of
hardcoded prototypes is still used in include/wintty.h.

The added #include "term.h" is also bypassed for NO_TERMS builds (builds
that don't link to terminfo/termcap at all, but still present a tty
interface using platform or window-port specific functions to fulfill
the same role as that of terminfo/termcap).

- some scattered, unnecessary #include "integer.h" were removed from
various files, since that's always included in current NetHack-3.7
sources, either directly from config.h or indirectly from #include
"hack.h".

- system.h references removed.

- new cstd.h added; the #include "system.h" references in Makefiles
and project files (Xcode, visual studio), were replaced
with #include "cstd.h" references. A "make depends" is probably
warranted.

Also:

 - Use of <term.h>, which defines clear_screen() as a macro, conflicts
with an actual function with that name in win/tty/termcap.c. The most
straight-forward course of action was to rename the NetHack function,
and change the references to it, from clear_screen() to
term_clear_screen(), so that was done.
2023-04-05 11:49:09 -04:00
nhmall
de79240dea some comment spelling fixes 2023-03-16 22:27:01 -04:00
PatR
3a30e434d8 "<mon> hits [again]"
Add "again" to the hit message when an attack sequence has
consecutive attacks of same type and they hit.  A {bite, claw, claw}
sequence won't give that for first claw attack regardless of whether
the bite hits but will give it for the second claw attack when both
of the claw attacks hit.

The message sequence
|The fire ant bites!  The fire ant bites!  You're on fire!
or |The fire ant bites!  The fire ant bites!  You avoid harm.
when the first bite was for physical damage and the second was
for fire damage seemed a little confusing.

This changes that to be
|The fire ant bites!  The fire ant bites again!  You're on fire!
or |The fire ant bites!  The fire ant bites again!  You avoid harm.
It still isn't crystal clear that both bites are from a single
attack and that the second bite is for different type of damage
but I think it's an improvement.
2023-03-16 01:54:29 -07:00
PatR
4021a63bcf wand/spell/breath killer reason
Extend "killed by the touch of death inflicted by <monster>" to buzz().
"Killed by a bolt of cold" becomes "killed by a bolt of cold zapped by
<monster>" or "killed by a blast of cold" becomes "killed by a blast
of cold exhaled by <monster>" and so forth.

More work than expected; the zap code isn't passed enough context.

BZ_M_WAND() was producing the wrong value for wands zapped by monsters.
2023-03-07 02:47:42 -08:00
Pasi Kallinen
fc7a32b86e Tutorial level
Add a tutorial level to teach commands to new players.
Very much a WIP.

Breaks save and bones compat.
2023-03-01 14:00:29 +02:00
nhmall
fbd9a7bae8 another update to the soundlib interface
sound_verbal(char *text, int32_t gender, int32_t tone, int32_t vol,
             int32_t moreinfo);
    -- NetHack will call this function when it wants to pass text of
       spoken language by a character or creature within the game.
    -- text is a transcript of what has been spoken.
    -- gender indicates MALE or FEMALE sounding voice.
    -- tone indicates the tone of the voice.
    -- vol is the volume (1% - 100%) for the sound.
    -- moreinfo is used to provide additional information to the soundlib.
    -- there may be some accessibility uses for this function.

It may be useful for accessibility purposes too.

A preliminary implementation has been attempted for macsound to test
the interface on macOS. No tinkering of the voices has been done.

Use of the test implementation requires the following at build time with make.
    WANT_SPEECH=1
That needs to be included on the make command line to enable the test code,
otherwise just the interface update is compiled in.

I don't know for certain when AVSpeechSynthesizer went into macOS, but older versions
likely don't support it, and would just leave off the WANT_SPEECH=1.

If built with WANT_SPEECH=1, the 'voices' NetHack option needs to be enabled.

It was a bit strange, when I first started up the test, to hear Asidonhopo,
the shopkeeper, talking to me as I entered his shop and interacted with him.
2023-02-07 00:44:36 -05:00
nhmall
ea4a81901d add an interface for sound libraries
Groundwork for a more versatile interface for using
sound libraries. A lot of sound libraries work across
multiple platforms.

The current NetHack sound stuff is quite limited.

Binaries can have a variety of window ports linked into
them, and it makes sense to have something similar for
sound.

This tries to set things up in a more soundlib-centric way,
rather than inserting things in a platform-centric way.

It establishes a new top-level directory sound (akin to win
for the window interface routines, or "window-port") where
sound-related additions and sndprocs and support files can be
added and used across platforms.

The default interface is nosound and the 'nosound' interface
is in src/sounds.c

The interface for 'windsound', which contains the same minimal
USER_SOUNDS support using built-in routines that has been in the
windows port for a long time is added to
sound/windsound/windsound.c.

For now, the sound interface support for 'qtsound' has been added
to the existing Qt files win/Qt/qt_bind.h and win/Qt/qt_bind.cpp,
and a note has been placed in sound/qtsound/README.md to avoid
confusion.

New header file added: include/sndprocs.h.
2023-01-19 18:51:42 -05:00
PatR
85c908cb03 displaying generic objects
Add 17 fake objects to objects[], one for each object class.  All
specific color as gray.  They're grouped at the start--actually near
the start since "strange object" is still objects[0]--rather than
being among the objects for each class.  init_object() knows to start
at [MAXOCLASSES] instead of [0]; other code that loops through every
object might need adjusting.

For potions, non-stone gems, and non-novel/non-Book_of_the_Dead
spellbooks that don't have obj->dknown set, display the corresponding
generic object rather the object itself.  Fixes the longstanding bug
of seeing color for not-yet-seen objects whose primary distinguishing
characteristic is their color.  Walking next to a generic object
while able to see its spot will set dknown and redraw as specific.
It's slightly disconcerting to have objects change as you reach them;
I hope it's just a matter of becoming used to that.  (If there is any
code still changing the hero's location manually instead of using
u_on_newpos(), it should be changed to use that routine.)

Most of the new tiles are just a big rendering of punctuation
characters.  The potion, gem, and spellbook ones could be cloned from
a specific object in their class and then have the color removed.  I
started out that way but wasn't happy with the result.  I'm not
artisticly inclined; hopefully someone else will do better.  Each of
them is preceded by a comment beginning with "#_"; the underscore
isn't required, just being used to make the comments stand out a bit.

Invalidates existing save and bones files.
2023-01-10 14:33:21 -08:00
nhmall
2fc0d25d45 introduce support for coloring the frame behind a map location
Also includes support by paxed for polearm targeting using the
frame color.

Also renames USE_TILES to TILES_IN_GLYPHMAP which is a more
accurate description.

Not all window interfaces have full support for the color framing
of the background square yet.

MS-DOS needs further work (to bring it to both VESA and VGA, with
and without tiles.

Windows GUI is missing support.

X11 and Qt have been started, but may require further refinement.
2023-01-01 19:55:02 -05: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
PatR
249e431e46 new 'sortvanquished' option
Allow the preferred sort order for the vanquished monsters list to
be specified in the run-time config file
|OPTIONS=sortvanquished:X
where X is t, d, a, c, n, or z.  It can also be set to 'A' or 'C'
but those aren't documented and aren't offered as choices when
setting the value interactively, which can be done via 'm O' or by
using 'm #vanquished'.

Guidebook.mn has been updated but Guidebook.tex is lagging again.
2022-12-26 14:56:12 -08:00
PatR
91e2ab13b2 last? role/race/&c option values update
Keep track of how a role|race|gender|alignment option got its value
so that role:!Tourist in .nethackrc and role:!Priest in NETHACKOPTIONS
yield 'role:!Priest' rather than merging into 'role:!Priest !Tourist'.
It also doesn't write the value into new config file for #saveoptions
if that value comes from environment or command line (not applicable
since the command line arguments for role,&c don't go through options
handling).  Also, the old config file value takes precedence over
the current game's value file so that 'role:random' doesn't become
'role:Healer' or such in a new config after the random value gets
picked for play.

This only tracks the role, race, gender, and alignment options but the
concept could be extended to all options.  The data would need to be
saved and restored if values set interactively need to be retained in
restore sessions (doesn't apply to role,&c since those don't change
during play).
2022-12-22 15:07:33 -08:00
PatR
7096c68492 more interactive role selection
This ended up combining several unrelated changes.

Add missing 'fixes' entry for curses-specific item in New Features.

When answering "Shall I pick ... for you? [ynaq]", accept \m as well
as \n and space for choosing the default of 'y', same as normal
ynaq() would.  Also add '*' to '@' as not-shown potential answers;
they force 'random'.

When tty tore down any of the menus, things were reasonable if they
were short enough for corner windows, but tall ones that switch to
full screen weren't fully erased.  The parts of those outside of the
map window stayed behind when the tall menu was closed and cleared.
Mainly affects picking the "~ - reset filtering" choice but also
affected the role menu on 24 line tty screens.  (Didn't affect curses
because it tracks and refreshes its base window when some overlaying
window goes away.)

The role menu used 25 lines so required a second page for the case
of a 24 line screen on tty.  Dealing with that is a bit ugly but it
wasn't an issue when this form of role selection was tty-only (because
the info about choices made so far was displayed on the base window
rather than in an extra menu line back then) so I added a hack for it.
If the role menu will take one more line than the screen height, the
separator between 'random' (below 'Wizard') and 'pick race first' gets
squeezed out.  If the menu needs two more lines (doesn't happen now,
except by changing screen size to 23 lines for testing), a second line
gets squeezed out.  (Not attempted for curses because it wouldn't
help.  'windowborders' and one or two extra separators it adds make
menus taller.  I doubt if many players use curses on 24-line screens
but if they do, they'll be using something new rather than going from
something that used to fit on one page with 3.6.x.)
2022-12-13 15:59:05 -08:00
PatR
4a965bbd83 boulder pushing feedback
Redo the details about giving or suppressing "with great effort you
push the boulder".  It works the same except that if push a different
boulder than previously, you'll get a new message.  If you do it
while riding, you have the same lack-of-message for successive pushes
instead of getting a message every turn.

Don't exercise strength when pushing a boulder if poly'd into a giant.
2022-12-07 16:45:35 -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
d80e8d9569 adjust 4 line lengths from previous commit 2022-11-03 15:50:32 -04:00
nhmall
fac75f5ae4 purge more E for extern 2022-11-03 15:42:24 -04:00
PatR
1572877429 build fix for NODUMPENUMS and more issue #916
I made more things in dump_enums() static and/or const.  In the
process I discovered both compile problems for NODUMPENUMS and when
fixed, link problems for NODUMPENUMS+ENHANCED_SYMBOLS.

The uft8map.c portion has no changes, just reformatting.
2022-10-31 15:43:14 -07:00
nhmall
88f6df2d8b some tabs to spaces
cd src
    grep -P -n '\t' *.c | grep -v "1:"
    cd ../include
    grep -P -n '\t' *.h | grep -v "1:"
    cd ..

side note: win/Qt/*.cpp are full of tabs
2022-10-26 14:21:23 -04:00
Michael Meyer
c78e7af013 Digestion attack can grant hero intrinsics
Monster purple worms can now gain intrinsics from swallowing foes whole,
so maybe the hero should be able to do so too.  Intrinsics aren't
granted immediately upon swallowing (that would probably have been
easier), but only once a corpse is created and then entirely digested.

I'm not sure if this is too powerful and was being avoided deliberately
for that reason, since it includes potential level gain from wraith
corpses in addition to other intrinsics.  That's consistent with monster
purple worms but may be a bit too much in the hands of the hero, though
it is limited by needing the corpse creation roll to succeed.
2022-10-08 16:06:50 -07:00
Pasi Kallinen
a733004912 Remove the per dungeon level door limit
Number of doors in a room-and-corridor style level was fixed
at 120; now the doors-array is dynamically allocated when needed.

Breaks saves and bones.
2022-09-09 19:40:45 +03:00
PatR
d4f0450afe fix the tty message spacing anomaly for messages \
delivered across level change checkpointing

Reported by entrez.  Simplest test case:  give level 1 a short
annotatation, level teleport to level 2, and level teleport back to
level 1.  The message window will show

|You materialize on another level.  You remember this level as <note>.

but ^P message history will show

|You materialize on another level.
|  You remember this level as <note>.

Spaces inserted to separate two messages that fit together on the
top line become part of the second message when saving a checkpoint
during level change flushes the top line into message history.

Change insurance checkpointing to record the full message history
without flushing the current top line so that toggling 'checkpoint'
doesn't affect what shows up on the screen or in message recall.
2022-08-30 15:01:49 -07:00
PatR
11c8d5cd5e Unix: command line --windowtype:foo fix
initoptions(), including initoptions_finish(), was running to
completion with the default window system before windowtype from the
command was parsed and activated.  When the default window system
is tty without MS-DOS the map type gets set to ascii; command line
--windowtype:X11 doesn't switch it back to the X11 default of tiled.

So,
| NETHACKOPTIONS=windowtype:X11 nethack
ran nethack in tiles mode but
| nethack --windowtype:X11
ran it in text mode (assuming .nethackrc left tiles vs text with the
default setting).

I think this fix is quite iffy but it seems to work as intended....
It reclassifies '--windowtype' as an "early option" in unixmain.c,
and the options.c code ultimately processes it twice.
2022-08-28 00:09:50 -07:00
Pasi Kallinen
5e9ed7a290 Some selection optimizations
- Add bounds, so that we don't process any locations outside
  as those locations are known to be unset
- The bounds are only recalculated if needed
- Replace instances of selection_not where we actually want
  a new selection with all locations set
2022-08-26 12:43:40 +03:00
Pasi Kallinen
c42e73fd9c Allow binding mouse buttons
Instead of hardcoding mouse button actions, allow the user to
bind mouse buttons to extended commands.  For example the new
defaults are:

BIND=mouse1:therecmdmenu
BIND=mouse2:clicklook

Currently a bit rudimentary; the defaults should be OK, but
documentation is bit lacking, and in-game binding and option
saving are missing.

Allowed commands to bind are "nothing", "therecmdmenu", "clicklook",
and "mouseaction". Clicklook replaces the "clicklook" boolean option,
and mouseaction does what mouse 1 button used to do - a context sensitive
action.
2022-08-23 23:27:21 +03:00
Pasi Kallinen
d91915dba3 Migration-safe monster movement iteration
The monster knockback could mess with the monster linked list while
the code was going through it for monster movements. (For example,
a monster knocked back another into a level teleport trap)

Add iter_mons_safe, which first grabs all the monster pointers in
the list into an array, and goes over that array instead of relying
on the "next monster" pointer. This is possible because dead monsters
are not removed from the linked list until after all the monsters
have moved.

Testing is very minimal, and I'm not sure the vault guard check
for migration is correct - it should probably check for more states?

Also the iterator could be improved by not continually allocating
and freeing the monster pointer array.
2022-08-10 11:04:04 +03: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
PatR
b37f922cf7 viz_array[][] type
viz_array[][] is indexed by coordinates but the data it contains has
nothing to do with them so it shouldn't have been changed to coordxy.
'char' was sufficient; 'uchar' would have been better; this invents
'seenV' instead.  This led to a cascade of required changes.  The
result is warning free and seems to be working but my fingers are
crosssed....
2022-07-15 13:48:29 -07:00
nhmall
c84e0ba6e1 rework TTY_PERM_INVENT; update window port interface
Change the inner workings of the experimental TTY_PERM_INVENT.

Switch to delivering the content to tty for the experimental perm_invent
via the existing window port interface (start_menu(), add_menu(), end_menu).

This also adds a new window port interface call ctrl_nhwindow() for
delivering information to the window port, and/or obtaining specific
information from the window port. The information and requests can
be extended as required. To be documented later once the changes settle
down.

Due to the intrusive nature of these changes and the possibility of
some bugs in the new code, I'm going to leave TTY_PERM_INVENT commented
out in the repository for a day or two.  Anyone wishing to test it out
can do so by uncommenting TTY_PERM_INVENT in config.h.
2022-07-03 00:35:32 -04: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
nhmall
18b28084f8 move some parts of TTY_PERM_INVENT into core
This starts the tty perm_invent just in time later in the
startup rather than initializing it with the other
game windows.

This also splits the duties:

The core will inquire from the window port about how many
inventory slots it can fill.

The core will handle figuring out the inventory text and
inventory letters, and will do the traversing of internal
data structures like obj chains, and passing customization
options on to the window port.

The window port will look after placing each inventory slot's
text at an appropriate location on the screen.

This, in theory, makes the core-portion available for
window ports other than tty to use, though none currently do.
The decision of what goes in an inventory slot is all left up
to the core with the update_invent_slot interface.

Documentation updates will come later, not at this time.
2022-06-24 15:01:38 -04:00
nhmall
65659b2cab experimental config option TTY_PERM_INVENT
Add a rudimentary experimental always-up inventory display
capability to tty when the perm_invent option is in effect.
It requires an additional 28 rows available on the terminal
underneath the bottom status line.

It hasn't been optimized for performance as of yet.
2022-06-20 10:40:55 -04:00
PatR
00fd2b79de simulated mouse click for #therecmdmenu
The #therecmdmenu command calls getdir() which issues an "in what
direction?" prompt.  This allows you to answer with "_" instead of a
regular direction, then it will call getpos() to allow you to move
the cursor and type "," (or ";") to behave as if a left-click had
been done or type "." (or ":") to behave as right-click.

Ordinarily I would think of the 'normal' getpos() response of "."
as suitable for left-click, then one of the other getpos finishers
for right-click, but comma is left of period on a standard keyboard
and that seems useful for remembering which is used for which click.

Left clicking on a spot farther than one step away offers travel,
throw iff lined up, and also click-look as choices.  If you right
click farther than one step away, it will only offer click-look.
The look choice for either left or right click isn't inhibited by
having the clicklook option set to False.  After all, player is
explicitly choosing the menu entry to look at something.

New getdir.mouse can be bound to some other key than "_" and the
getpos.pick* responses could already be re-bound, but there's no
separate getdir.left/right that could be used to bind different keys
from those used for the four getpos responses.
2022-06-13 16:06:06 -07:00
nhmall
e2e3c1f8de Re: [NetHack/NetHack] Prompts can overwrite copyright notice on the
starting screen (Issue #783)

On 2022-06-01 12:22 p.m., NetSysFire wrote:
> Steps to reproduce:
>
>1. Get any prompt and answer it. In my case it was a horribly old
>   save I forgot about or when I wiztested something and forgot
>   about that save, too.
>2. See that the copyright information got overwritten by the prompt:
>
>There is already a game in progress under your name. Destroy old game? [yn] (n)
>         By Stichting Mathematisch Centrum and M. Stephenson.
>         Version 3.7.0-59 Unix Work-in-progress, built May 31 2022 12:28:31.
>         See license for details.
>
>
> Shall I pick character's race, role, gender and alignment for you? [ynaq]
>
> Expected behavior:
>
> Redraw after a prompt was answered, so the prompt vanishes and the
> entirety of the starting screen will be shown.
>
> NetHack, Copyright 1985-2022
>          By Stichting Mathematisch Centrum and M. Stephenson.
>          Version 3.7.0-59 Unix Work-in-progress, built May 31 2022 12:28:31.
>          See license for details.
>
>
> Shall I pick character's race, role, gender and alignment for you? [ynaq]
>
> Proposed severity: low. Not gamebreaking, it is cosmetic only and does
> not have any other consequences.
>

The Copyright notice is placed by tty internal routines writing onto
the BASE_WINDOW fairly early in the startup sequence.

The prompt to "Destroy old game? [yn] (n)" is using the in-game
routine to write to the message window at the top of the screen and
prompt there, just like in-game prompts and messages.

If the player answered 'y' to that, the prompt for
"Shall I pick character's race, role, gender and alignment..."
appeared immediately after. That one, however, is written using
the BASE_WINDOW routines in tty, like the copyright notice.

This change does the following:

It moves the copyright lines down a little bit leaving room for the
"Destroy.." prompts.

It places the "Shall I pick characters's..." prompt further down the
screen by default, leaving some room for about 3 raw_print startup
messages after the copyright notice, just in case there are any.
The "Shall I pick character's..." prompt will still appear immediately
if there is a prompt such as "Destroy old game?..."

There were a couple of other issues around raw_print startup messages
too. Those are delivered using a raw_print mechanism to ensure they
are written even if the window-port is not fully operational. However,
they were only on the screen for the blink of an eye. This call
sequence in restore.c made them disappear almost immediately:
     docrt() -> cls()

Put in a mechanism to detect the presence of raw_print messages
from the early startup, and if there were some, wait for a
keypress before obliterating the unread notifications.
2022-06-08 23:41:45 -04:00
PatR
18639d2ef2 send lua warnings to paniclog instead to player
Now that the garbage collection problem has been fixed, record lua
warnings in the paniclog file rather than showing them on the screen.

Move nhl_warn()'s warnbuf[] to struct g in case restart ever gets
implemented so that it can be cleared if the restart occurred while
a warning message was under construction.
2022-06-01 01:03:11 -07:00
nhmall
4a8deefaa3 replace leading tabs in several more files 2022-05-30 12:38:22 -04:00
nhmall
cb0c21e91d ENHANCED_SYMBOLS
A new feature, enabled by default to maximize testing, but one which can
be disabled by commenting it out in config.h

With this, some additional information is added to the glyphmap entries
in a new optional substructure called u with these fields:
    ucolor          RGB color for use with truecolor terminals/platforms.
                    A ucolor value of zero means "not set." The actual
                    rgb value of 0 has the 0x1000000 bit set.
    u256coloridx    256 color index value for use with 256 color
                    terminals, the closest color match to ucolor.
    utf8str         Custom representation via utf-8 string (can be null).

There is a new symset included in the symbols file, called enhanced1.

Some initial code has been added to parse individual
OPTIONS=glyph:glyphid/R-G-B entries in the config file.

The glyphid can, in theory, either be an individual glyph (G_* glyphid)
for a single glyph, or it can be an existing symbol S_ value
(monster, object, or cmap symbol) to store the custom representation for
all the glyphs that match that symbol.

Examples:
   OPTIONS=glyph:G_fountain/U+03A8/0-150-255

(Your platform/terminal font needs to be able to include/display the
character, of course.)

The NetHack core code does parsing and storing the customized
entries, and adding them to the glyphmap data structure.

Any window port can utilize the additional information in the glyphinfo
that is passed to them, once code is added to do so.

Also, consolidate some symbol-related code into symbols.c, and remove it from
files.c and options.c
2022-05-07 10:25:13 -04:00
PatR
5d56da3d32 bubble/cloud save/restore overhaul
The air bubbles on the Plane of Water and the clouds on the Plane of
Air were being saved and restored as part of the current level's state
(which is the 'u' struct and invent and such) rather than with the
current level itself.  That was ok for normal play, but for wizard
mode's ^V allowing you to return to a previously visited endgame level
after moving to a different one it meant a new set of bubbles for
Water and new set of clouds for Air.  Even that was ok since it only
applied to wizard mode, but using #wizmakemap to recreate Water or Air
while you were on it added a new set of bubbles or clouds to the
existing ones.  If repeated, eventually there wouldn't be much water
or air left.

Instead of just adding a hack to #wizmakemap, change save/restore to
keep the bubbles/clouds with the level rather than with the state.
That wasn't trivial and now I know why the old odd arrangement was
chosen.  Saving hides u.uz by zeroing it out for levels that the hero
isn't on and it is zero during restore so simple checks for whether a
given level is water or air won't work.

This also adds another non-file/non-debugpline() use of DEBUGFILES:
 DEBUGFILES=seethru nethack -D
will make water and clouds be transparent instead of opaque.  It also
makes fumaroles and other light-blocking gas clouds be transparent
which wasn't really intended, but avoiding it would be extra work that
doesn't accomplish much.

Increments EDITLEVEL for the third time this week....
2022-04-29 12:44:26 -07:00
PatR
31affa0722 ^A/#repeat vs extended commands
Fix '#repeat' for tty; both it and ^A can repeat an extended command.

Fix both for curses; they can repeat an extended command instead of
just repeating the initial '#' to start getting an extended command.

X11 (tested), Qt (tested), and probably Windows GUI (not tested)
behave the same as before:  ^A (or #repeat) after an extended command
just repeats the # to run the dialog to get an extended command.

I hope this introduces fewer bugs than it fixes but I don't think I'd
bet on that....
2022-04-16 01:52:12 -07:00
PatR
58bc545cc6 \#dotypeinv ('I') - show title for inventory subset
When asking for an inventory subset for one of the meta-classes that
can generate output which spans object classes (so B,U,C,X, and P),
insert a title at the start of the resulting inventory list.  (Iu and
Ix produce alternate output that already includes a title.)

Also, stop handling '$' differently for menustyles traditional and
combination from full and partial.  'I$' was running the '$' command
for the first two styles but just showing the inventory entry for
gold for the last two.  Change to the latter for all styles.
2022-04-10 06:52:39 -07:00
Pasi Kallinen
eb9c7d77d4 Improve therecmdmenu
Turning on herecmd_menu and clicking with mouse is now actually
somewhat playable.
2022-04-06 21:23:27 +03:00
Pasi Kallinen
92c21b588b Ask to kick a locked door open, if hero has no unlocking tool 2022-04-03 13:58:50 +03:00
Pasi Kallinen
6977aef436 Fix stuck travel for good
My fixes to the travel stuck oscillation did not fix all of them,
and I've even seen a 3-step loop - which my fixes cannot detect.
I guess there could be arbitrary-sized loops too.

To definitely fix this, keep track of all the map locations travel
has moved the hero through, and if it tries to go on a location already
used, stop travel and give the unsure -message.
2022-04-02 18:27:53 +03:00