Fixes#202
When swallowed, you can take things from the engulfer's inventory, if
there are any, via pickup. Items might be worn by the engulfer and
when "picked up" those weren't being unworn before being added to
hero's inventory. Then they would be formatted as "(being worn)" and
could trigger warnings or worse.
Conceptually they should be worn on the outside and not be accessible
from the inside, so I've made attempts to pick up worn items fail
rather than fix up the unwearing.
Using ':' when swallowed to look at the engulfer's inventory describes
that inventory as "contents of <mon>'s stomach". That's weird for any
worn items, but the situation is so rare I haven't made any attempt to
deal with it.
A recent fix for #wizidentify showing "Not carrying anything" after
listing inventory items still showed "Not carrying anything" after
"(all items are already identified)". Fix is easy.
Trickier bug was that ^I performs object ID on selected items while
the inventory routine is still in progress (but after it has processed
every item) and the ID routine will call update_inventory() which
will call the inventory routine to reformat invent. So the inventory
display routine was called recursively without having returned to
wizidentify where iflags.override_ID gets cleared to revert to normal
inventory. The nested call was unintentionally narrowing the contents
of persistent inventory window to whatever items were still unIDed.
(Any inventory update, including ^R, restored it to full inventory.)
when carrying things. The fuzzer toggled on 'perm_invent' and after
interrupting it I used ^I. Having 'perm_invent' enabled makes the
inventory code avoid having a totally empty inventory display (by
supplying "Not carrying anything" instead--in the menu rather than
via normal pline) so that interface code will see a change and know
that an update is needed. But to decide whether the menu was empty,
the inventory code was testing union 'any' field 'a_char' to check
whether some item had used the union (implying that something had
been passed to add_menu()), but wizidentify (^I) uses field 'a_obj'
instead. Apparently the a_char bits stayed 0 because the menu ended
up with "Not carrying anything" after a list of inventory items.
Switch to a separate variable to track whether anything has been put
into the menu instead of trying to rely on the union.
Unrelated but noticed when checking other "Not carrying anything"
instances, the #adjust command ends early when there's no inventory
but it was asking for a letter to adjust even when the only thing in
inventory was gold in '$' slot, which isn't allowed to be adjusted
away from that slot. Treat gold-only like no-invent.
For the inventory of a probed monster, if the probing took place in
a shop the inventory display would have selling price appended to
all the items. That wouldn't really be a problem if it was just for
a pet who was carrying one shop item, but it applied to every item
being carried by any probed monster (including shopkeeper) with no
regard for whether the shop actually claimed ownership.
When ^I was changed to allow picking more than one item to make
its temporary identification become persistent, group accelators got
left out. So to pick all potions, you needed to select them letter
by letter (or via '.' to select everything, then deselect non-potions
letter by letter). Now you can use '!' to select all potions.
This is based on the multiple-RNGs code fron NetHack4, but using
only the parts relevant to the display RNG (and with substantial
changes, both because of post-3.4.3 changes, and because Nethack4's
display code is based on Slash'EM's rather than NetHack's).
They're never modified. Minor complication: &zeroobj is used as
a special not-Null-but-not-an-object value in multiple places and
needs to have 'const' removed with a cast in that situation.
More shop price determination fallout. After the most recent change
to get_cost_of_shop_item(), using ':' inside an engulfer carrying at
least one item while inside a shop would try to follow the item's
obj->ocontainer back-link and crash when that led to the engulfing
monster rather than to a container.
Some object classes (such as armor and weapons) are split into
"subclasses" when sortloot applies an ordering (for armor, all helms,
then all gloves, then all boots, and so on). Give gem class subsets.
Simple (1) valueable gem, (2) worthless glass, (3) gray stone, (4) rock
would give away information; instead, factor in discovery state and use
(1) unseen gems and glass ("gem")
(2) seen but undiscovered gems and glass ("blue gem"),
(3) discovered gems ("sapphire"),
(4) discovered glass ("worthless pieced of blue glass"),
(5) unseen gray stones and rocks ("stone"),
(6) seen but undiscovered gray stones ("gray stone"),
(7) discovered gray stones ("touchstone"),
(8) seen rocks ("rock").
If everything happens to be identified, the simpler ordering happens
(via 3, 4, 7, and 8) because the other subsets will be empty.
It was possible to have the guaranteed luckstone at Mines' End become
merged with a random one and lose its specialness for achievement
tracking. Mark it 'nomerge' when created and clear that if/when the
achievement is recorded.
stolen_value() treated hero-owned container holding shop-owned goods
as free for the taking.
The fix I'm working on which led to discovering this first added
stolen_value() then eventually stopped using it so I don't have an
example of where it is giving the wrong result.
Dropping an existing fragile item while levitating will usually
break it. Getting a new wished-for fragile item and dropping it
because of fumbling or overfull inventory never would.
Some callers of hold_another_object() held on to its return value,
others discarded that. That return value was unsafe if the item
was dropped and fell down a hole (or broke [after this change]).
Return Null if we can't be sure of the value, and make sure all
callers are prepared to deal with Null.
I don't know why we have two different functions which do exactly
the same thing (checking whether an item is unpaid or is a container
that holds at least one unpaid item), but switch the #H2504 fix to
use 'the other one' and reverse one of the changes made when using
the inventory one.
I thought that the earlier fix for #H2504 was too easy for anything
shop related. It didn't deal sensibly with containers owned by hero
but holding unpaid shop goods.
Add a new line for one last missing status field: gold.
Also add one for proficiency with current weapon.
Move a few lines from 'characteristics' to 'background' and a few
more from 'characteristics' to new 'basics', leaving characteristics
with the six original characteristics: Str, Con, Dec, &c.
Remove trailing spaces, and remove tabs from the files that had
trailing spaces.
Also, rndorcname() was using a random value to terminate a loop
and was recalculating a new one each iteration.
Get rid of bold/non-bold distinction in #wizidentify inventory menu
by only showing items which aren't yet fully identified instead of
full inventory with bold for unID'd. Support for bold text might
be lacking.
I was considering this even before the report that X11 menus ignore
attribute. The "_ - (use ^I for all)" menu entry is still present,
but it could be discarded in favor of '.' to pick everything via
ordinary menu selection.
Bug report #H7156 listed three items, all relating to perm_invent:
1) it shouldn't persist across save/restore since restore might be
on a system which doesn't have enough room to display it (report
actually complained that config file setting was ignored when
restoring old games, which is an expected side-effect for options
that persist across save/restore);
2) permanent inventory wasn't updated when using scroll of charging;
3) attempts to update permanent inventory during restore could lead
to crash if it tries to access shop cost for unpaid items.
Items (2) and (3) have already been fixed. This fixes (1).
Replace 'flags.perm_invent' with a dummy flag, preserving save files
while removing it from flags. Add 'iflags.perm_invent' to hold the
value of the perm_invent option.
The win32 files that are updated here haven't been tested. Whichever
branch contains the curses interface needs to be updated; ditto for
any other pending/potential interfaces which support perm_invent.
Don't display the selection to identify all items if there are none.
Complete an item marked ToDo in cmd.c: allow selection of one or more
particular items to permanently identify rather than just all or nothing.
Fixes#124
Fix github pull request #124 which was also reported directly (but not
through the contact form so #Hxxx number). Using ^I or #wizidentify
displays inventory with everything ID'd for that command only and adds
a menu entry "_ - use '^I' to identify" that can be chosen to make
those ID's persistent. Picking underscore would work but picking the
alternate '^I' wouldn't work if the platform had unsigned characters
for plain 'char'. Switch the return value from magic number -1 to
magic number ^I which isn't a valid inventory letter and isn't subject
to sign conversion. Casting -1 to '(char) -1' would have worked too
despite some confusion expressed in discussion of the pull request.
If ^I has been bound to some other command and #wizidentify hasn't
been bound to any keystroke, temporary ID didn't disclose any extra
information (ie, acted like ordinary inventory display) and the extra
menu entry to make temporary ID become persistent wasn't available.
This fixes that too.