This doesn't solve the <0,0> problem but it does prevent mnexto()
from using uninitialized coordinates if enexto() fails. It also adds
several debugging messages.
enexto() was ignoring map row #0 (unlike column #0, row #0 contains
valid map locations). Fixing that doesn't matter for Plane of Water
though since that row is stone there--that's probably a bug. It was
also repeatedly re-testing the top+1 and bottom rows and left and
right columns after they had already failed to be acceptable. It
still does some of that, but less.
Fixes#177
The monst struct has 'mintrinsics' field which attempts to handle
both mon->data->mresists and extrinsics supplied by worn armor, but
polymorph/shape-change was clobbering the extrinsics side of things.
Potentially fixing that by changing newcham() to use set_mon_data(...,1)
instead of (...,0) solved that but exposed two other bugs. Intrinsics
from the old form carried over to the new form along with extrinsics
from worn armor, and update_mon_intrinsics() for armor being destroyed
or dropped only worked as intended if the armor->owornmask was cleared
beforehand--some places were clearing it after, so extrinsics from worn
gear could persist even after that gear was gone.
So, fixing the set_mon_data() call in newcham() was a no go. This
fixes update_mon_intrinsics() and adopts the suggested code from
github pull request #177 to have mon->mintrinsics only handle worn
gear instead of trying to overload innate intrinsics with that. This
is a superset of that; the flag argument to set_mon_data() is gone
and mon->mintrinsics has been renamed mon->mextrinsics. (The routine
update_mon_intrinsics() ought to be renamed too, but I didn't do that.)
Fixes#101
If you tell the vault guard your name, drop carried gold, wait one
turn, then pick up the gold again, the guard will move a step away
during the wait. If you teleport away, the guard will seal vault
walls and then park himself on the one-square (so far) temporary
corridor adjacent to the vault wall. Periodically he'll say "Move
along!" and the hero will hear it, regardless of location on the
level. Unless you dig a corridor to rescue him, or one or more of
the vault's walls get breached again, he will never move.
The report emphasized that you could use this to steal the vault's
gold, but it relies on being able to teleport beyond the gaurd's
reach and if you can do that, you might as well do so before the
guard comes. The stranded guard, and him saying "Move along!" when
no longer leading hero out of the vault, are more significant bugs.
Bonus fix: if the game ends and the guard seals up the vault while
the hero is in a spot that gets fixed up (vault wall or temporary
corridor) don't give the "You are encased in the rock" message if
game end was due to death rather than quit.
Fix fuzzer feedback. The new wizard mode ^T menu had an early return
which bypassed destroy_nhwindow(), leaving the menu around. Fuzzer
eventually got "No window slots!" panic from tty. Make sure that the
menu window is torn down fully before returning.
Also, make the normal wizard mode teleportation chioce be preselected
so that not picking anything doesn't lead to an early return any more.
ESC still does though.
Fixes#172
Casting teleport-away via ^T used different requirements for energy,
strength, and hunger than casting it via 'Z'. The strength and hunger
requirements were more stringent, the energy one more lenient. When
it rejected a cast attempt due to any of those, it used up the move,
but 'Z' didn't.
When testing my fix, I wanted an easier way than a debugger to control
how ^T interacts with wizard mode, so finally got around to a first
cut at being able to invoke it via wizard mode but not override those
energy/strength/hunger requirements. It uses the 'm' prefix to ask
for a menu. 'm^T' gives four options about how to teleport. (There
are other permutations which aren't handled.)
Also noticed while testing: ^T wouldn't attempt to cast teleport-away
if you didn't know the corresponding spellbook. 'Z' will attempt that
because it is possible to forget a book and still know its spell.
Jumping or teleporting while levitating in xorn form wouldn't toggle
blocking of levitation when moving from open spots to wall/stone and
unblocking of same when moving the opposite way.
This handles those cases but there are no doubt others. The only
other one I checked was when failed #untrap moves hero onto trap.
That case works correctly--at least after this fix is in place.
Noticed while working on it: change of terrain didn't always update
the status line. When levitation became blocked, it still said Lev
and when unblocked, didn't say that. Next status update got status
condition back in sync.
Add code to run a fuzz tester, simulating (more-or-less) random
keyboard mashing. There's no option to turn it on, you need to
set iflags.debug_fuzzer on via a debugger or something along
those lines.
Make being trapped in/on/over floor block Levitation and Flying, the
way that being inside solid rock already does, and the way levitating
blocks flight.
Blocked levitation still provides enhanced carrying capacity since
magic is attempting to make the hero's body be bouyant. I think that
that is appropriate but am not completely convinced.
One thing that almost certainly needs fixing is digging a hole when
trapped in the floor or tethered to a buried iron ball, where the
first part of digactualhole() releases the hero from being trapped.
If being released re-enables blocked levitation, the further stages
of digging might not make sense in some circumstances.
I recently realized that being held by a grabbing monster is similar
to being trapped so should also interfere with levitation and flying.
Nothing here attempts to address that.
Save files change, but in a compatible fashion unless trapped at the
time of saving. If someone saves while trapped prior to this patch,
then applies it and restores, the game will behave as if the patch
wasn't in place--until escape from trap is achieved. (Not verified.)
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.
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).
Requested by one of the beta testers 13 months ago... when a visible
monster becomes invisible and vanishes, mark its map location with
the remembered, unseen monster glyph. (When the player zaps a
monster with a wand of make invisible, that only happens if the wand
type is known. I'm not sure that's right but didn't alter it....)
The request suggested also doing it for a monster who disappears by
teleporting away, but I haven't attempted to implement that.
Make 'zeromonst' global instead of local to makemon.c. Its address
isn't used as a special value like &zeroobj, but it is useful to
have available for initializing various pseudo-monsters.
modified:
include/decl.h
src/decl.c, makemon.c, mkobj.c, mplayer.c, teleport.c
The automated reformatting put a space in casts of the form
'(type)(expression)', yielding '(type) (expression)', but it didn't
do that for '(typedef)(expression)'. There are lots of instances of
'(boolean)(expression)'; (uchar) and (xchar) also occur. I haven't
noticed other types, but I haven't looked in very many files yet.
End of first pass, but '[&|?:][ \t]*$' doesn't catch trailing operater
followed by end-of-line comment so more needs to be done. As with the
past couple of batches, I've removed redundant parentheses from 'return'
statements but only for files that had continuation fix-ups.
I've also removed tabs from comments in some of the files, but didn't
start until part way through this subset of the sources.
Reported for pre-beta, getting "you feel disoriented" when attempting
to teleport within a level while carrying the Amulet, you still ended
up teleporting. Wizard mode allows the disorientation to be overridden
but the logic was wrong. It worked as intended when in wizard mode but
unintentionally always overrode disorientation when not in that mode.
Most of the time, rloc() is used for teleporting monsters and it's not a
big deal if they can't find somewhere to go. In a few cases, it is. I
went through all the callsites and made calls to rloc() not cause
impossible()s if they don't need to.
Fixes a bug/suite of bugs reported by ais523.
I'll push a formatting guide at some point. There may still be
outstanding changes, but please feel free to resolve those as you arrive
a them.
To the best of my knowledge, there is no changes to the actual code
content, but the formatter does have the occasional bug. If you run into
an issue, please fix it!
* Replace variadic debugpline() with fixed argument debugpline0(str),
debugpline1(fmt,arg), and so on so that C99 support isn't required;
* showdebug() becomes a function rather than a macro and handles a
bit more;
* two debugpline() calls in light.c have been changed to impossible();
* DEBUGFILES macro (in sys.c) can substitute for SYSCF's DEBUGFILES
setting in !SYSCF configuration (I hope that's temporary).
Move debugging output into couple preprocessor defines, which
are no-op without DEBUG. To show debugging output from a
certain source files, use sysconf:
DEBUGFILES=dungeon.c questpgr.c
Also fix couple debug lines which did not compile.
This also includes fixes due to Derek Ray to depugpline to work better
on other platforms.