Instead of just "while helpless", the death reason will tell
more explicitly why the player was helpless. For example:
"while frozen by a monster's gaze"
This finally eliminates all direct increases of `oeroded` and `oeroded2`
and moves them all to go via `erode_obj()`. They are still manipulated
directly in a few places, but not to erode objects.
This now merges the `fire_damage()` function to a common codepath, used
for items on lava and burning oil, but fire needs more work. There is
still a duplication between `destroy_item()` and `fire_damage()`; the
two codepaths should eventually be merged in some manner so that there
is only one codepath to say "an object was affected by fire". This path
might require some parameters, such as whether the fire will just erode
objects or burn them outright, but that can happen another day.
From the newsgroup, losing spells to amnesia always took away the
last 'N' spells after choosing a random N. That kept casting letters
sane, since letters for lost spells became invalid and those for non-lost
ones stayed the same as they were before amnesia. But 3.4.x gave the
player the ability to swap pairs of spells, so he could make his favorites
to be the first spells, and only lose them if the random number of spells
being affected was as large as the whole list. (Also, divine spellbook
gifts give preference to books for unknown spells; in theory, you could
use spell letter manipulation plus deliberate amnesia to make a particular
spell revert to unknown in order to improve the chance of getting a new
spellbook for it. A bit of cleverness by a determined player but it
makes the game and/or its patron deities seem a bit dumb in the process.)
I first implemented losing spells throughout the list, with later
spells moved forward to fill any gaps. But that results in new casting
letters for every spell past the first lost one, potentially wreaking
havoc if a player chooses a casting letter from his own memory of the
pre-amnesia list. So, instead of losing some spells entirely, either
from the end of the list or spread throughout, I've changed amnesia to
set the retention amount (of N spells from throughout the list) to zero,
the same as happens when it's been 20000 turns since the spell was last
learned. Letters for all known spells stay unchanged, and forgetting
due to amnesia becomes the same as the other way of forgetting spells.
(So now a different potential clever use of amnesia occurs; a player who's
trying to a make speed ascension could get access to expired spells--to
cast in order to become confused--without waiting for 20000 turns after
reading the first book.)
From the newsgroup: player saw "The spell hits the <monster>?"
where the question mark punctuation reflected negative damage occurring.
Another player diagnosed it as a 2 point force bolt (from 2d12 dice role)
modified by -3 penalty for hero who has Int less than 10. This changes
spell_damage_bonus() to avoid reducing damage below 1 point.
Something else <Someone> forwarded from the newsgroup long time ago:
attempting to read a dull spellbook ought to have a chance of making the
hero fall asleep.
From the newsgroup (subject: "3 xorn fixes"): casting spell of
protection would report "the air around you begins to shimmer" even when
you were embedded in rock or swallowed. It included a pointer to a patch;
I looked at that but ended up not using it.
The latest Micrsoft compilers complain when a function is
assigned to a function pointer, and the function's argument
list does not match the prototype precisely.
It was evem complaining about the difference between this:
int x()
{
[...]
}
and a prototype of
int x(void);
when assigning that function's address to a function pointer.
This quiets those warnings, without suppressing the mismatch
check altogether for more serious mismatches.
Add the capability of sorting the entire spellbook by various criteria,
augmenting the existing ability to swap pairs of spells. In the menu that's
put up for the '+' command, add a non-spell entry after the last known spell
+ - [sort spells]
Selecting that brings up a new menu
View known spells list sorted
a + by casting letter
b - alphabetically
c - by level, low to high
d - by level, high to low
e - by skill group, alphabetized within each group
f - by skill group, low to high level within group
g - by skill group, high to low level within group
h - maintain current ordering
z - reassign casting letters to retain current order
'a' corresponds to the normal ordering; 'b' through 'g' cause the order
to change, but during the current invocation of the '+' command only.
(Entry 'h' is a no-op, something aside from ESC to get out without doing
anything. 'a' is only a no-op if you haven't picked any of 'b' through
'g' yet.) After making a choice, you're taken back to the '+' command to
view the spells in the requested order. And once back there, you can pick
'+' again to come back to this menu, where picking 'z' will cause casting
letters to be shuffled such that present display order becomes the actual
spellbook order. Newly learned spells get appended to the end as usual;
the most recent sorting order isn't sticky even if finished off with 'z'.
No doubt seeing it in action will be clearer than this description.
This also updates the Guidebook to mention the spell retention field added
to the '+' menu some weeks back.
Make a not-very-robust fix for the report from <email deleted> about
being told a scoll disappears as you read it, then for the case of cursed
remove curse being told that the scroll disintegrates. He missed similar
case for scroll of fire erupting into flames after it had disappeared.
This suppresses the "disappears" part of the scroll reading message for
those two cases, but won't be very reliable if other scroll messages
referring to the scroll itself get introduced in the future. [Several
paths through scroll of fire won't report that it burns, and now it doesn't
give the disappears message any more. I don't think that's worth worrying
about; the scroll leaving inventory after burning up is implicit.]
Also cut down on redundant feedback for several scrolls (genocide,
charging, identify, stinking cloud) that start off by informing the player
what they are. That's only needed when the the player doesn't already
know the type of scroll. I've always felt it silly to be told that I've
"found a scroll of genocide" when I'm intentionally reading a known scroll
of genocide. All these types of scroll give a subsequent prompt which
makes them recongizable if you somehow manage to choose the wrong object
when picking the one to read.
Lastly, make spell of identify behave like ordinary uncursed scroll of
identify by default instead of ususally ID'ing multiple items. Now you'll
need to be skilled or better in divination spells skill in order to get the
blessed scroll effect out of it. And give some feedback if the spell is
cast when not carrying any inventory; it was just silently moving on to the
user's next command in that case.
Move NO_SPELL and MAX_SPELL_STUDY from hack.h to spell.h. I didn't
even remember that the latter existed when I put MAX_SPELL_STUDY in the
former recently.
Add a couple of new "spell is almost gone" messages that occur when
casting spells. One matches up with yesterday's change for when you can
re-read a spellbook to reinforce memory of a known spell.
When "too hungry", you can't cast any spells, except detect food so
that you can find something to eat. When "too weak" you couldn't cast any
spells at all; now you can cast restore ability so that you can recover
lost strength. [We still need to come up with a better crowning bonus for
monks than spellbook of restore ability.] I couldn't think of a reasonable
exception for the "can't cast when carrying too much" restriction. If we
can come up with one (levitation?), then remove curse could/should become
an exception for the "no free hands" restriction.
Instead of just marking forgotten spells with an asterisk, add a new
column to the '+' spell menu which gives an estimate of how well the spell
is remembered. Precision of the estimate depends upon the hero's skill in
the category of spell; expert gets the most detail with a low-to-high range
spanning just 2%, such as 19%-20% or 75%-76%; skilled sees 5% ranges; basic
10%, and unskilled the least detail with 25% ranges (ie, one of 1-25, 26-50,
51-75, or 76-100 for percentage of time left available for the spell).
[The tab-separator variant for the menu is untested.]
This fixes an off by one bug for spell retention. It got set to 20000
as intended when a spellbook was read, but then it would be decremented to
19999 before the player had a chance to do anything else, cheating him out
of 1 turn of memory. Spells known at game start last exactly 20000 turns.
Also, adjust the point at which you're allowed to reread a spellbook
and refresh your memory of the spell. When the current spell system was
instituted, that was 10% of the retention period (1000 turns or less left
out of 10000); when retention got doubled to 20000 turns, the relearn point
was left as is. Increasing it to 10% (ie, doubling to 2000) makes it fit
better with the displayed retention percentages. Otherwise expert casters
would be left to guess when they've hit that point (1000 is 5%, falling
within their 5%-6% range, which really indicates (4%+1) to 6%). At 10%,
it's the threshold for the 9-10 range for experts, 5-10 range for skilled,
and 1-10 range for basic so the player can see when it has been reached;
only unskilled, with a bottom range of 1-25, is left to guess. Players
will likely prefer to wait until later, when the spell is nearly expired,
to refresh, but if they're about to abandon their books on the way to the
endgame then being able to re-read sooner is beneficial.
Refine last week's change dealing with polymorphing spellbooks: when
a spellbook has faded to blank after multiple readings, randomize its
spestudied value so that it doesn't always polymorph into another blank
book on the first subsequent transformation attempt.
From a bug report... some
special case handling for polymorph of spellbooks never worked as intended.
It's possible to polymorph a spellbook, use it to learn a new spell, and
then repeat as many times as you like unless/until you run out of polymorph
magic or the small chance of "object shuddering" causes it to be destroyed.
Polymorph was incrementing the book's ``number of times read'' field with
the intent that it would fade to blank after being read 3 times (which
turns out to the 4 times since the check is actually for re-reading 3 times
after the first). That didn't work because the spestudied field was ignored
when learning a new spell, only checked when relearning a known spell.
Now it will be checked when learning a new spell, and also the book
tweaking during polymorph is slightly more elaborate. If you happen to
get a blank book during the item selection, it will have a read counter
of 0 and can be re-polymorphed into something readable. But if you get
some other book, its read counter will be set to one greater than than the
original book's (same as before). And then the counter will be checked
to see if it has gone over the limit, in which case the book will be made
blank and its counter will be reset to a random value. Re-polymorphing
that blank book again has 1/4 chance apiece among the following cases
book gets blanked again; goto step 1...
book is non-blank but too faint to read; reading attempt will fail
book can be read normally and then re-read once
book can be read normally and then re-read twice
which is more inline with the intent of the original special case code.
It's actually slightly nastier since you'll occasionally get a book for a
spell you don't know yet but then not be able to learn it from that book.
Finally apply the patch sent by <Someone> in 11/2003 for slashem-Bugs-799278,
updated to match the current code and handle additional cases. The fix
is brute force: always ensure nomovemsg is set when nomul is called with
a negative value. I also scanned the code for places manually setting
multi negative, they all set nomovemsg. It would be nice to have a function
that did the right thing, but there are several special cases and I was
not feeling creative.
- can shift into fog clouds, vampire bats, and vampire lords into wolves
- after being "killed" in shifted form, they transform back rather than get
destroyed, and you must take them on in vampire form to defeat them
- can deliberately shift into fog clouds to pass under closed doors
It is not physical damage if:
1. it already qualifies for some other special type of damage
for which a special resistance already exists in the game
including: cold, fire, shock, and acid. Note that fire is
extended to include all forms of burning, even boiling water
since that is already dealt with by fire resistance, and in
most or all cases is caused by fire.
2. it doesn't leave a mark. Marks include destruction of, or
damage to, an internal organ (including the brain),
lacerations, bruises, crushed body parts, bleeding.
Current exceptions to the rule (already existing):
- holy water burning chaotic ("it burns like acid") is physical damage.
- unholy water burning lawful is physical damage.
- [fixed in trunk] Jumping/Newton's-Thirding into something solid
- [fixed in trunk] Being hit by Mjollnir on the return
- [fixed in trunk] Contaminated or boiling water from a sink
- [fixed in trunk] Falling on a sink while levitating
- [fixed in trunk, fire only] Any passive attack
- [fixed in trunk] Zapping yourself with a wand, horn or spell
- [fixed in trunk] Burning (un)holy water
- [fixed in trunk] Thrown potion (bottle)
- [fixed in trunk] Bumping head on ceiling by cursed levitation
- [fixed in trunk] Exploding rings and wands (under all circumstances)
- [fixed in trunk] Stinking cloud damage
- [fixed in trunk] Sitting in a spiked pit, in lava
- [fixed in trunk] Exploding spellbooks
- [fixed in trunk] Falling off or failing to mount a steed
- [fixed in trunk] Falling into a (spiked) pit
- [fixed in trunk] Land mine explosion
- [fixed in trunk] Fire traps
Introduce a new set of functions to manage delayed killers in the trunk, used
in addressing the various reports of delayed killer confusion. Since existing
delayed killers are related to player properties, the delayed killers are
keyed by uprop indexes. I did this to avoid adding yet another set of
similar identifiers.
- the new delayed_killer() is used for stoning, sliming, sickness, and
delayed self-genocide while polymorphed. Some other timed events don't
use it (and didn't use the old delayed_killer variable) because they
use a fixed message when the timeout occurs.
- A new data structure, struct kinfo, is used to track both delayed and
immediate killers. This encapsulates all the info involved with
identifying a killer. The structure contains a buffer, which subsumes the
old killer_buf and several other buffers that didn't/couldn't use killer_buf.
- the killer list is saved and restored as part of the game state.
- the special case of usick_cause was removed and a delayed killer list
entry is now used in its place
- common code dealing with (un)sliming is moved to a new make_slimed function
- attempted to update all make dependencies for new end.c -> lev.h
dependency, sorry if I messed any up
Pat Rankin wrote:
> collect them all into some new struct and
> save that separately rather than jamming more non-option stuff
> into struct flags.
This patch:
- collects all context/tracking related fields from flags
into a new structure called "context."
It also adds the following to the new structure:
- stethoscope turn support
- victual support
- tin support
A skilled/expert caster of fireball/cone of cold was not able to target
a location with a monster seen only by infravision/ESP. Since you can
focus on the monster there, targetting shouldn't fail in this case.
Attempting to lock onto a monster inside stone still won't work.
Pulled out the code that handles reading spellbooks while confused into a
new function that can be called from learn() to handle the timed onset of
confusion starting while you're reading.
When reading a cursed or too-hard book that's covered in contact poison
(presumably in the too-hard case, reading it made the poison), and you die,
the book would not be in the bones. remove in_use mark while assessing
damage.
On the other hand, not From a bug report, the message in the "6" case says
the book explodes, but had a 1/3 chance of not disappearing in the normal
case, and 100% chance of remaining if cursed while reading - when the
player survives. Return a flag to allow the book to be destroyed in this
case. No work needed for the death case; in_use is set.
> I'm working on a Nethack port, and one of the header files a
> library uses has a structure with a member named "red". Since
> includes/decl.h #defines red to something, this totally loses.
>
> Attached is a patch which fixes the color defines.
Reported to the newsgroup, the code in study_book for the effect of
confusion on studying a book was never reached. The study_book code
didn't completely handle continuing to read a book when you got confused
after getting interrupted.
- Changed a cancelled chat direction to abort the chat -- it seemed odd
that the old behavior would sometimes take time, sometimes not, depending
on the previous direction.
- Documented the current spelleffects behavior of re-using the last
direction after a cancelled getdir() & added a message.
The spellcasting code stopped counting a spell class's skill
exercise once that reached expert, so the only way that it could
end up being flagged as having reached maximum in the #enhance
feedback would be if it had already received enough exercise to
reach the hypothetical level beyond expert while it was still at
skilled or less.
It also didn't count the exercise if you were restricted in
the spell class, but that wasn't necessary because becoming
unrestricted--which I don't think is even possible for spells at
present--resets the counter back to 0 to discard any exercise
achieved while ineligible.
Make a change suggested by <Someone> to have the Wizard
enter harassment mode when you perform the invocation, in case
you manage to obtain the Book of the Dead without killing him.
Instead of just initiating that periodic effect, behave as if
you have actually killed him (which also affects random monster
generation frequency, prayer timeout, and shopkeeper salutations).
The comment about Book of the Dead's taming effect working
on nearby monsters when read while swallowed was wrong. It was
only put there in the first place to avoid adding extra code to
suppress taming while swallowed when that was done for the other
methods of taming. Any need for extra code here turns out to be
unnecessary due to the cansee() check.
If you get interrupted while reading a spellbook and then
the book gets destroyed or you change levels, the object pointer
remembered for the book will be invalid and could accidentally
match one subsequently allocated to some other book. That would
result in "you continue your efforts to memorize the spell" when
starting to read that other book; it would also end up bypassing
the reading difficulty check and reuse the old book's delay counter.
I don't remember who reported this. It was quite some time
ago and I have an abandoned patch dated last March from when I
first started to fix it.
Files patched:
include/extern.h
src/save.c, shk.c, spell.c
This adds <Someone>'s lens patch.
This is probably it for me adding in any more user-contributed patches for
3.3.2 (except maybe coin flipping; does anyone object to it?)
--Ken A.