Fix 'Bugs 4, 5, and 6' which all use a similar fix but would have
conflicts over '#define BIGBUFSZ' if committed separately.
Format ("short explanation %s", string_argument), where the
explanation always has modest length but the string is potentially
up to 4*BUFSZ in length, into a 5*BUFSZ buffer. Then truncate the
result to at most BUFSZ-1 characters so that it can be safely passed
to interface-specific putstr() or raw_print().
Applies to pline(), raw_printf(), and config_error_add(). Also done
for impossible() although there's no evidence that its buffer could
be overflowed in a controlled manner.
Fix 'Bug 3' where too long SYMBOL=string in run-time config file could
overflow a local buffer and clobber the stack.
Valid value is only one character long after processing an 'escaped'
encoded character which can be at most 6 characters (plus terminator):
backslash M backslash and up three digits. If/when UTF8 gets added
the number of digits will increase. Use a truncated copy of the input
(substantially bigger than 6+1); ignore any excess.
Fix 'Bug 2' where too long MENUCOLOR=string in run-time config file
could overflow a local buffer and clobber the stack.
Theoretically a menu coloring regular expression could require a
bigger buffer but I don't think we need to try to support that.
255 characters minus the amount needed to specify color and/or
attributes should be ample.
pick_role() had a 5 year old copy+paste error where a pair of lines
were cloned multiple times but one of the resulting lines didn't get
the intended revision, preventing OPTIONS=align:!chaotic or !neutral
or !lawful from working as intended when letting the game choose role
randomly. The bad line should have been calling ok_align() but that
routine turned out to have a bug too.
Fixing those lead to other less obvious problems with role selection,
particularly the tty menu version for picking manually. Roles and/or
races which should have been excluded by partial specification weren't
always kept out. Also, if any filtering was specified, trying to
disable all filters (via choosing 'reset filtering' and de-selecting
everything in the menu) was a no-op. Once any filtering was in place
you had to leave at least one role or race or gender or alignment
flagged as not acceptable in order to change any of the filtering.
When that was fixed and it was possible to turn off all filtering,
there was no way to turn it back on because the menu choice to reset
the filters wasn't offered unless there was some filtering in place
(that was intentional but turned out not to be a good idea).
I checked curses and X11; they both offer less versatile selection
capability that don't seem to need the tty-specific fixes.
have string_for_opt() return the value string or empty_optstr to
provide some level of crash protection if some future added option
processing misbehaves. Callers of string_for_opt() and
string_for_env_opt() should always check for a match to empty_optstr.
Guard against potential bad arguments: first index greaer than last.
Return STRANGE_OBJECT instead of hardcoded 0 if it ever fails (which
should be impossible with good arguments).
Give 'novel' a 1 in 1000 chance of being created in place of each
random spellbook (except for hero's initial inventory and NPC
priests' monster inventory and divine reward for prayer--those all
force regular spellbooks; statue contents aren't among the
exceptions--those books can now be novels). Shop inventory (where
first book or scroll shop created is guaranteed one novel) hasn't
been touched. If there is any other special spellbook handling
somewhere, I've overlooked it.
Polymophed into a giant and moving onto a boulder's location could
yield "you easily pick it up" (without actually doing so) followed
by "you see a boulder here". It would happen if autopickup was Off,
or if the 'm' move-without-autopickup prefix was used, while either
boulder was included in pickup_types (including when that is set
for 'all') or hero had thrown that particular boulder and
pickup_thrown was On. The check for whether auto-pick should try
on an object relied on its caller verifying that autopickup was On.
pickup() does that for
pickup() -> autopick() -> autopick_testobj()
but moverock() wasn't doing that for
moverock() -> autopick_testobj()
so the logic controlling moverock's message was subverted.
I first thought that logic itself was incorrect and changed the
message. This keeps the new message even though it turned out not
to be cause of the problem.
Fixes#279
teleds() is used for more than just teleportations, the teleportation message
was also given when mounting a steed.
Trying out a new bit flags method parameter design pattern.
When browsing the map while hallucinating and looking at a pool, a
moat, or 'other' water or at molten lava, report with hallucinatory
liquids rather than the ordinary substance. Likewise when browsing
self on map or using ^X would report "sinking into lava".
Changing data.base lookup to accept leading spaces as an alternative
to the normal leading tab ended up adding an invalid integrity check.
Lines without any leading space or tab were considered to be in error
but empty lines are present so need to be accepted.
The change to make "ouch! you bump into a door" use up a turn didn't
end running, so when it happened while running useless turns took
place and that message was delivered repeatedly until some other
action interrupted the hero. It didn't matter whether autoopen is
enabled.
Fixes#277
When trapped in lava, change the text from "stuck in the lava" to
"sinking into lava" to describe the situation much more accurately.
Instead of doing that twice, move the u.utraptype feedback into a
separate routine that both enlightenment and self-lookat can use.
Noticed while testing the look-at-self feedback for traps. When
punished and the iron ball gets buried, hero becomes "tethered to a
buried object". It is possible to simply walk away (like from a pit,
bear trap, web, stuck in floor by solidified lava or sinking into
molten lava) but that requires many tries. Once the escape happens,
"you finally wrench the ball free" and are supposed to have it
reattached to a replacement chain. However, buried_ball() wouldn't
look at buried objects if the trap countdown timer was 0 (which is
the case when finally wrenching free). So hero got a new chain to
drag around but it had no heavy iron ball attached.
I didn't turn on sanity checking but that would have complained about
this. Normal dragging didn't care but I wouldn't be surprised if
various actions that checked Punished and picked up the ball in order
to put it down again elsewhere would have had possibly serious trouble.
Use trapname() in several more places. I wasn't systematic about it.
trapname() could generate a random value of 0 and attempt to use
"real trap #0" but 0 is NO_TRAP. So it ended up with "water" from
the preceding block of entries in defsyms[]. Treat 0 as an extra
chance for the actual trap instead of an hallucinatory one.
Add a couple more hallucinatory traps. "Roach Motel" is trademarked
but like Spam and Band-Aid, general usage has trampled over it. I
included "(tm)" anyway. Also, sometimes generate "<role> trap" or
"<rank> trap" on the fly. Why should tourists get all the fun?
^X reports whether you're caught in a trap, but neither looking at
yourself (via '//' or ';' or other getpos autodescribe) nor looking
"here" (via ':') said anything about that. Make looking at yourself
do so.
Make wish for "amulet of yendor" be the same as "real amulet of yendor"
instead of preserving the 3.6.x behavior of having a 50% chance of it
yielding "fake amulet of yendor".
Both the "real" and "fake" prefixes are still accepted, but "real" has
become a no-op:
!real and fake, real and fake => fake
real and !fake, !real and !fake => real
so fake vs !fake always decides the result.
globwt() didn't check for wizmode, so unpaid globs would be shown with weight
information even for normal player.
Eliminated globwt() completely and consolidated the output of aum in one place
as we don't really care about the ordering of debug info in wizmode.
Report complained that having autoopen not work when fumbling was
inconvenient and mentioned that the "ouch! you bump into a door"
result didn't take any time. This updates the documentation to
state that autoopen won't work while fumbling (so the inconvenient
behavior persists) but changes movement so that bumping into a door
now takes time. (Despite "ouch!", it doesn't inflict any damage.)
Also, document the recently added autounlock option.
Recent object formatting changes for wielded weapon put some pline
arguments in the wrong order.
a - aklys (weapontethered in hand)
or worse, when dual-wielding
a - aklys (wieldedtethered in right hand)
Change back to
a - aklys (tethered weapon in hand)
or
a - aklys (tethered weapon in right hand)
I considered (tethered weapon wielded in right hand) for the two-
weapon case, but I think that's too verbose.