For those pro players who really want to try their hand
at that zen samurai, without needing to reroll thousands
of times to start with blindfold. Nudist starts without
any armor, and keeps tabs whether you wore any during
the game, for even more bragging rights.
Also makes the Book of the Dead readable even while
blind, for obvious reasons.
Restricting the text display only to the end of game disclose,
so it doesn't clutter the inventory during gameplay and so that
the readability of t-shirts is not given away.
There is a lot of code affected by this, and Pat Rankin correctly
observes that it would be better to store roguelike as a level flag
rather than just using Is_rogue_level. A note for the future.
From a bug report, if reading a cursed scroll of genocide created only
one monster it would give the plural message "Sent in some <monsters>."
Now it will say "Sent in a(n) <monster>." in such case. (The grammar is
accurate even if you can't see what happened; that situation is unusual
enough that I'm not going to worry about giving information away.)
From a bug report, flashing yourself
with a camera while in gremlin form blinded as with any other form, but
didn't inflict any damage the way that flashing a monster gremlin does.
This fixes that, and also makes light from wand/scroll/spell that hits
you-as-gremlin or monster gremlins do 1d5 damage too. It happens even
if the target is already in a lit spot, but doesn't continue afterwards:
simply being in a lit spot doesn't cause any damage, nor does lamp light.
Simplify many of the intrinsics macros from
#define xxx_resistance (Hxxx || Exxx || resists_xxx(&youmonst))
down to
#define xxx_resistance (Hxxx || Exxx)
by setting or clearing an extra bit in Hxxx during polymorph so that the
resists_xxx() check becomes implicit.
Unfornately there were lots of places in the code that treat Hxxx
as a timeout number--primarily for Stunned, Confused, and Hallucination;
Stunned happens to be one of the revised macros--rather than as a bit
mask, so this patch needed a lot more changes than originally antipated.
Something I've had in mind for a long time and finally gotten around
to implementing: when you fill in the last pit or hole of a sokoban level,
it's considered to be completed so luck penalties for unsokobanish things
(breaking a boulder, dropping everything and squeezing onto a boulder's
spot, reading a scroll of earth) stop being assessed and most Sokoban-
specific movement restrictions (against pushing boulders diagonally,
squeezing diagonally between boulders, floating over a pit or hole without
falling in, digging of new holes by monsters) are lifted. Teleporting,
level teleporting, and phasing through walls are still prohibited when in
the sokoban branch of the dungeon. (Keeping the non-phasing one in place
prevents taking a shortcut to the final prize in order to bypass the
treasure zoo monsters.)
This adds level.flags.sokoban_rules, defines Sokoban macro to access
it, and replaces most In_sokoban(&u.uz) tests to check it instead. It
gets set when a sokoban level is pre-mapped at the end of level creation,
and if it is set then whenever a trap is deleted, the flag gets cleared
if there are no more pits or holes present on the level.
Apparently I lied yesterday when I said that patch was the last
polyself one. This has been on my agenda for a long time: when dragon
scale mail merges with your skin during polymorph into the corresponding
dragon, have it revert from mail to scales. Its enchantment stays the
same when reverting. So after returning to your original form, using
enchant armor to convert it into scale mail again will eventually risk
its destruction due to over-enchanting. (Cursed scroll of enchant armor,
spell of drain life, or being hit by a disenchanter can be used to reduce
its enchantment back to a safe-to-enchnat value. Or cancellation if
you're desperate. I think those all work on all colors of dragon scales
despite the assorted magical properties that scales confer.)
From a bug report, when reading an unknown
scroll which turns out to be teleportation, if you happened to land on
another scroll of teleportation it wouldn't be discovered yet, even
though you ought to know that type of scroll by then. Fixing it required
moving handling of that scroll into the teleport code, since discovery
depends upon where you arrive and by then it's too late for seffects() to
do anything that affects feedback for any objects you land on.
Also fixes a post-3.4.3 bug where seffects() was making decisions
based on Teleport_control without being aware that Stunned now negates it
during teleportation.
The dungeon_overview bits in the rm structure were being
clobbered by a run-length encoding save/restore because
they weren't taken into consideration.
This patch pulls that data out of the rm structure completely.
It also adjusts the run-length encoding checks to take the
candig bit into consideration and adds a comment to rm.h
reminding people to make run-length encoding adjustments
in save.c for any new bits that get added.
From the newsgroup:
As you read the scroll, it disappears.
The scroll erupts in a tower of flame!
Your spellbook of force bolt catches fire and burns!
[...]
Your potion of paralysis boils and explodes!
Something seems to be holding you.
Do you want your possessions idenified?
This character survived the burning and boiling objects then succumbed
to the initial flame explosion.
A fatal explosion calls done() without any explanation. Or rather,
it dated to the time where it would immediately follow "the scroll erupts
in flame" (or "you are caught in <some kind of> explosion") without the
chance for intervening messages. Then when item destruction was moved
sooner (for bones file purposes), message sequencing was left dangling.
This patch adds a new "it was fatal" message in front of done().
A while back there was a change in how the initial shape for a
shapechanging monster gets chosen during monster creation, and a side-
effect of that lets/makes you choose the shape when #monpolycontrol is
enabled. But ^G was overriding your choice by forcing the shapechanger
to start out looking like the type of monster that you specified (to ^G,
not to subsequent #monpolycontrol prompting), hence always in its natural
shape. The intent for ^G was that if asked for a unique monster but got
a doppelganger instead, it would initially look like the requested unique
monster. Post-3.4.3 code, so no fixes entry needed.
There was an issue reported where save files between different
versions of a manufacturer's compiler were incompatible because the time_t
ubirthday field was changed from 32 bits to 64 bits.
32 bit time_t implementations will break at 19:14:07 on January 18, 2038.
64 bit time_t implementations will break at 23:59:59 on December 31, 3000.
This removes the dependency on the size of time_t from the save file.
The ubirthday field is no longer embedded in struct you.
This also adds two general purpose routines to hacklib.c, one to convert a time
value to a 14 character char representation and the other to convert that
back to time_t. Those are used by the save/restore routines.
This is a savefile breaking change, so editlevel in patchlevel.h was
incremented.
From a bug report, reading a scroll
of mail violates illiterate conduct and he requests that it not do so.
I didn't go that far, since unlike needing to read the Book of the Dead
to be able to finish the game, reading scrolls of mail is completely
voluntary and someone attempting voluntary challanges can choose not to
do it. Instead, this issues a prompt to require confirmation if reading
such a scroll will be the first violation of that conduct. Ordinary
players can answer no and then use '!' to read mail from a shell. I'm not
sure what'll happen to players on public servers who aren't given access
to a shell. Usually they wouldn't be able to get mail either, so more
elaborate servers like the one at nethack.alt.org which allow players to
use mail to communicate with each other will have to come up with their
own solution (perhaps by providing a mail-reader-only shell).
While testing something, I noticed that my last remaining discovery
would never be forgotten. The formula
count = ((count * percent) + 50) / 100
always yields 0 with count==1 and percent==25 (the value used for mind
flayer attacks). Not likely to come up in actual play very often....
Reported--more or less--by <email deleted>:
chargeable rings don't show up as likely candidates in the "what do you
want to charge?" prompt. They're supposed to be there once the type has
been discovered but it was using the wrong field so basing that on whether
the player had assigned a name to the type instead. (Picking a chargeable
ring's letter even though it wasn't listed did work correctly though.)
One of the complaints included in the Dec'04 report from <email deleted> was that spell of charm monster doesn't give
any feedback. This makes that spell, and scroll of taming, always give a
message. And the scroll will become discovered if a visible or sensed
monster gets converted from hostile or peaceful to tame, or from hostile
to peaceful.
Scroll of taming/spell of charm monster didn't hit steed when hero
is mounted; now it does. I don't know whether that matters though. You
can saddle a non-tame monster, but you can't ride one even in wizard mode.
However, I'm not sure whether a tame steed you're already riding can
become untame, let alone if it can do so without throwing you. If latter
is possible then re-taming while still mounted has now become feasible.
Move the code for determining monster class from user's input string
out of do_class_genocide() and into new routine name_to_monclass(). I'm
planning to use it when name_to_mon fails to match anything for controlled
polymorph (not ready for prime time yet).
Also, avoid getting stuck in a loop if hangup occurs while prompting
player for class of monster to genocide. ESC, whether deliberate or fake
input after hangup, will now be the same as specifying "none", throwing
away the genocide opportunity.
Noticed while testing crysknives; a post-3.4.3 change (not present in
the branch code) introduced a bug that prevented scrolls of enchant weapon
from being used up properly when read.
Wizard mode's ^G lets you specify "tame <foo>", "peaceful <foo>", or
"hostile <foo>" to override the created monster's default disposition.
Since it also lets you override the restriction against creating unique
monsters and various other special ones like shopkeepers (a post-3.4.3
change), it became possible to produce tame versions of monsters that
ordinarily are impossible to tame. That's pretty iffy even when it only
applies to debugging, so switch from internal tameness conversion to use
of tamedog() to get the non-tameable cases handled. (Minor side-effect:
full moon might prevent a request for "tame dog" from starting out tame.)
Also, for <N>^G, give up before the specified count is reached if
creation fails when creating multiple copies of a specific type of monster,
on the assumption that the level has become filled up. (When the type is
random, keep trying in case you subsequently get something different which
could survive on water or inside solid rock.)
This is an overhaul to the NetHack drawing mechanism.
- eliminates the need to have separate lists in drawing.c
for the things and their associated explanations by grouping
those thing together on the same inializer in a struct.
- replaces all of these options: IBMgraphics, DECgraphics, MACgraphics,
graphics, monsters, objects, boulder, traps, effects
- drawing.c contains only the set of NetHack standard symbols for
the main game and a set of NetHack standard symbols for the
roguelevel.
- introduces a symbols file that contains named sets of
symbols that can be loaded at run time making it extensible
for situations like multinational code pages like those reported
by <Someone>, without hardcoding additional sets into the game code.
- symbols file uses names for the symbols, so offsets will not break
when new things are introduced into the game, the way the older
config file uchar load routines did.
- symbols file only contains exceptions to the standard NetHack
set, not entire sets so they are much less verbose than all of
the g_FILLER() entries that were previously in drawing.c
- 'symset' and 'roguesymset' config file options for
preselecting a symbol set from the file called 'symbols'
at startup time. The name of the symbols file is not under the
users control, only the symbol set name desired from within the
symbols file is.
- 'symset' config file option loads a desired symbol set for
everything but the rogue level.
- 'roguesymset' config file option loads a desired symbol set
for the rogue level.
- 'SYMBOLS' config file option allows the user to specify replacement
symbols on a per symbol basis. You can specify as many or as few symbols
as you wish. The symbols are identified by a name:value pair, and line
continuation is supported. Multiple symbol assignments can be made on
the same line if each name:value pair is separated by a comma.
For example:
SYMBOLS = S_bars:\xf0, S_tree: \xf1, S_room:\xfa \
S_fountain:\xf4 \
S_boulder:0
- 'symbols' file has the following structure:
start: DECgraphics
Handling: DEC
S_vwall: \xf8 # meta-x, vertical rule
S_hwall: \xf1 # meta-q, horizontal rule
finish
start: IBMgraphics
Handling: IBM
S_vwall: \xb3 # meta-3, vertical rule
S_hwall: \xc4 # meta-D, horizontal rule
finish
- 'symbols' file added to the source tree in the dat directory
- Port Makefiles/scripts will need to be adjusted to move them into
HACKDIR destination