Reported internally, if a prayer resulted in 'fix all troubles' and
one of those was TROUBLE_STUCK_IN_WALL but safe_teleds() couldn't find
any place to relocate the hero to, nothing was done and STUCK_IN_WALL
would be found again as the next trouble to fix. Since safe_teleds()
eventually resorts to trying every single spot on the map, there was
no other result possible than failing to find an available spot again,
nothing would be done, and next trouble would be STUCK_IN_WALL, ad
naseum.
I started out with a fix that looked for secret corridors to expose
and doors to open, to make more space available, then try to move a
monster off the level, then try digging out rock and/or walls and
smashing boulders. None of those guarantee success and I got bogged
down by the digging case. This was going to be a last resort if all
of those still failed to make somewhere to move the hero, but for now,
at least, I'm skipping all that other stuff and going directly to the
last resort: give the hero Passes_walls ability for a short time, and
let him or her find own way out of trouble. The next trouble to fix
won't be STUCK_IN_WALL because Passes_walls makes that a non-issue.
I'm not thrilled with the new messages involved but want to get this
behind me.
Changes to be committed:
modified: doc/fixes36.1
modified: include/unixconf.h
modified: sys/share/ioctl.c
github pull request #19 made reference to resulting code behaviour
being better when windows were resized when USE_WIN_IOCTL was defined.
The logic for including the necessary enabling code in the build in
sys/share/ioctl.c was an explicit "opt-in" strategy, so anything not
deliberately and explicitly listed was not able to take advantae
of the potentially useful code. The need to add #defines to that
list would have been perpetual as new platforms came online, and
unnecessarily restrictive for everything else.
This switches the logic to include the code by default now,
and thus
unless there is an explicit "opt-out" by uncommenting
AVOID_WIN_IOCTL in include/unixconf.h
Some platforms, and we have no way of knowing which ones, may have
to ensure that AVOID_WIN_IOCTL is #define'd.
Incorporate some git information into NetHack so that it
is potentially visible to a player. That's useful when
collecting details about the version that they are
running and, if the gitinfo is present, it can tie the
code to a specific git commit in the repository.
This modifies 'makedefs -v' to check for the presence of a data file
called dat/gitinfo.txt and if it is there, parse out its
contents, then write additional lines to include/date.h beyond
what 'makedefs -v' was previously putting in there, similar to
this sample:
#define NETHACK_GIT_SHA "0c84e564c78e2024e562d39539376ce2e21eec8e"
#define NETHACK_GIT_BRANCH "NetHack-3.6.0"
The contents of an appropriate dat/gitinfo.txt are as follows,
and trailing/leading whitespace is not significant:
githash = 0c84e564c78e2024e562d39539376ce2e21eec8e
gitbranch = NetHack-3.6.0
It also adjusts the contents of the 'v' version information to
include the additional git info when available.
Also adds some hooks DEVEL/hooksdir and a perl file to DEVEL
for simplifying and automating the deposit of dat/gitinfo.txt
so that it generally reflects the most current git commit.
DEVEL/gitinfo.pl can be used to build dat/gitinfo.txt at any
time without doing a commit, merge, or checkout.
perl DEVEL/gitinfo.pl
command line --version and -version support
To complement the extra information being provided in the
version by the 'v' command, this also adds support for the
following new command line arguments:
--version
-version Output the NetHack version string then exit.
--version:paste Output the NetHack version string and also copy it to
-version:paste the platform's paste buffer for insertion somewhere,
then exit.
If the paste variation of -version is requested on a platform that
hasn't incorporated any support for the capability, it will deliver
the version info then an error message, prior to exiting.
To support the extended -version:paste variation, a port needs to:
- provide a port-specific routine to perform
the paste buffer copy in a port code file.
- #define RUNTIME_PASTEBUF_SUPPORT in the include/portconf.h header file.
--skeleton--
void port_insert_pastebuf(buf)
char *buf;
{
/* insert code to copy the version info from buf into
platform's paste buffer in a supported way */
}
macosx and Windows have both added support for RUNTIME_PASTEBUF_SUPPORT
An inventory of unpaid items where more than one was present would
show
|> bag's contents N zorkmids
if any of the items were inside a container whose contents aren't
known. But if there was only one item (so container must be owned
by hero) the 'Iu' output menu was skipped for pline and yielded
|> scroll of magic mapping 133 zorkmids
Force the menu display if the lone unpaid item is inside a container
whose contents are unknown.
I'm not sure whether a hero-owned container can have both unknown
contents and an unpaid item in normal play. I managed it while
trying to fix a reported problem--except I can no longer find the
relevant report--where itemized shop billing also revealed unseen
container contents (for any number of items, not just 1). That isn't
fixed yet, but I want to get the simpler 'Iu' part out of the way.
Report was for dual-wielding hitting an enchanter and assumed that
a resistant artifact as primary weapon was protecting vulnerable
secondary weapon. Actual reason was simpler.
When in normal form, dual-wielding attacks against creatures which
cause erosion to the weapon which hits them would only inflict the
passive erosion damage to the primary weapon, even if it missed and
secondary hit. Make primary attack always trigger passive counter-
attack--before second swing now, rather than after--even if it misses,
and secondary attack trigger another one if that hits. Both weapons
are now subject to passive erosion (but only when they actually hit);
when secondary weapon hits, hero gets a double dose of counter-attack.
Hero poly'd into a monster with multiple weapon attacks (various
leaders: dwarf lord, orc-captain, and so forth) would try to emulate
dual wielding and first hit with uwep then with uswapwep. But it
would do that even if uswapwep was a bow or stack of darts that the
player had no itention of using for hand-to-hand. Stick with repeat
hits by uwep when uswapwep seems inappropriate.
Splitting a pudding while dual-wielding would only do so when hit by
uwep of appropriate material, never when hit by uswapwep. So silver
saber and longsword could split if longsword was primary but never
split if saber was primary. Check material and splitting separately
for each hit. It's now possible to split twice with one dual-weapon
attack if both weapons hit and both are made of the right material
(iron or 'metal'; among relevant objects the latter is only used for
tsurugi and scapel).
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).