Commit Graph

5010 Commits

Author SHA1 Message Date
PatR
a0c481c2f9 fixes entry for PR #1077 - #sit while flying
Pull request from Ardub23:  trigger a squeaky board trap if flying hero
uses #sit while over it.

Supersedes #1067
Closes #1077
2023-07-09 13:40:28 -07:00
PatR
7b32ce02ea fix github issue #1072 - pets pick up cursed items
Issue reported by vultur-cadens:  tame monsters capable of using items
would pick up cursed ones and even wear cursed armor.

The report cites commit 6c9700ab25 but
I don't see any reason why it would be the cause.  However, I was able
to reproduce the misbehavior and this commit seems to fix it.

Fixes #1072
2023-07-08 15:24:40 -07:00
PatR
8948ad0327 fixes entry for PR #1069
Pull request from vultur-cadens:  writing an unknown spellbook will
succeed if corresponding spell is well known (feasible via divine gift
in 3.7 or object amnesia in earlier versions).  When nearing the point
of fading from memory, Luck is still required but non-wizards only
need the much lower wizard amount.  If already forgotten, the chance
to write the book remains the same as if the spell wasn't known.

Closes #1069
2023-07-07 12:20:04 -07:00
PatR
78a2260830 fixes entry for PR #1057 - altars vs pits
Pull request from entrez:  pits created by breaking a wand of digging
or applying a drum of earthquake used to be able to destroy altars
but a change to prevent placing traps on 'furniture' unintentionally
caused that to stop working.

Closes #1057
2023-07-07 10:45:13 -07:00
PatR
b914f79c2f fixed entry for PR #1051 - water-vault escape item
Pull request from entrez:  when creating a detached theme room of type
"water-surrounded vault", make sure that one of the chests contains an
item that could be used to escape from the room in case hero arrives
via trap door or [level] teleportation.

Closes #1051
2023-07-07 09:50:57 -07:00
PatR
60a3263a85 fix github issue #1070 - Minetown achievement
Issue reported by vultur-cadens:  arriving on the Mine Town level
via falling or level teleport won't register the "entered Minetown"
achievement if hero doesn't arrive inside a room.

Reorder some code in check_special_room() so that town entry will be
tested before the early return if no room entry has occurred.  This
adds 'level.flags.has_town' to make the town test be cheaper when
the hero hasn't attained the achievement yet and is wandering around
the mines.

Fixes #1070
2023-07-06 13:18:19 -07:00
PatR
c360822c89 github PR #1052 - levltyp[] re-synchronization
Pull request from entrez:  the legend for wizard mode #terrain wasn't
updated to include terrain type "lava wall", so the entries for it
and everything that followed were inaccurate.

I've expanded the comment about level type codes in rm.h.

Closes #1052
2023-07-04 23:17:30 -07:00
PatR
8a3a5c0c9f fix PR #1034 - special level bullet proofing
Pull request from copperwater:  if a special level's lua file
specified invalid coordinates for some things, the code in sp_lev.c
might use them instead of rejecting them.  This could lead to severe
problems.  Presumeably the existing special levels aren't affected
by this.

Closes #1034
2023-07-04 16:23:53 -07:00
copperwater
2ae5ce8ab3 Fix and guard against out-of-bounds writes in splev code
I traced a memory corruption bug in xNetHack to a themed room that
looked something like this:

    function()
       des.room({ type="themed", contents = function()
          des.feature({ type='sink' })
          ...
       end })
    end

Placing a feature at a random spot within a room or region is a
reasonable thing for the parser to handle, but the code was not equipped
to handle it, and so the unspecified x and y set as -1 got passed
directly to SP_COORD_PACK, ending up as coordinates way off the map.
Since sel_set_feature does not do an isok() check, this ended up writing
data to unrelated memory.

This commit does the following things:

- Enables des.feature() with no coordinates specified, both via a table
  with 'type' set, and as the single string argument. When no
  coordinates are specified, it will pick a random normal-floor spot
  within the enclosing room or region if there is one, or anywhere
  on the level if there isn't.
- Prevents sel_set_feature from corrupting memory outside
  g.level.locations. Additionally, if EXTRA_SANITY_CHECKS is defined and
  this gets attempted, it causes an impossible.
- Guards the existing "door coord not ok" Lua error with an immediate
  return from lspo_door.
- Adds similar "coord not ok" errors to all the other locations in
  sp_lev.c which did not already check for a unspecified/invalid
  coordinate and for which a random coordinate is nonsensical:
  des.terrain(), des.drawbridge(), and des.mazewalk().
2023-07-04 16:19:27 -07:00
PatR
bd9ff5cda6 fixes entry for PR #1032 - des boolean 'trapped'
Pull request from copperwater: accept 'true' or 'false' (also 'yes'
or 'no') in des.object specification for 'trapped'.

After resolving a merge conflict one diff band of this went away, but
the settings of otmp->otrapped from o->trapped and otmp->greased from
o->greased without it look ok to me.

Closes #1032
2023-07-04 15:46:58 -07:00
PatR
34f91484fb fixes entry for PR #1031 - lua: subtract and xor
Pull request from copperwater:  selection subtract and selection xor
didn't work as intended.

Closes #1031
2023-07-04 14:55:45 -07:00
PatR
2d6d151b28 PR #1009 - higher statue trap difficulty
Pull request from NulCGT:  make statues created for statue traps be
5 to 10 points higher in difficulty than the default would be.

5 to 10 points of difficulty higher is already used for figurines.
The pull request chose the same amount but I've reduced it to 3 to 6.
Partly so that they won't be the same, partly so that they won't be
too hard when activated, and partly so that the creature won't be
quite as obvious a give away that the statue is a trap.

Closes #1009
2023-07-02 15:27:58 -07:00
PatR
5daec07300 PR #1008 - get doppelganger form from 'record'
Pull request from NulCGT:  when a doppelganger is choosing to become
a fake player, get role from an entry in the high scores file.  Use
that entry's name too if the doppelganger is within view at the time.

I'm not sure how well this will work for a single user score file if
the player always runs the same role and name.  I've given it a small
chance (1/13) to ignore the topten and stay with random role instead.

Closes #1008
2023-07-02 14:58:11 -07:00
nhmall
02343aa43b fixes entry for Windows setlocale issue 2023-07-01 09:34:56 -04:00
PatR
9212ae75f8 tentative fix for issue #1026 - Enhanced1
Issue reported by ostrosablin (and mentioned previously but I still
I haven't remembered where):  loading a roguesymset removes any utf8
data that has been set up for primary symset.  The curses interface
explicitly initializes roguesymset to the default set and if config
file has specified OPTIONS=symset:Enhanced1 (or some other uft8 set
if someone adds such), that stays the active set but no longer gets
rendered with the intended symbols.

I have no idea whether having symset and roguesymset both use uft8
with different symbols and/or colors works at all and if so whether
it will still work after this revision, but this prevents loading one
set with non-utf8 while the other still uses utf8 from clearing out
the cached utf8 data.

Closes #1026
2023-06-30 12:55:33 -07:00
PatR
ab0de251cd fix #K3938 - sleeping monster tamed by thrown food
Player reported that a cat which was asleep in a treasure zoo would
catch and eat thrown food, becoming tamed in the process, without
waking up.

Temporary sleep was handled (via checking for !mon->mcanmove) but
indefinite sleep wasn't.  Make a monster hit by taming effect (either
magic or thrown food) wake up from indefinite sleep.  For temporary
sleep, the remaining duration is cut in half.  The timeout isn't
dropped all the way to 0 because a monster with mon->mfrozen set
isn't necessarily asleep.  That timeout is shared by timed sleep,
timed paralysis, and busy time when donning armor.
2023-06-27 08:51:29 -07:00
PatR
6cef49ed54 Guidebook update; mostly paranoid_confirmation
add paranoid_confirmation:AutoAll
update paranoid_confirmation:pray (for paranoid_confirm:Confirm)
update paranoid_confirmation:swim (reorder, and on by default)

update menustyle:full (for paranoid_confirm:AutoAll)

Guidebook.tex is updated but not tested.
2023-06-25 15:51:41 -07:00
PatR
2f25ee734e paranoid_confirm:Autoall followup 2023-06-24 01:24:52 -07:00
PatR
cd9f145dba fix leaving the tutorial levels
While running the tutorial, the Save command is disabled.  When the
tutorial was extended to two levels, stashing and restoring the
hero's equipment stopped working as intended if player entered the
second level.  The attempted fix for that broke re-enabling Save
even if the player left the tutorial without entering its second
level.

This seems to fix things, but I'm flailing around with barely a clue
here.  A couple of simpler attempts didn't work and I haven't figured
out why, so this is a bit more complex than what I wanted.

Reorganizing nhl_callback() isn't part of the fix, just avoids use
of some redundant code.
2023-06-23 15:19:36 -07:00
PatR
8b9a93f797 stinking nemesis
Noticed when testing erodeproof Mitre of Holiness:  the cloud of
stinking gas released by Nalzok when he died ending up killing my pet
and my hero got blamed for that.  Don't blame--or credit--the hero for
monsters affected by the gas cloud when a dying nemesis produces such.
2023-06-17 14:15:49 -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
7d052bafb0 crystal armor bit
Accidentally left out of the "breaking crystal armor" commit
e9c58c2fe4.
2023-06-14 16:14:18 -07:00
PatR
450f060132 github issue #1060 - crystal helmet
Issue reported by vultur-cadens:  changing helm of brilliance to
crystal made it stop being classified as "hard helmet" so it gave
less protection against things falling onto the hero's head.

Change the is_metallic() tests used on helmets to new hard_helmet().
Unlike when thrown, crystal helmets don't break when objects fall
on them.

Fixes #1060
2023-06-14 06:13:11 -07:00
PatR
c4c31ae6a8 fix issue #1025 - stuck in Mines' End
Issue reported by AndrioCelos:  if you arrived at the Wine Cellar
variation of Mines' End by falling or by level teleportion instead
of via the stairs, you could end up in the treasure chamber.  If
you lacked a way to dig or to level teleport, you would be stuck.
Since most of that level is undiggable, it would likely fill up with
monsters before one that could dig would appear close enough to dig
to you and you'd eventually starve.

The initial report suggested including an escape item in the treasure
chamber.  This adds a teleport region to control hero's arrival spot
instead.  There was a suggestion fix things this way from copperwater
but I didn't notice that until I had already chosen this method....

Fixes #1025
2023-06-10 01:49:55 -07:00
PatR
0ca2af4d8b wizwish fountain and sink bookkeeping
Noticed while considering the pull request about loosening
restrictions on trap creation at furniture locations.  If you wish
for a terrain feature while on a fountain or sink, the counters
used to control whether sounds for those should be given will be
off by one.

It was incrementing the appropriate counter if you wished for a
fountain or sink, but it shouldn't do that if recreating the same
feature (perhaps to reset a magic fountain or looted sink) and it
needed to decrement when replacing either of those with some other
feature.  After the count became wrong, if all fountains or sinks
on the level were destroyed, those splashing, gurgling, &c sounds
would continue to be generated periodically.
2023-06-10 01:46:35 -07:00
PatR
e475dca209 add 'montelecontrol' option (wizard-mode only)
Add a new debugging option, 'montelecontrol', that allows a wizard-
mode player to choose a teleporting monster's destination.  If player
picks a bad spot, confirmation will be requested.  If accepted, the
spot will be used even though the consequences could be bad; that's
on the player.  If rejected, the destination will be assigned as if
no control had been attempted rather than try again.

The fuzzer isn't allowed to override a bad spot if it tries to pick
one.  That would probably trigger a sanity_check warning; the fuzzer
causes impossible warnings to behave as if panic, so accepting a bad
spot would just be fuzzer suicide.  It is allowed to randomly set the
option and maybe--though extremely unlikely--randomly pick a valid
controlled destination.
2023-06-09 00:56:53 -07:00
nhmall
43951d3ad8 fixes entries for two pull requests
also update submodule/pdcursesmod again
2023-06-05 00:51:37 -04:00
PatR
7e4be52a6c fix issue #1046 - unseen monster reading scroll
Reported by copperwater "on behalf of Maud":  when hero hears an
unseen monster read a not-yet-discovered scroll of create monster
and doesn't see any new monster appear, the player is given a chance
to call the scroll something.  When hearing an unseen monster read
a not-yet-discovered scroll of teleportation, the label is revealed
but no such 'call it' opportunity is offered, so the player could
deduce which of the two scroll types it was for either case.

Provide an opportunity to supply a 'called' name for scrolls of
teleportation when heard being read, same as with create monster.
Surprisingly complicated to achieve.

Eliminated a couple of goto's in the process.

Fixes #1046
2023-06-04 16:22:38 -07:00
PatR
2bbfed2183 fix github issue #1046 - tutorial anomalies
Reported by Noisytoot:  going from level tut-1 to tut-2 returned the
hero's starting equipment too soon, and exiting the tutorial from
tut-2 let the hero keep any equipment acquired within the tutorial.

Entering and leaving the tutorial was being handled by lua code in
the level description of tut-1 and adding a second level messed that
up.  I didn't see any way of handing that with level-specific lua
code so I made it become the core's responsibility.  gotolevel()
knows when the hero is moving from one dungeon branch to another so
it can recognize entry to or exit from the tutorial easily.

While fixing this, prevent #invoke of the Eye of the Aethiopica from
offering the tutorial as a candidate destination (was feasible if it
had been entered at start of game).

Not fixed:  levels visited in the tutorial become part of #overview.

Show location as "Tutorial:1" instead of "Dlvl:1" on status lines.
Only tested with tty; some interfaces handle location themselves and
may need their own fixup for this.

Fixes #1046
2023-06-03 16:39:12 -07:00
PatR
4e32364313 fix #K3934 - curses menu bug when entering count
Entering a multi-digit count when selecting from a menu in the curses
interface causes the menu to disappear.  Report was about putting a
large subset of an object stack into a container but the bug affected
all menus that accepted counts.

curses_get_count() was changed to call core's get_count() quite a
while back.  get_count() calls mark_synch() when more that one digit
is typed or when backspace to remove the first digit occurs.
curses_mark_synch() had been a no-op but more recently it was changed
to try to make sure that the screen was up to date.  But it did that
by refreshing the persistent windows, making any temporary popup menu
or text window become hidden.  Also, the count-in-progress is being
sent to the message window with the no-history flag, so refreshing
the message window removed that too.

Switch curses_mark_synch() to use the basic screen refresh call that
doesn't do anything window-specific.  This also changes menu count
handling to have get_count() echo the number starting with the first
digit instead of waiting until the second.

If anything in the menu makes it be very wide it can cover up the
message window and any count being echoed there won't be visible.
I'm not going to try to figure out how to deal with that; it isn't
all that different from the old single-digit/unseen-count behavior.
2023-06-02 11:42:18 -07:00
nhmall
579622c577 fixes entry for pull request 1028
Closes #1028
2023-05-29 22:44:46 -04:00
PatR
17d867d084 fix github issue #1038 - vampshifted Vlad in bones
Reported by vultur-cadens:  if Vlad made it to a level which allowed
bones and was in wolf or bat or cloud form when the hero died, he
would not be excluded from the bones file as intended.  When those
bones got loaded in another game, Vlad would become flagged as
extinct.  If that happened before his own level was reached, he
wouldn't be created when hero arrived thus there would be no way to
acquire the Candelabrum of Invocation.  (Even if his vampshifted
form had been carrying it, it wouldn't be present in the bones data
because it would have been converted into candles.)

Fixes #1038
2023-05-28 15:17:51 -07:00
PatR
5cd7f1823c feedback when seeing hider-under hide under
If an monster hides under and object or under water while in view,
say so.

Also, the sanity check for a hidden eel wasn't consistent with the
hiding criteria for it.  An eel can't hide on the Plane of Water even
when it's in the water rather than in an air bubble.
2023-05-27 08:52:45 -07:00
PatR
b6a5be8d77 fix #K3922 - magic whistle vs hidden pet
When a hidden pet was relocated via magic whistle, a message was given
about "your <pet> appears" but it didn't show up on the map.

It was being marked as no longer undetected, but that was after rloc()
had moved it and redrawn its location.  use_magic_whistle() needed to
redraw its location again after clearing monst->mundetected.
2023-05-27 08:47:26 -07:00
PatR
aa63aa8d98 issue #1027 - sticky 'nofollowers' flag
Reported by copperwater:  entering the tutorial sets 'u.nofollowers',
changing to the tutorial level saves a copy of 'u', post-level change
from entering the tutorial level resets u.followers, but subsequently
changing levels to return to the original level 1 restores 'u' from
the saved copy with has 'u.nofollowers==True', overriding the reset.

Move the nofollowers flag from 'u' to 'iflags'.  Invalides save and
bones files.

Fixes #1027
2023-05-25 17:08:53 -07:00
PatR
42356daec0 pull request #1024 - keep hero movement points
Pull request from saltwaterterrapin:  record current move's pending
movement points in save file.  They were being thrown away during
save and hero given 12 at time of restore.  Hero had to have had at
least 12 in order for player to issue the S command, but might have
had more than that if able to move faster than normal speed.

This implements it differently from the suggested commit.  Add new
field umovement to 'struct u' instead of using youmonst.movement and
needing to save and restore that separately.

Invalidates existing save and bones files.

Closes #1024
2023-05-24 11:16:23 -07:00
PatR
8385d0a10e fixes entry for PR #1037 - use-after-free
when applying an object.

Pull request form copperwater:  applying a cream pie always uses it up
and applying a lump of royal jelly sometimes uses it up, then after
that use the apply got checked for a talking artifact.  If it had been
used up when the apply routine would access memory which had already
been freed.

Closes #1037
2023-05-23 15:03:03 -07:00
PatR
1f8b3dfef5 ^P vs sanity_check
Normally when sanity_check is enabled it will take place for every
command executed.  Avoid that when the command is ^P because if a
sanity warning is a recurring one and the msg_window setting is
single or combination (tty-only) which shows one message, ^P will
just repeat each new warning without having any chance to cycle back
to earlier messages.
2023-05-22 00:32:25 -07:00
PatR
92a993a0b6 fix github issue #1029 - erroneous death feedback
for monsters that haven't died, when being removed from play to keep
them out of bones.

Reported by copperwater:  if the quest nemesis was present on a level
being saved as bones, it was removed from the map to keep it out of
the bones level but the quest feedback for nemesis death was given
in the process.  Would happen for blessed genocide of "*" too.  (It
didn't happen for #wizmakemap and I'm not sure why.)

This was an unintended side-effect of moving some common stuff from
mondead() and mongone() into m_detach().  The quest feedback isn't
actually common to both.  Instead of moving that back, pass a flag
that m_detach() can use to determine which routine called it.

Fixes #1029
2023-05-20 16:44:18 -07:00
PatR
9052bd5099 fix #K3925 - u.ustuck of long worm tail
Don't allow stick/wrap/engulf attacks directed at long worm tails
to succeed.  Achieved by making sure that 'notonhead' is up do date
in a bunch of places and utilizing the fairly recent can't-{stick,wrap,
engulf}-unsolid-monsters code.

Should prevent a 'sanity_check' warning about being too far from
u.ustuck that would happen when holding the tail while the head was
not adjacent to the hero.

Also don't let pet ranged attacks from choosing a long worm's tail
as target.  They'll still be able to target long worms provided that
the head is lined up and not shielded by tail segment(s).
2023-05-20 15:34:32 -07:00
PatR
f176318c45 covetous fixe(es)
Extracted from a larger pending commit.  While trying to make sure
that bhitpos and notonhead are up to date when attacks are processed,
I noticed that covetous monster handling was buggy.  For dist2(),
a value of 1 means adjacent in an orthogonal direction, so testing
for less than 2 unintentionally excluded diagonal adjacency.
2023-05-20 15:26:36 -07:00
PatR
49e93760a8 collect_coords() revisited
Make recently added collect_coords() global even though it is still
only being used in teleport.c.

Add CC_SKIP_INACCS flag to only collect accessible locations so that
there's no need for a custom filter callback or of collecting spots
that will always be rejected when put to use.  Caller needs to check
Passes_walls/passes_walls() to decide whether that is suitable.

Merge some of the old safe_teleds() with the new, making it try
randomly 40 times before collecting coordinates for an exhaustive
selection.  Prior to the recent change which added collect_coords()
it was trying 400 times and giving up if that didn't find a good spot.

Start using collect_coords() for rloc() as well as for safe_teleds().
Only try to pick a spot randomly 50 times now instead of 1000.  If
those all fail, it does an exhaustive search of a randomized list of
candidates instead of old left-to-right, top-to-bottom map traversal.
Has not had nearly as much testing as safe_teleds() underwent.

rloc() was explicilty ignoring map column 1 for some reason.  Unlike
reserved column 0, column 1 is part of every level and should be
considered for monster teleport destination even though most levels
don't utilize it.
2023-05-17 00:33:54 -07:00
nhmall
ec9d3cb88e keep external identifiers under 31 characters length 2023-05-13 13:49:57 -04:00
Pasi Kallinen
f4f74b2e07 Purple worm burp wakes up monsters 2023-05-12 09:17:09 +03:00
Pasi Kallinen
91257e00c7 Werewolf howling wakes up monsters 2023-05-11 18:48:02 +03:00
PatR
92ca5dbf71 describe monster's size for stethoscope/probing
Monster size affects knockback but it wasn't provided anywhere within
the game.  Have wand of probing and stethscope feedback for monsters
include tiny|small|medium|large|huge|gigantic as applicable.
2023-05-10 02:23:57 -07:00
PatR
3f4634211f fix #K3918 - statue-to-boulder polymorph in water
'sanity_check' complains if it finds a boulder in water or lava.
Polymorphig a statue usually produces another statue but might
produce a boulder.  If done it water, keeping the boulder intact
would trigger the sanity warning.  Break it into rocks if object
polymorph produces a boulder at water or lava location.
2023-05-08 02:07:31 -07:00
nhmall
2de3409113 Guidebook change follow-up 2023-05-07 07:38:22 -04:00
nhmall
2986d03adc Guidebook fix 2023-05-07 07:33:18 -04:00
PatR
01df119ae6 Guidebook.tex catchup
Add Guidebook.mn's recent #genocided changes to Guidebook.tex.
Not tested.
2023-05-07 01:22:43 -07:00