Similar to how the pick-an-attribute menu for menu colors and
status highlights shows the attribute names using the attribute
so that you can see how it looks (or whether it is supported),
have the pick-a-color menu show the color names in the
corresponding color. Does so by temporarily removing any
user-specified menu colors and setting up another list of such
for matching color names.
Forces the 'menucolors' option On while the pick-a-color menu is
in use, then restores the previous setting along with the user's
menu colorings. Might need some way to avoid setting that for a
configuration where colors don't work.
In addition to 'true', 'yes', 'on' and 'false', 'no', 'off',
accept 1 and 0 for the value of a boolean option. Other numeric
values are rejected rather than treated as non-zero.
Relax the parsing for true, false, yes, no to accept one or more
letters instead of requiring at least three for true and false
and full word for yes and no. Full word is still required for
on and off.
Don't report two errors for the same mistake:
|% NETHACKOPTIONS='legacy:flase' ./nethack
| * Illegal parameter for a boolean.
| * Unknown option 'legacy:flase'.
|2 errors in NETHACKOPTIONS.
is changed to
| * 'legacy:flase' is not valid for a boolean.
|1 error in NETHACKOPTIONS.
Report described this as a panic triggered by the sanity_check
option, but that's because it was running under the fuzzer, which
escalates any impossible() to panic(), rather than because nethack
panicked.
I couldn't find anything wrong--which doesn't mean that there
isn't something wrong--with place_worm_tail_randomly() and
random_dir(). They use xchar for map coordinates which should be
fine as long as no negative values are generated and I couldn't
discover any such. The suggested fix of changing xchar to int
might indicate a compiler bug (although the odds of that are low).
The bogus coordinate of -15000 in the report suggests that
typedef short int schar;
(which changes xchar too) is being used in the configuration but
I don't recall having any problems attributable to that.
This switches from xchar to int as a side-effect of replacing the
offending code entirely. The new code might produce an 'ny' of -1
before goodpos() rejects it, so xchar would be inappropriate now.
The old code is commented out via #if 0 _after_ changing it from
xchar to int.
This also adds an extra sanity_check for worm tails, unrelated to
the current bug. I'm not aware of any instance where it fails.
EXTRA_SANITY_CHECKS needs to be defined for it to do anything.
Part of pull request #308: when using des.terrain to set terrain,
default for lit state becomes 'unchanged' rather than 'unlit'.
des.replace_terrain already operates that way. Replace lit state
magic numbers -1 and -2 with SET_LIT_RANDOM and SET_LIT_NOCHANGE.
Also change SET_TYPLIT() to not operate on map column 0 and move
it from rm.h to sp_lev.h. It never belonged there, is only used
in sp_lev.c, and now because of the SET_LIT_ macros it couldn't be
used anywhere else unless sp_lev.h gets included too.
Move clearing of polearm context from migrate_to_lev() to lower
level relmon(). Add missing transfer of polearm context from
old mon to new mon in replmon(). These days it seems to only be
used for creating a monster from saved traits, so polearm context
in it should be moot.
Eliminate the feasibility of micro-managing ring hunger by swapping
back and forth between a pair of rings of slow digestion. Wearing
one at a time causes normal ring hunger (wearing both at once just
increases such hunger), but being able to put on the second ring
and take off the first just before the 1 out of 20 turns where it
affects hunger, then vice versa a few turns later, is an insanely
tedious way to avoid any hunger at all, made possible by the 'time'
option. Make the turns where extra hunger get imposed be randomized
so that that can't be done reliably.
Also closes githib issue #336: hunger caused by melee attacking
adds ring and amulet hunger a second time for that turn. That has
always been intentional behavior; now the amount varies for any
given attack due to the randomization, but on average is the same
as before.
Closes#336
Core issue noticed while working on some Qt stuff. If hangup
occurred while prompting for "right or left?" ring finger, the
hangup yn_function() would return ESC and the accessory-on routine
would not see '\0', 'r', or 'l' so reprompt. Endlessly.
The turn-to-slime countdown is one of the ones that uses turns/2
to stretch the sequence out longer and it was displaying the hero
as green slime when there was another turn before it happened.
(In theory anyway. I could not get my hero to be shown as slime
and still have one move left, even when hasted.)
Make the hero mimic green slime starting on the last turn before
being polymorphed instead of next to last.
Fixes#380
Infrastructure bits: Qt tombstone uses a short buffer; make sure that
the plname value fits instead of relying on snprintf() to truncate it.
A warning about gold, if any, was iffy but this should guarantee no
reason for future complaint. Year was safe but a compiler sensitive
to buffer overflows wouldn't know that.
Actual bugs: Qt used money in inventory for gold amount on tombstone;
that overlooks gold in containers and will be 0 by tombstone stage if
bones get saved. Year was recalculated from current date+time instead
of using the value that gets passed in--blindly flagging that variable
as UNUSED was a mistake.
During hallucination, actions which triggered update of persistent
inventory made Qt's display of map tiles for equipped objects have
those tiles switch randomly, but ordinary move-by-move fluctations
applied to floor objects left them alone.
Initially I took out hallucination of inventory items altogether,
but ended up putting that back and changing the floor hallucination
to affect Qt's paper doll too. The display.h change isn't needed
but I've left it in.
The revised options processing from however long ago broke using
'O' to change 'symset'. ('roguesymset' worked ok.) Picking it
in the main 'O' menu behaved as it nothing had been picked. The
symset-specific submenu wasn't offered to the player because a
two-line block of code was omitted.
It seems amazing that no one has noticed in all this time.
The end of game disclosure for inventory was passing want_reply==True
to the inventory display routine. I don't know why because you can't
select anything. This resulted in Qt disclosure showing inventory
with the [Ok] button disabled and blank boxes instead of object
glyphs beside the inv letters. Changing to want_reply==False fixes
both aspects of that.
It has no apparent effect on tty or curses; on X11 (where [Ok] was
already enabled) it disables the [Search] button, a plus. I don't
know whether it might mess up final disclosure for inventory on
WindowsGUI. Or whether any interface which uses perm_invent window
for final inventory disclosure (if there are any) will be adversely
affected.
Noticed while working on Qt's version of persistent inventory
window (paper doll-style display of equipment in use), leashing
or unleashing a pet wasn't updating persistent inventory. Leash
descriptions format differently when in use so immediate update
is warranted.
The Qt menu entries which were executing nethack's help command
(the '?' menu) were doing so because their command keystroke was
a meta-character and such characters are being converted to '?'
to indicate an error in conversion to Latin1 character set. The
old Qt3 code didn't perform any such conversion.
This fix feels fragile because there are two different places
deciding how to disambiguate partial extended commands (the code
for Qt's '#' handling and a new routine in the core). Qt menus
now send '#' and enough letters to satisfy '#' handling for any
command which uses M-c or has no regular keystroke nor M-c one.
(If it were to send the full extended command name, the letters
after the unambiguous prefix would be left in the input queue to
be processed as subsequent commands.)
There is a fundamental problem that this doesn't address: if
the player uses BIND directives in the run-time config file, the
Qt menu bindings will break unless the BINDs are all done before
selecting windowtype. Qt's menu bindings translate a click on
a menu entry into the keystroke used to invoke the corresponding
command, so using BIND to change that after the menus are set up
will result in the wrong commands being executed.
An earlier change resulted in place_worm_tail_randomly() sometimes
removing a long worm from the map unintentionally. It was still on
the monster list so if wizard mode sanity_check option was On, there
would be warnings of a monster which isn't on the map.
The change which triggered this was necessary so I'm inclined to
blame place_worm_tail_randomly() laziness.
This is a superset of the pull request's fix.
Fixes#377
Instead of an additional options file directive to end the last
section of a CHOOSE directive, simplify by using an empty-name
section, [], instead. So
...
CHOOSE one,two
[one]
...
[two]
...
[]
...
As with the short-lived END-CHOOSE directive, if no [] is present
then the rest of the file is part of the last choice.
Add an optional way to terminate the last section after a CHOOSE
directive in the run-time options file so that it's possible to
revert to common options. If no END-CHOOSE directive is present
then the last CHOOSE section continues until the end of the file.
(All existing uses of CHOOSE already behave that way.)
Change the Guidebook to refer to OPTIONS=x, AUTOPICKUP_EXCEPTION=y,
CHOOSE=z, and so on as "directives" rather than "statements". It
just feels like a better fit.
When there was only one supported interface included in the program,
feedback of
|Supported windowing system:
|"tty" (traditional text with optional line-drawing)
was missing the intended final period. When there were more than
one, the clause describing the default could be preceded by a
spurious space.
|Supported windowing systems:
|"tty" (traditional text with optional line-drawing) and "Qt" , with a
|default of "tty".
There was a fixup for " , " but it only worked as intended when
that was on the last line, not when the default's text spanned lines.
This adds description of "Windows GUI" to the mswin entry. X11 could
have its formal name "The X Windows System" as the description but I
didn't add that since it just seems like extra verbosity. Apparently
Qt doesn't stand for anything else so still has no extra description.
options.c gave some unused variable warnings in the 'msg_window'
parsing if compiled without having tty enabled.
The 'msg_window' option should be available if either tty or curses
is the interface in use, hidden otherwise. The code to parse it
was included if TTY_GRAPHICS is enabled, so it worked in curses for
a tty+curses binary but not curses without tty one. This fixes that.
It is still displayed by 'O' when X11 or Qt is in use if the binary
also supports tty or curses. I've left that as is.
Assuming you have the prerequisite packages, You can specify the
window ports to include on the make command line:
make WANT_WIN_QT=1 WANT_WIN_X11=1 WANT_WIN_CURSES=1 WANT_WIN_TTY=1 all
Prequisites for window ports beyond tty:
(some sample homebrew commands to obtain them shown but that is not the
only way):
xquartz for x11 support
brew install xquartz
Qt for Qt support
brew install Qt
When chatting to the quest leader to try to gain access to the
rest of the quest, if your experience level is good enough but
your alignment strength isn't, in wizard mode you'll get prompted
about whether to have piety boosted. Normally you would answer
'y' and be able to go to lower quest levels. But if you answer
'n' you'll immediately be prompted a second time. Not because
the no response didn't register but because the if/else-if/else
logic checks twice for whether your alignment is inadequate and
if you answered no the first time it will still be too low the
second, with the first answer not carrying over.
Fixes#376
When hunger state is "not hungry" (so omitted from the status line),
say so in the status section of ^X output. Mainly so that wizard
mode can append the internal nutrition value without inserting an
entire line that [previously] wouldn't be present in regular play.
Show an internal value for encumbrance too, although that would be
better if it also included some indication of the amount where the
encumbrance state changes. Encumbrance is confusing and I didn't
pursue that.
I noticed that Qt status showed both Lev and Fly at the same time
when they should be mutually exclusive (Levitation overrides Flying).
I wasted a bunch of time trying to track down a Qt problem but it
turned out to be a core issue. If Flying is set first (which won't
happen if both are set in the same #wizinstrinsic operation), setting
Levitation via #wizintrinsic was attempting to update the flag that
indicates that Flying is blocked, but doing so too soon and failing.
Setting Lev via other means while Fly was already set didn't have
this problem so it wouldn't occur during normal play.
Also, #timeout lists timed properties which can have a timeout value
in normal play, then a separator, followed by properties that can
only become timed due to #wizintrinsic. Move Displacement from the
second group to the first now that it can be obtained as a timed
value by eating a displacer beast corpse.
The check for mon's max HP being at least as high as its level
turns out to be wishful thinking. Just disable it. Maybe we'll
flag critters who got or gave up HP during cloning and let them be
exceptions, then turn it back on, but not now. Or maybe reduce
mon->m_lev when cloning. That would weaken them though.
Keep the 1 extra HP that an earlier fix for this check gave to
monsters who rolled the minimum possible value while being created
(Nd8 that yielded N boosted to N+1, 1d4 for 1 boosted to 2).
Tin handling code used tin->cknown to indicate that the variety
(soup, deep fried, pureed, &c) was known, but neither object
identification nor end of game disclosure was setting cknown for
that type of object.
^I behaves as if cknown is set, so the problem was hidden during
times when anyone was likely to be paying attention.
Adopt the suggestion that candy bar stacks which get split should
keep the same wrapper text for both halves of the stack. The patch
stuck with using obj->o_id to manage the wrapper which prior to the
patch wasn't a factor in merging and splitting. Switch to obj->spe
instead, comparable to tin varities, so mergability is already
taken care of.
End of game disclosure tacks on T-shirt text to formatted items.
Do the same for candy bar wrappers.
Recently combat between monster mind flayer and headless monster was
changed to skip extra tentable-for-drain_intelligence attacks after
hitting with one for no effect. Do the same for monster mind flayer
against headless poly'd hero and for hero poly'd into mind flayer
versus headless monster. As before, it only applies to additional
actions during the current attack. As soon as the attack is over,
the ineffectiveness of intelligence drain upon target is forgotten.
Give better feedback if reading a scroll of identify when it is the
only item in inventory (making that empty when scroll is used up).
Reading a cursed scroll of identify used to always ID 1 item besides
itself. Change it to behave like confused identify--only identifying
itself--if read when the scroll hasn't been discovered yet. Same as
before when scroll has already been discovered: identify 1 item.
I looked for places where changing "{blinding,acid} venom" into
"splash of {blinding,acid} venom" might make messages become too
verbose. Turns out to have been unnecessary work because the full
name won't be used unless you get a venom object in inventory and
formally identify it. Wizard mode, or bones from wizard mode, is
necessary for that to happen so the possibility can be ignored.
[The name change is still useful for wizard mode wishing though.]
Many messages use hard-coded "venom" instead of xname() so won't
be affected even if such identification takes place. However,
thitmon() was producing
|The <mon> is hit by the splash of venom.
|The splash of venom blinds the <mon>.
which seems rather redundant even without the longer full object
name. So change the second message to be generated as
|The venom blinds the <mon>.
It also shortens "cream pie" in first line to "pie" in second one.
Prevent corpses left by cancelled trolls from reviving. Their
revival is an innate ability but is clearly a magical one, so make
that be subject to cancellation magic.
Change existing corpses that are scheduled to revive to rot instead
if they get cancelled as objects. Rider corpses are excluded.
Uncancel an ice troll whose corpse is put into an ice box.
Commit e9f53ab7f6 at the end of May
to fix corpses taken out of ice boxes by monsters changed removing
corpses from ice boxes by anybody to always give them rot-away
timers, even for trolls. Make an exception for ice troll corpses:
give those revive timers instead.
A reddit thread mentioned that throwing rocks at unicorns behaved
the same as throwing gems at them: not treated as an attack and if
teleporting away is allowed, they will. Change to treat shooting
gems and glass at unicorns with a sling as an attack rather than as
just giving the gem or piece of glass to them, and treat throwing
or shooting rocks and gray stones as an attack too.
If picked up by blind hero while not yet seen, gems and glass
format as "gem" and rocks and gray stones format as "stone" so the
player can always tell the difference. Forgetting to unwield a
sling before interacting with a unicorn is on the player's head.
I tried wishing for "splashes of venom" but was told that no such
thing exists even though "splashs of venom" and "2 splash of venom"
both work to produce "2 splashes of venom". After the spurious
failure, retrying with EDIT_GETLIN enabled showed that "splashes"
had been singularized to "splashe" so fix that.
"2 splashes of venom" IDed to "2 uncursed blinding venoms" because
the base name omits "splash of" prefix. And due to that, explicitly
wishing for "splash of {acid,blinding} venom" didn't work either.
Change the names to include the prefix, and add a hack to makedefs
to keep generating the old macro names without the prefix. (Wishing
for "{acid,blinding} venom" still works due to post-3.6.6 changes
to " of " matching.)
A recent newsgroup or reddit complaint stated that only 75% of a
monks attacks used martial arts. It turned out to be true; the
'valid_weapon_attack' intended to control whether skill gets
exercised was being overloaded for skill use. So the monk's 1..4
base damage used skill for 2..4 but not for 1. That was never
intended (nor for other roles and other skills; a damage value of
1 is meant to miss out on a chance to train the skill for future
enhancement but should still get a skill bonus or penalty for the
current attack).
If hero is a monk who is wearing a suit, have ^X mention the to-hit
penalty for that in the status section even though it isn't a normal
status line item. Combat feedback makes it annoyingly obvious, but
player might forget if MSGTYPE=hide is used to suppress the "Your
armor is rather cumbersome..." message.
Noticed when the comment about "this can go away when compatibility
with 3.6.x is no longer needed" was modified recently. Make it and
the code it applied to go away.
The recently added sanity check for monster maximum HP was giving
false complaints when Nd8 monster had N mhpmax. Most noticeable
for level 1 monsters (level 0 monsters use 1d4 instead of 0d8 and
weren't affected) but possible for higher level ones if they were
unlucky--from their own perspective--with all their d8 rolls.
Give level N monsters a minimum of N+1 HP, so minimum of 2 for
level 1 monsters, making 1/8 of those stronger. Same minimum for
level 0 monsters, 25% of which will become stronger now. (The pull
request's patch gave every Nd8 monster 1 extra HP; this only does
so for Nd8 and 1d4 ones which have rolled lowest possible amount.)
Also relax the sanity check so that existing to-be-3.7 save files
don't continue to trigger sanity complaints for existing monsters
that have the old minimum.
Fixes 365
When a mind flayer scores a hit against a headless target (or worm's
tail), there's a message that says that the attack hits and that the
target is unharmed. Since an ordinary mind flayer has 3 such attacks
per turn and a master mind flayer has 5, it can become excessively
verbose.
This doesn't eliminate the attacks until a hit fails to do harm, so
ordinary misses still get repeated if they happen first. Once a
successful hit doesn't do anything, any remaining AT_TENT+AD_DRIN
attacks are silently skipped. That way feedback isn't as verbose
and mind flayers don't seem to be quite so stupid about using their
tentacles when those won't work. Unfortunately they need to relearn
the lesson every turn they attack.
hitting a hidden monster didn't reveal that monster. It stayed
hidden despite the feedback describing it as if it could be seen.
The pull request's two line fix handled a monster's blast hitting
another monster but left two related issues as-is: monster's blast
hitting hidden poly'd hero left hero unrevealed and poly'd hero's
blast left hidden monster unrevealed. Same code, different bug:
poly'd hero's blast affected mindless monsters.
This unhides an affected target before the message about it being
hit rather than after. That would look better if preceded by a
message describing the object (mimic or hides-under) or furniture
(mimic) or empty spot (ceiling hider) as being or concealing a
monster but I didn't put in sufficient effort to accomplish that.
Fixes#367Fixes#362
If the Wizard fled up the stairs on level 1 and escaped the dungeon
(which can only happen if he isn't carrying the Amulet or any of
the invocation items), the number_of_wizards counter wasn't being
decremented. If that was the only Wizard, he couldn't be brought
back into play because he wasn't on the migrating monsters list, and
he wouldn't appear on the Plane of Earth when the hero eventually
went there. If that was one of two, the remaining one couldn't use
Double Trouble anymore. (I'm not sure about Earth handling in that
situation; should be moot now.)
Wizard mode blessed genocide of "*" when the Wizard is on current
level caused the same problem.
Fix by keeping the number_of_wizards counter up to date if mongone()
is called for the Wizard, handling both cases. Also, don't let the
Wizard escape the dungeon unless he's one of two at the time, making
the first case no longer possible.
If wizard mode blessed genocide of "*" is used on the level where
the quest nemesis is present, the killed-the-nemesis feedback will
now be given. I'm not completely convinced that this was the right
thing to do, but it only applies to wizard mode so may not matter.
Fixes#372
Starting out replacing ambiguous pronoun "it" since it might seem
to be referring to "--More--" rather than to "...", then ended up
rewriting whole paragraph.