Remove trailing spaces from doc/fixes36.1 (only a couple),
doc/Guidebook.mn (several), and doc/Guidebook.tex (many). I re-split
some lines made wider by embedded formatting directives, but tried to
avoid getting carried away with that.
I think I added one missing period to Guidebook.mn and one missing
comma to Guidebook.tex. Aside from that, they should format the same
as they did before this patch.
A bunch of trailing spaces crept in with the most recent udpate;
remove them. Also, most sentences are separated from each other by
two spaces, but 2 or 3 had only one space. Also, rewrap a couple of
the widest lines although none of them were too wide for displaying
within 80 columns.
When a getlin() response is being typed, it wraps to second line if
the cursor tries to go past COLNO-1, but if a previous response is
treated as part of the prompt, using pline() to write prompt+space+text
wraps at a whole word boundary. tty's getlin() assumes that the screen
position can be derived from that prompt+space+text_so_far but that
doesn't match if wrapping at a word boundary leaves blank space at end
of the top line.
When a prompt is accompanied by default answer, output the answer
separately instead of pretending it is part of the prompt. Line-wrap
should occur at same point as when it was originally typed and avoid
the confusion about how far to back up when deleting characters.
This hasn't been exhaustively tested but it seems to work correctly
for ordinary input, input erased one character at a time, and input
killed all at once. One thing which definitely hasn't been tested is
having the prompt itself be so long that it needs to wrap.
The #wizwhere command (formerly ^O) has given the location of the
invocation position when on the relevant level for ages. It was
extended in 3.6.0 to give magic portal location when on the any
of the four elemental plane levels. Extend it again to show the
location of any magic portal when on a level which has one (so an
extra line of feedback at end of ^O output for quest entry, quest
home, Ft.Ludios entry once that's been assigned, and Ft.Ludios).
Allow the 'm' prefix for wizard mode level teleport command. Using
it skips the initial prompt for level destination and goes directly
to the menu of special level locations that you get when answering
'?' to that prompt.
Some github feedback pointed out that getting annotation input from
the player behaved differently from similar input for naming of
monsters and objects. The complaint stated that hitting <return>
without supplying any input removed the old annotation, where other
naming would leave the old name intact. 3.6.0 did misbehave that
way; current code does too if EDIT_GETLIN is disabled but behaves
as desired when it's enabled. (There's nothing that I can spot in
donamelevel() to explain why. I'm confused. Is tty_getlin()
returning the default answer instead of empty if that default text
is deleted at the prompt and no new text entered prior to <return>?)
Make donamelevel() work like mon/obj naming. Empty input leaves
existing annotation, if any, intact.
Having the autodescribe feature enabled and moving the cursor onto
a statue yields "statue of a <mon>" under normal circumtances, but
when done while hallucinating the feedback was just blank (because
the lookat() code couldn't find any monster at statue's location).
Now it will be "<random mon>" (not "statue of a <random mon>")
instead, same as when moving cursor over glyphs of actual monsters.
When the fire command prompts for missile, it autoquivers the chosen
item. Originally that was only done when the chosen item was a stack
but that got changed (back in 2007...) and the relevant comment was
not updated at the time.
I once changed dump_map() to suppress blank lines as it processed the
known portion of current dungeon level so that no blank lines would
be shown above the mapped area and at most one would be shown below.
Any blank lines within were put back. But the count of the current
block of suppressed lines wasn't being zeroed when an internal gap
did get put back, so after that every line got spurious blank lines
inserted in front of it. I'm surprised that no one seems to have
discovered this problem.
This fix also changes the dumped map to suppress trailing spaces. In
the process, I noticed that the original DUMPLOG code was clobbering
column COLNO-1 if that was ever part of known map. buf[x - 2] = '\0'
overwrote the final map character in buf[] with the terminator.
After about the third time typing '#' and getting a prompt of "# K", I
decided that it wasn't clumsy typing. The call chain for get_ext_cmd()
was passing an uninitialized output buffer to [hooked_tty_]getlin()
which treated random junk as the previous result to be used as current
default. Other interfaces may need a similar fix.
The cavemen quest description includes an 'S' in the lower right
corner of the MAP...ENDMAP section of the locate level. It produced
a secret door as intended but did not have horizontal vs vertical set
because the latter was only being done for DOOR directives. Instead
of adding an explicit directive, make the loading code set horizontal
vs vertical for all doors.
This fixes the orientation of that secret door in the Cav locate
level, but I noticed that it showed up an a visible horizontal wall
when the spots on either side were still blank. It's behaving as
if the door is on a lit spot and the adjacent walls are unlit (this
misbehavior was already present before the current change; it was
just shown incorrectly as a visible vertical wall before).
PatR [Sat, 31 Mar 2018 23:55:29 +0000 (16:55 -0700)]
steed sanity check
Wizard mode sanity checking gave spurious "mon not on map" warnings
for steed when hero is mounted. Steed is in the fmon list but not
expected to be present on the map.
PatR [Sat, 31 Mar 2018 00:05:23 +0000 (17:05 -0700)]
fix #H7015 - explosion chain reaction bug
The fix to prevent "crushed by a gas spore's explosion" set killer.name
to an empty string after a gas spore explosion finished, but that made
nested explosions end up with empty killer.name after the innermost
call completed. explode() shouldn't have been hanging on to a pointer
to a global value that is subject to change while it executes. Making
a local copy of the current value at the time explode() is called will
solve that (I hope...).
Simply reverting the reset of killer.name wouldn't have been correct.
The innermost explosion would still be clobbering killer.name for any
outer MON_EXPLODE explosions in progress. When the only exploding
monster is gas spore, that wouldn't be noticeable. But having other
types of exploding monsters and a chain reaction which affected more
than one type would have exposed that bug. I think this fixes both
aspects of this problem but don't have a second type of exploding
monster to verify the second part.
PatR [Tue, 27 Mar 2018 23:34:47 +0000 (16:34 -0700)]
{dgn,lev}_lex.c - suppress yyunput() complaint
When dgn_comp.l and lev_comp.l are processed by older versions of
flex, 'gcc -Wunused' complains when compiling dgn_lex.c and lev_lex.c
because flex creates 'static void yyunput()' and nethack doesn't use
it. Newer versions honor macro YY_NO_UNPUT to hide the offending
code, but that doesn't help with older versions (like the one
masquerading as 'lex' on OSX). Adding a dummy usage would probably
cause problems with other lexers, so change it from static to
'void yyunput()' as a 'sed' fixup in util/Makefile after flex has
finished. That will be a no-op when yyunput doesn't exist or isn't
static.
In addition to the sys/unix/Makefile.utl change, this checks in new
sys/share/{dgn,lev}_lex.c with the fixup in place.
PatR [Thu, 22 Mar 2018 02:12:51 +0000 (19:12 -0700)]
Cleaver tidbit
Fix a comment typo. While in there, change the cleave attack to
swing counter-clockwise the very first time instead of setting up
for that but then toggling to the opposite direction before the
actual attack. Also, refactor a bit of common code for choosing
< xdir[], ydir[] > index for next target.
PatR [Tue, 20 Mar 2018 00:59:24 +0000 (17:59 -0700)]
wishing for containers
Noticed while investigating the broken chest whose lock was already
broken: wishing for locked, unlocked, or broken chest (or large box)
was treated as asking for something unknown. Add support for those
three prefixes, although they only have meaning for chest and box.
If more that one is specified in the same wish, whichever one comes
last overrides the others.
Also, "empty" was already an accepted prefix (for tins); honor it for
containers too.
Lastly, wishing for "box" failed. Give a large box instead. I went
back and forth about whether to do the same for "small box" and ended
up not including it, but turns out that small/medium/large prefix for
globs ends up making "small box" and "medium box" match "box" which
has now become a synonym for "large box". I'm not sure whether that
is a bonus or a bug; small box is clearly not the same thing as large
box, but getting the only available box when asking for any box seems
better than claiming not to understand the request.
PatR [Mon, 19 Mar 2018 22:48:46 +0000 (15:48 -0700)]
fix #H6960 - redundant feedback for '#force'
When using #force at a spot which has a broken or unlocked chest (or
large box) whose lock state has been previously discovered, avoid
|There is a broken chest here, but its lock is already broken.
|There is an unlocked chest here, but its lock is already unlocked.
by suppressing "broken"/"unlocked" from the chest description for
that particular message.
We might still want to change "broken chest" to "damaged chest" but
I don't think there should be any reference to its lock as the reason
it's broken or damaged. The fact that #loot, #force, and applying a
key still treat it as a container is sufficient to reveal that it
functions as one.
Alex Kompel [Mon, 19 Mar 2018 04:57:38 +0000 (21:57 -0700)]
win32-gui: fix truncated status fields call to get dimensions of the text bounding rectangle needs to be made after the font is set in order to get the accurate reading
Alex Kompel [Sun, 18 Mar 2018 19:52:30 +0000 (12:52 -0700)]
win32-gui: Do not auto-assign non-alphabet accelerator characters to menu items. Picking up pile that contains gold forces accelerators to start with $ so the next one becomes %, ...
nhmall [Sun, 18 Mar 2018 03:05:52 +0000 (23:05 -0400)]
broken large box wording change
> When you try to #force a large box or chest whose lock is already broken from a
> previous #force, the game tells you "There is a broken large box here, but its
> lock is already broken." It's minor, but this implies that the box being broken
> is separate from the lock being broken (as well as that the box itself *can* be
> broken).
change the wording to "lock-damaged box" and suppress
", but its lock is aleady broken" when "lock-damaged box" has
already been displayed.
(Nobody particularly likes the wording "lock-damaged box" either, but at least
it seems less misleading)
nhmall [Fri, 16 Mar 2018 02:02:41 +0000 (22:02 -0400)]
more pluralization bits
Handle more *man and *men cases.
Some plural usage of completely made up fruit names that should
be entered in singular form but have what appears to be a
valid plural name it will end up singularized. Not much
we can do about that for ficticious words.
For instance, if you try to name your fruit bigmen or snakemen
and you intended that to be the singular name, NetHack will likely
singularize it to bigman or snakeman.
Many real dictionary words that end in "men", however, should
be handled a wee bit better now. A real word such as stamen,
for example.
PatR [Thu, 15 Mar 2018 20:05:08 +0000 (13:05 -0700)]
fix plural of box
"boxen" may be hacker slang for plural of "box", but "foxen" is
definitely not the plural of "fox". Restrict the "ox"->"oxen"
entry to full word "ox", not "*ox" suffix.
PatR [Tue, 13 Mar 2018 18:27:04 +0000 (11:27 -0700)]
prevent pline() segfault
The use of debugpline() in tty_curs() got me wondering what would
happen if debugpline() was called while pline() is in progress. I
don't know how to trigger the bad coordinate situation, so I put an
unconditional debugpline() in the NHW_MESSAGE case of tty_putstr()
and used DEBUGFILES=wintty.c to enable it. Instant segfault, and
the backtrace was short and not useful so the stack might have been
clobbered. I didn't spend any time trying to figure where or why
the segfault occurred.
Change pline() so that if it is called while the previous pline()
hasn't finished yet (ie, recursively), use raw_print() and return
early. The raw_print message isn't very useful--it pops up wherever
the cursor happens to be, just like the cursor position bug that has
been an issue recently--but does get delivered without any segualt
and isn't completely useless if DUMPLOG is enabled and you save or
quit before the message buffer gets recycled. Message readability
situation could be improved but avoiding the segfault was my goal.
Putting any debugpline() into *_raw_print() would be inadvisable....
nhmall [Mon, 12 Mar 2018 03:29:06 +0000 (23:29 -0400)]
ensure tty_curs() behaves the same whether DEBUG defined or not
ensure tty_curs() behaves the same whether DEBUG defined or not
when it comes to positioning the cursor.
The return statement, in the debug case only, was preventing
the cursor from being moved following a range check, so the
next output was written whereever the cursor happened to be
previously.
The messaging that detects the failed range check will get
written in the DEBUG defined case hopefully allowing resolution
to the range check failure, but now the cmov will still
be attempted just as it is in the case where DEBUG is not
defined.
PatR [Sun, 11 Mar 2018 19:39:01 +0000 (12:39 -0700)]
fix #H6955 - wielded potion 'object lost' panic
Report classified this as 'segfault' but it's actually a controlled
panic(). When hero has lycanthropy and is wielding a potion of unholy
water while in human form, if that potion is boiled then it triggers
a transformation to beast form which in turn causes wielded weapon to
be dropped. When the code unwinds back up through potionbreathe() to
destroy_item(), the boiled potion won't be found in inventory any more
and useup() -> useupall() -> freeinv() -> extract_nobj() panics.
PatR [Sat, 10 Mar 2018 20:32:52 +0000 (12:32 -0800)]
more Unix gitinfo
When make uses 'makedefs -v' to create date.h, force it to create
gitinfo.txt all the time instead of just when that doesn't already
exist. Use 'make GITINFO=0' to get the previous behavior.
To skip it entirely, you need to do that and also make sure that
some file by that name already exists. 'touch dat/gitinfo.txt' or
perhaps 'echo "#no git" > dat/gitinfo.txt' would suffice.
PatR [Fri, 9 Mar 2018 22:11:04 +0000 (14:11 -0800)]
mplayer valkyries w/ Mjollnir
If an mplayer Valkyrie on the Astral Plane is given a war hammer,
give her gauntlets of power instead of random gloves since that will
either be Mjollnir or a very wimpy endgame weapon. (Maybe someday
mplayer Valkyrie's will be able to throw Mjollnir; their chance of
having it on the Astral Plane is moderately high if it hasn't already
been created prior to arriving there.)
I also gave monsters wearing gauntlets of power a 3..6 damage bonus
for hand-to-hand. While making that change, I noticed that monsters
wielding a scalpel or tsurugi wouldn't split puddings, unlike the
hero (a post-3.6.0 change), so fix that.
PatR [Thu, 8 Mar 2018 18:26:08 +0000 (10:26 -0800)]
Files update
I'm not sure of the status for possibly maintaining 'Files' via
automation, so manually add the new file 'gitinfo.sh' to sys/unix.
There was a sys/unix/hints file that wasn't listed, so add linux-qt4.
The whole win/Qt4 subdirectory is missing though. I don't even
remember that being added.
PatR [Mon, 5 Mar 2018 20:26:44 +0000 (12:26 -0800)]
stuck_in_wall tweak
When divine aid granted temporary Passes_walls ability to stuck hero,
it was giving 4d4 turns (4..16, avg 10). But the first warning that
it's timing out is given at 4 turns left so wouldn't be seen if the
random amount of time picked was the minimum. Switch to 4d4+4 (8..20,
avg 14) so that the message at 4 turns left will always happen.
PatR [Mon, 5 Mar 2018 20:01:31 +0000 (12:01 -0800)]
removing a monster from current level
I ended up not using this, but it might as well be included for
potential future use. Extend mlevel_tele_trap() to support forcing
a monster off the current level to make room either for the hero or
some other monster. goto_level() does something similar when the
hero is arriving on a level. This is for situations where the hero
is already there (such as divine aid attempting to fix STUCK_IN_WALL).
mlevel_tele_trap(mon, (struct trap *) 0) will usually move 'mon' off
the level, scheduled to migrate back if the hero leaves the level and
subsequently returns. 'Usually' because it doesn't work in endgame
and certain monsters are excluded regardless of dungeon location, so
caller has to be prepared to try to move another monster (or resort
to goto_level()'s unconditional forced migration).
PatR [Sun, 4 Mar 2018 22:17:13 +0000 (14:17 -0800)]
gitinfo.txt on Unix
Hide the scary perl command during 'make all' feedback in src/.
I'm not a shell programmer but this works fine for me when skipping
NHgithook::NHversioning because dat/gitinfo.txt is already present,
when creating dat/gitinfo.txt successfully, and when creation fails
because perl can't find NHgithook.pm. It hasn't been tested when
perl itself is absent.
PatR [Sun, 4 Mar 2018 00:46:39 +0000 (16:46 -0800)]
fix prayer infinite loop
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.
PatR [Sat, 3 Mar 2018 23:26:49 +0000 (15:26 -0800)]
buried_ball()
Noticed when I was looking at float_up()/float_down() vs being trapped.
(I have a substantial patch for that but it involves infrastructure
changes so will have to go into master instead of the 3.6.0 branch.)
buried_ball() was using nested loops as a very convoluted way to test
if (otmp->ox >= cc->x - 2 && otmp->ox <= cc->x + 2
&& otmp->oy >= cc->y - 2 && otmp->oy <= cc->y + 2)
I think this revised version is closer to what was intended.
There are issues. buried_ball() finds the buried iron ball nearest to
the specified location--which is always the hero's current location--
rather than the one which was 'uball' before being buried. A player
can spot that since iron balls aren't necessarily identical. Also, it
searches within a radius of two steps but a tethered hero is only
allowed to move one step away from buried ball, so something is off.
PatR [Sat, 3 Mar 2018 18:54:43 +0000 (10:54 -0800)]
aklys tweaks
It turns out that Mjollnir before the recent aklys enhancement and
aklys since then would end up both wielded and quivered if it returned
to thrower's hand while quiver was empty. Remove it from quiver before
restoring it to hand.
Limit the throwing range of an aklys if it is expected to return (ie,
thrown while wielded as primary) since it is a "thonged club" which is
supposedly attached by a cord to the thrower's wrist or hand. I have
no idea how long a real cord like that might be. I set the range limit
to BOLT_LIM/2. Shorter makes throw-and-return uninteresting for an
item that needs to be wielded to throw--so would probably be swapped
back and forth with a stronger melee weapon or longer range missile
weapon--and longer seems absurd.
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.
PatR [Sat, 3 Mar 2018 02:19:23 +0000 (18:19 -0800)]
Cleaver update
I worked on this a while back but didn't commit it because I couldn't
figure out the dead monster which wouldn't die. Pasi beat me to that.
Clean up the Cleaver code some and make the three-target swing alternate
between counter-clockwise and clockwise to simulate normal right-to-left
swing followed by left-to-right backswing. (Alternation happens on each
swing regardless of whether it is consecutive with the most recent one.
That's suboptimal but easy....) Also, stop three-target attack early if
hero is life-saved after being killed by a passive counter-attack from
the first or second target.
Prevent rogue backstab and two-hander breaking foes' weapons when using
Cleaver hand-to-hand because getting more than one of either of those
bonuses at a time would be excessive. I think allowing those for the
primary target but not for the two adjacent ones would be better, but I
just thought of that and am not going back for another round of revising.
This doesn't incorporate the two pull requests: one to avoid hitting
tame or peaceful adjacent targets unless the primary was also tame or
peaceful, the other to avoid hitting unseen adjacent targets. I'm not
sure if that includes remembered-unseen 'I' on the spot or no monster
shown at all. (There's a third one about updating the map but it isn't
needed for the existing Cleaver code either before or after this patch.)
I'm in favor of the first one and am not sure about the second. My
original concern was that someone could use Cleaver to find/hit three
unknown monsters at a time via 'F' prefix, but forcefight aimed at
thin air doesn't reach the Cleaver code so that can't happen, nor can
attacking two known close monsters at once by targetting an empty spot
between them.