X11 was still initializing a blank map to 'stone' instead of to
'unexplored'. When the core started forcing 'unexplored' as part
of cls(), you could see the S_stone background show up and then be
overwritten with S_unexplored.
Also, X11 is [still] drawing unused column 0. That was also 'stone'
but has been changed to 'nothing' so is now blank for both tiles map
and text map (regardless of S_unexplored value). The extra useless
column doesn't look too bad normally but does if a vertical scroll
bar is added to support a clipped map.
Another SliceHack feature. It's possible for you to eat the chameleon
tin and turn into a fiery monster that burns off the slime in its
natural form, either extremely luckily at random or if you have
polymorph control.
This buffs the blessed effect of the teleport scroll by providing the
reader control over their destination even if they lack teleport
control. This seems like it makes the blessed/uncursed distinction
actually meaningful, rather than mostly pointless.
Ported from SpliceHack, and generalized to all shapeshifters (Splice
only implemented it for chameleons). It's very aggravating when your
powerful but hungry pet chows down on a shapeshifter before you can stop
them and then turns into something much more useless, so this aims to
prevent that.
The extreme circumstances under which a pet will eat a shapeshifter are:
1. The pet is starving, and prefers polymorph to starvation
2. The pet's tameness is 1
The reasoning behind the second condition is that if you mistreat your
pet almost to the point of untaming it, it might want to take a chance
on turning into something that might get some more respect from you.
Practically, whenever this happens, this will result in the player now
owning a newly polymorphed and *still* nearly feral pet.
This makes a lot of sense. Why would they hate one artifact sword so
much and not really care about the one that is especially designed to
kill their type personally?
The scroll of remove curse is trivially identified by checking inventory
after reading it to see whether anything became uncursed. This leads to
annoying tactics like remembering which scroll you just read so you can
go call it "remove curse" on the discoveries list.
This simply autoidentifies it when an item that was known to be cursed
has its curse removed.
This is aimed at providing a little quality of life in the form of not
having to divest yourself of your sources of magic resistance before
using a level teleporter. The player is already able to use regular
teleport traps while Antimagic; there's no reason why it should be
different for level teleporters.
This ultimately comes from "Stevie-O's level teleporter jump patch", by
way of SliceHack. I simplified it a bit: deliberately jumping onto the
trap always takes time even if it fails to levelport you (which would
only happen with level teleporters in the End Game, which don't exist).
Another feature from SliceHack. Randomly averting an instadeath might
seem a little too generous, but the only time you get food poisoning is
if you're a new player who hasn't learned about tainted corpses yet or
if you just did something stupid. So, be a little nicer in those
scenarios.
If you survive, your Con silently decreases by 1. Hey, it's better than
dying.
This is also from SliceHack, but with the odds of enlightenment toned
down a bit, to 4/9 for a blessed potion and 1/6 for an uncursed potion
(SliceHack had it at 50% blessed, 20% cursed, and strangely, 0%
uncursed). It gives a much-needed use to one of the potions that's
commonly blanked or discarded.
Tame cancelled lights are actually quite interesting and useful: they
are a mobile light source that will follow you around, and because they
are cancelled they won't explode at hostile monsters.
This replaces the existing confused scroll effect of creating an area of
darkness (the cursed scroll of light still produces this effect). If you
are confused *and* the scroll is cursed, it summons black lights instead
of yellow ones.
Original change by copperwater <aosdict@gmail.com>, added with
formatting and some functional changes.
Shriekers only spawn purple worms when they're appropriate difficulty.
Non-tame Purple worms eat corpses off the ground.
Baby purple worms attack shriekers.
Hero polyed into baby purple worm is warned against shriekers.
Original changes by copperwater <aosdict@gmail.com>, added with some
formatting adjustments and consolidation.
When moving onto a different terrain type, the logic for whether to
block or unblock levitation and flying (for the case of moving in
or out of walls and solid stone with Passes_walls while levitating)
was correct but the XOR logic for whether to do a status update
because of such a change was incorrect. So stepping from room floor
to furniture or to doorway and vice versa or from corridor to doorway
and vice versa was requesting a status update when there was no need
for one.
Some other code must be requesting a status update when it is needed
for this (or possibly even more often than that?) because the status
line does seem to show the current state of Lev and Fly accurately.
Otherwise this should have been noticed when switch_terrain() was
first implemented.
'use_inverse' used to be unconditionally present but conditionally
had default value True for WIN32 and False for others. The options
changes that moved things to optlist.h made it present for WIN32 and
absent for others. Put it back, and change the default value to be
unconditionally True.
Far-look and getpos's autodescribe feedback described the castle moat
as "water" and Juiblex's swamp similarly. Describe them as "moat"
and as "swamp" instead.
Before this commit, the name of a novel in the level files was ignored for
setting novelidx. But the name was set nevertheless, so you got a named novel
that showed quotes from a different novel.
Now, 'des.object({ id = "novel", name="Raising Steam"});' will work as
expected.
When swallowed by an air elemental, going down into a pit
placed the attached iron ball on the floor. Saving (or
using #wizmakemap) then deallocated the iron ball.
Check being swallowed before trying to go down.
If you're in a vault, the vault guard enters, and your tame purple worm
swallows and kills the guard, the worm ended up inside the vault wall.
Instead return the attacker to the old location, if the defender's
position isn't good.
Report complained about multiple Archons causing his character to
be swarmed by monsters on the Plane of Fire. I don't think that
the behavior has changed significantly from how it worked in 3.4.3.
Nobody can summon an Archon directly because they're excluded from
the nasties[] list. But whenever summoning picks a genocided
'nasty', the result gets replaced by random monster of appropriate
difficulty for the level (which could be an Archon for a high level
character in the endgame). [Note that that won't pick an Archon
in Gehennom or at arch-lich outside of there because the random
monster creation honors the only-in-hell and never-in-hell flags;
picking from the nasties[] list doesn't.]
This prevents that for any creature (except arch-lich or the Wizard)
casting the summon nasties spell. If a replacement creature is a
spellcaster it now has to have lower difficulty than the summoner.
If not, it will be discarded even though its difficulty is classified
as appropriate. So to summon an Archon, the summoner has to have
higher difficulty than an Archon; arch-lich and the Wizard are the
only ones meeting that criterium. When summoner is an arch-lich,
it can't summon another arch-lich (since that wouldn't have lower
difficulty than the summoner) and can summon (via replacement for
genocided type, and only if outside of Gehennom) at most one Archon.
When summoner is the Wizard, he could summon an arch-lich (when in
Gehennom; demoted to master lich elsewhere--see below) or an Archon
(outside Gehennom only), but at most one per summoning.
For post-Wizard harassment, which effectively has infinite
difficulty level, it could still happen. However, each instance of
harassment is only allowed to create at most one Archon or arch-lich
now, so chain summoning should be lessoned. Also if it tries to
pick an arch-lich when outside of Gehennom it will switch to master
lich instead (which won't be allowed to summon an Archon or an arch-
lich or even another master lich).
(The monmove.c bit is unrelated, just some comment formatting that
I had laying around that got mixed in.)
Same race corpses, deceased pet corpses, wraith corpses, and unicorn
corpses could be sacrificed even when otherwise too old. This
prevents that for wraith and unicorn corpses but leaves the same
race and dead pet cases as is. I'm not sure that this is the right
way to resolve things but at least has the virute of being simple.
This also lets chaotics get the trivial bonus for sacrificing a
wraith corpse even though alignment matches. Alignment doesn't
matter for anything else (except unicorns) and giving up a wraith
corpse that isn't too old to eat is a tangible sacrifice. Unless
the hero is vegetarian (or the supersets vegan and foodless) since
giving up a corpse that won't be eaten isn't worthy of a bonus.
(It will still retain regular sacrifice value in that situation.)
Fixes#304
From a reddit thread, praying on the altar in orctown behaved like an
ordinary prayer directed at Moloch rather than being an exceptional
event. Make it always be rejected. The penalty is very trivial.
Before this commit, attaching a lit candle would reduce the amount
of fuel in the candelabrum to 0, 15 or 75 turns due to a failure to
account for time stored in the candle's burn timer. Fixing this is
very important because a time of 0 turns on the candelabrum is not
supposed to be possible.
Juiblex should be a little bit harder to beat than zapping a digging
wand once you've gotten swallowed and then whacking him once.
Make his HP halve every time you zap digging instead of setting it
to 1.
Change via UnNetHack.
X11's "fancy status" does its own highlighting that predates
STATUS_HILITES, showing things which have changed in inverse video
for a turn. However, it excluded conditions plus hunger and
encumbrance. Make it highlight those similarly when they come On
(and when they change from one non-blank state to another in the
case of hunger or encumbrance). There's no corresponding
unhighlight when going Off because they're blanked out instead.
This fixes the reported situation of recoiling from a throw while
levitating and carrying the ball not bringing the chain but it might
introduce other problems. If it does, drag_ball() would be the place
to fix that, not hurtle_step().
Separate bug (not fixed): throwing while the ball is on the floor
ought to let you recoil to as far as the chain will reach but it just
yields "you feel a tug from the ball" and you don't recoil at all.
Instead of forgetting maps and objects, make amnesia forget skills.
Forgetting maps and objects could be circumvented with taking notes,
or by using an external tool to remember the forgotten levels.
Forgetting skills allows the player to optionally go down another
skill path, if they trained the wrong weapon in the early game.
Amnesia still forgets spells.
As a replacement for the deja vu messages when entering a forgotten
level, those messages will now indicate a ghost with your own name
existing on the level, given only when the level is entered for
the first time.
These changes based on fiqhack, with some adjustments.
Scroll of scare monster completely shut down most of the actual
challenging monsters, such as uniques. Tone it down, so you can
use it to ignore the smaller threats while dealing with uniques,
or get most of the effect in the early game when you're usually
dealing with normal monsters.
I started out adding a few new status conditions to X11's "fancy status"
(the default) to gauge how difficult it was going to be. In the process
I found several latent bugs. After fixing those, I decided that the same
status conditions should be added to the alternate "tty-style status".
Lots more latent bugs, some of the same nature, others different. Things
spiraled until the code change is very substantial.
Code for the old two-line status is still present but I don't know how
to activate it. Unlike tty-style status, it composes and displays two
lines of text and isn't capable of highlighting portions of that text,
so it would be considered deprecated anyway.
All testing was done with the default NetHack.ad (except when turning
'fancy_status' off) so I don't know whether the new code might override
previously customizable status settings. I'm not sure whether this list
covers all the fixes....
both tty-style and fancy
add new status conditions 'grabbed' (by eel), 'held', 'trapped', and
'sinking-into-lava' (others will eventually follow); grab and lava
are on by default, the others have to be enabled via options
both tty-style (not handled) and fancy (faulty boolean logic)
polymorphing didn't change Xp to HD (silver lining: rehumanizing
didn't need to reverse it)
tty-style only; fancy was ok
force white text (on black background) instead of settling for gray
turning on optional showexp, showscore, and/or time worked but turning
them back off again didn't remove the relevant fields
polymorphing when showexp was on didn't suppress Exp-points
tty-style only; fancy uses different layout
condense conditions into simple left-to-right space separated list
instead of giving them specific locations and having gaps of blank
space for conditions that aren't in effect
tty-style only; not applicable for fancy (status_hilites not implemented)
all highlights stuck if 'statushilites' was reset to 0 to disable them
displaying anything with bold attribute stuck; it wouldn't revert to
normal text if a different highlight rule without bold was used for
subsequent updates
avoid inverting leading space that separates from preceding field when
highlighting with inverse video attribute
add support for 'dim' attribute using gray foreground (only viable
after the fix for white foreground)
fancy only
reorganize the field layout so that things line up nicely instead of
having columns with six, seven, or eight lines be spread over same
amount of vertical space
line up the values of the six characteristics, similar to how vertical
status works in curses: all two digits; when exceptional strength is
present, the '18' lines up and rest goes past implicit right margin
use status conditions as provided by core instead of duplicating them
(other fields still duplicate stuff done in botl.c); doing this
required forcing 'VIA_WINDOWPORT()' if built without STATUS_HILITES
For some reason the vault guard fake corridor code checked
if the hero was outside the corridor before removing monsters.
But the vault end of the corridor usually gets sealed off
even while you're still in the corridor. This left monsters
stuck in solid rock.
In a rare case, a random room's width can be 2 tiles, and if
that room was converted into a temple, the priest ended up
inside the wall. Try to put the priest on a random valid position
around the altar, or on it.
From a reddit thread. Quaffing from a fountain can curse some of
hero's inventory, but when doing so it wasn't updating the persistent
inventory window if that was enabled.
It could also set the cursed flag on goid pieces; so could dipping.
"remove_obj: obj not on floor" when trying to move the iron ball.
For the circumstances involved, the ball wasn't supposed to be
moved anyway, just the chain.
I could reproduce the problem using the steps specified. I didn't
track down the precise point of failure but after this fix the
panic can't be reproduced anymore.
When making a random door into a random wall or random position
in a room, keep trying harder to find a location that doesn't
have solid wall behind it.
Fixes the Wizard tower door.
Remove the entry about creating Guidebook.dat on Unix since it got
moved to 3.6.6.
The orc town raiders were introduced in 3.6.2, not to-be-3.7, so the
fixes entry for unintentionally giving orc zombies and orc mummies
clan names should be in the general fixes section rather than the
exposed by git section.
If a special level explicitly requests eg. a statue with a genocided
monster class, allow generating it.
Rationale is that those objects were generated before the monsters
became extinct. Also fixes a lua error.
Reported 3.5 years ago. Specifying a count for pickup to pick up a
subset of a stack was processed after scrolls of scare monster were
handled, so a whole stack of those got picked up or crumbled to dust
whether you gave a count or not. Also, if you were too encumbered to
pick up the full stack, they still all crumbled or all changed state
to crumble next time, then for the latter case you picked up as big a
subset as you could handle.
While polymorphed and underwater, an eel bite killed the hero who
rehumaized and crawled out of the water, then the eel continued with
its second attack and "wrapped itself around you" even though no
longer adjacent. That's a long reach....
| ...@.
| .;}..
| .}}..
Make any additional attacks silently miss if hero changes location
during the attack sequence of a monster who has pinpointed the hero.
Role selection is insanely complex. I had to use a debugger to force
the relevant routine to be executed.
The analysis was correct: it could use rn2(14) to pick a role (valid
values 0 through 12) and randomly getting 13 would lead to a crash.
The terminating element of roles[] passes all the ok_role(), ok_race(),
etc tests. Explicitly exclude that element when collecting the roles
to choose from.
Implement the request that a wielded+thrown aklys be given the same
inventory letter when it returns and is caught and rewielded, even for
the !fixinv setting where inventory letters don't stick. Works for
Valkyrie-thrown Mjollnir and returning (ie, didn't hit) boomerangs as
well as for aklys.
I'm not sure how useful this really is, because on the rare occasions
that it either doesn't return or fails to be caught, it won't be given
the same letter when subsequently picked up. So the player who relies
on it will still be vulnerable to using the wrong letter next time a
throw is attempted. But at least picking it up explicitly displays
the new inventory letter, unlike catching it upon return.