Commit Graph

15274 Commits

Author SHA1 Message Date
PatR
925ebf6ea1 fix #K3924 - teleport as giant eel
The safe_teleds() change that restored picking random destination
attempts prior to making an exhaustive search contained a typo tjat
accidentally only accepted invalid positions instead of valid ones.
So unless it randomly picked 40 good spots, erroneously rejecting
all of them and then falling back to the try-everywhere situation
(which has its own testing without any typo), it would yield strange
results by placing the hero in walls or solid rock via choosing the
first inappropriate spot it tried.

Not part of that bug but related, sort of:  for rloc(), use
rloc_pos_ok() instead of goodpos() during the exhaustive search as
well as during the random tries, but hang on to the first (after
randomization) position that passes goodpos() for a last resort.

The collect_coords() flag for 'skip-inaccessible' intended to be a
quick way to filter out walls and solid rock was using !ACCESSIBLE()
which also rejects water and lava locations.  So such spots wouldn't
be picked by either safe_teleds() or rloc() when they were finding
a spot for aquatic or lava-tolerant forms.  Instead of duplicating
a bunch of code to decide whether the hero's current form or the
teleporting monster should avoid !ACCESSIBLE() for a reason other
than having Passes_walls, make collect_coords(CC_SKIP_INACCS) use
!ZAP_POS() which rejects walls and rock but allows pools.
2023-05-17 18:51:28 -07:00
nhmall
75e8e06dee commit 02a48aa8 split of g fixup 2023-05-17 21:17:35 -04: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
d7f581d8ad fix compiler complaint
a check for baselen being less than or equal to zero drew a compiler
complaint because the variable is unsigned
2023-05-15 23:14:26 -04:00
nhmall
420048b8d3 keep external identifiers under length of 31 char 2023-05-15 23:11:34 -04:00
PatR
59677e7440 rewrite safe_teleds()
The teleport to safety routine would try to find a viable spot 400
times, the first 200 rejecting trap locations and the last 200
accepting such.  While testing various escape from lava variations
recently, I noticed that I could fail to reach safety even when there
was an open spot immediately adjacent to me.  I added a BandAid(tm)
to make another 400 tries if the first attempt failed, but that was
clumsy and still didn't guarantee picking a viable spot.

This adds a new routine, collect_coords(), which will gather a list
of coordinates for the entire map.  safe_teleds() goes through them
one by one until either finding a spot or exhausting the possibilies,
without randomly trying and retrying the same spot multiple times and
without missing other potential spots, also without just scanning the
map from left to right and top to bottom or similar.

Various other things which retry over and over, and especially the
ones which make a bunch of random attempts and then fallback to trying
every spot on the map, could be switched over to this, at least for
the falling back phase.  Right now collect_coords() is local to
teleport.c but that could be easily changed.

The try-at-random method is much quicker when there are lots of
available spots but the gather-shuffled-candidates method is
guaranteed to succeed if success is possible.  The way safe_teleds()
is presently using it collects the list with all locations within
2 steps first, then those within 3 to 4, then 5 to 6, and so on out,
randomized within each block of ranges.  So the destination will be
within one step of being as close to the starting spot as possible
but not always immediately adjacent when that happens to be available.
2023-05-15 01:42:13 -07:00
PatR
2646688e2d back_on_ground()
Replace a couple of hardcoded "back on solid ground" messages with
something more versatile.

Also, make life-saving handling for failed rescue from drowning
similar to that of failed rescue immolation by lava.  If there are
any cases where more than two tries is needed, they elude me.  The
new code doesn't confer temporary water walking if emergency teleport
fails; perhaps it should.
2023-05-15 01:08:04 -07:00
nhmall
b4f3a0fac2 submodule update 2023-05-14 07:49:19 -04:00
PatR
910868cba8 revise m_at()
Get rid of some unnecessary code when ignoring unimplemented buried
monsters.  A smart compiler probably optimizes away the useless bits
even when not explicitly optimizing but a dumb one isn't likely to.

m_at(x,y) was
|  (levl.monsters[x][y] != 0
|   && (levl.monsters[x][y] ? levl.monsters[x][y] : 0))
when
|  levl.monsters[x][y]
accomplishes the same thing.
2023-05-14 03:03:04 -07:00
PatR
1851c7ca88 update Medusa's data.base entry
The second paragraph about Medusa is an excerpt from Bulfinch's
Mythology, but first paragraph is not.  Insert an empty attribution
line between them.  Also, remove the reference to Graeae from the
introduction since it contradicts Bulfinch, which describes them as
"three sisters who were gray-haired from their birth" and Gorgons as
"monstrous females with huge teeth, brazen claws, and snaky hair".
2023-05-13 11:23:49 -07:00
nhmall
ec9d3cb88e keep external identifiers under 31 characters length 2023-05-13 13:49:57 -04:00
Pasi Kallinen
a54b6ba75c Split object init out of mksobj
Move the random erosions in there, as those should only be done if
the object is getting a random initialization.
2023-05-13 12:12:36 +03:00
nhmall
7ef93ba86a Revert "In file included from ../win/X11/winX.c:42:"
This reverts commit e70310c67b.
2023-05-12 17:47:40 -04:00
Pasi Kallinen
f4f74b2e07 Purple worm burp wakes up monsters 2023-05-12 09:17:09 +03:00
nhmall
68e76e0d88 Revert "add stddef.h include to cstd.h"
This reverts commit 55791c5668.
2023-05-11 23:44:40 -04:00
nhmall
55791c5668 add stddef.h include to cstd.h 2023-05-11 23:32:22 -04:00
nhmall
e70310c67b In file included from ../win/X11/winX.c:42:
In file included from /opt/X11/include/X11/Xos.h:146:
/opt/X11/include/X11/Xarch.h:44:13: fatal error: 'sys/byteorder.h' file not found
            ^~~~~~~~~~~~~~~~~
1 error generated.
make[1]: *** [winX.o] Error 1

Xarch.h has an #ifdef SVR4 block.
2023-05-11 23:26:08 -04:00
PatR
7737fcc97c fix out of date safe_teleds() calls
When safe_teleds() was changed to take an int flags argument instead
of a boolean, some calls weren't updated.
2023-05-11 12:12:12 -07:00
PatR
56f0340f0c fix #K3920 - migrating mimicker sanity
Report says that Wizard of Yendor posing as some other monster
triggers a sanity_check warning if on the migrating_mons list and
hero has Protection_from_shape_changers attribute.  My attmpts to
reproduce that failed, but this updates the mon_sanity checking to
explicitly allow a monster posing as another monster to be on the
migrating monsters list.

This also adds checks for whether a monster on the fmon list has
MON_MIGRATING or MON_LIMBO or MON_DETACH bits set in monst->mstate
and whether a monster on the migrating_mons list has MON_DETACH set
or both MON_MIGRATING and MON_LIMBO clear.  I won't be surprised if
these new checks trigger sanity complaints.
2023-05-11 11:51:57 -07:00
Pasi Kallinen
91257e00c7 Werewolf howling wakes up monsters 2023-05-11 18:48:02 +03:00
Pasi Kallinen
8c8acee423 Fix hero trapped in nonexistent pit
If hero was trapped in a pit, and a monster threw a boulder
at that location, the boulder filled the pit but hero was still
trapped in it.
2023-05-11 16:00:57 +03:00
Alex Smith
fcb86ad709 Fix "while helpless" showing up for some characters who weren't helpless
If the game ended while the player was in the middle of a repeated
command (that was not cancelled), this would spuriously cause a
"while helpless" to appear in the death message and logfile entry.
This bug is hard to observe because most things that can kill the
character also cause repeated commands to stop repeating, but is
easy to reproduce by command-repeating the #offer command that's
used to ascend (as "n20#offer" or "20#offer" depending on the
control scheme): doing so produced "ascended, while helpless"
prior to this patch.
2023-05-11 01:43:06 +01:00
PatR
65debc1adb incorporate 3.6.7+ build fix for VMS
Make sure CLR_MAX is defined when winprocs.h uses it.
sys/vms/vmsmail.c uses wintypes.h and winprocs.h without hack.h;
a change in 3.6.3 broke that but wasn't noticed until now.

I haven't added a fixes entry since we don't know whether 3.7.x
will eventually be buildable on VMS.
2023-05-10 12:47:42 -07:00
Pasi Kallinen
81884a92e0 Don't show error when monster in lava cannot tele away
... due to the level being full of monsters.
2023-05-10 18:43:35 +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
Pasi Kallinen
ead2f94d6e Fix genetic engineer poly hit killing the defender
The polymorph hit can kill the monster, but this info wasn't
propagated back.  If the defending dead monster retaliated,
the game issued an impossible.
2023-05-10 09:34:28 +03:00
PatR
845e813e86 fuzzer vs repeat deaths, take IV
A limit of 20 deaths on the same move before having the fuzzer give up
was not enough.  Bump that to 100.  No effect at all on normal play.
2023-05-09 22:38:53 -07:00
PatR
dd7d7f2eae fuzzer vs lava, take III
Change dying in lava to attempt life-saving at most twice.  The first
time might be via amulet or via declining to die.  The second time
can only be via declining to die after failing to teleport to safety
the first time, but could happen in explore mode as well as in wizard
mode, either interactive or fuzzer.

If the hero dies twice without ending the game, confer temporary fire
resistance and water walking so that other actions can be attempted.
After 5 turns without getting away from the lava or doing something
to acquire those capabilities, the hero will be subject to falling in
again.

Then the whole cycle might repeat, even many times, but the fuzzer
will eventually choose ^V or #wizmakemap and escape.  Players in
explore mode will either figure out a way to get out of it or
eventually have to give up but can try as many times as they like,
not that much different than being cornered by a deadly monster.
2023-05-08 15:21:03 -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
PatR
210387c176 break fuzzer out of life-save loop, take II
When being burned up by lava, die 20 times before giving up the
attempt at life-saving (was unlimited).  Giving up leads to the hero
standing on lava rather than dying.  Normally moveloop() dunks the
hero again on next turn but fuzzer life-saving now has a chance to
confer temporary fire resistance.  So hero might have an opportunity
to level teleport or use ranged attacks that free up spots so have
somewhere available to teleport to safety if/when dunked again.

The recent code to give up on trying to resurrect the dying hero
after 15 deaths on the same move is extended to 20.  They apply to
each of the 20 lava resurrect attempts but still doesn't guarantee
that the hero will eventually get free before done() gives up.
2023-05-08 01:35:21 -07:00
Pasi Kallinen
9ca1c5fb56 Fix dmonsfree warning caused by knockback
When a monster being attacked was knocked back into a level
teleport trap, the attacker could still hit the defender.
If the second hit then killed the defender, this could result
in dmonsfree warning.
2023-05-07 22:12:56 +03:00
Pasi Kallinen
3ffb69bf2f Fix another "no monster to remove" impossible
Pet ranged attack code was using the same variable for
both pet attacking a monster and then the monster's possible
retaliation attack. The retaliation obviously overwrote the
pet attack return code, allowing pet to move afterwards.
In certain case this could result in "no monster to remove"
warning.
2023-05-07 22:12:56 +03: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
nhmall
afca423f06 build fix 2023-05-07 07:20:11 -04:00
Pasi Kallinen
e18548c821 Fix knockback impossible
When monster attacked another monster, and the retaliation attack
knocked back the attacking monster, the variables holding the
attacking monster coordinates were out of sync and caused
"no monster to remove" warning.

Propagate back the knockback hit, so the current monster cannot
do anything further.
2023-05-07 12:57:09 +03: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
PatR
b4b251b618 temporary blindness vs permanent blindness
While testing the fix for unicorn horn vs blindness, I noticed that
when 'blind from birth' (OPTIONS=blind) you would get "your vision
seems to dim for a moment but is normal now" when timed blindness
was added to persistent blindness.  That happened for both 3.6.x and
to-be-3.7.  Change it "you have a strange feeling for a moment".

In 3.7, having temporary blindness timeout while permanently blind
produced "your vision seems to brighten for a moment but is normal
now".  Change that to strange feeling too.  For some reason I haven't
tried to figure out, 3.6.x stayed silent when this took place.
2023-05-07 01:03:29 -07:00
PatR
76fbca7d25 fix github issue #1020 - unicorn horn vs blindness
Reported by argrath:  the test for whether blindness could be fixed
by applying a unicorn horn got broken by the recent change to the
Blinded macro.

While in there, undefine macros once they stop being useful.  I put
these #undef lines closer to their #define instead of at end of file.

Also, remove an out of date comment about encoding property troubles.
It became obsolete when unicorn horn stop fixing lost Str, Dex, &c.

Fixes #1020
2023-05-07 00:37:51 -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
5023e4bfad Fix tame soldier being angry
Wizard-mode created tame soldier got angry when another
soldier played a bugle.
2023-05-06 23:12:59 +03:00
Pasi Kallinen
fe3dcb4416 Genetic engineer uses up turn when polying a monster
The fuzzer encountered a "no monster to remove" impossible,
this should fix it, even though I did not manage to reproduce
it manually.
2023-05-06 20:16:28 +03:00
Pasi Kallinen
d036116dee Fix hiding under nonexistent obj
Zapping a wand of teleportation at a location with object and
a monster hiding under it, but with the level full of monsters,
the monster would stay hidden even when the object was moved.
2023-05-06 20:13:10 +03:00
PatR
6de996971b fix #K3915 - "deleting worn obj" warning
Knocking a monster into lava triggering impossible warnig "deleting
worn object" for a wooden shield.  The monster had to be wearning
flammable armor and be fire resistant to survive instead dying and
dropping inventory, and it couldn't be a creature that can survive at
lava locations like a salamander and the armor needed to already be
thoroughly burnt.

It wasn't hard to figure out what needed to be fixed, but it was very
hard to reproduce the situation in order to verify that fix.  The
report was for monster vs monster knockback but I jousted with a lance
instead.  I still don't understand why burning up a worn wooden shield
triggered the warning but burning up a worn orcish cloak did not.
2023-05-06 00:08:35 -07:00
PatR
41c8a18d3d hurtling monster bumping into hero
Typo/thinko resulted in passing wrong monster variable to x_monnam().
2023-05-05 17:50:57 -07:00
PatR
e28d15f491 endgame portal fix
A recent change to prevent creating webs at water locations also
deliberately prevented them at air locations but had the unintended
side-effect of preventing creation of magic portals on the Planes
or Air and Water.  Those two levels always place the portal in air.
Explicitly allow air if the trap being created is a magic portal.
2023-05-05 17:42:57 -07:00
PatR
180042434e more engraving sanity feedback
Delete engravings made in a breach of a shop's wall or of a vault's
wall or in the guard's temporary corridor when the wall is repaired
or the corridor removed.  If 'sanity_check' was On, those would
trigger impossible warning "engraving sanity: illegal surface (x)"
where x was the terrain type code for solid rock or relevant walls.

Adding del_engr_at() calls to the shop code was straightforward.
The vault code is very complicated and I'm not sure that all the
calls I added were actually necessary.
2023-05-04 06:02:23 -07:00
PatR
c0441126b8 fix #K3912 - engraving sanity: closed doors
Engraving in an empty doorway and then using locking magic to create
a door there resulted in an impossible warning: "engraving sanity:
illegal surface (23)" if the 'sanity_check' option was On (wizard
mode only).  Engraving in an open doorway and then simply closing
the existing door produced the same effect.

Accept engravings at closed doors.  Presumably hero will be using
Passes_walls to attempt that so treat closed doors same as open ones.
Update the engraving sanity check to deal with that.

Bonus fix: engraving sanity checking stopped after the first problem
instead of checking every engraving.  Have it continue instead.

Not fixed:  vault wall repair and temporary corridor removal does
not delete engravings and can trigger the illegal surface warning if
player engraves before the repairs.  I didn't test shop wall repair
but it doesn't have any engr references so probably has the same bug.
2023-05-03 14:29:03 -07:00
PatR
53adba6602 maybe fix #K3909 - hurtled monster detached twice
I haven't forced a test case to verify this, but the logic for
calling mliquid() at the end of mhurtle() was clearly wrong.

Also, implement missing case of one monster causing another to
hurtle and hit the hero.  Compiles but is otherwise untested.
2023-05-03 12:18:15 -07:00
nhmall
a687e75e9b WIN32 file name normalization 2023-05-03 12:31:15 -04:00