I was trying to reproduce the reported "no monster to remove" warning
from remove_monster() when a mounted hero was knocked off jabberwocky
steed but so far haven't been able to.
While trying, I came across a more minor bug. The hero got knocked
off a flying steed and got feedback of "you fly off" rather than
"you fall off". Flying capability came from the steed and dismount
feedback is aware of that but calls u_locomotion() which isn't. This
commit fixes that.
This adds some groundwork (DISMOUNT_KNOCKED) for better dismount
control. With a map fragment of
|....
|.Du.
|....
I got knocked off my steed by the attacking dragon and ended up with
|..@.
|.Du.
|....
It would be better to prefer spot 1, then the 2s, then 3s, then 4s
(not sure about farther spots if none of those are available)
|.432
|.D@1
|.432
when forced to dismount by knockback. This does _not_ implement that.
Reported by eakaye: orcish hero has maximum strength of 18/50 but
hero poly'd into an orc was given 18/100 strength. Also, a comment
from vultur-cadens pointed out that orcish heroes start with poison
resistance while monster orcs lack it.
Even though the boost to 18/100 is only temporary until the poly
times out, make orcs a special case where strongmonst from poly'ing
into them only gives 18/50 strength instead of 18/100. Adopt the
suggestion that Uruk-hai be an exception and continue to give hero
poly'd into them 18/100.
If any gnome becomes strongmonst (currently none are), treat them
as 18/50 too. Elvenking and elf-lord are strongmonst; treat their
forms as plain 18 though, matching the limit of elf heroes. Lesser
monster elves aren't strongmost.
While in there, add another special case so that hero poly'd into a
giant gets 19 strength. Monster giants are still plain strongmonst
so might warrant some sort of adjustment.
Give orcs poison resistance, but eating their corpses doesn't provide
an opportunity to confer it. Note goblins and hobgoblins still don't
have the resistance (to distinguish them from orcs a bit).
Take away strongmonst from orc shamans and give it to orc mummies.
Human mummies should have it too (at least according to movies) but
I didn't alter them becuase they're already pretty dangerous at the
point they start occurring. Take away strongmonst from plain 'elf'
placeholder.
New: when hero polymorphs into a form that lacks the strongmonst
attribute, take away any exceptional strength (drop 18/01 through
18/100 down to 18; as mentioned above, the drop is only temporary).
There's no attempt to set the maximum even lower for wimpy forms.
Fixes#679
The macro (currently unused, I think) for checking whether a particular
index designates a subroom was off by one on the maximum allowable
value.
Because of the dedicated extra space for the g.rooms array terminator
flag (hx == -1), subroom indices in g.rooms are set out in the range
[MAXNROFROOMS+1, MAXNROFROOMS*2], inclusive.
Also some minor formatting tweaks.
Pull request #607 by Vivit-R proposed renaming "huge chunk of meat"
to "giant meatball" to better reflect the similarity to meatball.
But an object name that contains a monster name prefix requires extra
work in the wishing code. I considered "huge meatball" which retains
more of the original name but decided to go with "enormous meatball"
becaues it seems more evocative.
Supersedes #607Closes#607
Refine commit 4885653014.
> I'm not sure whether gcc 3 is really the right test for whether the
> returns_nonnull attribute setting is available.
The gcc.gnu.org website only goes back to 5.1, and searching the
documentation of that version for returns_nonnull finds it. I used
ftp to get gcc-core-3.0.0 and gcc-core-4.0.0 and their doc files don't
mention this attribute. It might have been added for some later 4.x
but that really doesn't matter for nethack's purposes.
Use __GNUC__ >= 5 instead of __GNUC__ >= 3 when testing whether
__attribute__(returns_nonnull) is available.
This is an alternate way to deal with pull request #876, where
splitting a stack that has a name assigned updated perm_invent when
cloning the name and ran into trouble with shop billing when trying
to format for persistent inventory display.
The PR#876 fix has been left in place but wouldn't have been needed
if this had gone in first.
Mark alloc()--also dupstr() and re_alloc()--for gcc and clang as
always returning non-Null. This should silence some of the static
analysis complaints.
Almost all the monster and object naming functions (anything that
returns an mbuf or an obuf) should be marked this way too but I'll
leave that for somebody else to deal with.
I didn't attempt to mark alloc() with the 'malloc' attribute because
macro definitions could end up causing trouble. Specifying its
deallocator would probably be useful but is at even bigger risk of
macro interference.
I'm not sure whether gcc 3 is really the right test for whether the
returns_nonnull attribute setting is available.
Trap doors saved their destinations as an absolute level, rather than a
relative one, so if you loaded bones from a special level their
destinations would reflect the dungeon layout from the bones player's
game. For example, die on the Oracle level, on dlvl5, with a trap door
that goes to dlvl6. Another player gets those bones on their Oracle
level, which is dlvl8... the trap door would still go to dlvl6. Pretty
amazing trap door -- something you might see in a funhouse!
Include relative rather than absolute destinations in save and bones
files, much like stairs do, to avoid this problem.
I bumped EDITLEVEL because although this won't break save files in an
obvious way, it will interpret the (absolute) destinations in existing
save and bones files as relative, leading to some crazy long falls. :)
Use verbiage for mon vs mon and hero (mostly hero) engulf attacks that
matches recent changes to monster vs hero engulf attacks more closely
(e.g. "swallows whole" instead of "engulfs" for purple worm, other
changes in b07fe59...). Also ensure non-AD_DGST engulf attacks
(e.g. from revamped trapper or lurker above polyforms) aren't treated as
"eating" (or as involving "debris").
Also change the enfolds and digests macros so they produce booleans
rather than attack pointers (I got a compiler warning about casting
struct attack * to boolean when I did 'boolean b = digests(ptr);').
Reported by Umbire:
|You kill SpaceMannSpiff! SpaceMannSpiff puts on a dwarvish cloak.
|SpaceMannSpiff puts on a dwarvish iron helm.
|The seemingly dead SpaceMannSpiff suddenly transforms and rises as
| a Vampire.
This was tough to reproduce but I finally managed it. The issue
text mentions that it was fixed by copperwater in xNetHack with
commit 8c4af50f0aa3e72522f3eb98df039ff25c2a1ea0 to the repository
for that variant. My attempt to cherry-pick that failed--I'm not
even sure whether it should have been expected to work--and some of
the code has been impinged upon by changes, so I ended up applying
the contents of that commit manually.
The commit changes how/when monsters put on new armor rather than
anything directly related to vampires. Circumstances similar to
the example above now yield:
|You kill SpaceMannSpiff!
|The seemingly dead SpaceMannSpiff suddenly transforms and rises as
| a Vampire.
on one turn, then on the next turn the revived vampire produces:
|SpaceMannSpiff puts on a dwarvish cloak.
My test case only had one item of interest; I assume that the second
item of armor gets worn on a subsequent turn rather than at the same
time as the first one.
Fixes#843
Format a horn of plenty whose charge count is unknown but is known to
be empty as "empty horn of plenty" like is done for real containers.
This was too easy; I must have missed something....
Previously, the tetris-shaped rooms were always either
normal rooms, or turned into shops or other special rooms
in NetHack core. Now, the themed room lua code first picks
the themed room (which can be a themed or shaped), and some
of those will then pick a random filling (eg. ice floor,
traps, corpses, 3 altars).
Adds a new lua binding to create a selection picking locations
in current room.
The content-function in special level regions now get passed
the room data as a parameter.
For tipping purposes, a horn of plenty is treated like a container.
But using one as the source container in a container-to-container tip
wasn't supported. Implement that.
Also, #tip was offering carried bags of tricks as candidate containers
to tip some other carried container into. Only do that for ones which
aren't known to be bags of tricks (so when type not discovered yet, or
specific bag not seen yet due to blindness).
Reported by k2: tipping one container's contents directly into
another container allowed transferring a wand of cancellation (not
mentioned: or a bag of holding or a bag of tricks) into a bag of
holding without blowing it up.
That's now fixed. There are other issues that this doesn't touch:
I think it's odd that you can transfer stuff from one carried
container to another but not from a carried container to a floor
container nor from one floor container to another one at same spot.
I didn't test shop billing so an not sure what happens when #tip
blows up a bag of holding and there are some unpaid items involved.
Using #tip on horn of plenty treats it like a container, but doing
that when it's carried doesn't offer the chance to tip its contents
directly into a carried container.
Tipping a carried container does not require free hands or even
limbs (for playability) but tipping such into another container
should require at least one free hand.
Fixes#872
Reported seven and a half years ago: if you are in a vault but not
carrying any gold and the guard arrives, you're told "Follow me."
Then if you pick up gold while the guard is still in the wall breach
rather than out in the corridor, you would be told "I repeat, drop
that gold and follow me!" "Repeat" refers to the follow part but
sounds as if it refers to the drop-gold part which isn't actually
being repeated. Keep track of whether the guard has issued a drop
gold demand and use that to vary the wording of subsequent "I repeat"
message.
Modifies monst->mextra->egd so save and bones files are invalidated.
The pull request included some changes that were neither accidental nor
unintentional, so only a subset of the changes from pull request #869
submitted by klorpa were manually applied.
behaviour -> behavior
speach -> speech
knowlege -> knowledge
incrments -> increments
stethscope -> stethoscope
staiway -> stairway
arifact -> artifact
extracing -> extracting
The uses of "iff" were left alone.
Close#869
Wizard-mode command to cast any spell without checks that would
prevent casting, and with no energy use.
Mainly to allow the fuzzer to exercise the spell code paths.
Some static analyzers flagged the last-resort values as
out of bounds (which they were).
There's a small number of other complaint-suppression items in here too,
but nothing drastic.
Nothing about read_simplemail is incompatible with using const, and the
lack of const required some contortions (copying ADMIN_SERVER_MSG to
another buffer with nonconst() to prevent a compiler warning).
This was the last place nonconst() was used, so I removed it.
This is a large iteration on a previous implementation of making
nh.getmap() parse its coordinates as relative to the last defined map or
room rather than absolute to the entire level. Now, everything in the
nh.* and obj.* functions interprets coords as relative rather than
absolute. (By default; if no map or room has been defined, or if the lua
code is executing after level creation is done, they will interpret the
coordinates as absolute).
The general motivation is basically the same - routines that use
absolute coordinates are difficult to use in level creation routines,
because then the designer has to remember to convert the relative
coordinate to an absolute one (and that was impossible before
nh.abscoord was added, particularly in themed rooms). And once
nh.getmap() takes relative coordinates, it would be very strange to have
all the other functions (setting timers, burying objects, etc) remain
with absolute ones.
In a couple places, code is changed to account for coordinates that are
relative to a *room* (which uses g.coder->croom->[lx,ly] as an offset,
instead of relative to a *map*, which uses [xstart,ystart].
Specifically, selection.iterate did not account for this, and without
this the ice themed room timer was not being started in the proper
place.
All tests are updated to respect the new behavior. Most of the modified
functions are not actually used anywhere in level files; the one
exception is starting a timer in a themed room, and that has been
adjusted.
Documentation updated as well to clarify when various things are tossing
around relative and absolute coordinates, both in comments and in
lua.adoc.
delivered across level change checkpointing
Reported by entrez. Simplest test case: give level 1 a short
annotatation, level teleport to level 2, and level teleport back to
level 1. The message window will show
|You materialize on another level. You remember this level as <note>.
but ^P message history will show
|You materialize on another level.
| You remember this level as <note>.
Spaces inserted to separate two messages that fit together on the
top line become part of the second message when saving a checkpoint
during level change flushes the top line into message history.
Change insurance checkpointing to record the full message history
without flushing the current top line so that toggling 'checkpoint'
doesn't affect what shows up on the screen or in message recall.
initoptions(), including initoptions_finish(), was running to
completion with the default window system before windowtype from the
command was parsed and activated. When the default window system
is tty without MS-DOS the map type gets set to ascii; command line
--windowtype:X11 doesn't switch it back to the X11 default of tiled.
So,
| NETHACKOPTIONS=windowtype:X11 nethack
ran nethack in tiles mode but
| nethack --windowtype:X11
ran it in text mode (assuming .nethackrc left tiles vs text with the
default setting).
I think this fix is quite iffy but it seems to work as intended....
It reclassifies '--windowtype' as an "early option" in unixmain.c,
and the options.c code ultimately processes it twice.
Some discrepencies between glyph_is_cmap and glyph_to_cmap
arose after b14b830b because the change resulted in
glyph_is_cmap matching on zap beams which weren't accounted
for in the glyph_to_cmap macro. It is unlikely that
glyph_to_cmap will ever be used on such a glyph, but at least
have glyph_to_cmap return a sane value rather than drop through
to the last-resort value (currently NO_GLYPH) which is far
outside the range of the defsyms[] array indices.
I think some of these discrepencies between glyph_is_cmap and
glyph_to_cmap started after b14b830b because the additional
ranges added by that didn't have a corresponding return in
glyph_to_cmap.
- Add bounds, so that we don't process any locations outside
as those locations are known to be unset
- The bounds are only recalculated if needed
- Replace instances of selection_not where we actually want
a new selection with all locations set
Issue #838 from clausecker, relayed by copperwater: old workarounds
for lack of type 'time_t' from pre-standard days aren't suitable any
more. One of the instances was incorrect (diagnosed by entrez) and
no one had noticed for years (or possibly just ignored a compiler
warning).
Remove most of the old cruft from hacklib.c and some from system.h
but put in commented workarounds in unixconf.h in case someone needs
to resurrect it. It would have been better to do things this way
back in the old days.
Resurrecting some non-Unix port might need to clone the unixconf.h
bits in its own *conf.h, but that probably won't be necessary for a
standard C compliant system.
Closes#838
Previously the mouse clicklook mentioned every tile that matched
the character symbol, leading to overload of information and
if playing with tiles, it was mostly useless. Also the most
important bit - the tile info - was last in the text.
Now mouse clicklook only reports the exact tile information
that was clicked on.
My change to allow binding the mouse buttons made getpos
push the mouse commands into a command queue, so when you
were asked for a map location, clicked on it with a mouse,
you'd first get the expected effect, and then (most likely)
immediately traveled there.
Change getpos to clear the commands bound to the mouse buttons,
and restore the binds afterwards.
When moat and lava use the same screen symbol and color is Off, lava
is rendered in inverse video. It used to be similar for floor and
ice, but that got broken last year. Fix inverse ice, and now that
fountain and sink might be same symbol (recent IBMgraphics change),
render sinks in inverse if they match fountains and color is Off.
I started to give sink its own mapglyph flag but then got lazy and
used the same value as ice. That can be amended if some interface
wants to use some more elaborate distinction than inverse video.
Instead of hardcoding mouse button actions, allow the user to
bind mouse buttons to extended commands. For example the new
defaults are:
BIND=mouse1:therecmdmenu
BIND=mouse2:clicklook
Currently a bit rudimentary; the defaults should be OK, but
documentation is bit lacking, and in-game binding and option
saving are missing.
Allowed commands to bind are "nothing", "therecmdmenu", "clicklook",
and "mouseaction". Clicklook replaces the "clicklook" boolean option,
and mouseaction does what mouse 1 button used to do - a context sensitive
action.
By temporarily changing the type definition for each of xint16 and
coordxy to int32_t, the compiler was able to find several places where
the type definitions were wrong.
This will fix some complaints from static analysis. Note that the
code it complained about wasn't incorrect and that's likely to be
the case of a lot of its complaints.
If a monster cannot move, for example because it's being
blocked off by boulders or walls, it will try to escape by some
method - such as a wand or scroll of teleportation.