Refine a recent change: Moloch should only have a chance to blast
you for offering the Amulet at an ordinary altar (instead of high altar)
when you're still in Gehennom (Orcus' Level or Valley of the Dead), not at
the unaligned altars in a couple of quests.
There was code to give feedback if you attempted to offer the Amulet
on a regular altar instead of the final high altar, but that code was
unreachable; getobj() yielded "that's a silly thing" whenever you picked
an amulet while not on the Astral (or recently changed, Sanctum) level.
This allows you to try to offer the real or fake Amulet of Yendor on any
altar, but they'll only be listed as likely candidates when on the Astral
level. Conversely, it no longer lists carried corpses as likely candidates
at the Astral high altars; they're still acceptable but not what the hero
is supposed to be fiddling with there. Also, allow corpses on the floor
to be offered on high altars, fixing a complaint we've gotten a few times
over the years. (Unfortunately there's no way to suppress them as likely
candidates on the high altars while still allowing them to be sacrified.)
Several small related changes that ended up being not quite so small:
Allow the Amulet of Yendor to be offered on the altar in the temple
of Moloch's Sanctum level; doing so is fatal. Fake ones can be offered
too, but that doesn't do anything special (they act the same as they do in
the temples on the Astral level). Unlike in the endgame, the Amulet and
its fakes aren't listed as likely candidate for #offer's pick-an-object
prompt; like the endgame, corpses must be carried rather than being on
the altar in order to be sacrificed.
Prevent non-chaotics from destroying the chaotic high altar on the
Astral level via same-race sacrifice. From a bug report. (Chaotics converting non-chaotic high altars
via same method was already handled. I think the behavior for ordinary
altars if wrong here; why should a chaotic altar be destroyed this way?)
Prevent demon princes and demon lords from being summoned in the
endgame. Lesser demons answer instead. Mostly prevents Yeenoghu from
being summoned by a chaotic who performs same-race sacrified on the
chaotic high altar, but might affect the Wizard and arch-liches too.
Identify (via ':', ';', '/') altars in temples on the Astral and
Sanctum levels as "high altars" rather than just as "altars". '/' and ';'
commands now work on those when you're adjacent, like they do when used on
adjacent high priests; from farther away, the altars' alignment is still
suppressed.
If you get "you have summoned <demon>" after making a same-race
sacrifice, treat that as having been the "<demon> appears" message so that
the latter won't be given if it subsequently teleports to you after you've
moved out of sight of it. There are probably some more cases like this
still lurking in the code.
<Someone> says he reported this five years ago, but I don't think I ever
saw it. Receiving an artifact as the result of #offer would add it into
the discoveries even if the hero was blind and never saw it. It either
needed to have the dknown bit set, as if it had been seen, or else should
not be added to the list. I've opted for the latter.
move oattached and oname and other things that vary
the size of the obj structure into a separate
non-adjacent oextra structure, similar to what has
already been done for mextra. The obj structure
itself becomes a fixed size.
New macros:
#define ONAME(o) ((o)->oextra->oname)
#define OMID(o) ((o)->oextra->omid)
#define OMONST(o) ((o)->oextra->omonst)
#define OLONG(o) ((o)->oextra->olong)
#define OMAILCMD(o) ((o)->oextra->omailcmd)
#define has_oname(o) ((o)->oextra && ONAME(o))
#define has_omid(o) ((o)->oextra && OMID(o))
#define has_omonst(o) ((o)->oextra && OMONST(o))
#define has_olong(o) ((o)->oextra && OLONG(o))
#define has_omailcmd(o) ((o)->oextra && OMAILCMD(o))
changed macros:
has_name(mon) becomes has_mname(mon) to correspond.
The CVS repository was tagged with
NETHACK_PRE_OEXTRA
before commiting these, and
tagged with
NETHACK_POST_OEXTRA
immediately after. The diff
between those two tags is this oextra patch.
The associated mail daemon changes to use an oextra
structure instead of a hidden command located in the
name after the terminating NUL, have not been tried
or tested.
Remove a couple of false comments about Luck, and an unreachable
switch case based upon them. I don't know if the comment in you.h was ever
true, but it was false by the time Kevin brought across assorted changes
from slash'em however many years ago. Full moon does not change the range
of possible Luck values, and ``rn2((Luck + 6) >> 1)'' produces a value
between 0 and 8 for prayer result, never 9. Natural luck is always within
the range of -10 to +10, and extra luck from carrying blessed or cursed
luckstone can add or subtract another 3. Full moon and Friday the 13th
change the equilibrium point for luck timeout but do not change the overall
range of possible values, which remains at -13 to +13.
Note: The CVS repository was tagged with NETHACK_PRE_MEXTRA
prior to application of this patch to allow easy withdrawal if necessary.
Adds a new mextra structure type that has a set
of pointers to various types of monster structures
including:
mname, egd, epri, eshk, emin, edog
Replaces the mextra bits in the monst structure
with a single pointer called mtmp->mextra of type
(struct mextra *).
The pointer can be null if there are no additional
structures attached. The mextra structure is not
adjacent to the monst structure.
Reduces the in-memory footprint of the monst that
has no other structures attached, at the cost
of adding 6 extra long ints per monster to
the save file
The new mextra structure has the mextra fields
independent of each other, not overlapping as was
the case with previous NetHack versions.
This patch doesn't do anything to capitalize on
that difference however.
Consolidates vault.h, epri.h, eshk.h, emin.h and edog.h
into mextra.h
Adds a macro for checking for whether a monster has
a name:
has_name(monst)
This fixes the magic trap panic
expels() -> spoteffects() -> dotrap() ->
domagictrap() -> tamedog()
because the monst no longer varies in size so no
replacement is required.
From a bug report, "You have summoned it!" (when human
sacrifice brings a demon which you can't see) is poorly worded, to put it
mildly. I'm sure there are plenty of other places where "it" seems odd,
but this one is now fixed....
Fix the crash caused by division by zero (attempt to compute rn2(0))
when deciding prayer boon for a character whose Luck went negative during
the course of the prayer. <email deleted> triggered it
by killing a shopkeeper with the ongoing damage from a scroll of stinking
cloud; his non-chaotic character was branded a murderer and lost two points
of Luck after the prayer was already in progress. (Prayers fail when Luck
is already negative, so the code to pick a boon expects non-negative values;
the fact that is always adds at least +2 leads to me to suspect that someone
already realized that luck timeout on Friday 13th could result in Luck of -1
at the end of a successful prayer--that value doesn't trigger this crash.)
From <Someone>, half a year or so ago:
> When you've already entered the Castle, I think your God shouldn't be
> giving you the two Castle-related messages anymore.
>
> This might be difficult to track, I realise that.
It already suppressed the tune delivery feedback if you had opened the
drawbridge with music or if that drawbridge had been destroyed. And if
you've entered the castle by the back door or via wand of opening/spell of
knock, learning the tune could still be useful, so I didn't try to extend
dungeon tracking to the point of "entered the castle". However, if you've
already passed beyond the valley below then you most likely no longer have
much interest in the drawbridge, so add a check for that to the prayer
feedback suppression.
<Someone>'s real concern was probably more about the message phrasing
than the "useless" prayer boon (since it says "to enter the castle" rather
than "to open the castle drawbridge"), and that does make the god sound a
bit silly if you've already entered the building. It would make sense to
skip the first of the two messages if you make it inside without opening or
destroying the bridge, but this patch doesn't attempt to address that.
Make it easier for a low level character with ordinary Max HP to get
the healing result from a successful prayer. Mid level characters are the
same as before: will be healed if at 1/7 (or worse) of max. High level
characters, or anyone with Max HP really high for their level, will need
to wait until current HP is lower before being able to obtain that result.
This mainly affects spoilers; the actual impact for any player who doesn't
know the old formula is fairly small. The exception is for "protection
racketeers" who manage to build up a high HP without gaining any levels;
a level 1 character will only get healed when at HP 5 or less, regardless
of what percentage of max their current hit points are.
Under the old system you could get healed at 6 HP if you had 42, at
7 HP out of 49, and so forth. Now you'll need to be at least level 2 to
get healed at 6 HP out of 30 or more, at least level 3 for 7-9 out of 35-45.
"Normal" max is capped at 15 times level and anyone above normal is treated
as if their max was that lesser normal value. Levels 1 to 5 use a new
threshold of current HP being 1/5 (or worse) of max, levels 6-13 use 1/6,
14-21 retain old 1/7 threshold, 22-29 now use 1/8, and level 30 uses 1/9.
The somewhat odd level break points are based on where rank titles change.
Make petrification initiation or termination go through a new routine,
make_stoned(), instead of manipulating its countdown timer and delayed
killer directly. No change in behavior.
There's no reason in terms of bug risk or game play or saved data why
this shouldn't be done in the branch too, but so much of the surrounding
context has already diverged between trunk and branch that it's trunk only.
While auditing nomul() I noticed unconscious() treats (multi < 0 && !nomovemsg)
as unconscious. This explains the behavior in M29 (unconscious message
while performing #turn). I checked all the places with this combination,
and found a few that did not appear to fall under the "unconscious" category.
Most I changed to use You_can_move_again to ensure the same display w/o the
unconscious behavior. Also:
- found another string that unconscious() should have considered
- vomit() now sets nomovemsg, one caller was also doing this redundantly
- vomiting_dialogue() was calling stop_occupation() after vomit(), which can
reset multi. I reversed the order and removed a doubly-redundant nomul call.
tele() still has a problem: some cases where multi < 0 should probably take
a branch like the unconscious() branch but with a different message.
doturn()'s behavior - turn then wait - is also less than perfect, but I
think this is a known problem.
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
<email deleted> wrote:
> When wielding greyswander and a black light explodes, the
> message is still "You are freaked by a blast of kaleidoscopic
> light!" giving no indication that you are immune to
> hallucination. Maybe something like "You see a blast of color,
> but seem unaffected" would be more appropriate?
return the changed status back to the caller from
make_hallucinated().
From the newsgroup: when invisible and unable to see invisible,
if successful prayer results in being given a spellbook you'll get the
message "an object appears at your feet" but the spellbook won't show on
the map. Add a newsym() to force its location to be updated. (I didn't
try to figure out why spellbooks use place_object() when all other divine
gifts use dropy() but that's why only this case has the display glitch.)
This also fixes up the message vs map update sequencing for a couple
of other "at your feet" cases so that all of them use the same ordering:
first the message is given, then the object drops.
[Timing is the only reason not to put this simple change into 3.4.3.]
- [fixed in trunk] Alchemical explosion
- [fixed in trunk] Artifacts' blasting
- [fixed in trunk] Boiling/freezing potions
- [fixed in trunk] Chest/door/tin traps
- [fixed in trunk] Falling rocks/boulders (trap, digging, scroll of earth)
- [fixed in trunk] Mixing water and acid
- [fixed in trunk] Thrown potion (acid)
This is my last patch on this today.
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
+ Separate the two uses of flags.soundok.
+ Player-settable option is now called "acoustics".
+ Deafness is now handled as a full-fledged attribute.
+ Check for deafness in You_hear(), rather than caller.
+ Check for deafness in caller, rather than verbalize(),
because gods can speak to characters in spite of deafness.
+ Since changes are being made to prop.h, reorder it to the
same order as youprop.h and enlightenment.
There are still some extraneous checks and missing checks
for deafness, which will be followed up in a future patch.
Because of the size of this patch and its savefile incompatibilities,
it is only being applied to the trunk code. Portions of this patch
were written by Michael Allison.
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
This patch introduces a change to yname() and Yname2() that avoids the
possessive "your" for the hero's normal, fully identified artifacts.
Quest artifacts still get the possessive, as do all other objects and all
objects not in the hero's possession. shk_your()/Shk_Your() are used in
many places with a specific, generalized name for the object, so I didn't
introduce the artifact behavior there, although I did change them to append
a space, which simplified some other code. Through added use of yname(),
there may be some places that used to just say "corpse" that will now be more
descriptive via yname()'s use of cxname(). I'm sure <Someone> will point
out any such places that are too onerous, although nothing obviously is.
I took the opportunity to inspect many uses of "your" and even Your(). Two
new functions are also introduced, yobjnam() and Yobjnam2(), which work
like aobjnam() and yname() combined, because I found that many uses of
aobjnam() were preceeded by "your" and I couldn't generally provide the
desired behavior for artifacts (or future artifacts) without a combined
function. In some cases, this change allowed better sharing of code.
rust_dmg() still takes a string as input which is sometimes initialized
from xname() and often prepends "your" to it. Currently, this isn't a
problem since there currently are no normal, armor artifacts. If/when any
are introduced, rust_dmg() will need to be addressed.
The patch is for the trunk only. A lot of research was required and I
didn't feel the upside was there for repeating it in the 3.4.3 branch.
This started out as a change to address the strange sequence of messages if
you remove a blindfold while engulfed in a dust vortex. That is addressed
by a new function that can be called in such situations. Calls to this
function were added in all the cases where the can_blnd() engulfing
conditions end as a result of player action. There are some other cases
that end ucreamed or usleep, but they happen between turns and shouldn't
need extra handling.
While I was at it, I noticed that a unicorn horn or prayer would cure
blindness even while engulfed in a dust vortex. This is useless, because
you immediately get blind again the next turn. So, I added checks to avoid
doing this. Finally, it didn't make sense for eating a carrot to cure your
blindness in these situations either, only for it to return immediately.
> Receiving Excalibur from a fountain while blind doesn't update the
> display (i.e. the missing fountain) immediately.
Various other topology changes had the same problem. The display
was only being updated if the hero was invisible on the assumption that
it wouldn't matter otherwise, but a blind character who moved off the
affected location would still have the old map info (fountain, trap, &c)
shown--until he walked back onto that spot or searched next to it or
regained sight--even though the player is told about the map change as
it happens.
Prevent burying a ball from ending your punishment.
When you bury the ball, internally NetHack Punishment
ceases, but a new trap type of TT_BURIEDBALL immediately
kicks in (acting similar to TT_INFLOOR in some ways).
You can eventually work the ball free (or teleport, etc.),
but that will just return you back to normal Punishment.
3.4.1 included a change which requires you to be able to use hands
in order to manipulate containers; that makes sense but has introduced
an unintended side-effect. It has become much harder to uncurse a
two-handed weapon or combination of a one-handed weapon and a shield
because you can't get scrolls or potions out of your bag. This adds a
new major trouble for prayer to address that, escalating it above the
normal minor cursed item trouble. It also removes a nonsensical check
for combination of two-handed weapon and shield that I added long ago.
Not related, but same file: add the missing artifact touch checks
for putting on accessories (quest amulets and lenses). I can't remember
if this was From a bug report.
You won't be hallucinating at the end of a prayer which reveals
the Castle passtune even if you were hallucinating before hand, so
there's no point in adding joke messages in that case. Also, you
can't pray while unconscious, so ignore the soundok flag when dealing
with that tune; otherwise the player could toggle that option off in
order to bypass the tune result in favor of the golden glow effect.
Instead of adding a new artifact.h to pray.c, remove the existing
ones from attrib.c, invent.c, and mkobj.c. This also updates the Unix
and VMS editions of Makefile.src; having stale dependencies in those
for other ports could cause unnecessary recompilation but can't break
anything in this case.
The change to fix a typo of `max(action,2)' to `min(action,2)'
for the trouble fixing effect of prayer made it impossible to get
rid of a loadstone or welded weapon by praying at non-altar locations.
That's an awfully drastic change in game balance for a typo fix....
This boosts the 2 to a 3, allowing the worst minor trouble to be
eligible for fixing.
That's a one line change; the rest of this is stuff that I've
been waffling over about whether to hold for the next big release or
to include in the patch release. It cleans up the trouble handling
code a bit--particularly the two competing choices for selecting a
piece of cursed equipment--and adds fumbling and cursed saddle as new
categories of minor trouble.
Noticed while testing something recently: if you're wearing
a non-cursed ring of levitation but can't remove it because of
some other cursed item, you'll never get the high priority result
of TROUBLE_LEVITATION when praying. This remedies that.
> 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.
- Don't guarantee high results when you have high Luck, add Luck into
random param of rn1(), and just add 1 to the basis, keeping the guaranteed
fix of a single major trouble mentioned in the block comment
Fixing some iron ball/teleds stuff:
-- If the player can pass through walls, ignore all checks for walls, or else
things will behave weirdly.
-- Instead of using the kludge "if the distance is >2 it must be a teleport",
pass a parameter indicating whether they crawled or teleported onto the new
space. This fixes a special case, where the player moved one space and the
ball didn't move, but the chain moved through solid rock. This is acceptable
if teleporting and unacceptable if dragging.
This also required some rearrangement of teleds() so that u.ux,u.uy
are set after placing the ball, not before. I'm still not sure the pit
filling line is in the right place; anyone know?
-- add some comments so I can look at the code in a month and still know what
I did.
Most of this patch is just adding the new parameter.
Don't report that undead monsters are "turning to flee"
when they're about to be made peaceful or killed outright,
and add a missing alignment fixup for the case where they do
get made peaceful.
Also, a trivial bit that only matters when using wizard
mode to wish for altars. To #offer the Amulet you need to be
on the Astral level rather than just anywhere in the endgame.
Addresses the follwing missing updates:
- Quest Artifact identification by Quest Leader.
- Rust damage from a rust trap.
- Remove curse as a result of prayer (both fixing TROUBLE_CURSED_* and
the blessed-remove-curse boon.)
- Charging via PYEC
Add absent prototypes to some core routines.
Also add some port function() to function(void) in some win32 routines.
Also updates the Borland C Makefile for win32.
When potions of full healing got added, they included the
ability to restore lost experience levels when blessed ones are
quaffed. This patch throttles them so that when multiple levels
have been lost, drinking multiple potions can only restore half
of those levels. Also, it prevents them from fixing any level
loss which occurs if you polymorph into a "new man" (or woman
or dwarf, &c, where you can gain or lose up to 2 levels).
This also makes the "golden glow" prayer result be at least
as good as blessed full healing by restoring a lost level instead
of giving 5 extra hit points when you have any recoverable lost
levels pending.
And tangentially related: gaining a level while polymorphed
now gives your current monster form an extra hit die in addition
to the latent boost your normal human/whatever form gets.
Files patched:
src/exper.c, polyself.c, potion.c, pray.c