Commit Graph

318 Commits

Author SHA1 Message Date
nhmall
d3acd8aa07 Merge branch 'ice-running' of https://github.com/copperwater/NetHack into several-pr 2021-09-26 08:54:47 -04:00
nhmall
026aec1086 Merge branch 'fix-travel' of https://github.com/entrez/NetHack into several-pr 2021-09-26 08:54:10 -04:00
Pasi Kallinen
12800bf84b Walking near buried zombifying corpses wakes them up
Moving without stealth will reduce the zombifying timeout
of buried corpses under and around hero's location.
2021-09-18 21:24:52 +03:00
copperwater
5b0c2033f7 Fix: running on ice sent hero in weird directions
This is because ice was being treated as a type of corridor rather than
a ROOM space, and running has rules for following similar terrain. In
reality it's not a corridor and should behave like normal room for
running purposes.

This was obvious in the valkyrie quest upper levels with ice fields, in
which running into the edges of the map obliquely, or into the corners
of the map, would send the hero flying around the edge in a different,
probably unintended direction.
2021-09-07 15:17:33 -04:00
Pasi Kallinen
2748ac746e lookaround comments
trying to figure this out
2021-08-12 19:38:29 +03:00
Michael Meyer
38d027d1f9 Fix: travel from 'interesting' position
(including resuming travel after being interrupted)

Attempting to travel from an 'interesting' spot that would normally
stop travel mid-attempt (next to a door, next to a monster, etc) would
fail to get off the ground, because the 'interesting thing' would halt
travel before taking the first step.

Prior to 433f0cc, initiating travel would immediately trigger a call to
domove in rhack; as part of refactoring travel, the order of events in
rhack was changed so that this didn't happen immediately as before.  Add
domove to the end of dotravel_target to produce a similar effect to the
previous arrangement.

domove also zeroes out g.domove_attempting, which I think is the reason
c0c617c seemed to mitigate some of the issues associated with this
problem (e.g. travel target selection seemingly not registering right
away).

Fixes #559
2021-08-11 09:19:56 -04:00
Pasi Kallinen
7a9dd64cb5 Use mon_visible 2021-08-09 19:16:36 +03:00
PatR
e5f96cd329 diagonal movement glitch
|..X..
|.X}X.
|..X..
When testing the odd Samuari moats, I discovered that you could
easily walk diagonally between any two of the solid stone pillars
and fall into the water but you would always drown because it's a
no-teleport level and the crawl routine wouldn't let you back out
via that same diagonal.

The crawl routine is also being used by travel for the last step--a
post 3.6 change--so there was an unnecessary restriction on diagonal
movement there too.
2021-08-02 17:44:03 -07:00
Pasi Kallinen
c0c617c413 Try fixing interrupted travel oddities
My earlier commit (433f0cc) changed traveling, and caused some
strange problems when travel was interrupted. This seems to
fix those problems.
2021-07-29 21:21:28 +03:00
Pasi Kallinen
f25a6e26ee Use enums and defines for directions 2021-06-27 15:46:56 +03:00
Pasi Kallinen
76f77ee0cc Add assistance to fire-command
Allows the fire-command to autowield a launcher; it will now
do either swapweapon or wield an appropriate launcher, if you
have ammo quivered.

This assistance can be turned off with the fireassist boolean option.

Adds a rudimentary command queue, which allows the code to add keys
or extended commands into the queue, and they're executed as if
the user did them.  Time passes normally when doing the queue,
and the queue will get cleared if hero is interrupted.
2021-06-16 13:14:32 +03:00
nhmall
254c6c55f5 Windows build warning and Makefile update
.\hack.c(2657): warning C4389: '!=': signed/unsigned mismatch
Visual Studio autodetection update for Makefile.msc
2021-06-04 00:14:37 -04:00
Pasi Kallinen
6b60618e0e Exploding spheres cause real explosions
Despite active explosion attacks being called explosions in-game,
they only affected a single target, and were handled differently
from actual explosions. Make them do an actual explosion instead.
This should make spheres more interesting and inspire different
tactics handling them.

Because spheres deal more damage on average and can destroy items
in their explosions, their difficulty has been increased slightly.

Polyselfed hero exploding won't cause elemental damage to their
own gear.

Originally from xNetHack by copperwater <aosdict@gmail.com>.
2021-05-22 13:37:39 +03:00
Pasi Kallinen
9fa9f00f8a Entering special room, wake up only that room
... instead of doing a level-wide wake-up.

Fixes #429
2021-05-05 20:34:05 +03:00
PatR
b4ae19ed0c fix "Killed by foo, while paralyzed by a monster"
If the killer and the paralyzer are the same monster, truncate
that to "Killed by a foo, while paralyzed".  When not the same,
spell out the paralyzer's monster type instead of using generic
"monster".  "Killed by a fox, while paralyzed by a ghoul", or
"Killed by a ghoul, while paralyzed by a ghoul" *if* they were
two different ghouls.
2021-04-22 16:13:41 -07:00
PatR
8bd08ebb71 level teleporters vs Ft.Ludios
From newsgroup discussion where slash'em changes have revealed a
latent nethack bug:  prevent placing level teleporters in single-
level branches.  The Knox level doesn't have any level teleporters
(or random traps) but wizard mode wishing could create them there.
They wouldn't do anything because the only possible destination
would be the same level.  Pushing a boulder onto one used to trigger
an infinite loop (and still does in slash'em, which has other
single-level branches besides Ft.Ludios) trying to relocate it.

Boulder pushing was changed 15 years ago to prevent the infinite
loop and to avoid giving "the boulder disappears" message when a
level teleporter failed, but rolling boulder traversal lacked that
same change--it wasn't vulnerable to looping but could give an
inaccurate message claiming that the boulder disappeared when it
actually didn't.  Fixing this is a bit late; rolling boulder trap
creation was recently changed to not choose a path that rolls over
teleportation or level tele traps any more.
2021-04-12 13:25:52 -07:00
PatR
7d77267f93 fix pull request #487 - one-step diagonal travel
When travel destination is one step away the code stops probing
for a path and reverts to normal movement, but it wasn't handling
the case where the one step was an impossible diagonal except for
hero being a grid bug.  If the situation was a diagonal that's
too narrow to squeeze through, travel would end and regular move
would fail.

I've rejected the suggested fix and done it differently, without
attempting to figure out why the change to end_running() would
have been wrong.  Clearly it was code that called end_running()
which needed to be fixed.

The test case was
 ..x|.
 ..|@.
 .....
while carrying enough that directly moving from '@' to 'x' will
not be allowed.  '@' would move one step south west and then stop
because findtravelpath() had ended travel due to single step move.
A similar case is
   ###
  |x-#-
  |0@.|
where 'x' is a doorway with intact open door and '0' is a boulder.
Prior to this fix, player would get "a boulder blocks the way" and
not move.  After, '@' will move northeast then northwest then west
to get into orthogonal position and finally south into the doorway.

Even though it definitely fixes both mentioned test cases, I won't
be surprised if this results in regressions for other situations.

Fixes #487
2021-04-04 17:23:46 -07:00
PatR
1e9fc3ddb3 pull request #465 - explding hero waking monsters
A polymorphed hero who exploded when attacking thin air would use a
radius based on experience level rather than the fixed radius that
the monster form itself used.  When exploding at a monster it didn't
wake other monsters at all.

Fixes #465
2021-03-29 09:35:43 -07:00
nhmall
7900632b50 Qt c++ function name shadow warnings
We have a struct called mkroom and a function called mkroom()
so c++ complains about the mkroom() function hiding the
initializer for the struct.

Similarly, we have a struct called attack and a function
called attack().

There may be a more elegant way of eliminating those two
warnings, but renaming mkroom() to do_mkroom() and
attack() to do_attack() was straightforward enough.
2021-02-03 10:55:07 -05:00
nhmall
d79365c6b0 add format string arg to Sprintf in hack.c 2021-02-02 17:20:41 -05:00
Bart House
a54a8c6854 Remove awful kludges dealing with command counts. 2021-01-30 19:06:27 -08:00
nhmall
f963c5aca7 switch source tree from k&r to c99 2021-01-26 21:06:16 -05:00
PatR
4c8a8bcfee fix github issue #431 - failed displacing
Being able to swap places with peaceful monsters instead of just
with pets made it possible to cause them to flee. Shopkeepers
wouldn't abandon the shop door but temple priests would attack
if hero tried to chat while they were fleeing.
2020-12-31 11:23:29 -08:00
nhmall
0c3b9642e4 pmnames mons gender naming plus a window port interface change
add MALE, FEMALE, and gender-neutral names for individual monster species
to the mons array. The gender-neutral name (NEUTRAL) is mandatory, the
MALE and FEMALE versions are not.

replace code uses of the mname field of permonst with one of the three
potentially-available gender-specific names.

consolidate some separate mons entries that differed only by species into a
single mons entry (caveman, cavewoman and priest,priestess etc.)

consolidate several "* lord" and "* queen/* king" monst entries into
their single species, and allow both genders on some where it makes some
sense (there is probably more work and cleanup to come out of this at some
point, and the chosen gender-neutral name variations are not cast in stone
if someone has better suggestions).

related function or macro additions:
    pmname(pm, gender) to get the gender variation of the permonst name. It
    guards against monsters that haven't got anything except NEUTRAL naming
    and falls back to the NEUTRAL version if FEMALE and MALE versions are
    missing.

    Ugender to obtain the current hero gender.
    Mgender(mtmp) to obtain the gender of a monster

While the code can safely refer directly to pmnames[NEUTRAL] safely in the
code because it always exists, the other two (pmnames[MALE] and
pmnames[FEMALE] may not exist so use:
    pmname(ptr, gidx)
      where -ptr is a permonst *
            -gidx is an index into the pmnames array field of the
             permonst struct
pmname() checks for a valid index and checks for null-pointers for
pmnames[MALE] and pmnames[FEMALE], and will fall back to pmnames[NEUTRAL] if
the pointer requested if the requested variation is unavailable, or if the
gidx is out-of-range.

Allow code to specify makemon flags to request female or male (via MM_MALE
and MM_FEMALE flags respectively)to makedefs, since the species alone doesn't
distinguish male/female anymore. Specifying MM_MALE or MM_FEMALE won't
override the pm M2_MALE and M2_FEMALE flags on a mons[] entry.

male and female tiles have been added to win/share/monsters.txt.
The majority are duplicated placeholders except for those that were
separate mons entries before. Perhaps someone will contribute artwork in the
future to make the male and female variations visually distinguishable.

tilemapping via has the MALE tile indexes in the glyph2tile[]
array produced at build time. If a window port has information that the
FEMALE tile is required, it just has to increment the index returned
from the glyph2tile[] array by 1.

statues already preserved gender of the monster through STATUE_FEMALE
and STATUE_MALE, so ensure that pmnames takes that into consideration.

I expect some refinement will be required after broad play-testing puts it to
the test.

    consolidate caveman,cavewoman and priest,priestess monst.c entries etc

This commit will require a bump of editlevel in patchlevel.h because it alters
the index numbers of the monsters due to the consolidation of some. Those
index numbers are saved in some other structures, even though the mons[] array
itself is not part of the savefile.

Window Port Interface Change

Also add a parameter to print_glyph to convey additional information beyond
the glyph to the window ports. Every single window port was calling back to
mapglyph for the information anyway, so just included it in the interface and
produce the information right in the display core.

The mapglyph() function uses will be eliminated, although there are still some
in the code yet to be dealt with.

win32, tty, x11, Qt, msdos window ports have all had adjustments done to
utilize the new parameter instead of calling mapglyph, but some of those
window ports have not been thoroughly tested since the changes.

Interface change additional info:

    print_glyph(window, x, y, glyph, bkglyph, *glyphmod)
            -- Print the glyph at (x,y) on the given window.  Glyphs are
               integers at the interface, mapped to whatever the window-
               port wants (symbol, font, color, attributes, ...there's
               a 1-1 map between glyphs and distinct things on the map).
            -- bkglyph is a background glyph for potential use by some
               graphical or tiled environments to allow the depiction
               to fall against a background consistent with the grid
               around x,y. If bkglyph is NO_GLYPH, then the parameter
               should be ignored (do nothing with it).
                -- glyphmod provides extended information about the glyph
               that window ports can use to enhance the display in
               various ways.
                    unsigned int glyphmod[NUM_GLYPHMOD]
               where:
                    glyphmod[GM_TTYCHAR]  is the text characters associated
                                          with the original NetHack display.

                    glyphmod[GM_FLAGS]    are the special flags that denote
                                          additional information that window
                                          ports can use.

                    glyphmod[GM_COLOR] is the text character
                                       color associated with the original
                                       NetHack display.

Support for including the glyphmod info in the display glyph buffer
alongside the glyph itself was added and is the default operation.
That can be turned off by defining UNBUFFERED_GLYPHMOD at compile time.
With UNBUFFERED_GLYPHMOD operation, a call will be placed to map_glyphmod()
immediately prior to every print_glyph() call.
2020-12-26 11:23:23 -05:00
PatR
1b7c372f5d fix #K3231 - objects vs pits and holes
This got out of hand pretty quickly.  can_reach_floor() had
different criteria than trap activation.  Objects dropped at a
hole locations that don't fall through were treated as if they
were at the bottom of an abyss, so couldn't be examined or
picked up.

This a bunch of changes; it is bound to introduce some new bugs.
2020-12-22 13:48:29 -08:00
PatR
b9535a84f1 displacing pets into water
Don't let hero at water or lava location swap places with a
pet that can't survive there.  This was a regression to 3.4.3
behavior introduced when displacer beast monster was added.
I can't remember whether the regression was intentional at the
time, but guess not because I'm fairly sure that I would have
included a comment about it.
2020-12-18 15:46:13 -08:00
Pasi Kallinen
ec1d01bbe1 Fix monster hide status when moving ball & chain 2020-12-15 17:35:18 +02:00
Pasi Kallinen
36d977f61f Unify HP loss and passing out from overexertion 2020-11-27 23:43:59 +02:00
PatR
6cbd2c5d85 warning fixes
Using 'ladder' as a variable conflicts with 'struct flag flags'
because of a macro in rm.h.  Also remove or hide a couple of
unused variables.

The hack.c diff is unrelated; just a reformatting bit that I had
laying around.
2020-11-13 14:11:54 -08:00
PatR
0e713dc4e9 fix #K2617 - metallivores eating iron bars
Monsters with rust attacks (rust monster) and corrosion attacks
(black pudding, gray ooze) can eat or otherwise destroy iron bars
but xorns could only move through the iron bars spot without being
able to eat the metal there.  Change xorn to eat bars instead of
phazing through them.  Lets rock moles eat bars too.

Hero polymorphed into a rust monster would eat bars if trying to
move to their location but couldn't do so if already there (maybe
was in xorn form and now in rust monster form).  Xorns could pass
through them but not eat them.  Allow hero metallivores to eat
bars at the current location via 'e', similar to eating food off
the floor.  Hero as rock mole behaves like rust monster.
2020-10-23 19:43:10 -07:00
PatR
239620ffd7 fix pull request #386 - monster interaction
The previous teleport scroll fix was mislabeled with this pull
request number.  Too late to fix that now; should have been

Closes #307

Now...  Interaction between voluntarily busy hero (resting,
searching, and so on) with approaching monsters to decide whether
to stop had some inconsistencies.

Really closes #386
2020-09-18 15:53:43 -07:00
nhmall
ac9ba38449 file header bump from "NetHack 3.6" to "NetHack 3.7" 2020-08-03 22:07:36 -04:00
nhmall
e440e9569d change is_safepet macro name
Leaving the word "pet" in the macro name, when it applied to non-pets
seemed too contradictory, even for NetHack.
2020-05-03 21:52:41 -04:00
PatR
7817e69c41 two new monsters from slash'em
Adds two monsters originally from slash'em.  I used the slash'em
tiles this time, also its code as a starting point but made various
revisions.  Both the tiles could benefit from some touch-ups.

displacer beast:  blue 'f'.  Attempting a melee hit (ie, trying to
  move to its spot) has a 50:50 chance for it to swap places with you.
  Fairly tough monster to begin with, then half your ordinary attacks
  effectively miss and if you try to face a mob by retreating to a
  corridor or backing into a corner you can end up being drawn back
  into the open.  I added bargethrough capability, and also it won't
  be fooled about hero's location by Displacement.  [It only swaps
  places during combat when contact is initiated by the hero, not
  when attacked by another monster or when attacking.]

genetic engineer:  green 'Q'.  Its attack causes the target to be
  polymorphed unless that target resists.  Hero will almost always
  have magic resistance by the time this monster is encountered, but
  it can make conflict become risky by hitting and polymorphing other
  monsters.  Slash'em flagged it hell-only but I took that flag off;
  I also took away its ability to teleport.  Slash'em polymorphs the
  hero if a genetic engineer corpse is eaten; that's included and I
  introduced that for monsters too.

I added both of these to the list of candidates for monster spell
'summon nasties' and for post-Wizard harassment.

I also gave all the 'f's infravision.  Probably only matters if the
hero polymorphs into a feline.

Displacer beast is originally from AD&D which depicts it as a six-
legged cougar with a pair of tentacles; it has Displacement rather
be able to affect an attacker's location.  I think genetic engineer
is original to slash'em where it expands Q class but seems mainly to
be the base monster for Dr.Frankenstein (a unique monster with a
one-level side-branch lair in slash'em's incarnation of Gehennom).
2020-05-03 14:13:08 -07:00
PatR
b2b8d508dd comment typo 2020-04-27 11:54:52 -07:00
PatR
54cfb86936 fix pull request #340 - untrap steed sanity
When a failed #untrap attempt while mounted caused hero to be moved
onto the trap, it neglected to set the steed's coordinates to match.
If 'sanity_check' was On, that would trigger warnings about steed's
anomalous position.  Eventually a normal move would put steed's
coordinates back in sync with the hero's.

The pull request code set u.usteed->{mx,my} directly.  I've used
u_on_newpos() instead.  I also replaced some direct manipulations of
u.{ux,uy} with u_on_newpos() so that if clipping is in effect it will
be updated.

Fixes #340
2020-04-27 11:48:55 -07:00
PatR
f8e1f38cb0 swapping places with peaceful monster
When swapping with a peaceful monster rather than a pet, say so.
2020-04-22 02:51:45 -07:00
Pasi Kallinen
02f222bc0c Add vault guards to undisplaceable monsters 2020-04-15 08:59:35 +03:00
copperwater
6134c6f165 Pet displacement improvements
Pets can no longer be displaced out of a trap, because that was
inconsistent with peaceful monsters refusing to be displaced out of a
trap. The untaming-via-displacement-out-of-trap code is removed.

Pets also now have a better survival instinct: they follow the code for
peaceful displacement into a bad position, and refuse to swap places.
This means it's no longer possible to accidentally kill a pet by
levitating/walking over water and displacing it.
2020-04-15 08:46:47 +03:00
copperwater
92b9db7630 Shopkeepers are immune to peaceful displacement as well 2020-04-15 08:46:47 +03:00
copperwater
5a1bbb4d16 Fix: rn2(0) when trying to displace peaceful out of trap
A side effect of making is_safepet() count peacefuls. Now checks
directly for a trapped, peaceful monster and says "they can't move out
of the trap"; this is inconsistent with pet behavior, and pet behavior
should probably be changed to be in line with it (ie they can't be
displaced out of a trap at all.)

Also refactor the code here a bit: a bunch of different if statements
have the exact same resetting code and steed resetting code in them.
Change this to a boolean flag and put the resetting code in one place
checked by that flag.
2020-04-15 08:46:47 +03:00
copperwater
21351fc13c More peaceful monsters that can't be displaced: priests, Oracle
Shouldn't be able to displace priests since that could theoretically
eventually force them out of their temple, which would probably cause
problems. The Oracle doesn't usually move anyway, but seems like she
should "not want to swap places" in any circumstance.
2020-04-15 08:46:47 +03:00
copperwater
2ee09b9210 Player can now displace peaceful monsters
Changes domove() code to allow displacing peaceful monsters.
Specifically, is_safepet() now returns true if the monster is peaceful.
Peacefuls are slightly pickier than pets about whether they consent to
being displaced: they will not displace if a goodpos() check fails for
the displaced space, or if there is a trap on the displaced space, or if
they are your quest leader. is_safepet should probably be renamed to
something else.

In the process of doing this, some other changes were made: the code now
checks whether the player and monster should be swapping places at all
first (previously it ran some code for displacing pets out of traps
first, which was a little weird if the displacement didn't actually
happen.)

In the original commit for this, I needed to guard the spoteffects()
call made in domove with a clause testing whether the player actually
moved; it was previously possible to fail to displace a monster and then
re-trigger a trap on the space you were still standing on. However, the
devteam has apparently put in an if (u.umoved) clause in the same place
and serving the same purpose.
2020-04-15 08:46:47 +03:00
Pasi Kallinen
e215f09ddb Fix even more warnings 2020-04-06 13:34:07 +03:00
PatR
c8044a202b switch_terrain() logic bug causing status updates
When moving onto a different terrain type, the logic for whether to
block or unblock levitation and flying (for the case of moving in
or out of walls and solid stone with Passes_walls while levitating)
was correct but the XOR logic for whether to do a status update
because of such a change was incorrect.  So stepping from room floor
to furniture or to doorway and vice versa or from corridor to doorway
and vice versa was requesting a status update when there was no need
for one.

Some other code must be requesting a status update when it is needed
for this (or possibly even more often than that?) because the status
line does seem to show the current state of Lev and Fly accurately.
Otherwise this should have been noticed when switch_terrain() was
first implemented.
2020-04-04 02:41:13 -07:00
PatR
d58e449d6c set_uinwater() bit
Assignment target is a one bit wide bitfield; callers only pass 0 or 1
but guarantee that value fits so that no compiler has reason to complain.
2020-04-03 11:39:40 -07:00
PatR
b37b9f25ce mention_decor vs Underwater or drowning escape
Avoid redundant
|You are on solid land again.
|You are back on floor.
when walking or teleporting out of water with the mention_decor option on.
2020-04-03 10:41:30 -07:00
PatR
a2338e92aa groundwork: u.uinwater manipulation
Toggle u.uinwater on or off in just one place.
2020-04-03 01:04:27 -07:00
PatR
40d19525c3 updating 'time' status
Handling botl updates for 'time' was inconsistent.  Set the flag to
do that when moves is incremented (where the update is suppressed if
running) or when running stops short.

losehp() would cancel running/traveling if called when in normal form
but not if called when polymorphed, so theoretically you could take
damage and keep on running.  I don't have a test case to verify that.
2020-03-16 17:32:12 -07:00
PatR
be50da07d9 botl update for trapped/untrapped
Make set_utrap() set context.botl when changing between untrapped and
trapped or vice versa.
2020-02-27 02:26:57 -08:00