Restricting the text display only to the end of game disclose,
so it doesn't clutter the inventory during gameplay and so that
the readability of t-shirts is not given away.
Bag of tricks that had been used at least once was being described
as "empty" regardless of charge count, because it always fails the
Has_contents() test. After half this patch fixed that, it started
being flagged as "empty" as soon as the last charge was used rather
than after attempting to use it again after that, since 'cknown' was
being set whenever it was used. Only set that flag when applying
the bag has been observed to fail.
No, not a blindness cure. :-} Post-3.4.3 revisions to makesingular()
inadvertently made it impossible to successfully wish for "the Eyes
of the Overworld" because the string got changed into "the Eye of the
Overworld" which doesn't match anything. So don't singularize "eyes".
(After this fix, wishing for "the Eyes of the Aethiopica" no longer
yields the Eye of same, but I think that's the correct behavior.)
From a bug report, dropping and selling a container that had some things owned
by the hero and some already owned by the shop, you could get "You sold
some items inside <a container> for N gold piecess." Shop handing for
containers has been changed significantly since 3.4.3, but the typo
"pieces" that then optionally gets plural "s" appended was still there.
While testing the trivial fix, I noticed suboptional feedback in the
prompt about selling. For a container owned by the shop, it said "items"
even when there was just one hero owned item inside. Fortunately this
potentinal can of worns only seemed to have one tiny weeny worm in it....
The revised version of count_buc() that I've had laying around for
a while is also included.
The fixes entry is for "piecess", not escaped/captured/exterminated
worms, and goes into fixes34.4 despite this patch being labeled "trunk
only". Separate patch for trunk to follow.
Wishing for "{gain,restore,sustain} abilities" works since
makesingular() changes it to "* ability", but a post-3.4.3 change to
makesingular() caused "potion(s) of {gain,restore} abilities" and
"ring of sustain abilities" to fail to match the name, then yield a
random potion or ring. If there turn out to be many other similar
situations, makesingular()'s behavior for "foo(s) of bars" may need
to revert. For now, handle "* of * abilities" as a special case.
Allow wishing for a "potion of detect objects" to generate a
"potion of object detection", or for a "spellbook of monster detection"
to generate a "spellbook of detect monsters".
To get a spellbook you'll need to explicitly specify "spellbook"
even when using a name that's unique to books: asking for "detect food"
will yield a "scroll of food detection" rather than "spellbook of detect
food" because it finds potions and scrolls first. [That's nothing new
for the case where a spellbook and potion or scroll have the same name,
only new behavior for "detect X" vs "X detection" matches.]
Wishing for "detect food" used to yield a random food item rather
than a "spellbook of detect food". That's fixed now, although as
mentioned above it will actually produce a "scroll of food detection".
Change the way wishing for bear traps in wizard mode is handled so
that spelling of "bear trap" vs "beartrap" doesn't affect the result.
Land mine doesn't have a similar spelling variation, so it already had to
be handled differently (if you wanted an armed trap, you needed to append
something--anything--such that it didn't match the object name). Now
they're consistent with each other. By default, you'll get an object
regardless of whether you include a space inside the name, and you'll
need to specify a prefix ("trapped") or a suffix ("trap"--actually,
anything other than "object") to get an armed trap placed on the ground.
"bear trap", "beartrap", "untrapped bear[ ]trap", "bear[ ]trap object"
will yield the disarmed object,
"trapped bear[ ]trap", "bear[ ]trap trap", "bear[ ]trap<anything else>"
will yield an armed trap.
"land mine" works the same way, treating the embedded space as optional
even though both object and trap include it.
Remove some clutter from the wish handling code, mostly by taking
advantage of the fact that the wizard flag is valid even for the !WIZARD
configuration. No change to game play.
When testing singularizing of fruit names I noticed that "bunches of
grapes" became "bunche of grapes". makesingular() had a comment about
not recognizing "es" and suggesting that recursion could solve it. But
makeplural() already handled things like that without resorting to
recursion, and it also recognized more compounds than just "foo of bar"
and "*man-at-arms" (such as "pie a la mode" and "soup du jour"). This
moves the compound phrase recognition into a separate routine so that
both makesingular() and makeplural() will handle the same stuff, and it
modifies makesingular() to do as well as makeplural() when processing the
front half of compound phrases (the "foo" part in "foo of bar").
Also, a minor plurization tweak: algae was recognized as already
plural but larvae and several similar words weren't.
I almost abandoned this when Michael beat me to it, but besides
handling the fruit rename bug it also moves `current_fruit' into the
context structure to eliminate separate save/restore for that.
The post-3.4.3 ring removal bug also applied to suit when wearing a
cloak and shirt when wearing a suit or cloak or both, although it would
never give "you have nothing else to take off" because the covering item
was always present as a likely candidate. The ring fix also fixed armor.
When testing that fix, I saw "you can't take that off" for trying to take
off a suit while wearing a cloak. That isn't new or a bug, but it seemed
awfully terse so I've changed it to give "you can't take that off without
taking off your cloak first". (Likewise, "cloak", "suit", or "cloak and
suit" as appropriate when trying to take off a shirt.)
This adds new routine `suit_simple_name()', comparable to 3.4.3's
cloak_simple_name() and post-3.4.3 helm_simple_name(). No doubt there
are other places besides "without taking off your X first" that could
make use of it but I haven't attempted to track them down. The "you are
already wearing _some armor_" one doesn't quite fit. It would need to
adjust "some" to "a"/"an" at times ("some mail" or "some dragon scales"
vs "a suit" or "a jacket").
ansimpleoname() and siblings always reported statue and figurine
type to be "of a giant ant" because the corpsenm field was left as 0.
Explicitly set it to -1 in the minimal object and teach xname() to leave
off the monster type in that situation, yielding just "a statue" or "a
figurine". [It's tempting to classify this as an xname() bug since other
object types which use corpsenm do so in doname().] No fixes entry; this
is post-3.4.3 code.
"The death ray hit it." Changes to vtense() during the makeplural
makesingular overhaul four weeks ago contained a typo, or rather a set of
matching thinkos.
Move some common code from makeplural & makeingular into a separate
routine. Also, add ``candelabrum <-> candelabra''. Wizard mode wishing
for "candelabra" now works; "Candelabra of Invocation" does not--not due
to case but because the " of " isn't preceded by 's' in the plural form.
Move some of the singular<->plural transformations from code to data.
Also fixes one more missed singularization: lurkers above. A big chunk
of this is just a bit of minor reorganization: moving otense() & vtense()
next to makeplural(), and moving the wishable subranges array from between
makeplural & makesingular to in front of the wishing code.
I was going to redo makeplural to use the same style as makesingular
(switch from ``len >= N && !strcmpi(buf, spot-(N-1))'', with spot pointing
at final character, over to ``BSTRCMPI(bp, p-N)'' which tests p-N against
bp as the bounds check and has p pointing to the string's terinating '\0')
but have decided not to tackle that.
Extend makeplural/makesingular case-insensitivity to vtense() and to
wizard mode wishing for dungeon features. And the previous set of fixes
missed one: makesingular("zombies") was producing "zomby". Plus a bit of
groundwork for a likely second overhaul of makeplural/makesingular.
I stumbled across a copy of an old newsgroup bug report which
complained that wishing for "Gauntlets of Power" didn't work. I thought
that this was something which had already been fixed, but when I tried it
out, I discovered that you still couldn't wish for that. It was failing
because case-sensitive makesinglar() didn't recognize that "Gauntlets"
needs special handling. After the unwanted transformation, the case-
insensitive object matching would fail to find "gauntlet of power".
Removing case-sensitivity for special cases like "boots" and "gloves"
would have fixed that, but this patch goes further and removes case-
sensitivity entirely for both makesingular and makeplural. Words which
get their endings modified work when the input is upper or mixed case.
Any modified letters retain the case of the original, so the reason for
case-sensitivity--user specified fruits that aren't lower case--is covered.
Some makeplural fixes: the plural for dingo is dingoes (dictionary
says "-es", not "-s") and for roshi is roshi (just guessing here; most of
the Japanese names use same spelling for singular and plural, but we were
producing roshis). Several words which makesingular leaves in plural form
(boots, gloves, &c) are now recognized by makeplural (avoiding gloveses).
It also fixes a bunch of incorrect singularizations of plural monster
names: foxes, *wolves, lynxes, fungi/humunculi/succubi, mumakil, wumpuses,
baluchitheria, Aleaxes, *elves, erinyes, djinn, priestesses, & valkyries.
Some non-monsters that makeplural handles correctly were also not being
singularized right: feet, hooves, lice/mice, algae, children, nemeses.
Noticed while testing a patch for touching cockatrice corpses;
corpse_xname(,, CXN_ARTICLE) would produce "a cockatrice corpses" when the
object stack quantity was greater than 1. (This applies to the post-3.4.3
expansion of corpse_xname() in the trunk code, so no fixes entry.)
killer_xname() was adversely affected by yesterday's change to
obj_is_pname() that required artifacts to be fully identified in order to
use just their name.
Many (most?) non-weapon artifacts show up in inventory and messages
as "the <foo> of <bar>" even when their underlying object type hasn't been
discovered yet. For types which don't use the `known' bit, obj->known is
forced to 1; obj_is_pname() checked that but not the oc_name_known flag
for the type. So you'd see things like "the Heart of Ahriman" instead of
"a luckstone named <the H of A>" or "a gray stone named <the H of A>" even
though it hadn't been identified yet, unintentionally hiding the artifact's
object type from the player.
When wishing for terrain, allow type "moat" as well as "pool". And
when wishing for a trap, verify that trap creation succeeded instead of
always reporting that the requested type was made.
simple_typename and obj_typename operate on item types rather than
particular objects so have to assume that the item involved has been seen.
That means that simple_typename(obj->otyp) is not suitable; if obj->dknown
hasn't been set, it gives away information. This adds mininal_xname(obj)
to be used for that purpose. I'm not aware of any straightforward way to
actually expose the original problem; it's more than hypothetical but not
something anyone's likely to have come across.
Not fixed: test driver program reveals that obj_typename(GOLD_PIECE)
and simple_typename(GOLD_PIECE) yield "coin of gold piece". But I don't
think there's any way to get nethack to show that to the user.
Some code I recently added was misusing count_unpaid() and would
traverse some or all of inventory instead of just container's contents
when looking for unpaid items. Add mew routine `is_unpaid(obj)' to do
what I was intending to do with count_unpaid().
Inventory display adds "(unpaid, N zorkmids)" to carried unpaid
items, but it didn't show anything comparable for indirect unpaid ones
(hero-owned containers holding shop-owned objects). Now it will include
"(contents, N zorkmids)" in such cases.
Change safe_qbuf() so that instead of picking one of three strings
for sprintf() to plug into a prompt string, it actually constructs the
full prompt string itself. Also pass in the unformatted object and a pair
of formatting functions instead of performing dual formatting in advance.
The actual formatting is done via new routine short_oname() which also
takes an object and a pair of formatting routines plus a target length.
It uses the first routine, typically xname() or doname(), and formats the
object, then if the result is too long it makes some transformations, and
tries again. If truncating "called foo" and "named bar" down to 12 chars
and omitting "uncursed, rustproof, thoroughly corroded" attributes still
result in a string that's too long, it uses the other formatting routine.
The latter calls one of several jacket routines around simple_typename()
to produce a short result.
This has been through about four incarnations now and has gotten a
bit less testing each time, but I need to get it in place before I end up
running out of gas and abandoning it. I've got some changes to shk.c
(where safe_qbuf is needed but not currently used) that now need to be
redone and will come eventually.
Fix the bug From a bug report.alt.org server, where killing a monster by closing the
castle drawbridge resulted in a panic after the dead monster's possessions
were dropped into the moat and a potion of acid exploded in the process.
water_damage() deleted the object but had no way to tell flooreffects()
that it was gone, so flooreffects() couldn't tell its own caller not to
place and stack the object. After that, a chunk of freed memory became
part of the floor objects chain and eventually triggered a panic which
tried to make a save file but whose reason didn't get logged properly.
There were routines that were passed the
object name as an argument. Before the oextra
patch, ONAME() always returned a valid pointer
to a location within the obj struct. The oextra
patch worked around those cases by
using a temporary variable that was either set
to ONAME (if the obj passed the has_oname() test),
or to "" (pointer to an empty string) if no name was
present.
Since that might be a common thing to do, provide
the safe_oname() routine that you can use as a
function parameter without having to worry about
about whether ONAME(obj) is valid, and without
the need for the temporary variable.
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.
This patch alters wiz_identify so that it displays an
inventory menu with all items shown identified
without actually identifying them.
You can just press ^I (or whatever the wiz_identify command
is) a second time, while the menu is displayed to actually identify
them (tested with TTY menus only).
Reveal more tin details at end of game disclosure.
b - an uncursed carrot
c - an uncursed tin of broiled kobold meat
d - an uncursed tin of stir fried fox meat
e - 4 uncursed tripe rations
f - 4 uncursed food rations
g - an uncursed cream pie
n - 4 uncursed tins of spinach
o - 3 uncursed tins of pureed newt meat
p - an uncursed homemade tin of fox meat
Note that in the case of homemade and rotten
it sounded better to have the term before the
word tin, rather than after:
homemade tins of newt meat
rather than:
tins of homemade newt meat
The wishing code should probably be
changed to reflect this so people can wish for
a "homemade tin of newt". As it stands, they must
wish for a "tin of homemade newt" which differs
from the final display. That is not included.
Extend the capabilities of corpse_xname() so that various callers can
be simplified. It can how handle an article prefix, effectively turning it
into corpse_doname() (not quite; still need doname() to see a count when
quantity is more than one, or to see bless/curse state). It can also handle
inclusion of adjectives like "partly eaten" or "bite-covered". For unique
monsters those come out in the form
the Chromatic Dragon's partly eaten corpse
instead of the old
partly eaten Chromatic Dragon corpse
[so wishing probably needs to be taught about potentially finding a monster
name before assorted adjectives such as blessed; also, name_to_mon() needs
to learn how to cope with the possessive suffix].
A sizeable chunk of this patch deals with consolidating some of the
redundant "petrified by a cockatrice corpse" handling. It may be possible
to consolidate all remaining instances together since they're quite similar,
but I didn't think about that until just now and I want to get this patch
over with.
Have killer_xname() handle corpses properly and also avoid having it
use user-supplied fruit names as per <Someone>'s suggestion. Also make
a start at eliminating the umpteen inconsitent checks for whether a monster
type (like "Oracle") ought to be prefixed by "the ".
I used a stub which looped over all object types, all artifacts, and
corpses of all monster types to print the output of killer_xname() for each
one; its prefix choice among {[no article], a, an, the} looked right.
The code let you wish for trapped containers in wizard mode and tried
not to let you do so in normal mode. But it handled the trapped attribute
by overloading the poisoned one, so wishing for a "poisoned chest" would
produce a trapped chest in any mode. This fixes that by removing the
overloading. You can wish for a trapped box/chest (or tin) in wizard mode
and you can now also explicitly wish for an untrapped one in any mode.
Asking for trapped in normal mode--most likely hoping to seed a dangerous
bones file--just negates any preceding "untrapped" handled earlier within
the same wish, and specifying "poisoned" for a container no longer has any
effect.
cknown and lknown flags for containers are now checked when deciding
whether an item is fully identified, and they're set when identification
takes place. (You'll learn how many items are inside even if you haven't
looked to see what they are yet. This means that an inventory listing of
unpaid items will reveal the contents after you've used enouch magic to ID
an unpaid container.) Also, set those flags for any container in initial
inventory; rogues should know that sack starts out empty.
Suggested by Janet, after inhaling paint fumes. Unlike mother-in-law,
which is an entry in the hallucinating monsters list and would be pluralized
if chosen as a tin description, I think the rank title man-at-arms will only
ever go through plural/singular handling if used as a fruit name. But since
the man/men part was already implemented for pluralization, adding the -at-
part is trivial. Also adds men/man singularization for the general case
where -at- isn't involved.