Someone in the newsgroup claims to have reported this in mid-October,
but he uses a fake address in news and maybe he did so with his mail too,
resulting it not being delivered. Anyway, arming a land mine on the Plane
of Air, then setting it off, produced a pit in the air. This fixes that
directly, in case someone manages to do it again, and it also prevents
land mines and bear traps from being armed in midair in the first place.
Ditto for Plane of Water; water/pool locations were already covered (can't
arm there), and the bubbles ought to be treated similarly to Plane of Air.
When testing this, I managed to get a crash while restoring a saved
game. I had worn a blindfold and armed a land mine on the water level
(with just the no-pit part of the patch in place), then saved. When
restoring, I got a crash in restore_waterlevel() at one or the other of
these lines (traceback pointed at the first, but it has to have actually
been the second; an access violation from an address derived by applying
a small offset to a null pointer):
ebubbles = b;
b->next = (struct bubble *)0;
After that, I couldn't reproduce it with a wished-for trap and couldn't
stay in one place long enough again to successfully arm a trap object.
So there may be a nasty bug still present, perhaps now hidden by no longer
being able to create a new trap on that level.
Thrown boomerangs travelled in a clockwise path, appropriate for
left-handed throwing. But nethack heroes are treated as right-handed by
the weapon wielding and shield wearing code, so make boomerangs travel
counterclockwise instead. Switching is straightforward, in case we ever
implement user-specified or random handedness.
Make worm teeth and crysknives be stackable. Positively enchanting
a stack of multiple worm teeth produces a single crysknife, negatively
enchanting a stack of multiple crysknives produces a single worm tooth.
A dropped stack of N fixed crysknives has 90% of remaining N crysknives,
10% of becoming a stack of N worm teeth, rather than produce an average
of 0.9*N crysknives and 0.1*N worm teeth. (The code which handles that
transformation operates on loose objects so cannot handle stack splitting
because it wouldn't have any idea of what to do with extra objects.)
Terminate multi-shot volley throwing of boomerangs if one comes back
and isn't caught. The sequence throw-catch-throw-catch is odd, but would
take a substantial amount of code and effort to be changed to the more
intuitive (for rapid volley throwing) throw-throw-catch-catch. Even if
feasible, doing that for underused boomerangs would be a waste of effort.
Reading the comments in the previous patch, I realized that keeping
the old behavior for monsters who are shooting multiple missiles was
leaving an obscure but potentially serious bug. I haven't attempted to
trigger it but 3.4.3 is bound to be vulnerable.
Make all stackable weapons capable of multi-shot volleys when thrown.
Affects knives, spears & javelins, and boomerangs; requires advanced skill
assignment (skilled: 1-2 missiles per throw, expert: 1-3 missiles) or
role-specific bonus (ranger class's general +1 bonus is the only one that
applies to any of these weapon types). For monsters, prince-caste get 1-3
missiles and lord-caste get 1-2, as before, with fake player monsters now
also getting 1-2; those counts apply to all stackable weapons regardless
of whether the species or role ordinarily uses whatever is being thrown.
Related changes: monks now get a role-based +1 count for shuriken,
throwing 1-2 instead of just one (they're only allowed to achieve basic
skill so won't reach any higher volley count). Monster monks and ninjas
get that too; ninjas now get the same for darts and they're guaranteed
weapons in starting inventory. Also, fake player rogues now sometimes
get orcish daggers instead of short sword, providing a decent chance to
occasionally have Grimtooth be randomly generated on the Astral level.
Potentially controversial: wizards can still become expert in dagger
skill and receive the to-hit and damage bonuses for that when throwing as
well as when wielding, but the number of missiles for them has now been
reduced to 1-2 (in other words, going from skilled to expert no longer
improves the max count for the volley amount for wizard role). They're
supposed to be spellcasters; being able to throw up to three +7 daggers
at a pop was a big temptation for resorting to brute force, particularly
since they'll already want highest dagger skill for wielding Magicbane.
To do: throwing multiple boomerangs either needs to behave as if
they're all in flight before the first returns, or else the volley needs
to be cut short if one comes back and isn't successfully caught. The
latter is a lot easier to do but the former fits better with what multi-
shot volley is supposed to represent. Another alternative is to change
them to no longer be stackable, then this sequencing issue goes away.
To do too: make worm teeth and crysknives become stackable like the
other knife-skill weapons.
Part of "multi-shot throwing proposal" last January. Unfortunately
some of the bits that I had implemented back then have vanished, so I'm
doing it over from scratch. There were three main parts:
1) allow multi-shot volley throwing for all stackable weapons (affects
knives, javelins, spears, and boomerangs; other weapons either don't
stack or are already multi-shot);
2) make worm teeth and crysknives be stackable like ordinary knives;
3) merge spear and javelin skills, so that allocating skill points to
their use becomes more attractive and they might get used more.
This patch only does #3.
Since the monk skill set shrinks by more than any of the other roles,
I bumped max skill for escape spells (haste self, invisibility, jumping,
levitation, and teleport away) from basic to skilled; that's the only
skill adjustment included here. For the couple of roles had different
max values for spear and javelin skill; this keeps the higher of the two.
From the newsgroup: ``Something is engraved here on the water.''
An engraving written on a lowered drawbridge would be transfered to the
underlying terrain when the bridge was raised. The coverse was also true;
if you plugged the moat and then engraved on the ground, that engraving
would remain visible--and touchable if blind--when the bridge was lowered
to cover its spot. Rather than try to handle two different engravings at
the same coordinates (with one of those two changing locations when the
bridge is raised or lowered), this just wipes out any engraving at both
span and portcullis locations whenever the bridge state changes, like is
done for traps.
Typing a response at the "Who are you?" prompt didn't allow digits in
the character's name under Unix and VMS; something like "arc15" came out
as "arc__". This allows them to be used anywhere except for the first
character. "arc15" now works; "15arc" ends up as "_5arc" so that there
still won't be a leading digit abutting the uid value when they're joined
to form the save file name.
From a bug report:
crossbow shot range shouldn't depend upon strength. Make it fire for a
distance of BOLT_LIM regardless of whether if would have gone shorter or
longer by using the normal ranged calucations. However, strength is
necessary to load crossbows, so make characters with low strength be less
capable of launching multi-shot volleys.
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.)
Also from the newsgroup (2nd from "Three bugfixes for Xorns" [I got
the subject wrong on the previous spell of protection patch]): when
phazing through walls or rock you could engrave as if it was ordinary
floor. Again I didn't use the user's patch; it left closed doors, raised
drawbridge, and iron bars as locations where engraving was still feasible
and said "you can't write in solid rock" even if you were inside a tree.
[The 3rd of "3 xorn fixes" was for misleading feedback when attempting to
engrave while underwater; we've already fixed that one.]
There was a suggestion that you should be able to engrave within solid
rock if you use a wand of digging, and that seems like a pretty good idea,
but the check for location comes before the check for writing instrument so
would be tricky to implement.
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.
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.
From a bug report: if swallowed and blind
and in quantum mechanic form, hitting the engulfer would yield "the <mon>
disappears" even though you were still swallowed by <mon>. The pre-teleport
criteria for whether you knew the target was there were different from the
post-teleport ones. Make them match; swallower will remain sensed by touch
and won't be described as disappearing.
A couple of months ago Michael forwarded a thread from the newsgroup
about how wielding a cockatrice corpse without gloves while polymorphed
into something capable of that would leave you wielding that corpse
bare-handed if you changed form, turned to stone, then got life-saved.
That got fixed; the corpse becomes unwielded. However, one of the
messages in that described a different bug: if you were wielding such a
corpse as a stone golem and cast stone-to-flesh at yourself, you would
continue to wield it bare-handed as a flesh golem. This makes you revert
back to stone golem once the first transformation has finished.
This also fixes an attribute exercising bug in polymon(). It was
being done after the polymorph was completed, so the attempt to exercise
Con didn't do anything because exercise() of anything other than Wis has
no effect when the hero is polymorphed.
From a bug report: entering lava cures sliming,
but if you got [re-]afflicted by green slime after becoming stuck in lava,
#sit failed to cure it. Fix that, and have sinking farther into lava cure
it too (although not necessarily right away).
Also, suppress leaving the corpse in a bones file for death caused by
being dissolved in lava. Lastly, suppress the "you rise from the dead as
a <monster>" message during bones creation when the game ends due to being
turned into green slime since you transformed rather than died (and sliming
timeout gives "you have become green slime" just prior to that).
Something's wrong with the way lava was being handled in moveloop().
If you were trapped in lava (ie, moved into some but didn't die on the
spot thanks to fire resistance), you could sink and ultimately die without
ever taking another actual turn (typing ``i<space>'' repeatedly is an easy
way to reproduce). [`didmove' was only being checked for the sinking
deeper case and not for the decrement which ultimately leads to the fully
sunk case.] On the other hand, if you could manage to start an occupation
and avoid being interrupted, you would never sink while it was in progress.
[Lava handling followed ``if (multi && occupation) { ...; continue; }''.]
While testing some other code (lava vs slime, coming shortly) I ended
up with the cursor sitting on the status line while the game was waiting
for me to enter my next move. I don't really understand what's going on
there, and moving the lava handling before bot() might have hidden that
particular problem now by changing the point at which Slime will get taken
off the status line, but this attempts to fix it anyway.
From a bug report: you
can dip a worn item such as shirt or suit into a potion of polymorph and
it will become unworn--but as of a couple of days ago, unworn only if the
transformed object's new form can't be worn in the same slot--even if it
is covered by a cursed worn item (suit or cloak). It didn't seem like
trying to fix that special case would be very worthwhile; this fixes the
more general situation of "you could dip worn items even though they were
covered up by other worn items".
In the same report: you could apply grease to rings while wearing
cursed gloves. The code already prevented greasing a suit when it was
covered by a cloak (regardless of whether that cloak was cursed), and a
shirt when it was covered by a suit or cloak or both. This moves that
code into a separate routine which is used for dipping as well as for
applying grease, and now handles rings vs gloves.
Since covered rings, shirt, or suit are no longer eligible to be
dipped or greased, this also makes "?" for the pick-an-item prompt leave
such things out of the list of likely candidates.
From a bug report: zapping a wand of striking or locking or spell of
force bolt or wizard lock up or down when standing at an open drawbridge's
portcullis didn't affect the bridge if the portcullis was positioned north
of the open span. One of the two drawbridges on the Valkyrie quest goal
level has that orientation. is_drawbridge_wall()'s name is somewhat
misleading; it isn't boolean and returns -1 rather than 0 for "no".
From a bug report. That's hard to fix in the general case because armor
and tools might not fit back into the same equipment slot, but most other
types of worn items can be re-worn after being transformed. This makes
any transformed worn item stay worn if it is wearable in the same slot.
Noticed when examining resists_magm() while working on anti-magic
traps: if you were polymorphed, you would be granted magic resistance by
keeping a cloak of same or gray dragon scales/mail in your quiver slot,
your alternate weapon slot, or main weapon slot (ie, by wielding it). And
you obtained light-based blindness resistance regardless of whether you
were polymorphed if you carried a potion of blindness in any of those slots.
Make anti-magic fields do something against targets which have magic
resistance, expanding the functionality of that trap type and giving a
minor drawback to the most valuable intrinsic in the game. Make them work
against monsters too.
Heroes who lack magic resistance lose spell energy as before, except
that if they drop below 0 they don't take as hard a hit against max spell
energy as they used to. Monsters with spell or breath attack and lacking
magic resistance get their ability-last-used field bumped up a little bit,
so they can't cast or breathe for a few turns. Heroes and monsters who
have magic resistance take HP damage instead. I retained the concept of
feeling lethargic when being hit by something which normally drains enery,
and also tried to make it be the inverse of a "magical explosion": the
message refers to torpor/lethargy/sluggishness and cause of death if the
damage happens to be fatal is "anti-magic implosion". The latter suggests
some sort of compression, so creatures who can pass through walls (xorns
and ghosts) have been given partial resistance and take reduced damage.
If a Rider's corpse revival timer ends with failure (presumeably
because the level has become entirely filled with monsters), give it a big
chance to try again in a few turns instead of always rotting the corpse
away. Also, if there is another monster standing on the corpse when it's
due to revive, try to bump that monster out of the way to let the Rider
revive in place instead of having it be diverted to some other location.
High resistance made the Riders unlikely to be polymorphed, but
they were susceptible to being turned into green slime (and then never
reviving if killed in that state). Now they'll be immune to both types
of transformation.
<email deleted>:
> If you enter a magic trap on the same turn that you lose your levitation
> and "float gently to the floor", you are hit by the trap twice.
I don't think this is actually a bug, but it does look fairly strange
if there aren't any monsters attacking (after you move on to the trap,
monsters get a chance to move too before timeouts are run, but if there
aren't any messages triggered by monster activity then it feels like the
timeout and second activation happens immediately). To prevent this, if
levitation is due to time out on the same turn that a trap is being
entered, either extend the duration by an extra move or make it end
immediately instead of waiting until end of current turn. Deferring
timeout is a lot easier but doing that unconditionally would allow player
to move back and forth between adjacent traps without ever descending.
The early timeout might lead to anomalous behavior in obscure cases; it
seems to be working ok so far though.
Eliminate the somewhat redundant "You die..." following "You turned
to stone..." when becoming petrified by touching a cockatrice (reported
by <email deleted> for kicking, but occurs for weaponless hitting too).
Also, if a cockatrice killed you with normal damage, your tombstone would
erroneously report petrification and presumeably there'd be a statue
instead of a ghost in the resulting bones file. This fixes both things.
The earlier change involving "you sneaky cad!" got me wondering, so
I looked up cad in the dictionary: "an ungentlemanly man". I can see
that being extended to a male gnome, even to an orc, but not to a women.
Make objects created by applying or #tipping a horn of plenty which
is owned by a shop also start out being owned by the shop. That's in
addition to the usage charge for using an unpaid item.
I think wishes conferred by unpaid objects, or by entities released
from unpaid objects, should probably work that way too, but have left
that alone.
[I can't get access to my mail at present, but `cvs update' shows
that there aren't any patch notification messages pending for me.]
Extend a pre-3.4.3 fix--for objects picked up in an untended shop--
to container contents. Without it, dropping a bag or box in a tended shop
and declining to sell it, then picking it back up after the shop has become
untended (shk killed or evicted) would leave the contents with no_charge
set. After that it could be sold in another tended shop, picked back up
for free, then kept or sold a second time. (Picking it back up in the
tended shop would clear the bit; afterwards it behaved normally. And it's
not something prone to abuse; if you can make a tended shop become untended
you really don't need to sell stuff twice. But it'd be noticeably wrong if
anyone ever stumbled across it.)
Inventory display adds "(unpaid, N zorkmids)" to carried unpaid
items, but it didn't show anything comparable for indirect unpaid ones
(hero-owned containers holding shop-owned objects). Now it will include
"(contents, N zorkmids)" in such cases.
Prevent getobj() from overflowing its inventory letter collection
buffer if someone figures out some new way to fill up their inventory with
a huge number of # entries. Inventory manipulation might become crippled
at that stage but at least it shouldn't be able to trigger a crash.
Also, the !fixinv configuration was never taught about # and did
strange things if you had more than 52 items, both for inventory display
and object selection with getobj.
The reassign()/getobj() situation is definitely confused regarding
gold, using GOLD_SYM in some places and def_oc_syms[COIN_CLASS] in
others, and it's schizophrenic about whether the GOLDOBJ configuration
keeps gold in a letter slot or specially named $ slot. I'm sure there
are some problems there but I'm not planning to try to figure them out.
Prevent heroes in giant form from picking up boulders once they run
out of available inventory slots to avoid an uncontrolled number of '#'
entries. There is an exception: if not already carrying any boulders,
they can put one into the '#' slot. Loadstones are treated the same way,
although since they stack and are rare to begin with, someone would have
to have gone far out of their way to have gotten many # entries with them.
Assuming that you can get something other than a boulder or loadstone
into the # slot (which is definitely possible, I just can't remember how),
you could relatively easily get three total # entries by picking up a
loadstone and polying into a giant and picking up a boulder. But I don't
think there's anything wrong with that.
This eliminates a whole bunch of the "Query truncated" entries in
the nethack.alt.org paniclog file by using safe_qbuf() where applicable.
It also makes selling queries and some other shop messages be less verbose
when shopkeepers are invisible (not uncommon after characters achieve see
invisible capability) by using shkname() to get "Manlobbi" instead of
Monnam()'s "Manlobbi the invisible shopkeeper" (something I had planned
to do even before seeing the truncations in that paniclog; repetition of
"the invisible shopkeeper" was very annoying when stepping through
multiple unpaid objects with itemized billing).
This also simplifies several GOLDOBJ conditional sections which
happened to be near the other code I was modifying.
Explicitly truncate the query prompt string to QBUFSZ-1 characters.
For tty and Amiga, no longer include the choices and default within that
length limit; use a bigger buffer to hold them along with the prompt.
-----
While trying to eliminate the "Query truncated" entries present in
nethack.alt.org's paniclog, I seem to keep going backwards. Allowing
<win>_yn_function() to accept a full QBUFSZ worth of characters will
simplify the existing yn_function() in the core and greatly simplify the
revised safe_qbuf() I've been working on.
Some interfaces don't seem to care how long the prompt string is; I've
left those along. Several of the others already copied the prompt string
into a BUFSZ sized buffer instead of a QBUFSZ sized one, making them
unlikely to suffer from buffer overflows. This changes the rest (just tty
and Amiga, I think) to do the same. Also for all that have any size
constraint, it now truncates the prompt query to QBUFSZ-1 chars as it is
used rather than continue to rely on the caller doing so. This assumes
that appending the set of acceptable choices and the default response won't
overflow, which is a safe assumption unless/until QBUFSZ gets enlarged til
it's too close to BUFSZ.
Only tty's topl.c has been tested. The others should work ok, but
might possibly be bitten by a typo or two. Qt's implementation of the X11
"slow" method (reusing a persistant one-line window for prompts) has been
handled, but its C++ class-based variant is untouched; NetHackQtYnDialog::
Exec() is completely baffling to me but doesn't appear to have any length
issues.
According to a newsgroup followup, a hidden pet summoned via magic
whistle could produce the same effect as the level change case (where
sometimes the glyph for unseen monster would appear unexpectedly). I was
unable to reproduce this one, but I don't see anything in the code to deal
with the situation, so I suspect that the monster is moving immediately
and being revealed before I have a chance to notice anything odd.
I assume that other situations where hidden monsters get teleported
are being handled as attacks which expose them. At least I hope so.
From the newsgroup: if a pet was hiding under an object next to you
when you changed levels, it could arrive hidden at the destination if there
was something available to hide under there too, and sometimes you'd start
the new level with a hidden monster glyph at its location. I was able to
reproduce that once with current trunk code, but while trying to figure
out what is actually happening I've been unable to make it happen again.
However, it doesn't make sense for a monster to be able to remain in hiding
during the level change in the first place, so this patch prevents that.
(I'd still like to know how/why map_invisible() is sometimes getting called.
[The test character was a level 1 tourist without auto-search capability.]
I'm reasonably sure that it won't happen any more once this fix in place.)
This also brings adjacent pets out of hiding when they accompany you
during ascension or dungeon escape, but it seems that that wasn't actually
necessary. The end of game disclosure already lists such by name rather
than as "it", contrary to my expectations. (I had forgotten that end-of-
game forces true names so that blindness and hallucination don't interfere
with disclosure; obviously that ends up handling hidden monsters too.)
Add putmixed() to the window port. It allows map symbols to
be included in the string by encoding them in a unique fashion.
This was done because Unicode symbols, for instance, could be
longer than the size of a char.
The encoding of the map symbols in this patch is done by
prefixing a glyph value with \GXXXX, where XXXX is a
random value for the current game. The reason for the random
prefix is to minimize the possibility that a player can trigger
the escape sequence processing within text under their control
(dog names, etc.) the way they could if the sequence was fixed
in the source code. The random prefix remains the same throughout
the lifetime of a game because message window strings are
saved in the save file.
(There was actually a bug present because of the embedded
character even before the recent symbol changes, because if
someone was using a different set of characters between games,
the saved messages would reflect the original characters, rather
than the current. That bug was introduced with the ability to
save messages to the savefile.)
A window port does not have to supply an XXX_putmixed() routine,
it can use genl_putmixed() which uses the old behavior of
embedding the sequence as a character within the string
and calling putstr(). genl_putmixed() takes care of the decoding
of the escape sequence.
This also #ifdef's out code in pager.c for converting a glyph
to a character, and uses mapglyph() to do that instead. Does
anyone see a problem with doing that through mapglyph instead
of repeating similar code within pager.c?
From the newsgroup: if you were wielding a cockatrice corpse without
gloves while polymorphed into something capable of doing that, then were
turned to stone when rehumanizing, you'd be left wielding the untouchable
corpse if life-saving kept the game going. This causes it to stop being
wielded if you get that far. Likewise for monsters.
From the newsgroup: it was possible to saddle, mount, and ride on a
sleeping jabberwork without it ever waking up. Movement was checking for
timed sleep (!mon->mcanmove, set when mon->mfrozen contains a timer count
for either sleep or paralysis) but not indefinite sleep (mon->msleeping).
This moves the checking into its own routine which handles both types.
And it gives monsters a chance to wake up when they get saddled or mounted.
Extend the identifying information used to prefix paniclog entries
from version + date to version + date + time + userid + mode (where mode
is 'D' for wizard mode, 'X' for discover mode, and '-' for normal play).
hacklib.c ended up getting more of a revision than I intended, but
the date/time handling routines now have less clutter. I hope I didn't
break anything in the process.
There is a quote in data.base for squeaky board traps:
A floorboard creaked. Galder had spent many hours tuning them,
always a wise precaution with an ambitious assistant who walked
like a cat.
D flat. That meant he was just to the right of the door.
"Ah, Trymon," he said, without turning, and noted with some
satisfaction the faint indrawing of breath behind him. "Good
of you to come. Shut the door, will you?"
[ The Light Fantastic, by Terry Pratchett ]
This patch makes each squeaky board trap on a level produce
a unique sound. If you had visited the trap yourself prior
to hearing a monster on it, you could actually know where
a monster was by the unique pitch of the squeak.
If someone wants further refinement of the roles, this could
be adjusted to only work for musically adept roles/species,
with the others only hearing a generic squeak. As it stands
right now, everyone benefits. Does anyone thing the
separation by role or species would be good? If so, which
roles/species are musically proficient, and which are not?
Since this patch increments editlevel anyway, it also sneaks in a
context structure change for an upcoming patch.
From a bug report: if you
attempted to eat a Rider corpse and got the 1/7 chance that non-yet-rotten
food will be treated as rotten, then also got "the world spins and goes
dark" result for rotten food, you would both survive the eating attempt
and also end up with a partly eaten Rider corpse. This patch treats Rider
corpses like lizard and lichen corpses; they'll never yield rotten food
effects. That way, they'll always be fatal to eat. They'll still end up
being partly eaten if you are life-saved, but since they'll immediately
revive, the only way you'll know that is to use probing or stethoscope to
discover that they've revived at less than full health.
Nearly two years ago, <email deleted>
suggested that lembas wafers and cram rations be treated like fortune
cookies and never yield the rotten food result. I'm guessing that cookies
are handled that way so that rotten food feedback doesn't override false
rumor delivery when they're cursed, rather than because they're considered
to be rot-proof. This implements <Someone>'s suggestion, except that cursed
lembas and cram will still behave like rotten food.
One from the way-back machine. A nurse would hit you-as-cockatrice repeatedly
and never turned to stone. With this change, nurses will turn to stone (and
also don't heal cockatrices, which seems fair). I considered giving them
gloves, but that seemed like too much effort. There are other cases where a
monster "hits" but will not petrify. However, it doesn't seem like passiveum
detects all the specific ways the monster "hit" you so I left them alone.
Fido grows up into a large dog.
The soldier becomes a sargeant.
Similar feedback was previously given only when the monster was going to be
killed off due to its new form having been genocided.
The shortest extended commands were being formatted differently in
Guidebook.txt than longer ones, looking a little odd. Force them to seem
longer so that they all end up with similar formatting.
Untested; based on how short option names are handled. And I have no
idea whether the TeX version ought to have something similar done; I lack
the means to view it. (In theory I could format it into Postscript,
transfer the result to a PC [a different one than what I'm using as a
terminal], convert it into PDF there, then use Acrobat to look at it. In
practice, that's more effort than I care to expend for something so minor.)
<Someone> pointed out that bugles, although noisy, only affect soldiers.
This didn't make sense to me either. Added code so they will also affect
monsters near the bugler.
Pat wrote:
> <Someone> has a patch (we've added a couple of
> his earlier ones) which changes the statue display from a single
> one size fits all "`" to a gray monster symbol instead.
> But I think the idea is a good one, and along with the
> bouldersym option could make the fairly hard to
> distinguish back-tick character go away.
Sources tagged before applying NETHACK_PRE_STATUE,
and afterwards with NETHACK_POST_STATUE for easy
rollback.
- reduce the number of symbol tables for each graphics
set {PRIMARY, ROGUESET} from three {map, oc, mon}
tables for each of the display symbols, the loadable symbols,
and the rogue symbols, to one continguous table for
each:
showsyms: the current display symbols
l_syms: the loaded, alterable symbols
r_syms: the rogue symbols
- Modify mapglyph so that the index into the symbolt table is
available as a return value (it was a void function), rather than
just the char converted from the glyph.
- That makes it possible for a window port to use the same
index value to extract from another table (perhaps a unicode
table) for a different set of display symbols. The index
is much more useful than trying to convert the character
into another type of symbol, as some contributed patches
have done.
- It is much easier to load a single alternative flat table to
make substitutions, since the corresponding value just
has to get placed into the same index offset in the
alternative table.
This also fixes a bug I found in botl.c, where you could
go to the rogue level, and the bottom line gold symbol
was not being updated with the new character as it should.
The reason was because the gold value had not changed,
only the field symbol used had changed.
This updates multiple ports to place a (void) cast on
the mapglyph call, now that it returns a value, so this
is going to generate a lot of diff e-mails.
About six weeks back, <email deleted> suggested that
bear traps should deal out damage and be escapable via opening magic.
This doesn't do anything about the first part, but it does allow opening
magic (wand of opening, spell of knock, blessed Bell of Opening) to get
the hero out of bear traps and webs if zapped either at self or downwards.
Zaps across the floor which hit monsters will free them from such traps,
with a chance that releasing a hostile monster will pacify it (using
existing #untrap code). Conversely, if you are at a web or bear trap
location but not currently trapped, closing magic (wand of locking, spell
of wizard lock) will cause the trap to activate; you may or may not become
trapped. Likewise for zaps at monsters who are at such locations, which
is treated as an attack.
Opening magic which hits the hero or a monster located at a trap door
or falling rock trap spot will cause the trap to activate; as above, it's
an attack for the monster case. At the moment, zapping opening magic
downwards at the hero's location (but not zapping at self or at monsters)
will also cause holes, pits, and spiked pits to activate. (Zapping down
triggers falling rock traps and zapping up doesn't; that'll need to be
changed.) Zapping opening down while mounted will untrap, if stuck in a
web or bear trap, and will trap, for the falling cases, in precedence over
releasing the saddle and forcibly dismounting. The latter still occurs
when there is no applicable trap present though.
Zapping locking magic downwards at a hole location will convert the
hole into a trap door. Zapping breaking magic (wand of striking, spell of
force bolt) down at a trap door location will convert the trap door into a
hole. (Neither conversion currently alters the made-by-you flag for the
trap. However, the rationalization that distinctive style is what makes
made-by-you recognizable suggests that conversion should clear the flag.)
Lastly, the old behavior (which pre-dated bare holes) of destroying trap
doors when zapping down at them with locking magic has been removed--it
didn't seem to fit very well with the new cases. I'm starting to have
second thoughts about that but am going to commit this before discovery of
some more niggling details drags it out for another six weeks.