Give more information when magic whistle is already discovered and
applying it affects multiple pets, without much increase in verbosity.
For each of the three categories
1) was already in view and moves to another spot still in view,
2) was out of view and arrives at a spot within view,
3) was in view but gets sent to a spot out of view,
show the pet by name (which might be "your <monst>" if it hasn't been
named) when there is just one, or "two creatures", "three...", "four...",
"several...", or "many..." when there are more than one. The first
category with more than 1 says "creatures". When there are additional
categories with more than 1, their part of the message says "others" if
prior part(s) already mention "creatures", or it says "other creatures"
if the prior part(s) only list pets by name.
For example
|Three creatures appear.
|Fido shifts location and Fang appears.
|Your pony shifts location and two other creatures appear.
|Many creatures shift locations, several others appear, and two others
disappear.
|Two creatures appear and two others disappear.
Restore old behavior of magic whistle causing pets to be moved to
different locations even when already adjacent to the hero.
This lets rloc() give its relatively new, more verbose messages if
a magic whistle isn't discovered yet but suppresses those when
already discovered in order to issue its own message. For a single
pet that starts within view and arrives elsewhere within view it says
"shifts location" rather than "vanishes and reappears". For multiple
pets, it gives one summary message instead of a separate one for each
pet affected by whistling.
original code:
if (linestart && (*cp & 0x80) != 0) {
g_putch(*cp);
end_glyphout();
linestart = FALSE;
} else {
(void) putchar(*cp);
}
new code:
if (linestart) {
if (SYMHANDLING(H_UTF8)) {
/* FIXME: what is actually in that line? is it the \GNNNNNNNN or UTF-8? */
g_putch(*cp);
} else if ((*cp & 0x80) != 0) {
g_putch(*cp);
end_glyphout();
}
linestart = FALSE;
} else {
(void) putchar(*cp);
}
The new code didn't output a character if linestart was true and the character did
not have bit 0x80 set.
fixed code:
if (linestart) {
if (SYMHANDLING(H_UTF8)) {
/* FIXME: what is actually in that line? is it the \GNNNNNNNN or UTF-8? */
g_putch(*cp);
} else if ((*cp & 0x80) != 0) {
g_putch(*cp);
end_glyphout();
} else {
(void) putchar(*cp);
}
linestart = FALSE;
} else {
(void) putchar(*cp);
}
Change table format to handle functions never to be included.
Clean up bit masks and tables of functions.
Remove some old comments and out-of-date code.
The preprocessor directives in win/tty/wintty.c were crossed-up
under MSDOS build. I think I got them straightened out now.
For a crosscompile situation, the tilemap utility (which runs on
the host) needs to produce an output src/tile.c that is compatible
for the target platform.
Don't use ENHANCED_SYMBOLS under MSDOS, for now anyway.
Reverse the sense of dochugw()'s new 'X' argument. Use True for the
usual case and False for the special case rather than the other way
around.
Call the special case variant when a monster teleports so that hero
stops occupation if the monster jumps to a position where it becomes
a threat.
A new feature, enabled by default to maximize testing, but one which can
be disabled by commenting it out in config.h
With this, some additional information is added to the glyphmap entries
in a new optional substructure called u with these fields:
ucolor RGB color for use with truecolor terminals/platforms.
A ucolor value of zero means "not set." The actual
rgb value of 0 has the 0x1000000 bit set.
u256coloridx 256 color index value for use with 256 color
terminals, the closest color match to ucolor.
utf8str Custom representation via utf-8 string (can be null).
There is a new symset included in the symbols file, called enhanced1.
Some initial code has been added to parse individual
OPTIONS=glyph:glyphid/R-G-B entries in the config file.
The glyphid can, in theory, either be an individual glyph (G_* glyphid)
for a single glyph, or it can be an existing symbol S_ value
(monster, object, or cmap symbol) to store the custom representation for
all the glyphs that match that symbol.
Examples:
OPTIONS=glyph:G_fountain/U+03A8/0-150-255
(Your platform/terminal font needs to be able to include/display the
character, of course.)
The NetHack core code does parsing and storing the customized
entries, and adding them to the glyphmap data structure.
Any window port can utilize the additional information in the glyphinfo
that is passed to them, once code is added to do so.
Also, consolidate some symbol-related code into symbols.c, and remove it from
files.c and options.c
Issue #752 by vultur-cadens: initialization of characteristics had
off by one errors when reducing over-allocation and when increasing
under-allocation, biasing Str over Cha.
This simplifies the code very slightly but it still seems somewhat
confusing to me.
A couple of reformatting bits are included.
Closes#752
For char *next; don't compare (next = index(...)) != '\0'.
'\0' has value 0 and 0 used in a pointer context is a null pointer.
So the code worked as intended even though it wasn't written as
what was intended. Fix: take off the char decoration.
Fix the problem reported by entrez of a zombie corpse reviving and
crawling out of the ground while the hero was busy doing something
(searching, digging, &c) and having the hero fail to react and just
keep doing whatever the thing was because the zombie was already
inside the range where a monster changes from no-threat to threat.
Done in the monster creation routine so any new monster (including
one revived from a corpse) that is visible,&c will cause the hero's
action to be interrupted. Teleport arrival probably needs this too.
Only interrupts an occupation, not other voluntary multi-turn
actitivy such as running or traveling. That would be trivial to
change ['if (g.occupation...' to 'if ((g.occupation || multi > 0)...']
but I'm not sure whether it ought to be extended to that.
Implement 'untrap' as an 'autounlock' action. Quite a bit more work
than anticipated. The new documentation is rather clumsy; too many
if-this and if-not-that clauses have intruded.
I'll be astonished if all the return values are correct....
[A couple of places were checking for (rx != 0 && ry != 0) to decide
whether they were performating an autounlock action at <rx,ry> but
that erroneously excludes the top line of the map if the current
level extends that far. Just check rx for zero/non-zero.]
When probing a trapped container, report that it is trapped.
Done with a one-line message in the zap code and also in the title
of the contents display if it isn't empty.
For wizard mode wishing, if both "trapped" and "broken" are specified,
produce an untrapped container with a broken lock.
Also for wizard mode wishing, ignore "trapped" if player wishes for
"trapped secret door".
High altars and normal temple altars had identical altarmasks, so
there was no way to distinguish between the two based on the altarmask
alone. Instead, anywhere it was necessary to determine whether an altar
was a high altar included a check whether the hero was currently the
Astral Plane or Moloch's Sanctum, and assumed any temple altar was the
high altar.
Since there's an extra, unused bit in altarmask anyway, use it to
explicitly mark high altars -- the lua level files already distinguish
between normal temple altars and so-called 'sanctum' altars anyway, so
rather than throwing away this distinction when generating the level,
keep it in the altarmask and use it in place of various u.uz checks.
I think this would require incrementing EDITLEVEL again...
This gives the player more control over what autounlock does. It is
now a compound option rather than a boolean, and takes values of
autounlock:none
!autounlock or noautounlock (shortcuts for none)
autounlock:untrap + apply-key + kick + force (spaces are optional
or can be used instead of plus-signs, but can't mix "foo bar+quux")
autounlock (without a value, shortcut for autounlock:apply-key).
Default is autounlock:apply-key.
Untrap isn't implemented (feel free to jump in) so is suppressed from
the 'O' command's new sub-menu for autounlock. It's parsed and
accepted from .nethackrc but won't accomplish anything.
[Just musing: it should be feasible to kick in direction '.' to break
open a container or #force to an adjacent spot to break open a door.
If that was done, autounlock:kick+force (or more likely autounlock:
apply-key+kick+force when lacking a key) would resort to force if hero
couldn't kick due to wounded legs or riding.
This changes struct flags so increments EDITLEVEL again.
This includes pull requests #750 from entrez and #751 from FIQ but was
entered from scratch rather than using use their commits.
Closes#750Closes#751