Take advantage of the ability of some compilers to warn if
not all values are covered in a switch statement, to draw
attention to the need to update make_corpse() when new
monsters are added to NetHack.
This adds explicit entries for the current "default" handling
in make_corpse().
It might be a good idea to review the explicit entries to see
if any of them represent others that are not being handled,
but should be.
To test this, I temporarily reverted 85c86444, and I did receive the
following warning:
mon.c:545:13: warning: enumeration value 'PM_GOLD_DRAGON' not handled in switch [-Wswitch]
545 | switch (mndx) {
| ^~~~
1 warning generated.
In 3.6.2 parts of the wakeup code were merged together, and this
caused pets consider any noise made by the hero - such as hitting
iron bars or digging - as whistling for them to come to the hero.
Change it to only consider actual whistling and ringing a bell.
From a reddit thread: a 'mausoleum' theme room picked a vampire for
its occupant and applied the wait-for-you strategy to it. Hero's ESP
or monster detection showed a meditating vampire bat. Change monster
creation by the special level loader (which also handles theme rooms)
to force such a creature into its normal vampire form.
That revealed an older bug which wouldn't have been exercized prior
to theme rooms: a meditating vampire could and would shape change
without ceasing meditation. Make it not shape change rather come out
of its trance.
Re-use the array allocated for iterating over all monsters during
monster movement much of the time. It was being allocated from
scratch for each round of monster movement, then freed after they
moved, then repeated the next round.
While hunting for a memory leak in object allocation--which I haven't
found yet--I discovered one in monster movement. iter_mons_safe()
allocates an array of (monst *) pointers for the monsters on the
current level, loops over that array to call a function for each
one, then frees the array. But if the game ends while that called
function is running, execution never returns to iter_mons_safe() so
it wasn't able to free the memory.
Since that can happen at most once per game, it wasn't a signifcant
leak. This fixes it anyway.
There was a second issue: make sure that iter_mons_safe() doesn't
call alloc(0) to make the temporary array for zero monsters when
there aren't any on the level. That might not be able to happen for
monster movement but the routine is written to be more general than
just movement. alloc(0) could confuse the MONITOR_HEAP code. In
C89/C90 I think malloc(0) is allowed to return NULL (don't recall
for sure; maybe that was just known pre-standard behavior for some
implementations). Null return would trigger a panic even without
MONITOR_HEAP. Don't know about C99 and later.
Consistent with their mythological role of punishing those who had
violated societal taboos -- oathbreakers, hosts who attacked their
guests, etc -- erinyes scale with the cumulative amount of alignment
abuse the hero has committed over the course of the game. This is
tracked separately from the alignment record, and cannot be cleared by
the hero improving her favor with her god via "good deeds" as the normal
alignment record can. Erinyes will gain abilities, levels, and attacks
as the hero's alignment abuse worsens. They will also aggravate
monsters when near the hero.
Pull request by mkuoppal: some objects which use the corpsenm field
to access the mons[] array can have a corpsenm value of NON_PM (-1)
and weren't avoiding array access in those cases.
In addition to a fixes entry for it, this makes some revisions to the
commited code, handling a few of the cases differently.
Closes#1175
corpsenm can be -1 (for EGGs and TINs) so touch_petrifies
using this as index would point to bad entry.
Fix this by making mstoning as helper function and bailing
out early if corpsenm <= LOW_PM (while keeping MEDUSA as is)
Issue reported by Umbire: an engulfing monster capable of passing
through iron bars (vortices and air elemental) could do so while
carrying the hero.
Prevent an engulfer from doing that unless the hero happens to be
polymorphed into a subset of the types of monsters that can move to
iron bar locations.
Fixes#1192
Adds a new boolean option, accessiblemsg. If on, some game messages
are prefixed with direction or location information, for example:
(west): The newt bites!
(northwest): You find a hidden door.
I added the info to the most common messages, but several are
still missing it.
Issue reported by Umbire: reviving a human corpse into a human
monster and then killing it entails murder penalty even when it is
hostile.
This is probably a non-issue. Human monsters tend to not leave
human corpses, they leave shopkeeper corpses or sergeant corpses
and so forth. Most human corpses created in normal play have
montraits attached and revive as a zombie, mummy, or vampire rather
than as a human.
This doesn't attempt to be clever, it just treats PM_HUMAN like
role monsters, not subject to 'murder'.
Closes#1180
Some functions are passed an obj or monst chain,
and the callers typically don't check them
against 0, so mark them explicitly as NO_NONNULLS
(NO_NONNULLS expands to nothing, but it flags that
some null arg analysis has been done)
Donning elven boots while riding and not already stealthy, you'd get
the message "you walk quietly" when not walking at all. Instead of
just changing the message, make riding a non-flying steed block
stealth. Riding a flying steed (or one you take aloft with an amulet
of flying) does not. It would have been quite a bit simpler to have
made riding anything block stealth, but the hard part is done.
Fixup some of the inconsistently formatted code that has been
introduced recently or been building up for a while. Done manually.
I wasn't systematic except for looking for lines ending in '&' or '|'
(which wouldn't find such things if they're followed by a comment)
so there might be lots more. I changed a bunch of C++-style //...
comments to old style C /*...*/ so that they'll match the rest of
the core's code rather than because they shouldn't be used.
Playtesting has shown that there is too much permafood in the game
at present: in the late-game the only food-related problem is how
much to carry in order to avoid burdening yourself. In the early
game, food could previously have been a problem prior to
Minetown/Sokoban (thus the recent commit to add a guaranteed ration
in the upper dungeons), but past that point, there is easily enough
food generated on the ground. Additionally, the recent commits to
make healing sources more available in the early game reduce the
amount of time that needs to be spent waiting to heal, thus
further reducing food requirements.
The main purposes of food as a mechanic are to given an incentive
to press onwards and to discourage grinding. However, if monsters
are deathdropping non-corpse permafood, then beyond the very
early game, grinding actually generates more food than it uses up,
so the nutrition mechanic doesn't do its job properly.
Playtesting (including a full ascension!) has shown that there is
still plenty of food available even without deathdrops available
(my test game had 8 spare non-deathdrop food rations upon reaching
the Castle, at which point nutrition is no longer an issue due to
the Castle food stores and the huge numbers of C- and K-rations
dropped by the soldiers). I will address the potential problems
this causes for vegetarian Monks in a future commit.
Various places checking for whether a monster was on the map based on
mstate flags were inconsistent about which ones they checked (and then
place_monster() was additionally inconsistent with all of them about
which bits were cleared when placing a monster onto the map). I think
some places were also more convoluted than is now necessary because they
date back to mstate being an alias for mspare1, which it shared with
migflags before those became two separate dedicated fields (MSTATE_MASK
also dates back to this and is no longer used, so I removed it).
I tried to go through all the MON_foo mstate bits, understand when/why
they are set, and make the various functions I noticed more consistent
(with each other, and with my understanding of how the bits work) about
how they are treated. I don't know for a fact that I understood
everything right -- some diagnostic bits that aren't used for much of
anything, like MON_OBLITERATE, had me mystified until I read the 5ee78c5
commit message -- but this patch hasn't caused any new problems (sanity
check or otherwise) with the fuzzer in my testing so far. All the same,
it could probably use review by someone who has a good sense of what the
mstate bits mean.
Change 852f8e4 by requiring a minimum impact before a buried zombie
nearby will be disturbed: light, but still excluding things like
scrolls, if it's a violent impact (dropped while levitating, thrown, or
kicked), and fairly heavy if the hero is just placing the item on the
ground normally.
Moving the call out of flooreffects meant it no longer applied to
pushing boulders around, so have moverock disturb nearby zombies. I
additionally had wake_nearby do the same thing.
Finally, I renamed check_buried_zombies (which doesn't really reflect
what it does) to disturb_buried_zombies.
Reported by a hardfought user, a ceiling_hider monster hid on the
Astral level, triggering a sanity check warning that gets repeated
each move until the hider comes out of hiding. Normally sanity_check
can only be set in wizard mode, but hardfought must force it on for
to-be-3.7.
I was able to reproduce it before this fix and unable to do so
afterward, but there is a random factor involved hence no guarantees.
I think that lack of ceiling for Astral is recent, but this could
have happened on other levels which lack a ceiling. I didn't try to
figure out whether it might happen with 3.6.x, just put the fixes
entry in the "exposed by git" (found in code not yet released, that
is) section.