It doesn't mention anywhere that newmextra() is responsible for
initializing struct mextra with null pointers to the various
sub-structs. So, when one follows the instructions and doesn't know or
remember to do this, they'll get segfaults when something tries to read
the uninitialized pointer to their new struct.
A reddit thread about an unaligned altar in an aligned temple was
a tipoff that mimics posing as altars didn't have any particular
alignment. The look-at code was misusing an operloaded field of the
underlying terrain. Pick an alignment at random when taking on the
appearance of an altar, store it in the mimic's mon->mextra->mcorpsenm
field, and have look-at use that.
Also, dropping a ring of polymorph into a sink can transform it, and
one possible outcome is an altar. In this case, the alignment is
part of the location's topology, but code setting that up was using
Align2amask(rn2(foo)). That's a macro which evaluates its argument
more than once. The first evaluation was effectively a no-op. If
the second evaluation picked lawful then the result was lawful as
intended. But if the second picked non-lawful and the third picked
lawful, the result would end up as none-of-the-above (a value of 3
when it needs to be a single-bit mask of 1, 2, or 4).
Mimic-as-slime_mold needs to keep track of the fruit index the same
way that mimic-as-corpse keeps track of corpse's monster type. The
mimic description was changing (for '/' and ';' feedback) whenever
the player assiged a new fruit name.
That wasn't noticeable when applying a stethoscope because
mimic-as-slime_mold always yielded "that fruit is really a mimic".
Change it to report the fruit's type instead of generic "fruit".
Lawful angels deliver taunt messages from a pool of messages which
might mention the lawful god; demons and non-lawful angels draw from
another pool which doesn't mention any gods. Since it is odd for a
'renegade' angel to claim to be operating for its god, choose taunts
from the other pool of messages for renegade lawful angels.
Not related: some formatting fixups in include/mextra.h.
I did my best to exempt some of the bigger aligned blocks from the reformatting
using the /* clang-format off */ and /* clang-format on */ tags. Probably some
that shouldn't have been formatted were anyway; if you encounter them, please
fix.
The clang-format tags were left in on the basis that it's much easier to prune
those out later than to put them back in, and it means that, modulo my custom
version of clang-format, I should be able to run clang-format on the source tree
again without changing anything, now that Pat has fixed the VA_DECL issues.
From a bug report, if you rob a shop, let the
angry shopkeeper catch up with you outside his shop, escape to another
level with adjacent shk tagging along, then pacify the shk by paying him
off, he will dismiss kops on the present level and return to his shop
but when you return to his shop level there'll still be kops chasing you
there. This fix adds an extra flag to the eshk structure so that kops
can be dismissed a second time when the shk migrates back to shop level.
The first dismisal (on the "wrong" level) still takes place in case any
kops are around. Neither dismissal actually occurs if there happens to
be another angry shk present on the level where dismissal is being done.
A mimic posing as a statue was displayed as a tengu statue (and
recognizeable as such now that statues are displayed as the corresponding
monster rather than rock-class back tick), but the lookat code described
it as a giant ant statue (since there was no obj->corpsenm available to
indicate the monster type, it defaulted to 0). This adds monst->mextra
field `mcorpsenm' so that mimics have a place to remember what sort of
statue or corpse they are mimicking. And it picks a random monster type
when they take such forms so that the old tengu hack becomes irrelevant.
newmextra() and newoextra() initialized pointers via memset(...,0)
which is not portable; switch to explicit assignments. The wizard mode
code to display memory used for monsters and objects added in amounts
for the miscellaneous things pointed to by monst->mextra and obj->oextra
structs but didn't include memory for those structs themselves; add it.
Simplify monster save/restore slightly; there's no need for extra zeroes
to represent monst->mextra->X sizes when monst->mextra is null.
Update the startup banner for 2009. I should have done this with a
separate patch but I'm taking a shortcut. :-]
move oattached and oname and other things that vary
the size of the obj structure into a separate
non-adjacent oextra structure, similar to what has
already been done for mextra. The obj structure
itself becomes a fixed size.
New macros:
#define ONAME(o) ((o)->oextra->oname)
#define OMID(o) ((o)->oextra->omid)
#define OMONST(o) ((o)->oextra->omonst)
#define OLONG(o) ((o)->oextra->olong)
#define OMAILCMD(o) ((o)->oextra->omailcmd)
#define has_oname(o) ((o)->oextra && ONAME(o))
#define has_omid(o) ((o)->oextra && OMID(o))
#define has_omonst(o) ((o)->oextra && OMONST(o))
#define has_olong(o) ((o)->oextra && OLONG(o))
#define has_omailcmd(o) ((o)->oextra && OMAILCMD(o))
changed macros:
has_name(mon) becomes has_mname(mon) to correspond.
The CVS repository was tagged with
NETHACK_PRE_OEXTRA
before commiting these, and
tagged with
NETHACK_POST_OEXTRA
immediately after. The diff
between those two tags is this oextra patch.
The associated mail daemon changes to use an oextra
structure instead of a hidden command located in the
name after the terminating NUL, have not been tried
or tested.
<email deleted> wrote:
> Eating gold in a vault (or polymorphing a pile of gold into 1 gold piece)
> doesn't anger the guard.
This addresses the eating part of that report, but the hero
has to get caught doing it.
Cut down on the excessive verbosity generated when entering a temple.
The first time you enter a particular temple (or more accurately, the
temple attended by a particular priest), you still get the three message
sequence
The <priest of foo> intones:
Pilgrim, you enter a sacred place!
You have a strange forbidding feeling...
or
You experience a strange sense of peace.
except that the last one doesn't say "strange" any more. On subsequent
visits to the same temple, you usually won't get the first introductory
message any more, often won't get the second entry one, and sometimes
won't even get the final one, depending upon how much time has elapsed
since the previous entry. The old verbosity could really be infuriating
when attempting to lug corpses to the altar before they spoil. Even
though the messages don't affect the passage of time, it always felt as
if they were slowing you down. And even when you weren't in any hurry,
it required at least one and often 2 or even 3 responses to --More--
depending upon the length of the deity's name and whether some other
message was also delivered on the same turn (fairly common in minetown).
Saving and restoring, or leaving the level and returning, resets
the priest's memory of when the messages were last given, so the next
entry after that behaves similar to the very first. This was initially
intended for cleanup prior to saving bones data, but it seemed reasonable
to have it apply to the current game too. Unattended temples now also
have a 25% chance of not giving any message when entering. That one is
random rather than based on the passage of time since last entry; there's
no priest available to track the latter data.
Add an introductory comment for each type of extension. Also move
ANGRY/NOTANGRY shopkeeper macros from old eshk.h out of the common header
and into shk.c so that their use doesn't end up spreading into other code.
Not fixed: entry #9 in the block comment at the top is truncated
mid-sentence.
<Someone> noticed the leftover zeromextra, this removes it.
Using memset() on a possibly failed mextra allocation was inapprorpriate,
so replace the newmextra() macro with a function.
Prevent a crash in christen_monst() if mextra was not initialized.