Fix a few typos, reword a couple of entries describing the bug rather
than its fix to use past tense, move a couple of entries to be adjacent
to closely related entries (there's a lot of scope for more of that...)
and remove a bunch of trailing spaces.
[fixes36.2 starts with a header line but the tags on it aren't being
substituted.]
Another bug from seven years ago, sent directly to devteam so no #H
number. Report stated that throwing recoil could move a levitating
hero diagonally through a shop's doorway to exit it. If the thrown
item was unpaid, it remained unpaid after landing on shop's floor
and was an unlisted item on shop's bill. Moving diagonally out the
door seems to have been fixed, but the same effect still occurred
if you were far enough from the door to have the shopkeeper vacate
his door-blocking spot and throwing recoil took hero to that spot.
The thrown unpaid item remained unpaid, and walking out the door was
treated as shop robbery.
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.
This one is only seven years old. Dropping an unpaid item inside an
engulfer leaves it unpaid and still on bill. If engulfer is killed,
it ends up unpaid when back on the shop's floor.
Treat dropping an unpaid item into engulfer's inventory as stealing
that item. You have to pay for it to leave the shop, and like any
other dying monster's inventory, the shopkeeper will take ownership
if it lands on the shop floor when the engulfer is killed.
The 'theft' doesn't anger the shopkeeper and the cost shows up on 'Ix'
as part of "usage fees/other charges" rather than as an itemized used
up item.
That #H number isn't a typo. This finally fixes--at least improves--
something reported eight years ago. The monster types chosen by
mkclass() could be way off in some circumstances. Cited example was
repeated same-race sacrifice by chaotic hero on dungeon level 20; it
produced about twice as many incubi as succubi even though they're
the same as far as difficulty goes. (No changes in the intervening
years had any discernable effect; that was still reproducible.)
The report also mentioned that ndemon() threw away the result from
mkclass() and retried quite often and suggested that mkclass() be
taught to filter by alignment when caller cared about that.
This seems to even things out, although it also made harder monsters
chosen more often. A test program generated these numbers when
picking a chaotic demon 10000 times (level 1 hero on dungeon level 20,
so not realistic; actually probably level 0 hero since the program
didn't initialize struct u.) Third column is the number of times the
monster type was chosen with the old mkclass(), fourth is same for
the new one.
mkclass() calls 27315 10000
286 succubus 2800 3309
288 incubus 5552 3262
291 marilith 973 780
292 vrock 477 1617
293 hezrou 150 626
294 bone devil 46 247
295 ice devil 2 107
296 nalfeshnee 0 23
297 pit fiend 0 15
298 sandestin 0 4
299 balrog 0 10
Note that vrock has generation frequency 2 and marilith only 1, so
getting twice as many vrocks as mariliths should be expected.
I temporarily changed ndemon() to ask for lawful demons instead of
chaotic ones and got this.
mkclass() calls 15762 10000
287 horned devil 3197 3375
289 erinys 4991 3339
290 barbed devil 1812 3286
I also ran it for dragons with any alignment (so the outcome was
never thrown away; 10000 calls were needed for 10000 picks) instead
of demons of specific alignment and am suspicious of the outcome.
mkclass() calls 10000 10000
140 baby yellow dragon 1124 0
141 gray dragon 1096 1096
142 silver dragon 1073 1099
143 red dragon 1061 1126
144 white dragon 1077 1128
145 orange dragon 1141 1118
146 black dragon 1154 1049
147 blue dragon 1137 1123
148 green dragon 1137 1154
149 yellow dragon 0 1107
There may be a flaw in the test program. Or else old mkclass() was
not very good at picking dragons.
The relatively recent change to lev_comp do deal with apparent junk
in some places in its generated data has triggered a bunch of
"cast to 'vA' (aka 'const char *') from smaller integer type 'int'
[-Wint-to-pointer-cast]"
from clang when building with USE_OLDARGS. Probably should have
added a zillion explicit casts to long and 'L' suffix for 0 rather
than trying to handle both int and long. Or maybe just turned off
that particular warning, which must be coming from -Wall or -Wextra.
This modification has no effect for USE_STDARG or USE_VARARGS configs.
We still don't know whether this will be of any help against
disconnected processes that hog the CPU instead of exiting, but I
don't think it imposes significant overhead on ones which aren't
disconnected. Install it before it suffers from more bit rot.
Stop pretending that long and int are the same size when picking status
highlight rule for gold or time or experience-points.
Also, K&R compilation might lack <limits.h>, so let XXXconf.h define the
necessary macro(s) (currently just LONG_MAX) so that it can be skipped.
While the fuzzer was running, amidst the continual screen updating I
caught a glimpse of "Cn" and was puzzled about how the hero became
cancelled. I quickly realized it actually meant confused, but I
think "Cf" is a better abbreviation for that. I've also changed "Ha"
to "Hl" for hallucination and "Ri" to "Rd" for riding. The rest is
formatting.
Salvage part of an old patch. Swapping places with any long worm,
even a baby one, always failed with "You stop. Foo is in the way!"
This lets you swap places with tame baby long worms, and adult ones
if they have no tail (which won't happen unless there are more than
32 long worms on the current level--even if a long worm appears to
be only a head, there is normally a hidden tail segment at the same
location).
Although choose_classes_menu() is only used for objects, it is written
to handle monsters too. My change to give <space> special handling
might have broken selecting ghosts if it's ever used for monsters so
fix that.
More on clearing pickup_types so that autopickup reverts to picking up
evertyhing: for menustyle:Full and Partial, add a menu entry for 'all
classes' as an alternative to unselecting every class already set.
Also, Full and Partial had no way to include venom. Now it's a choice
when in wizard mode. There's still no way--other than switching to
Traditional or Combination--during normal play (where venom objects can
exist if they were wished for in wizard mode and then left in bones).
'sz' is the size of the buffer; 'if (count < sz) buf[count++] = c;'
can fill the entire buffer, leaving count==sz, so buf[count] = '\0';
would be out of bounds.
Formatting was way off. Indentation these days should be multiples
of 4 spaces, never tabs.