Commit Graph

298 Commits

Author SHA1 Message Date
PatR
0d31bb8c88 change program_state.getting_a_command
to program_state.input_state

Rename program_state.getting_a_command and give it an int value
instead of treating it as boolean.  Start using to it for Qt to
suppress commands initiated from the drop down menus in the title bar
if nethack isn't expecting to get a command from the user.  Those menu
choices inject extended command text into the input stream and should
be avoided when entering text or waiting for a menu to be dismissed.

These menus would be better if they grayed out unavailable choices
when pulled down instead of accepting any choice and then treating
that no good.  I'm not going to try to figure out to do that with Qt.
And this workaround for the menus doesn't have any affect on the
toolbar buttons below the title bar.  Those execute core commands
directly and when I tried to use jacket routines instead, the tool bar
stopped showing up so I've given up.

This won't fix the reported problem of getting stuck in a loop.
2023-04-06 01:56:08 -07:00
Pasi Kallinen
62476fe101 Stop blinking cursor on hero when farlooking
I happened to notice when looking at a ttyrec that farlooking
with automatic description would blink the cursor on hero for
one frame, and then back on the farlooked map location.
2023-03-10 14:11:56 +02:00
nhmall
ecf74d5308 some pline()-like function usage 2023-03-08 19:12:52 -05: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
Pasi Kallinen
5d659cf1f6 Tips and option to disable them
Adds a more general way to handle gameplay tips, and adds
a boolean option "tips", which can be used to disable all
tips.  Adds a helpful longer message when the game goes
into the "farlook" mode.

Also adds a lua binding to easily show multi-line text
in a menu window.

Breaks save compat.
2023-02-19 15:56:18 +02:00
PatR
04ef7cba46 Address github issue #983 - getpos valid locations
Issue reported by entrez:  when getpos() is being used to have the
player pick a map location, if player types '$' (for some operations
like jumping or applying a polearm) then valid spots are highlighted
but the highlighting obscures what was shown on the map.  I'm not
sure whether this 'fixes' the issue but it's probably good enough.
Allow typing another '$' to toggle the highlighting back off,
redisplaying the map in the process, without needing to move the
cursor or type ^R to accomplish that.  Toggling seems more intuitive.

This is a lot more complicated than it needs to be because I assumed
that the background aspect of highlighting stayed visible when the
glyphs were reverted.  It doesn't work that way but I haven't thrown
out the effort to make toggling the highlights work sanely.  Prior
to this, typing '$' again just redrew the highlighting again, with
no visible effect.

Closes #983
2023-02-17 12:21:54 -08:00
nhmall
288cc01f3a Merge branch 'naming-overflow-fix2' into NetHack-3.7 2023-02-16 18:52:47 -05: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
PatR
b9bbf0205b Pending 3.7 edition of the naming overflow patch.
Like the 3.6.7 one, the original pieces have been combined into one
commit.  But it is separate from the one added to that version.
2023-01-28 13:02:46 -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
e4145f7dc1 calling objects
An earlier attempted fix was not working as intended.  This
accomplishes what I was trying to do.  I haven't reverted
interesting_to_discover() to static within o_init.c.
2022-12-14 14:07:22 -08:00
PatR
daeec9291c refine PR #946 - named armor
Move the new stuff from PR #946 out of xname() into new routine
armor_simple_name().

Noticed while testing:  tweak 'call object type' so that it doesn't
list instances of pre-discovered armor as likely candidates since
assigning a name to such wasn't showing up in the discoveries list.

Add "silver shield" as wishing synonym for "polished silver shield".
2022-12-14 07:37:04 -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
Michael Meyer
eebe30b037 Message for giving unnameable monster blank name
The message for trying to (re)name an unnameable monster was weird when
the player entered a blank name (a name consisting of only spaces), in
an attempt to delete the monster's existing name rather than give it a
new one.  Several of the normal messages looked incomplete due to using
the blank string as the "new name" (e.g., "I'm Feyfer, not ."), and the
one which didn't include the name still seemed a little off ("calling
names" is almost the opposite of what the player is doing).  Add a new
message for attempting to erase the name of one of the special
unnameable monsters, e.g. "Juiblex would rather keep his existing name"
or "The Oracle would rather keep her existing title".

I also noticed that the message for trying to give an unrenameable
monster the name it already has (e.g. trying to name Death "Death") was
revealing the genders of the Riders with personal pronouns.  This is
avoided elsewhere (e.g. using "the way" in mdisplacem, "its" baked
into the message in mhitm_ad_deth), so I also added a slightly rephrased
alternate message for Riders which avoids any pronouns.  For the
unnaming message, on the other hand, I just used "its" for the Riders,
since I couldn't think of a way to phrase it that avoided pronouns
entirely.
2022-11-01 16:21:47 -07: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
418fcd8764 comment typo 2022-10-20 10:39:11 -07:00
PatR
fc0f05398e getpos() reformatting
Some miscellaneous reformatting done while looking over getpos() usage
rather than reformatting of getpos() itself.
2022-10-20 10:33:38 -07:00
PatR
5226c9633d fix github issue #905 - ^A vs getpos()
Reported by entrez:  using ^A instead of #retravel after interrupted
travel can pick wrong location if cursor was previously positioned
with movement commands rather than feature targeting because it
won't be starting from the original spot.  Also, ^A after ';' will
just redescribe whatever was examined previously instead of having
the player pick a new spot.

This suppresses cursor positioning from the do-again queue so that
repeating travel or quick-look or other command that needs player
to choose a position will repeat the command but then need to have
a position chosen.  For interrupted #travel, the cursor will already
be placed on the previous destination so that's relatively painless,
but also allows a different destination to be chosen.

It adds iflags.remember_getpos that callers of getpos() could set to
be able to restore the old behavior but none do so far.

Fixes #905
2022-10-20 10:27:21 -07:00
PatR
0735b790f9 object name assignment vs persistent inventory
This is an alternate way to deal with pull request #876, where
splitting a stack that has a name assigned updated perm_invent when
cloning the name and ran into trouble with shop billing when trying
to format for persistent inventory display.

The PR#876 fix has been left in place but wouldn't have been needed
if this had gone in first.
2022-09-26 14:25:06 -07:00
nhmall
c548fff9e4 some spelling corrections
The pull request included some changes that were neither accidental nor
unintentional, so only a subset of the changes from pull request #869
submitted by klorpa were manually applied.

behaviour  -> behavior
speach     -> speech
knowlege   -> knowledge
incrments  -> increments
stethscope -> stethoscope
staiway    -> stairway
arifact    -> artifact
extracing  -> extracting

The uses of "iff" were left alone.

Close #869
2022-09-08 10:54:11 -04:00
Pasi Kallinen
601dba5279 Make glorkums emit impossible 2022-09-04 17:43:06 +03:00
Pasi Kallinen
51ac21bc88 Make mouse clicklook report only the specific tile
Previously the mouse clicklook mentioned every tile that matched
the character symbol, leading to overload of information and
if playing with tiles, it was mostly useless. Also the most
important bit - the tile info - was last in the text.

Now mouse clicklook only reports the exact tile information
that was clicked on.
2022-08-25 17:17:42 +03:00
Pasi Kallinen
7c8ccb8ccd Prevent getpos queueing mouse commands
My change to allow binding the mouse buttons made getpos
push the mouse commands into a command queue, so when you
were asked for a map location, clicked on it with a mouse,
you'd first get the expected effect, and then (most likely)
immediately traveled there.

Change getpos to clear the commands bound to the mouse buttons,
and restore the binds afterwards.
2022-08-24 14:21:27 +03:00
nhmall
d3208fa1c3 correct an rng mistake in 6e0d55df from Jan 2019
Reported by entrez
2022-08-17 20:32:07 -04: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
Michael Meyer
47a35ba8a7 Another getpos cmap followup
Hot on the heels of my previous commit, here's a way to do it without
any assumptions about the order of defsyms.
2022-07-23 17:04:12 -07:00
Michael Meyer
e9fb226dbf getpos cmap vs glyph followup
This is a bit more efficient, since everything up to S_hcdoor is
skipped anyway, but it's a little harder to understand so needs more
comments.  Not sure if it's worth it or not...
2022-07-23 17:04:12 -07:00
Michael Meyer
8fe02be5ae Fix: getpos cmap vs typ/glyph confusion
When some parts of getpos were rearranged in 7404597, tests of terrain
types and glyphs were moved to a loop which iterated through the defsyms
array without being updated to handle cmap values instead.  Consequently
they weren't excluding certain terrain types from being 'jumped to' as
intended.  (Though it seems as though they actually worked by chance to
some extent, just because there's some overlap between terrain types and
defsyms in terms of where the 'walls/doors' blocks start and end.)

I also noticed that cmap_to_type was missing S_darkroom (it fell through
to the default case so that the function returned STONE), so I added it.
2022-07-23 17:04:12 -07:00
PatR
fed367ccbd simulated mouse again
Change u.{dx,dy,dz} from schar to int and get rid of unused u.di.

Remove just added getdir_ok2click; it was declared as int but being
assigned booleans.  Rename getloc_click to getdir_click and have
getdir() use it for both input and output.

A simulated mouse is becoming quite a nuisance for something which
will probably never be used by anyone in actual play.
2022-07-10 11:14:10 -07:00
PatR
2d0ee19df5 a few miscellaneous comments 2022-07-03 17:51:47 -07:00
Michael Meyer
3e38c720ad Don't describe 'more info' prompt in #glance help
When using #glance, the player is never prompted about whether she wants
'more info' about something on the map, even if flags.help is true and
she has pressed '.' -- the 'more info' prompt is exclusive to #whatis.
getpos_help already changed its description of '.' based on whether
'help' was on or off; adjust those criteria so that the description of
the 'more info' prompt is only included for #whatis, where it is
actually relevant.

I recently looked at the help while using #glance and got confused
about why the 'more info' prompt was never appearing, so hopefully this
should help forestall that sort of thing.  #glance also prompts only
once, so there's some other information about "moving to another spot"
in the help text which is not relevant -- that could definitely be
addressed as well but I think it's less likely to be confusing, so I
didn't bother with it in this commit.
2022-07-03 17:32:38 -07:00
nhmall
3004cf2d34 be more consistent with coordinates 2022-07-02 09:10:03 -04:00
PatR
4f781e7850 fix #K3627 - impossible placing long worm at <0,0>
When migrating, a long worm is removed from the map to take off the
tail, then its head is put back to be treated like other monsters.
If that occurred when being forced to re-migrate during failure to
arrive from a prior migration, it wouldn't have valid coordinates
and the place_monster attempt produced an impossible warning.
(Other types of monsters don't get removed and put back so didn't
trigger the problem.)

The routine to format a monster when the data is suspect mistakenly
thought it was dealing with a long worm tail because the monster
didn't match level.monsters[0][0], so the warning inaccurately
reported the problem as "placing long worm tail".
2022-06-26 12:22:09 -07:00
nhmall
2770223d10 interface groundwork for core-side color decisions
(user-side decisions really, but as it stands right now
user-side decisions/options are made and processed by the core)

add a parameter to add_menu so color can be passed
2022-06-25 13:21:51 -04:00
PatR
d886b43107 fix [again] exploiting artifact name rejection
Reported by entrez:  attempting to name certain undiscovered items
after an artifact could be used to tell whether the item being named
was the same type as the artifact, so trying to name a gray stone
the Heart of Ahriman would let you tell whether it was a luckstone.
That was fixed years ago to reject for any undiscovered gray stone
rather than only for luckstone; you'll get "your hand slips" and the
name would be smudged.  But that fix allowed a loophole and could
still be exploited if the player used lowercase for the name:  it
would get changed to mixed capitalization if the object was the
artifact's type or stay lowercase if it only matched by description.

This changes to the capitalized name even when the type isn't an
exact match, so attempting to name either a luckstone or a touchstone
"the heart of ahriman" will name it "The Aeart of Xhriman" with at
least one smudged letter to avoid the actual artifact name.

Unrelated change:  when attempting to apply a new name to an existing
artifact, it now says "<Artifact> resists" rather than "The artifact
seems to resist" because there's no "seeming" about it.
2022-06-21 08:57:58 -07:00
PatR
efcd07f814 another x_monnam() tweak
The former special case for a/an prefix wasn't partlicularly special.
2022-06-19 11:36:40 -07:00
PatR
f598acd1c9 code paths through x_monnam()
Reduce the number of early returns in x_monnam().  There shouldn't be
any change in observable behavior.
2022-06-19 02:44:18 -07: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
be76727265 granular verbose message suppression mechanics
Switch to using a macro invocation Verbos(n, s) in place of the
flags.verbose checks.

Provide the mechanics for individual suppression of any of the
existing messages that were considered verbose.

Mechanics only - this code update does not provide any means of
setting the suppression bits.

iflags.verbose = 0
is still a master suppression of all the verbose messages.

iflags.verbose = 1
turns on the verbose messages only for those whose suppression
bit is 0 (not set).
2022-06-09 13:53:20 -04:00
PatR
af55e3d027 add new #wizkill command
Add a way to get rid of specific monsters in wizard mode without
fighting, zapping, &c.  #wizkill command lets you kill creatures by
picking them with getpos().

You can pick multiple monsters by targetting them one after another.
You don't have to be able to see or sense them but if you target a
spot that has no monster, the command ends.

By default, the hero gets credit or blame as if having killed the
targets but #wizkill can be preceded by 'm' prefix to treat their
deaths as if they had been caused by a monster.
2022-05-21 17:40:52 -07:00
PatR
4d9c568a8e \#therecmdmenu #name monster
Implement naming an adjacent monster with #therecmdmenu.

Also plug a memory leak using item-action name or call on objects.
2022-05-15 11:01:44 -07:00
PatR
d1217b9f25 add glyphs+tiles for door+chest traps
When trap detection finds trapped doors and trapped chests, it shows
those as bear traps.  When the hero comes within view, they revert to
normal and the detected trap is forgotten.  This doesn't change that,
it is just groundwork to be able to show them distinctly.  Like the
TT_BEARTRAP patch, it increments EDITLEVEL so this seemed like a good
time to put the groudwork in place.

There shouldn't be any visible changes even though internal glyph and
tile values have been renumbered after inserting two new entries.
Adding traps after S_vibrating_square was quite a hassle and suffered
though a couple of off-by-one errors that weren't trivial to find and
fix.
2022-04-27 11:22:12 -07:00
PatR
49b046f2e5 disallow assigning type name to Amulet of Yendor
Something I noticed when testing the item-action handling for name and
call; applies to the C/#name command too.  You were allowed to call the
real Amulet something and allowed to call fake ones something [else].
If you did that, xname/doname didn't show it but the discoveries list
did, giving away information when the player had access to more than
one unID'd Amulet of Yendor.  Rather than messing about with discovery
handling, make real and fake Amulet be ineligible from being given a
type name.  (They can still be given individual names.)
2022-04-19 14:19:48 -07:00
PatR
9f0e511b00 item-action name/call
Add opportunity to name an individual object or call the type of an
object to the context-sensitive inventory item-actions.
2022-04-19 04:33:01 -07:00
PatR
81a4c2ed4c aligned cleric corpse
I was looking into "The Lord Surtur's corpse" and got side-tracked by
something else:  move a priest hack for avoiding "aligned" in a corpse
description from corpse_xname() to obj_pmname().  The old variation
always picked "priest corpse" over "priestess corpse".  The new one
will use either one of those if the corpse is flagged as such, or use
"cleric corpse" (avoiding "aligned cleric corpse") if it's flagged as
random.
2022-04-08 00:35:13 -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
b0067493c9 fix #K3564 - obj sanity failure: N globs for N>1
Using #name and picking an item on the floor to be assigned a type
name allowed any of the four types of globs to be named.  After
that, wishing for those by the assigned name bypassed the code that
forced the quantity to stay at 1.  Asking for "3 foo" could then
produce "3 small globs of gray ooze" which fails obj_sanity() and
issues an impossible warning (which the fuzzer escalates to panic).

The "getobj refactor" patch changed the return value of call_ok().
When it gets used to check whether an object on the floor could have
a type name assigned (rather than as a getobj() callback), the test
that should have rejected the naming attempt accepted it instead.

Update the wishing code to handle globs differently:  you can still
specify the relative size via small, medium, large, or very large,
but now you can specify a count either instead or in addition.  A
count of more than 1 is used to multiply the created glob's weight,
although it's less likely to be honored as-is when the size is bigger
than small.  Quantity is always forced to 1, at a different place in
readobjnam() than previously.
2022-03-30 14:11:29 -07:00
Pasi Kallinen
39acd095b2 Add helpless monster macro 2022-03-18 10:19:04 +02:00
PatR
77dc522a62 artifact tracking again
Redo the recent artifact creation stuff by replacing several nearly
identical routines with one more general one.  Also adds a tracking
bit for one or two more creation methods.  That changed artiexist[]
from an array of structs holding 8 or less bits to one holding 9, so
bump EDITLEVEL in case the total size changed.
2022-03-12 17:25:54 -08:00
PatR
7a335eb030 more artifact tracking
This should have been broken up into multiple pieces but they're
all lumped together.  I did ultimately throw away a fourth change.

Implement artiexist[].bones and artiexist[].rndm artifact creation
tracking bits that were added recently.  Doesn't need to increment
EDITLEVEL this time.

Add a new wizard mode feature:  if you use `a to show discovered
artifacts, it will prompt about whether to show the tracking bits
for all artifacts instead.  If not using menustyle traditional,
you need at least one artifact to have been discovered in order to
have 'a' choice available when selecting what class of discovered
objects to show for the '`' command.

artifact_gift(), aritfact_wish(), and so forth return a value that
none of the existing callers use, so cast their calls to (void).
2022-03-11 11:00:44 -08:00