The special level loader would allow the level description to specify
an alternate monster appearance for any type of monster, and if one
was specified for a mimic then that mimic would be polymorphed into
the appearance instead of masquerading as it. This changes it to
only use an appearance for mimics, the Wizard, vampires, and general
shapeshifters (chameleons, doppelgangers, sandestins). The mimic
case doesn't work as expected: map display shows the symbol for the
specified shape but farlook describes it as a mimic. The Wizard case
hasn't been tested. The chameleon and vampshifter cases seem to work.
It also allowed shapechangers (including vampires) to be given an
object or furniture appearance. I didn't try things out to find out
what what their behavior would be if/when that happened.
I'm not sure whether the farlook issue for mimics-as-monsters is with
the pager code or the monster name formatting code. (Possibly the
mimic just needs to be flagged has 'hidden' as well has having an
alternate appearance.) I'm not going to worry about it since none of
our special levels attempt to give mimics a monster shape. Mimicking
a monster is a feature for clones of the Wizard, not for mimics,
although it might be nice if the latter worked correctly someday.
This should maximize save file compatibility between 3.6.1 and 3.6.0,
at the risk of breaking save files for folks using post-3.6.0 git
sources. (It's unlikely that many in that situation are using a
configuration which will be affected, so probably nobody will notice.)
When a monster killed a paper golem with a fire attack, the player was
told that the golem "burns completely" yet it might still leave some
blank scrolls as 'corpse'. The fix for that was one-line, but several
other death-by-fire situations which didn't report "burns completely"
were also leaving scrolls: fireball spell or scroll of fire or other
fire explosions (if any), also wand of fire. Fire trap and poly'd
hero with fire attack were already suppressing 'corpse'.
It seems to me that the reaction to "you feel dead inside" when you're
polymorphed into an undead creature at the time would be "so what else
is new?". Vary the "dead" when current form is something which gets
reported as "destroyed" rather than "killed" when killed. That happens
for things flagged as non-living. Now undead "feel condemned inside"
and golems "feel empty inside". Neither of those are ideal but they're
more interesting than "feel dead inside".
After becoming dead inside, give a reminder about that during
enlightenment and if you restore a saved game in that condition. It
was the latter that set this in motion: I wanted to confirm that
restoring with u.uhp == -1 didn't give "you aren't healthy enough to
survive restoration" when polymorphed. (It doesn't; the game resumes
and you'll die if/when you rehumanize.)
Some windowports that are currently being written by third parties
need more information about the engine than they currently have.
Two specific reported problems: a) needing to know whether a
putstr() call relates to a count (so that it can be placed in a
different part of the user interface from the message area); b)
needing to know whether a request for a character relates to
command input (some hangup handling routines need this so that
they can determine what behaviour is potentially exploitable).
Knowing whether or not you're inside parse() fixes both of them.
This would be cleaner to do by changing the windowport API, but
that'd break existing windowports, which isn't really ideal.
Setting a globalish variable that the windowport can inspect, but
can ignore if it prefers, means that existing windowports will
continue to work fine, but new windowports will have more
information and thus more flexibility in how they handle command
entry.
Due to the new player selection dialog I did, it was possible
to rename your character - but this didn't rename the lock files
and tried to load a save from the wrong name.
This is a bit of a hack, but seems to work and didn't seem to
cause problems for the tty.
Doors in des-files were always generated vertically.
This wasn't visible unless you had separate symbols for
closed vertical and horizontal doors, or used tiles.
Added support to detect when the current console font has glyphs
that are too wide and will cause rendering errors in the console.
If detected, we warn the user and change the code page to 437
and the font to Consolas. At exit, if we had changed the font
and code page then we will restore to the original font and code page.
Defined strbuf_t and related routines to support dynamically sized
strings. Modified strip_newline() to strip the last newline in a string
instead of the first.
Simplified splash window code using new strbuf_t.
Prior to exiting game, re-enable getreturn and call wait_synch() in
case there is buffered raw prints that must be displayed to user.
The followup message about the fix for #5056 was trapped by the spam
filter so didn't reach us for a while.
xlogfile has an extra field to track various achievements made during
the game it logs, two of which are fully exploring the gnomish mines
and fully exploring sokoban. Those are accomplished by finding the
special 'prize' item on the final level of their branch: luckstone
for mines and bag of holding or amulet of reflecition for sokoban.
3.6.0 had a bug where any item of the target type found anywhere in
the dungeon resulted in achieving the relevant goal. A post-3.6.1 fix
for that required that the item be found on the end level of the branch
and attempted to require that it an item explicitly placed there by the
special level loader, but the latter aspect had a bug which meant that
random items of the appropriate type placed on final level would count
as the prize. Chance of extra luckstones on mines' end is fairly high,
so potential for false completion of the achievement was also high.
The second complaint was that since the achievement was only recorded
if the special prize item was found on final level, then if a monster
took it to another level then the achievement became impossible. (Not
true, the player could take it back, drop it, and pick it up again, but
that is admittedly a pretty silly hoop to jump through.) On the other
hand, if a monster removed the item before the hero found it, then a
case could be made that the hero hadn't really fully explored the
level. However, this fix records the achievement no matter where the
hero picks up the item. The final level must be entered--otherwise no
monster could possibly acquire and transport the item--but it isn't
guaranteed to have been fully explored. Big deal....
The prize could also be acquired in bones data. Before the second
portion of this fix, that wouldn't have mattered. But now it does, so
clear the prize indicator when saving bones unless it happens to be the
same level where that item is created (impossible for sokoban, where no
bones are left; not sure offhand about mines' end). The former prize
stone or bag or amulet becomes an ordinary one of its type.
This can all be done in a much cleaner fashion once we give up on the
current save file compatability. Putting obj->o_id values into new
context.mines_prize and context.soko_prize, plus a hack to mkobj() to
not reuse those two values if the o_id counter ever wraps back to 0,
would cover most of the details. Adding an achievement tracking flag
to lev_comp's object handling for use by the special level loader
would cover most of the rest.
Poly'd into a giant with a full inventory that already contains at
least one boulder, moving onto a boulder (that can't be pushed due
to a wall or other obstacle) yielded
You try to move the boulder, but in vain.
However, you can easily pick it up.
You are carrying too much stuff to pick up another boulder.
You see here a boulder.
The second and third statements contradict each other. Make the
code that dishes out the second message smarter. If autopickup is
set for it and you will pick up the boulder:
However, you easily pick it up.
If autopickup is not set for it but would have worked if it was:
However, you could easily pick it up.
If your inventory is full and you have a boulder (or are in Sokoban)
However, you easily push it aside.
That last one is instead of "however, you can squeeze yourself into
a small opening" that you'd get if not a giant and not carrying much.
Reading a scroll while blind is permitted if you know its label, but
message is "as you pronounce the words, the scroll vanishes" unless
you are poly'd into a form which can't make sounds, in which case you
"cogitate" rather than "pronouce". Switch to the cogitate variant if
you are suffering from strangulation.
Casting spells didn't even have the distinction; you could cast them
without regard to speech capability. Check for that. Unlike with
scrolls, now you can't cast if you can't speak (or grunt or bark or
whatever) instead of having a variant description of the action, so
this is a bigger change.
The dialog shows the player's name, race, role, gender, and
alignment in a single window, similar to the Qt4 dialog.
Also allows randomizing the character selection.
Use the dialog by setting OPTIONS=player_selection:dialog
Fix several warnings about using 'void *' for a function pointer and
a couple of unused variables. Add a_nfunc for 'int NDECL((*func))'
alternative for union anything. Make the enum list of union anything
types actually match the alternatives (field a_uchar was missing from
enums, enum mask32 had no corresponding a_mask32 field).
Add another command, #therecmdmenu, so that the context menu for an
adjacent spot can be tested without mouse support. It revealed that
you could get an empty menu if nothing applicable was at target spot.
Add a few adjacent actions: lock/unlock door if carrying suitable
implement, search door for traps, examine known trap (door/ceiling,
not door), #untrap known trap, mount saddled critter, remove saddle.
Make "kick door" be the last choice for closed door instead of first.
Add one 'here' action: dismount.
Both #herecmdmenu and #therecmdmenu interact strangely with ^A, but
differently from each other. I didn't make any attempt to solve this.
There's no documentation for #therecmdmenu.
Add a new boolean option herecmd_menu. If this is on, and using
a windowport that supports mouse, clicking on your character pops
up a menu of actions doable in that location. Basically this is
nothing new, as almost all of the same actions were done before
on the mouse click.
You can also pop up the context menu with the #herecmdmenu
extended command
Accidentally caused by my grappling hook fix 2 months ago, attempting
to jump over water made hero enter that water and drown (or crawl out).
hurtle_step() was originally intended to be used for recoil while
levitating, but it is used in other situations where not levitating
and behavior for the two circumstances should be different.
This doesn't fix things properly, just gets jumping working again.
Make #untrap while carrying the non-cursed (for rogues) or blessed
(for non-rogues) Key work the same as #invoke has been doing (without
regard to its bless/curse state): when used on trapped door or chest,
that trap will always be found and disarming it will always succeed.
It should work when carried by monsters too: if they try to open a
trapped door while carrying the Key (must be blessed since they're
not rogues) the trap will be automatically disarmed. (Caveat: that
hasn't been adequately tested.)
TODO (maybe...): change the #invoke property to detect unseen/secret
door detection instead of #untrap. The latter isn't completely
redundant; it works when the Key is cursed. But quest artifacts
strongly resist becoming cursed so that isn't a particularly useful
distinction.
Also, trap hints when wielding the Key without gloves didn't notice
adjacent door and chest traps. Now it does. And the behavior is
slightly different: known traps covered by objects or monsters are
treated like unknown traps as far as the hot/cold hints go.
Originally by Ray Chason for 3.4.3, based on the Qt windowport by
Warwick Allison. The look and feel is mostly the same.
Some improvements over the Qt 3 interface are:
* Panes are resizable
* Full support for IBMgraphics, and walls and corridors are drawn with
graphical primitives for a continuous appearance no matter what the font
says
* Lots of irritating glitches fixed
* Menus support proportional fonts correctly
Adding this because the old Qt windowport cannot be compiled on Qt4,
even with Qt3 compatibility stuff.
TODO:
- background map glyphs
- status hilites
- menucolors
If the key is wielded and touching skin (that is, you're not
wearing gloves), it will give heat-related messages like
minesweeper, counting the undetected traps around player.
Adjust the Candelabrum of Invocation's weight when it has candles
attached. This has been a known issue ever since the candelabrum and
candles were introduced.
When the candelabrum burns out, update persistent inventory window to
show that it no longer has candles.
thitu() is mostly used for arrows and darts "thrown" by traps, but
scatter() uses it on items launched by a land mine explosion. Traps
had no need for potion handling, but scattering does. Changing thitu()
to call potionhit() required that more information be passed to the
latter in case killer reason was needed, and thitu()'s callers needed
to be updated since it now might use up its missile (only when that's
a potion, so scatter() is only caller which actually needed to care).
Quite a bit of work--especially the testing--for something which will
never be noticed in actual play. In hindsight, it would have been
much simpler just to make scatter destroy all potions rather than
allow the 1% chance of remaining intact (via obj_resists()), or else
leave any intact ones at the explosion spot instead of launching them.
Turning the boolean option force_invmenu makes all the commands
that ask for an inventory item pop up a menu instead of asking
a text query. This should be much more friendlier to new
players, and is very useful for window ports on systems
with touch screens and no physical keyboard, such as cell phones.
Reported directly to devteam, player threw a troll corpse into lava and
then later got messages about it reviving and burning to death. Items
thrown, kicked, or dropped into lava were being subjected to fire damage
(so scrolls burned up, potions boiled, non-fireproofed flammable weapons
and armor eroded), but corpses and a lot of other stuff not subject to
erosion remained unaffected. This makes things that are made out of
wood, cloth, flesh and other flammable stuff burn up (when in lava, not
when hit by fire).
I started out just reformatting the function header for regularize()
but ended up doing miscellaneous other stuff, including some code
changes. I think the CHDIR code is a bit cleaner now, but shouldn't
have any differences in behavior.
Along the way I noticed that 'nethack -dpath' or 'nethack -d path'
modifies argv[] before PANICTRACE attempted to save argv[0], so would
break having nethack invoke gdb to get a backtrace. ('ARGV0' seems to
be unnecessary since 'hname' holds the same value, but I didn't get rid
of it....)
The function handles comments, empty lines, config sections,
CHOOSE, and line continuation, while calling another function
for other lines.
Currently used for config file, sysconf, and WIZKIT.
Polymorph control gives the player a chance to accept or reject a form
change due to lycanthropy, but if it occurs during combat or movement
the player might type 'y' before realizing that the prompt is pending.
Provide a paranoid_confirmation setting for 'Were-change' to allow a
player to require "yes" instead of 'y' for that.
The existing setting 'wand' is renamed to 'wand-break' and now requires
at least two letters in the config file options instead of just 1. The
spelling of its synonym is changed from 'breakwand' to 'break-wand';
it can be shorted to as few as 2 letters (same as before) but if more
than 5 are present, the new dash is required.
Both 'wand-break' and 'Were-change' are placed before 'pray' in the 'O'
menu for paranoid_confirmation so that all the "yes" vs 'y' settings
are grouped together.
Bonus fixes:
Reverting from were-critter form to human (due to timeout) did not give
a player with polymorph control the option of remaining in creature
form; now it does.
The 'O' command's menu would not show "wand" (now "wand-break") in the
current value of paranoid_confirmation. (A post 3.6.0 issue, so no
fixes entry included.)
The revised Guidebook.mn has been tested; Guidebook.tex has not.
Some roles' quest message when returning the nemesis lair refer to
sensing the presence/aura/whatever of the quest artifact, but it might
not be there anymore. In reported case, the nemesis had picked it up
and later fled up the stairs to another level. Other situations are
possible; it's feasible for the hero to already have it. So provide
an alternate message, and some extra code to decide whether to use it.
Other anomalous messages, such as looking down on the dead body of a
nemesis who didn't leave a corpse, can still occur.
If user can make NETHACKOPTIONS point to a file, that user could then
get the file contents via the extended config file error reporting.
Add CONFIG_ERROR_SECURE compile-time option to make that case output
only the first error, no line number or error context.
Show the original line from the config file, followed by the line number and
a specific error message. Also show all errors from the config file before
waiting for key press.
Reduce the chance of a player playing on a public server encountering
their own bones, by implementing separate bones pools. The pool a player
belongs to is determined at game start, and only bones in that pool
are used. The sysconf BONES_POOLS allows the sysadmin to define how
many pools there are.
Report was for a blinded horse which ate a carrot but remained blind.
This fixes that, and also lets blinded carnivorous pets eat carrots.
Gelatinous cubes now handle carrots too, but since they lack eyses
there won't be any noticeable effect for them.
Overriding clang-format was justified, but the result was too wide.
Make the lines less that 80 characters.
Also, WC_PERM_INVENT and WC_PLAYER_SELECTION had comments cloned from
the preceding line.
Previously the "fast-moving" when getting a target location
was always by 8 units. If this option is on, fast-moving
will instead skip the same map glyphs. This should be much more
useful for blind players.
Files modified:
include/extern.h
src/pline.c, priest.c, potion.c, mkobj.c
A bunch of calls to pline() in pline.c started triggering warnings
either as-is or possibly after the changes to tradstdc.h. Fixing
them in place would include intrusive VA_PASSx() like in lev_main.c.
Moving them to other files is much simpler (and they didn't
particularly belong in pline.c in the first place, although I didn't
actually find any better place for them....).
The probing/stethoscope feedback went to priest.c, where there's a
comment stating that it should move to wherever englightenment ends
up once that is moved out of its completely inappropriate current
home in cmd.c. (Holdover from when ^X was wizard-mode only but even
the other wizard mode commands don't really belong with the command
processing code.)