Commit Graph

2814 Commits

Author SHA1 Message Date
PatR
a995929168 fix #H9118 - stoning a sandestin
causes "dmonsfree: N removed doesn't match N+1 pending" warning.  The
sandestin monster definition flags it as MR_STONE, immune to being
turned to stone.  If the hero hit it with a cockatrice while it was
shape-changed into something which isn't MR_STONE, it had its mon->mhp
set to 0, so died, and its form (mon->data) was set back to sandestin.
known_hitum() decided that it didn't turn to stone because of MR_STONE
for that form so proceeded to kill it off due to lack of hit points,
causing it to die twice.

I started to change that so that it didn't kill off the critter a
second time, bit it really shouldn't be able to kill it by stoning in
the first place.  So sandestin how shares some vampire code to revert
to innate form and not turn to stone when "killed" by stoning.  It
only yields the normal visible polymorph message:  "the <foo> turns
into a <bar>" without any attempt to explain why.  Once in sandestin
form, smacking it with a cockatrice corpse doesn't do anything special
(due to MR_STONE now being unambiguously in effect).  It will soon
shape-change to some other form and then become subject to being
forced back to innate shape by stoning again.
2019-08-14 18:49:16 -07:00
PatR
c814ca8e04 fix #H9117 - bookeeping for fatal status condition
When Stoned, Slimed, Strangled, Sick (TermIll or FoodPois or both)
counts down to 0 without being cured, keep it listed as an active
condition while killing off the hero.  It will show in the status
section when disclosing final attributes and in both that section
and map's status lines when producing a dumplog.
2019-08-11 18:56:43 -07:00
PatR
cc3d97d9b3 fix github issue #209 - typo in end_of_input()
Fixes #209

Fix typo:  program_statue should be program_state.  Apparently
NOSAVEONHANGUP+INSURANCE isn't used by anyone since it wouldn't
compile.
2019-08-08 11:01:56 -07:00
PatR
380a2d2848 fix #H9100 - typo in Mort #4
For "They look at you but the don't see you", "the" should be a second
"they".  Simple transcription typo rather than a mistake in the book.
2019-08-06 04:24:21 -07:00
PatR
508af05e42 fix #H9084 - teleported boulder left stale screen
Report was for Sokoban but it applied anywhere:  if a teleported
boulder landed in a pit or trap door or hole and flooreffects() used
it up (so returned True), rloco() didn't update the location it was
teleported from and it appeared not to have moved.  (Line of sight was
updated to reflect its absence but map spot wasn't redrawn without it.)
2019-08-02 11:51:26 -07:00
PatR
55e166ba08 fix #H9082 - post-3.6.2 monster throwing crash
Changing
  if (ammo_and_launcher(otmp, uwep) && mwep->otyp == ELVEN_BOW)
(with 'uwep' typo) to
  if (mwep->otyp == ELVEN_BOW && ammo_and_launcher(otmp, mwep))
(with fixed 'mwep') moved ammo_and_launcher()'s hidden non-null
test to after 'mwep->otyp'.  If mwep was Null (so monster must be
throwing non-ammo such as darts or daggers rather than shooting
with a launcher), a crash occurred.  (Throwing such things while
the monster is wielding any weapon doesn't have this problem.)

I don't think 3.6.2 can crash here.  If hero's uwep is a bow, otmp
must be arrows to get past pre-3.6.3's incorrect ammo_and_launcher()
check.  And a monster won't shoot arrows unless wielding a bow, so
monster's mwep would be non-Null regardless of what uwep is.

I tested a kobold with darts and an elven bow.  But I also gave it
one elven arrow to provoke it into wielding the bow and my test
didn't throw darts with nothing wielded....
2019-08-02 10:42:26 -07:00
PatR
31c8038344 bad weapon check for monster multi-shot shooting
A typo caused the bow and arrow check when a monster was wielding an
elven box to test the hero's weapon with monster's ammo.  [I looked
at the old slash'em code where I think this came from and it doesn't
have the typo but does have a different bug.  A monster could get a
multi-shot volley by wielding an elven bow when throwing darts or
spears.  The extra bow and arrow check is intended to prevent that.
The typo was probably by me but I have no memory of that code....]

Elves with bows (or other monsters who manage to pick up and wield an
elven bow) will shoot bigger volleys after this fix.  That will make
them more dangerous but also cause them to run out of arrows more
quickly.
2019-07-31 14:22:09 -07:00
PatR
6dffe52a27 Glory of Arioch vs spellbook
From the newsgroup (reported for slash'em but applies to nethack too):
a chaotic monk was crowned and told he or she had been "chosen to
steal souls for My Glory!" while being given a spellbook of restore
ability which has nothing whatever to do with soul stealing.  There's
alternate wording for when Stormbringer can't be given because it
already exists; also use that for when it's not going to be given
because the character is discouraged against wielding weapons.
2019-07-30 17:24:33 -07:00
PatR
ed18ebc545 timer validations
Add the contributed code that checks for attempting to start a
duplicate timer.  It's based on a comment which must have been there
at least 25 years and doesn't solve any known problems, but it is
conceptually similar to the large amount of sanity checking which has
gone into 3.6.x.

It didn't work as is because it was comparing two unions with '=='.
I don't know offhand whether C++ supports that but C doesn't (through
C11 at least; don't know about C17).  The union ('anything') is simple
enough that two instances can be compared without jumping through hoops.

I've also added another check for timer 'kind' (level, object, monster,
or global).
2019-07-27 16:12:24 -07:00
PatR
bfbe4e71ce make #panic honor paranoid_confirmatin:quit
If 'paranoid_confirmation:quit' is set, require "yes" instead of 'y'
to execute the wizard mode #panic command.
2019-07-11 02:54:02 -07:00
PatR
188eedc654 curses: #extended command vs erase/kill chars
Support erase char and kill char when getting an extended command.

Also, show the cursor so that it's obvious where input focus is.
2019-07-11 01:02:34 -07:00
PatR
58583cacf8 hero-as-nymph: steal items vs steal gold
Nymphs won't steal gold from the hero (so that their steal-item damage
isn't a superset of lerprechaun's steal-gold damage; straightforward
back when gold wasn't kept in inventory), but hero poly'd into a nymph
would steal gold from monsters.
2019-07-10 17:56:33 -07:00
PatR
094a9d8161 fix github issue #204 - theft while in nymph form
Fixes #204

3.6.2's attempts to fix turning off SEDUCE in 'sysconf' introduced
an unintentional change in behavior for hero poly'd into nymph form:
theft attack always angered the target.  The actual change was
intentional but its ramifications were unexpected.
2019-07-10 16:15:11 -07:00
PatR
0e8163e341 curses: ncurses vs Ctrl+Click
Asking curses to report whether the Ctrl key was being pressed during
a mouse click was sending mouse position reports--even those aren't
being requested--and actual Ctrl+Left_click was reporting a pair of
duplicate Ctrl+Mouse_position_report events when a click was actually
performed.  So turn off Ctrl key reporting.

Mac with one-button mouse can be configured to send "secondary click"
for Ctrl+Click.  A laptop trackpad handles that differently (press the
button while two fingers are on the touchpad to send secondary click)
and doesn't support Ctrl+Click as an alternate way to do that.  If this
would work within curses then they could operate the same regardless
of how the user set the mouse or trackpad configuraiton.  But I wasn't
able to make it work right.
2019-07-09 18:55:10 -07:00
PatR
9eefeef5d2 fix github issue #200 - docs for 'strange object'
Fixes #200

The Guidebook claims that there's no symbol for 'S_strange_object'
which is literally true, but there is one for S_strange_obj.  It has
been in place longer than the paragraph claiming that there's no way
to customize that symbol.  I'm not sure why variant spelling was used.

Also, files.c doesn't use loadsyms[], it calls a routine which returns
a pointer to a specific element in that array.
2019-07-09 17:42:32 -07:00
PatR
77aa61a59b looking at a trapped monster
would describe it as trapped if you could see its location, but if
the trap was unseen that trap would remain unseen, at least in some
circumstances.  Mark the trap as seen.
2019-07-08 17:38:00 -07:00
PatR
cfca15d02c finding hidden monsters
Wizard mode ^E and any mode spell of detect unseen or wand of secret
door detection failed to find mon->mundetected monsters if they were
hiding under objects, and failed to find those or other hiders or
mimics when the hidden monster was at a trap location.  The fix for
the latter initially only worked if the trap was known, so took two
tries when a monster hid at the location of an unseen trap.  So this
makes the additional change to find both things at the same time; it
isn't manual searching that stops as soon as something is found.
2019-07-08 16:57:52 -07:00
PatR
ceb2d51426 ^X/disclosure of night, moon, Friday 13th
For ^X and final disclosure, report external issues that affect game
play:  midnight, other night, new or full moon, and Friday the 13th.

The 'new feature' entry in the fixes file rambles a bit but if it
heads off even one spurious bug report, it'll have been worth it.
2019-07-07 13:52:24 -07:00
PatR
bac3a75174 fix #H8164 - kicking altar: injury vs wrath
When kicking an altar, trigger divine wrath (minor: luck or alignment
loss) before deciding whether hero has hurt himself in the process.

Add some variation to the wrath penalty so that it can't be used to
precisely control Luck.
2019-07-06 18:14:30 -07:00
PatR
e84a0625dc curses moving left with ^H
Typing ^H actually passed a 16-bit value back to the core which got
interpreted as ^G after the extra bits were discarded.  I don't think
any previous changes to the curses interface caused this.  It's
astonishing that no one ever noticed; the world must be full of numpad
users.
2019-07-06 16:41:04 -07:00
PatR
79ff4cd9c3 fix github issue #202 - worn items inside engulfer
Fixes #202

When swallowed, you can take things from the engulfer's inventory, if
there are any, via pickup.  Items might be worn by the engulfer and
when "picked up" those weren't being unworn before being added to
hero's inventory.  Then they would be formatted as "(being worn)" and
could trigger warnings or worse.

Conceptually they should be worn on the outside and not be accessible
from the inside, so I've made attempts to pick up worn items fail
rather than fix up the unwearing.

Using ':' when swallowed to look at the engulfer's inventory describes
that inventory as "contents of <mon>'s stomach".  That's weird for any
worn items, but the situation is so rare I haven't made any attempt to
deal with it.
2019-07-03 18:30:55 -07:00
PatR
1e7fb839a3 status_hilite for Xp and Exp by percent rules
Extend support for highlight rules that specify percentages from HP
and spell power to experience level and experience points.  For both
of those, the percentage is based on progress from the start of the
current Xp level to the start of the next Xp level.  100% isn't
possible so is used to enable highlighting a special case:  1 point
shy of next level, most likely to occur after losing a level.

This is something I had in mind a long time ago and then forgot all
about until fiddling with the final disclosure of experience points
recently.  It turned out to be trickier than expected because it needs
to check whether Xp should have a status update when it hasn't changed
but Exp has gone up.  The latter might hit a percentage threshold that
switches to another highlight rule.  Fortunately changes to Exp, at
least that aren't part of level gain or loss (which always trigger
status updating), are all funnelled through a single place (I hope).
2019-07-02 17:39:23 -07:00
nhmall
1ac321eadc test and adjust for curses with msdos 2019-07-02 14:01:44 -04:00
PatR
8bb8d32625 tty status highlighting via attributes
Highlighting via attributes got broken three months ago.  May or
may not have been noticeable depending upon which attributes are
supported.  Too many variations of attribute designations...
2019-07-02 01:37:04 -07:00
PatR
18ae35ef39 curses message history vs dumplog message history
When I implemented getmsghistory()/putmsghistory() for curses I was
assuming that DUMPLOG would only be used with tty, but it is interface
neutral and can be used with curses (or others).  So curses message
history needs to behave like tty message history and be sure to pass
along messages that bypass pline() and the normal message window.
(Mainly one-line summaries of long quest messages, but also old
messages fetched from a save file and available to be re-saved without
having been shown if new session doesn't generate enough new messages
to flush them.)
2019-06-30 11:50:08 -07:00
PatR
93ddb5c6d8 attributes disclosure: experience points
Wizard mode shows the number of points needed to reach the next level
(unless already maxxed out at 30) for ^X and end of game disclosure.
Do it in normal play for the latter too.  (I think it would ok to do
that for ^X too but haven't gone that far.)

Even when it was wizard mode only, the phrasing for past tense had a
minor grammar bug, and it could make the line a little too long for
tty and curses (not sure about others) when level was high, resulting
in wrapped text.  That looked bad for tty, which first tries removing
indentation (just 1 space in this case), making that line outdented
as well as wrapped.  So change the phrasing slightly when experience
level is 'too high'.  I had a version which formatted, measured, and
re-formatted if necessary but that was overkill; simple hardcoded
rephrasing suffices particularly when measuring was against assumed
display width (80) rather than actual width.
2019-06-30 10:51:00 -07:00
PatR
8d0edeb4ff curses+EDIT_GETLIN again
Turns the "fix" in commit 319dcf4746
handled removing the default answer for single-line-prompt plus
multi-line-answer but not for multi-line-prompt plus long-enough-
answer-to-reach-another-line.  The logic wasn't quite right and I
misunderstood what is stored in linestarts[] so even correct logic
wouldn't have solved things.
2019-06-28 17:00:20 -07:00
PatR
7013563415 ^I vs perm_invent again
A recent fix for #wizidentify showing "Not carrying anything" after
listing inventory items still showed "Not carrying anything" after
"(all items are already identified)".  Fix is easy.

Trickier bug was that ^I performs object ID on selected items while
the inventory routine is still in progress (but after it has processed
every item) and the ID routine will call update_inventory() which
will call the inventory routine to reformat invent.  So the inventory
display routine was called recursively without having returned to
wizidentify where iflags.override_ID gets cleared to revert to normal
inventory.  The nested call was unintentionally narrowing the contents
of persistent inventory window to whatever items were still unIDed.
(Any inventory update, including ^R, restored it to full inventory.)
2019-06-28 12:50:08 -07:00
PatR
bed5570e3b curses popup single char input
With 'popup_dialog' On, a one line popup with question and likely
responses and default answer was shown, but without having the
cursor displayed at the end of emphasize that it was waiting for an
answer.  Make the popup be one character wider so that there is room
to show the cursor.  No effect when 'popup_dialog' is Off and prompts
are shown at the bottom of the message window; those already have the
cursor sitting at the end.
2019-06-28 12:28:40 -07:00
PatR
2145387ac8 curses menu and text window size
Make final inventory disclosure use a full width menu instead of
the default 38-column width with lots of wrapping.  Also, increase
that default from 38 to 40 for the rest of the time.  Commit
9f6588af49 made the 38 vs 40 portion
matter much less but I decided to keep it in anyway.

When a menu or 'things that are here' popup has only a couple of
lines and they happen to be narrow, a sized-to-fit window isn't
always easy to spot when it is shown over the ends of old messages
rather than over the map, even with a border box around it.  Give
such windows a minimum size of 5x25 so that they always stand out
enough to be immediately seen.  This will cause more message text to
be rewritten occasionally (after dismissing the menu or text window)
but the curses interface seems to discount that as something to be
concerned about.
2019-06-28 11:59:14 -07:00
PatR
119f0365f7 curses mouse_support bit for fixes36.3 2019-06-28 03:17:25 -07:00
PatR
80374d46b5 Merge 'curses-mouse_support' into NetHack-3.6
Fully support the mouse_support option for curses, via 'O' as well as
via config file.  At the moment, mouse_support:1 and mouse_support:2
are equivalent.

Also, fix the screen-to-map coordinate translation.  When the mouse
is active and over the map, the pointer's cursor becomes a cross-hair
(may very by platform) and the character cell chosen for a click
seems to be a few pixels to the right of the center of the '+'.
2019-06-28 03:08:30 -07:00
PatR
df8eac79b5 curses erase char and kill char
Support user's terminal settings for erase char and for kill char.
Erase char is typically <delete> or <backspace>, both of which are
already explicitly handled so probably no effect there.  Kill char
(generally ^U these days) will be honored unless it is a printable
character (don't know whether there are any troglodytes out there
who still use '@' for that...).  The current handling for ESC works
the same if there is any input to kill, but yields 'cancelled' when
there isn't.

That's for message window getline(), which operates char-by-char.
The popup getline() uses a curses routine to get an entire string
and already honors kill char but treats ESC as input of ^[.
2019-06-27 17:18:07 -07:00
PatR
aada9e2706 mouse_support for win/curses using ncurses 2019-06-26 15:46:44 -07:00
PatR
4f0b1262c5 curses clipped map 'scrollbars'
The position bars shown by curses when the map is clipped weren't
being drawn as intended (integer arithmetic).  Changing parentheses
was enough to get it working, but it didn't handle the edge case
where non-zero got rounded to 0 (so when map was panned down, the
uppermost character of the vertical position bar still showed '*',
falsely indicating that top of map was currently within view.
2019-06-25 03:17:47 -07:00
PatR
3bd46a3536 curses cursor
Followup to 1c03d0970115c776d1c4791fea3c33f70b0b5378; that had been
too easy.  When map was clipped and panned to the side, the highlight
for hero's spot was shown next to the '@' instead of on it.
2019-06-25 02:30:27 -07:00
PatR
6506f769a6 fix #H7840 - curses ':' menu search+toggle
Using ':' to have search string matching toggle items chosen for
selection would show selection highlighting on the current page for
items matched off-page.
2019-06-24 19:28:50 -07:00
PatR
8a9c06f5c1 'sortpack' vs 'perm_invent'
The persistent inventory window wasn't being updated if you toggled
the 'sortpack' option interactively.  (The new setting was honored
once something else triggered a 'perm_invent' update.)

The logic for toggling 'fixinv' seemed backwards.  I hope this "fix"
for that hasn't actually broken it.
2019-06-24 18:54:38 -07:00
PatR
e3af33c9db curses 'perm_invent' fixes
I noticed the wrapping issue while testing out the 'bad fruit' fix,
then the other things while fixing it.

1) inventory entries too wide for narrow persistent inventory window
   wrapped without any control; normally can't be seen except for the
   last entry when the list is short enough to leave at least one line
   available; it looked fairly reasonable with window borders Off, but
   when On the last char of the first line and first char of second
   line were clobbered by the border box;
2) when there were too many entries to fit within the height, those
   after the last one which fit were appended to it for borders Off
   (or written on bottom line and then overwritten by the border box
   for borders On); noticed because the selector letter is highlighted
   with inverse video, even when written at an unexpected place;
3) suppress the inverse video hightlighting of inventory letters since
   they can't be selected from that 'menu';
4) for borders Off, the top line was left blank as if a border was
   going to be drawn there;
5) since the entries are truncated due to the narrow window (on a
   modest sized display), strip off leading "a", "an", or "the" prefix
   for inventory entries (written to curses perm_invent window only);
   lets a couple more characters of more interesting stuff be seen.
2019-06-24 18:39:24 -07:00
PatR
cfc8599e69 fix "Bad fruit #N" warnings when saving bones
savebones() sets all the fruit indices negative, then resets to the
normal positive value for each fruit it actually writes into the bones
file.  But if 'perm_invent' is enabled and something triggers an
update_inventory() while bones saving is in progress, object formatting
for the inventory display won't be able to find any fruits, resulting
in impossible "Bad fruit #N".  Fix is to turn off 'perm_invent' when
the game ends, so it won't be On when bones are written.  Disclosure
uses a popup for inventory so persistent window is obsolete by then
anyway.

[I don't know what is triggering update_inventory() while savebones()
is executing.  Also, I don't see where the fruits whose index stayed
negative--because there aren't any on level being saved--get purged.
Maybe when those bones are loaded by another game?]
2019-06-24 15:11:51 -07:00
PatR
83410a3d4f \#wizidentify bug - 'Not carrying anything.'
when carrying things.  The fuzzer toggled on 'perm_invent' and after
interrupting it I used ^I.  Having 'perm_invent' enabled makes the
inventory code avoid having a totally empty inventory display (by
supplying "Not carrying anything" instead--in the menu rather than
via normal pline) so that interface code will see a change and know
that an update is needed.  But to decide whether the menu was empty,
the inventory code was testing union 'any' field 'a_char' to check
whether some item had used the union (implying that something had
been passed to add_menu()), but wizidentify (^I) uses field 'a_obj'
instead.  Apparently the a_char bits stayed 0 because the menu ended
up with "Not carrying anything" after a list of inventory items.
Switch to a separate variable to track whether anything has been put
into the menu instead of trying to rely on the union.

Unrelated but noticed when checking other "Not carrying anything"
instances, the #adjust command ends early when there's no inventory
but it was asking for a letter to adjust even when the only thing in
inventory was gold in '$' slot, which isn't allowed to be adjusted
away from that slot.  Treat gold-only like no-invent.
2019-06-23 11:31:21 -07:00
PatR
456996509b fix #H8922 - no "you finish eating" message
after being interrupted and then resuming.  Resuming a multi-turn
food when it only had one bite left was the culprit.
2019-06-22 13:03:50 -07:00
nhmall
eaa8c278c8 code in parse_conf_file() to trim trailing blanks/cr was missing them
Observed on a text file with crlf endings on Linux, where the
so-called blank lines weren't being ignored as they should
have been, despite there being a line to remove \r from the
end.

A pointer was being pre-decremented before the check for a
matching whitespace character.
2019-06-22 00:05:16 -04:00
PatR
2fe57af3f3 fix #H8833 - wishing for "<foo> amulet"
and receiving a random amulet instead of an "amulet of <foo>".
Although the failure to produce the 'right' amulet wasn't a regression
compared to earlier versions as the report indicated, supporting that
wish is straightforward.
2019-06-20 18:42:35 -07:00
PatR
2da552e22f fix #8924 - demonic bribery while hero is deaf
Even though it isn't using verbalize() to make a specific statement,
don't let a demon ask the hero for a bribe when the hero is deaf.

Also, give alternate setup messages in a couple of places where a
divine voice is overriding deafness.
2019-06-20 13:08:47 -07:00
PatR
72afb0d4f6 muse wand/horn feedback for monst zapping at self
Recent commit 5d59b288c9 changed monster
zapping a fire horn at self to cure sliming to not use the wand-zap
feedback routine, but inadvertently did for zaps of wands of fire too.
Use the zap routine for wand and play-instrument routine for horn.
2019-06-20 10:54:59 -07:00
PatR
8bfe6f82f1 Re-do the formatting for help on menu control keys
and add the non-configurable keys:  space, return, and escape.
2019-06-20 02:26:48 -07:00
PatR
9f6588af49 curses text windows
Most of the entries for '?' looked awful because curses was using
((terminal_width / 2) - 2) for the window width ('- 2' was to make
for for a border around the popup window, regardless of what the
'windowborder' option was set to).  Splitting text that has been
manually formatted for 80 columns "worked" but looked bad when not
required.

Some of the help files are using 79 characters on a few lines,
producing wrapped text when displayed.  Those would look better if
limited them to 78 or if curses can be modified to suppress the
window border when the entire display is being covered by a popup.
2019-06-20 01:14:50 -07:00
PatR
1c03d09701 curses map window
tty ignores map column #0 (0-based index), like the core, and draws
the map in screen columns 1 (1-based index) through 79, leaving screen
column 80 blank.  curses was drawing all 80 map columns and since #0
was always unused, screen column 1 was blank and the map was shown in
2 through 80.  Change curses to work like tty.

This was too easy; there may be problems lurking.  One known issue: it
should be made smarter about when clipping/panning is necessary since
it thinks that a full 80 columns are needed but 79 suffice.
2019-06-18 03:52:28 -07:00
PatR
820320ba55 EDIT_GETLIN when naming monsters and objects
Like #annotate, #name monster, #name individual object, and #name
object type are places where it makes some sense to have an existing
name be the default for the new name, in case taking off from the end
and/or adding to the end is more convenient than retyping everything.

When there is an existing name used as default, clearing that default
and hitting <return> is not enough to remove the name, you still need
to 'assign a new name' of <space> to do that.
2019-06-15 08:19:32 -07:00