number_pad==1 adds
'5' => 'G'
M-5 => 'g'
'0' => 'i'
number_pad==2 swaps 5 and M-5 and adds M-0
'5' => 'g'
M-5 => 'G'
'0' => 'i'
M-0 => 'I'
M-5 and M-0 were missing from the bound key handling; they still
used hardcoded digits even though the actions for plain 5 and
plain 0 can be bound to other keys these days. This implements
the M-5 variation as NHKF_RUSH2. Changing numpad from 1 to 2
or vice versa will swap the NHKF_RUN2 and NHKF_RUSH2 actions
regardless of what keys they're assigned to. I haven't done
anything for unimplemented NHKF_DOINV2 though (and am not
planning to in case someone else wants to jump in...).
This also fixes the description of the 'I' command. The extended
command name for that still misleadingly refers to "type" rather
than "class" though.
When ?i shows key bindings, at the end of each group (movement,
prefixes, general, game, debug) report any commands for that
group which don't have any key assigned. Movement and prefixes
all have keys; they'd be pretty useless without and key bindings
won't override movement commands. For general, the "keyless" are
|#exploremode
|#herecmdmenu
|#therecmdmenu
after this adds the relevant flag to their command definitions;
for game, "#terrain" is the only one; the debug section has 20.
There is a known problem that I've going to pretend that I didn't
notice: if I use BIND=D:takeoffall then 'A' becomes unassigned,
'D' invokes #takeoffall, "#droptype" becomes keyless, and ?i
reports those correctly. But if I use BIND=M:takeoffall, 'A'
becomes unassigned, 'M' continues to be its usual prefix, and
the "#takeoffall" command is nowhere to be seen. The code that
tracks assignments is letting that case fall through the cracks.
'M' ends up assigned to both and the ?i code deliberately only
shows the first.
While testing some addtional ?i (list of key assignments)
changes, I wanted to give every key a binding. When I tried
BIND=M-^A:exploremode
the text to key conversion didn't like that. This adds support
for M-^x and M-C-x plus variations where dashes are omitted.
This adds support for ^? even though that isn't really a
control character. I bound #terrain to it and surprising--to
me at least--the <delete> key worked to invoke that command.
Also changes 'char txt2key(...)' to be 'uchar txt2key(...)'.
I was implementing a routine to show all the key bindings
when I discovered that we already have one. This fixes a few
small problems: 'n' prefix for number entry was missing for
number_pad mode. Meta+<direction> for running in number_pad
mode was missing too. ^A was present but being suppressed by
lack of #define for obsolete #if REDO. And ^C was shown as ^c
while all other ^ characters appear in upper case. Once ^A
appeared as the line before it, the inconsistency stood out.
I also changed the slightly verbose "Shift-<direction>" and
"Ctrl-<direction>" entries below the direction grid to use plus
instead of minus signs. Plus emphasizes that two things are
combined so seems more intuitive. (I left "M-c" alone.)
The two or three (wizard mode) menu choices at the start of
the '# ?' help menu look enough like headers that it can be
confusing. They're asking about changing the view of commands
to what those entries describe, but if considered as headers
they're describing the opposite of what is currently displayed.
Make them more verbose to try to clarify the situation.
This also moves the 'm' flag in front of the 'A' in the middle
column (of name, flag(s), description) when they both apply.
Rename "seegold" to "showgold". The character to invoke it ('$')
is similar to those for the various "seeXYZ" commands ('[','=',&c)
but unlike them, it isn't part of "seeall" ('*').
Expand or replace the one-line description of several commands
(shell, showgold, showtrap, suspend, versionshort).
Noticed while working on Qt's extended command handling, there
are an awful lot of "seeXYZ" commands. Keep the inventory display
ones (named versions of ')' to show wielded weapon(s), '[' for
worn armor, '"' for worn amulet, &c) and rename the others:
| #seenv -> #wizseenv debugging command
| #seespells -> #showspells '+' command
| #seetrap -> #showtrap '^' command
Also, expand the descriptions of #shell and #suspend a bit in
the Guidebook. LaTeX version is untested.
Since ^V is dead key for me with Qt on OSX, I use #wizlevelport
instead. It's annoying to have to type all the way up to the
'p' for it to become distinct. Rename the biggest conflict,
\#wizlevelflip to #wizfliplevel. I still have to type as far
as the first 'e' for #wizlevelport but 6 characters are easier
to type than 10.
It wasn't in the Guidebook so I've left things that way. I am
adding it to 'wizhelp' though.
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.
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.
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.
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.
Change obj->oextra->omid from a usually-Null pointer field in
oextra to a simple 'unsigned' that doesn't need any allocation
beyond obj->oextra itself. Value 0 means that it is not in use;
it is used to hold a monst.m_id and those are always non-zero.
Delete unused obj->oextra->olong. 'olong' used to be the last
field in struct obj, put there to force alignment of anything
which followed it back when obj structures were over-allocated to
append extra information. It had a comment about being used for
temporary gold but whatever that was, temporary gold was gone long
before obj->oextra got introduced.
Bump EDITLEVEL since this invalidates existing 3.7 save files.
Remove a bunch of tabs from obj.h and save.c.
Unicorn horns are just too good. Nerf it in similar way several
other variants have done: don't let it restore attribute loss.
This makes potion of restore ability more valuable, and the
int loss from the (nerfed) mind flayers matter more.
Generally speaking there's no reason to wait or search next to
a hostile monster, so let's just prevent those actions. You can
still do those commands by prefixing them with the 'm' prefix.
A couple of the new prototypes used 'char' where 'CHAR_P' is needed.
Also, move them out of middle of long block of command declarations.
I started to reorder the prototypes into the order in which those
functions appear in the file but gave that up pretty quickly.
When replacing Mines' End or top of Sokoban, the achievement for
finding the special prize there is reset. But the code to do so was
accidentally inside the monster processing loop and got repeated for
each monster on the old instance of the level (essentially a no-op
after the first one though). That code had been updated more than
once without noticing. Move it out of the loop.
Give wizard mode player control over how a level gets transposed by
prompting for the desired outcome.
Refreshing the screen showed that remembered, no longer in view wall
corners and T walls were shown with their old orientation instead of
being transposed along with the level. This fixes that, but does so
by adding a chunk of code that will be irrelevant for normal play.
When a special level is created, there's a chance it gets flipped
horizontally and/or vertically.
Add new level flags "noflip", "noflipx", and "noflipy" to prevent
flipping the level. Add a wiz-mode command #wizlevelflip to test
the flipping on current level - although this doesn't flip everything,
as level flipping is meant to happen during level creation.
Provide a way to communicate additional behaviors and/or appearances
desired from NetHack window port menus.
This is foundation work for changes to follow at a future date.
Setting or clearing u.ustuck now requires that context.botl be set,
so make a new routine to take care of both instead of manipulating
that pointer directly.
Introduce eight achievements that can be attained by more players.
Entered Gnomish Mines - self explanatory
Entered Mine Town - the town portion, not just the level
Entered a shop - any tended shop on any level
Entered a temple - likewise for temple
Consulted the Oracle - bought at least one major or minor oracle
Read a Discworld Novel - read at least one passage
Entered Sokoban - like mines
Entered the Big Room - not always possible since not always present
The novel and bigroom ones aren't always achieveable since novels are
only guaranteed if a book or scroll shop gets created and bigroom is
only guaranteed in wizard mode. No one ever claimed that every
possible achievement can be attained in a single game. (If one for
entering the Fort Ludios level--or perhaps entering the Fort itself--
eventually gets add, that won't be possible in every game either.)
The mine town one probably needs some tweaking. Two of the town's
seven variants have no town boundary (despite a rectangular area of
pre-defined map) and at present simply arriving on either of those
levels is enough to be credited with the entered-town achievement.
Bump EDITLEVEL because u.uachieved[] has increased in size. This
time it has been expanded to the maximum that xlogfile's bitmask of
achievements can handle, enough for up to 9 more achievements without
another EDITLEVEL increment.
Instead of an assortment of bits, assign numeric indices to the
potential achievements and keep an array of those in the order they
were attained. So disclosure might show the same subset occurring
differently in different games depending on the player's actions.
The encoded field in xlogfile doesn't care about that and remains
the same.
Modifies 'struct u', so EDITLEVEL has been incremented and existing
save files are invalidated.
Move enlightenment and conduct from cmd.c to insight.c. Also move
vanquished monsters plus genocided and/or extinct monsters from end.c
to there. And move the one-line stethoscope/probing feedback for
self and for monsters from priest.c to there.
Achievement feedback has been overhauled a bit. When no achievements
have been recorded, the header for them (after conducts) won't be
shown, and when at least one has been recorded, make the prompt for
asking whether to disclose conduct be about disclosing conduct and
achievements. Also, describe achievements in the Guidebook.
I ran out of gas before updating Guidebook.tex; it will catch up to
Guidebook.mn eventually.
Some of the MS-DOS Makefiles haven't been updated yet so linking
without insight.{o,obj} will break there.
When disclosing conduct at end of game (but not during except in
wizard mode), display achievements too. They're also included in
dumplog if it's enabled. Previously they were only output as an
extra field in xlogfile.
This turned out to be a lot more work than I anticipated, but it is
definitely simpler (other than having #wizmakemap take achievements
away if you replace the level that contains the 'prize', which wasn't
handled before).
I cheated and made Mine's End into a no-bones level because the new
flagging scheme for luckstone, bag, and amulet can't carry over from
one game to another. It probably should have been no-bones all along.
Sokoban didn't have this issue because it's already no-bones.
Existing save files are invalidated.
Make wearing a wet towel confer new attribute Half_gas_damage in
addition to the usual blindness. It reduces damage from being inside
a gas cloud region and from being hit by poison gas breath attack.
It also fully blocks breathing of potion vapors.
Might make the Plane of Fire easier although overcoming its blindness
with telepathy won't reveal elementals. Definitely has the potential
to make blind-from-birth conduct easier which wasn't the intent and
probably isn't significant.
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".
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.
groundwork only - window port interface change
This changes the last parameter for add_menu() from a boolean
to an unsigned int, to allow additional itemflags in future
beyond just the "preselected" that the original boolean offered.
There shouldn't be any functionality changes with this groundwork-only
change, and if there are it is unintentional and should be reported.
This adds a boolean option, autounlock, defaulting to true. When this is
set to TRUE, messages stating that some door or container is locked are
automatically followed by a prompt asking if you would like to unlock
it, if you are carrying an unlocking tool (key, lock pick, or credit
card).
Architecturally, this extends the pick_lock function to take three
additional arguments (door coordinates or a box on the ground you are
autounlocking).
The code that selects an unlocking tool will always look first for a
skeleton key, then a lock pick, then a credit card. Since curses, rust,
and other attributes don't really have an effect on the viability of the
unlocking device, it didn't seem to warrant making a more complex
function for that.
Add hallucinatory trap names
This adds many funny, realistic, and nonsensical traps to the game, to
be shown when the player is hallucinating.
Architecturally, the biggest change is merging the what_trap macro and
the "defsyms[trap_to_defsym(ttyp)].explanation" pattern into a single
function "trapname", which returns the name of the trap, handling the
hallucination case. There is also a second parameter used for overriding
hallucination in the occasional cases where the actual trap name should
always be returned.
In addition, the what_trap and random_trap macros are now obsolete and
not used anywhere, so they are removed.
reinstate anti-rng abuse bit on hallucination
updates to hallucinatory trap names and fixes37.0 entry