Noticed while working on Qt status highlighting: if levitation
and flying timed out at the same time, first Lev timeout called
float_down() which reported
You have stopped levitating and are now flying.
and then Fly timeout left stale "Fly" on the status line due to
an optimization which got subverted. ('was_flying' flag was
False due to Fly being blocked by Lev; that's correct behavior,
but the flag is effectively a cached value that becomes stale
when the Lev timeout code executes.)
The bug was wizard mode only because #wizintrinsic is the only
way to get timed flying.
commit 03d7d64d15:
| [...] but fixing this specific case is trivial.
Not trivial enough to avoid getting the details wrong. An old
commit log message (58137a608a,
June of 2006) claimed that this was fixed for bag of tricks but
that was for monsters in general; mimics could still be wrong.
Requested by a beta tester nearly four years ago: '$' is both an
inventory "letter" and a group accelator. The letter only works
if gold is on the current menu page and was taking precedence
over the group accelator. Allow '$' to toggle selection of gold
regardless of the page.
curses already behaves this way. X11 and Qt menus aren't
paginated so also pick gold even if the '$' entry in the menu
isn't visible at the time. No idea about Windows GUI...
When SCORE_ON_BOTL is enabled, you could tell how much gold is
inside a container with unknown contents by having 'showsore' On
and watching how much the score changed on the status line when
picking the container up.
Use horse/unicorn body parts. The result for HAIR is "mane"
which is appropriate. There's no field for SKIN so the question
of whether to specify "scales" is moot. (Snakes and dragons
describe HAIR as "scales" but that wouldn't be right for ki-rin.)
From an old bug report (sent directly to devteam, June of 2017):
wand or scroll of create monster becomes discovered if it makes
a mimic that is concealed as an object or as furniture within
the hero's view. Fixing this in the general case [when does
seeing a mimic as something other than a monster mean that the
mimic is being seen?] is a massive can of worms, but fixing this
specific case is trivial.
Let ki-rin cure themselves (of being stunned, confused, or blinded)
with their own horn, and make them be poison resistant. They
aren't unicorns but their horn is very much like a unicorn horn.
They're flagged no-corpse so this hasn't changed them to leave
behind a horn upon death.
They were flagged as animals who neighed but they are also spell
casters. I took the animal flag off (they're still no-hands so
shouldn't be able to use items; also, unicorns aren't flagged as
animals either) and changed sound to 'ms_spell'.
Condense the Qt status slightly, moving Alignment field from the
Conditons line to the Characteristics line and the Time and Score
fields from their own possibly blank line to the HP,&c,Gold line.
That's for statuslines:2, which is the default. statuslines:3
restores the previous layout. I tried to make that become the
default for Qt but it got messy fast and I gave up.
I also tried to make changing 'statuslines' back and forth on the
fly work but failed. I left the code in as #if DYNAMIC_STATUSLINES
but that isn't defined anywhere. For the time being at least,
'statuslines' is config file or NETHACKOPTIONS only for Qt, not
changeable via 'O' like for curses and tty.
Change the option description for 'statuslines'. That depended
upon whether curses was compiled in when it should depend on which
interface is active. This moves the alternate info to Guidebook.
I though that I noticed a problem but later couldn't reproduce
it, so this might not be redundant. Update persistent inventory
when putting on a helmet causes it to become cursed.
Minor change: if blind at the time, hero loses knowledge of BUC
state.
Try to set the initial window sizes to be big enough to show the
full welcome line in the message window when the Qt settings
(Preferences on OSX) specify Large font (Huge/Medium/Small/Tiny
seemed ok but I wasn't systematic about checking them).
While at it, I added a long comment about the status window format
and noticed a bug with experience formatting there. Again only
seemed to matter for Large font but the change to fix ignores font
size.
Plus add a couple of Qt "issues", one old and one just discovered.
If a monster threw a cocktrice egg that hit and petrified another
monster, the hero would credit (experience) and blame (possible
alignment penalty, &c) for it.
Fixes#410
Use a linked list to store stair and ladder information, instead
of having fixed up/down stairs/ladders and a single "special" (branch)
stair.
Breaks saves and bones.
Adds information to migrating objects and monsters for the dungeon
and level where they are migrating from.
Breaking a wand didn't require the hero to have free hands.
That's definitely a bug when they're both welded to the same
two-handed weapon. It's debatable when welded separately to
a one-handed weapon and to a shield but simpler to pretend
there's no such distinction.
This also makes glass wand join balsa wand as "fragile". Hero
doesn't need as much strength to break them as other wands and
the wording for breaking them is slightly different.
My fixes entry initially had a trailing space. When I took
that out, I spotted a couple of others so take those out too.
Attacking a concealed mimic at range by applying a polearm
could make the hero be stuck to that mimic in addition to
bringing it out of hiding. Only do that when adjacent.
This also adds a new sanity check when setting u.ustuck.
It may get triggered by other sticking activity since only
attacking has been tested. The check must be explicitly
enabled by setting the wizard mode 'sanity_check' option.
Fixes#408
Some eggs and tins could cause an out of bounds index into the
mons[] array. Post-3.6 bug: the faulty part of the test is only
relevant for 3.7 genetic engineer monster. Earlier versions just
called pm_to_cham() which does it's own index validation.
Fixes#406
Text window search behaved very strangely: at some point after
selecting [Search], entering a search string, having the string
entry popup go away, and having the search performed, but before
the result could be shown, the text window got pushed behind the
main window (map+messages+paperdoll+status). Clicking on the
main window's minimize button hid the main window and gave access
to the text window behind it. That was still functional even
after having been inaccessible; another search could be performed
and/or it could be dismissed. I still don't know what causes
that or how to properly fix it, but using raise() is a workaround
to bring it to the front where it belongs. Unfortunately you can
see it go away and come back so searching for text is distracting.
Allow <return> (when not searching) to dismiss all text windows
including RIP. Accept ctrl+[ as ESC.
Make text window searching be case-insensitive.
Searching wouldn't find a match on the first line of text. Now
it will.
This also includes an attempt to fix github issue #400 (typing a
pickup command while "things that are here" popup text window is
displayed seems to hang the program), but since I can't reproduce
that, I can't tell whether the fix works. The issue description
says that pickup started executing and "things here" couldn't be
dismissed which is different from "things here" being behind the
map waiting for it to be dismissed. The attempted fix is for text
window handling to tell Qt that it wants control of the keyboard,
so nethack shouldn't see any attempted pickup command.
If player got Qt's saved game selection widget at startup but
picked "new game" there, the save file for the last character
in the list of saved games would be clobbered with the new
character's game if a save was performed. It wasn't necessarily
easy to spot because saved game selection shows the character
name from inside the file rather than from the file name, so the
next restore would look normal except for one older character
missing.
Noticed while testing: when you used the character selection
widget (either by picking "new game" in saved game selection or
because there aren't any save files), if you blanked out the
name field or it was already blanked because a generic name like
"player" had been specified, then clicked on "play", the program
would get stuck in a loop somewhere. I didn't try to figure out
where, just changed qt_askname() to revert to original name if
it ended up with a blank one.
This fixes the Qt popup widget for selecting among saved games.
The character name from each applicable save file is shown in a
button and clicking on one of those buttons restores corresponding
file. Previously all the buttons were written on top of each
other so only the final name was visible and the button for the
initial name received the click. The widget also has [quit] and
[new game] buttons.
This fixes restoring an existing save file if no character name
is supplied on the command line in the options. It does not fix
the problem where picking [new game] remembers the file name of
the last saved game in the popup's list and overwrites that file
(after requesting confirmation to do so) if/when you eventually
save. The resulting file will contain the character just saved
but be named for the earlier one. It may not be obvious because
on subsequent restores it will list names from inside the files
rather than deduce those from file names, so the clobbered/
misnamed file will just show up as the former new character.
I'm not sure whether any yn_function() calls include ampersand
in the list of acceptable choices but if any did, the button
for that character would have shown up blank. (Clicking on it
would have successfully produced '&' as player's input though.)
Add support for the 'hitpointbar' to the Qt interface. Rather
than rendering the status title (name+rank or name+monster_species)
using inverse video for leading substring to produce distinct left
and right sides, draw a horizontal bar above that field.
The left portion (current health) is thicker and uses red for <10%
or <5hp, orange for <25% or <10hp, yellow for <50%, green for <75%,
blue for <100%, and black for 100%.
The right portion (missing maximum health) is thinner and runs
from white (paired with red), light gray (paired with orange),
dark gray (with yellow), plain gray (which turns out to be darker
than dark gray, with green), dark blue (with blue), and black (but
black is never shown for injury portion because that's suppressed
when at full health).
Qt already supports a square frame around the hero's map tile that
changes color according to health. Turning the hitpointbar option
Off or On has no effect on that.
When a monster used a fire horn or frost horn to attack the hero,
the feedback claimed that the attack was being directed at itself.
The error occurred in code that was added to 3.7 during 3.6
development but wasn't present in 3.6.x so fixes entry is in the
"exposed by git" section.
Monsters with rust attacks (rust monster) and corrosion attacks
(black pudding, gray ooze) can eat or otherwise destroy iron bars
but xorns could only move through the iron bars spot without being
able to eat the metal there. Change xorn to eat bars instead of
phazing through them. Lets rock moles eat bars too.
Hero polymorphed into a rust monster would eat bars if trying to
move to their location but couldn't do so if already there (maybe
was in xorn form and now in rust monster form). Xorns could pass
through them but not eat them. Allow hero metallivores to eat
bars at the current location via 'e', similar to eating food off
the floor. Hero as rock mole behaves like rust monster.
When a zombie (or lich) kills a monster in melee without a weapon,
the monster can rise few turns later as a zombie.
The only creatures that can be zombified are ones that actually have
a zombie counterpart monster. A zombie cannot turn a jackal into
a zombie, for instance. But it could turn a shopkeeper into a human
zombie, or a dwarf king into a dwarf zombie.
Zombies will fight with monsters that can be turned into zombies.
Originally this was a SliceHack feature, but this is based on xNetHack
version of it, with some modifications.
When the game windows were initialized, the anhk icon for alignment
was centered relative to Lawful/Neutral/Chaotic label but during
the first status update it noticeably shifted left. Non-blank
hunger or encumbrance states could change from centered to left
justified when they were present and the icon was replaced. Oddly,
resetting the 'centered' attribute for the widget wasn't sufficient
to fix this. Running the resize code for that widget did. Another
case of trial and error to make things work the way they ought.
Also, don't highlight a change in alignment or dungeon location as
"got worse" if the internal numeric value went down instead of up;
always highlight as "got better" for those two fields. There ought
to be a third choice for just "changed" but that would have been
more complicated.
New for Qt, moving the mouse over one of the slots in the paperdoll
inventory subset and letting it pause there will use Qt's tool tip
mechanism to give a description of the item under the pointer, if
there is one, or of what the slot would contain when there isn't.
So "e - uncursed leather gloves (being worn)" or "no gloves" when
the pointer is over the glove slot. If you do something with the
keyboard to make the paperdoll change while the mouse is still
hovering, you'll need to move the pointer slightly to have Qt
recheck for tool tip at that spot. It may be feasible to force
an immediate update, but I'm satisfied with how it's working.
Interestingly, you can move pointer and hover while yn_function()
has asked you to pick an inventory item and is waiting for an
answer. Mostly useful for Take-off/Remove or #adjust.
The toolbar contains do-Again, Pick up, Drop, Kick, Throw, Fire,
Eat, and Rest. Insert Search in front of Rest since it's useful
in its own right and some players prefer it even when resting.
Includes a new 12x13 icon; a tiny magnifying glass shown straight
on is something I can manage.
Both the toolbar button for pick up and the action menu entry for
pick up were labeled "Get". That's confusing for an experienced
player who is looking for "Pick up". Rename both of them.
Also, consolidate repetitive code used to set up toolbar buttons.
An issue in the core made the "Zz" button in the Qt toolbar only
work if rest_on_space was enabled. cmd_from_func() was returning
' ' instead of '.' for the keystroke to run the rest command.
Use ansimpleoname() instead of doname() to describe the key or
lock pick or credit card when reporting "You can't fix a chest's
broken lock with a <foo>." doname() includes BUC status when
known and feedback mentioning a particular bless/curse state on
the tool that can't be used to fix the lock suggests that some
other bless/curse state might be viable.
Clicking on the status panel runs ^X to show character and status
information without abbreviations. The code needed is identical
to what's now used for clicking on the paper doll inventory panel
except for the command to execute.
Clicking on the paper doll inventory subset window will cause
the '*' command (#seeall) to execute. They convey the same
information (unless multiple leashes or multiple light sources
are in use; seeall lists all of them instead of just the first
of each) but the doll shows the info with a small grid of map
tiles and seeall shows it with an inventory display of worn and
wielded items plus tools in active use.
Ideally it should show information about a specific item as a
"tool tip" when the mouse hovers over one of the doll slots.
I don't know whether I'll ever attempt to tackle that or even
if that's feasible with Qt. Perhaps use right click instead.
Remove a 'TODO' for once. Have the popup that's used to accept the
target string--after clicking on [search] or typing ':' to initiate
menu search+select operation--force keyboard focus to itself. Menu
searching worked without this, but only if you manually clicked on
the search popup prior to typing the target string. Failure to do
so resulted in typed characters being used to select menu entries.
roll parts of pr385 into source tree
This does not take the PR as is.
Unlike the PR, this streamlines and minimizes the integration somewhat:
- use hints/include mechanism instead of creating alternative
Makefile.dat, Makefile.src, Makefile.top, Makefile.utl in sys/lib;
those would have been a maintenance nightmare.
- don't have alternative mkmkfile.sh and setup.sh in sys/lib.
- sys/lib/libnethackmain.c differed from sys/unix/unixmain.c by
very little, so just place a small bit of conditional code at the
top of sys/unix/unixmain.c instead.
- changed the conditional code bits from __EMSCRIPTEN__ to
CROSS_TO_WASM.
- You should be able to build the wasm result by:
cd sys/unix ; sh setup.sh hints/linux.2020 ; cd ../..
make fetch-lua (<-one time)
make WANT_LIBNH all
- You should be able to build LIBNBH by:
cd sys/unix ; sh setup.sh hints/linux.2020 ; cd ../..
make fetch-lua (<-one time)
make CROSS_TO_WASM=1 all
As it is currently coded, winshim.c requires C99.
For Qt with 'popup_dialog' On, fix number entry when user types
a digit (or '#') directly onto the dialog instead of clicking
inside the Count box and then typing. Before, that first typed
digit was starting out as selected, so typing the next digit
replaced the selection instead of getting appended to the string
of digits being constructed. Fixed by moving the relevant code
to the KeyPress handler instead of re-executing the dialog.
Also, if a keypress is just a modifier, ignore it. The next
event should be the actual character. Prevents treating <shift>
(and <caps lock>!) as useless dialog responses. Before this,
attempting to type '#' to initiate a count wouldn't work because
the <shift> part of shift+3 ended the dialog. Now '#' works
(and is still optional; starting with a digit suffices).