This avoids a player being left standing on lava if their boots are burned up and
they survive the damage.
This change is originally due to Steve Melenchuk, fixed up by Derrick Sund.
In the newsgroup recently, someone mentioned that when polymorphed into
a flying monster, he couldn't retrieve items out of pits, even with the '>'
command. I thought that we had fixed that, but the fix apparently only
covered walk-through-wall creatures (xorns and earth elementals), not flyers
and ceiling clingers. Now those can also deliberately enter pits via '>'.
The fixes entry is in the new features section in order to be next to
the xorn one. '>' at pit locations is new, but it handles something which
was missing so feels more like a bug fix than a new feature to me....
[Keni, the bug page entry C343-12 about '>' (for xorns?) is general enough
to cover this fix, so we don't need to add a new one for flyers.]
I noticed an unrelated fixes35.0 entry mentioning '>' which was duplicated;
this removes one of the copies.
From a bug report, you could crawl
out of water to avoid drowning by moving diagonally into an intact doorway
even though regular movement won't allow that. (Second version of Medusa's
level has a door adjacent to water.) You could also escape diagonally when
polymorphed into a grid bug.
When testing armor theft by nymph I got a message "you dream that you
hear <something or other>" even though I was awake. steal() was leaving
nomovemsg null in order to get the default of "you can move again", but
unconscious() was treating null value as 'yes, hero is unconscious'. I'm
pretty sure its intent was just to guard against passing null to strncmpi()
and didn't really mean that null indicates unconsciousness.
> On 01/30/2012 08:20 PM, <Someone> wrote:
> The boulder from a rolling boulder trap can be generated on a
> lava pool. mkroll_launch() in trap.c, line 1584 checks only for pools
> of water.
Removing ring or boots of levitation while stuck in solid rock was
silent as intended, but timeout of potion or spell said "you float gently
to the ground" even though there's no actual movement.
Using '>' command while in solid rock said "you can't go down here"
without attempting to toggle off controlled levitation.
From a bug report. The first report complained about levitation
allowing you to move through water on the Plane of Water, something that's
come up in the newsgroup lots of times (mostly about how levitation is
the best way to get around, only occasionally wondering why it works:
water walking doesn't work there because there's no surface, so where are
you levitating such that you're kept dry?) The second report complained
about being told you were floating up if you put on a ring of levitation
while stuck inside a wall (perhaps after being stranded when polymorph
into xorn form ended).
This implements intrinsic blocking for levitation and also for
flying. Being inside solid rock (or closed door) anywhere and being in
water on the Plane of Water are the things that do it for levitation;
those two and levitating are what do it for flying. Entering such
terrain turns off ability to float/fly, and leaving there turns it back
on; starting levitation blocks flight, ending it unblocks (levitation
has always overridden flying's ability to reach the floor). Being able
to phase through rock doesn't prevent levitation and flight from being
blocked while in rock; you aren't floating or flying in that situation.
Simplify many of the intrinsics macros from
#define xxx_resistance (Hxxx || Exxx || resists_xxx(&youmonst))
down to
#define xxx_resistance (Hxxx || Exxx)
by setting or clearing an extra bit in Hxxx during polymorph so that the
resists_xxx() check becomes implicit.
Unfornately there were lots of places in the code that treat Hxxx
as a timeout number--primarily for Stunned, Confused, and Hallucination;
Stunned happens to be one of the revised macros--rather than as a bit
mask, so this patch needed a lot more changes than originally antipated.
Something I've had in mind for a long time and finally gotten around
to implementing: when you fill in the last pit or hole of a sokoban level,
it's considered to be completed so luck penalties for unsokobanish things
(breaking a boulder, dropping everything and squeezing onto a boulder's
spot, reading a scroll of earth) stop being assessed and most Sokoban-
specific movement restrictions (against pushing boulders diagonally,
squeezing diagonally between boulders, floating over a pit or hole without
falling in, digging of new holes by monsters) are lifted. Teleporting,
level teleporting, and phasing through walls are still prohibited when in
the sokoban branch of the dungeon. (Keeping the non-phasing one in place
prevents taking a shortcut to the final prize in order to bypass the
treasure zoo monsters.)
This adds level.flags.sokoban_rules, defines Sokoban macro to access
it, and replaces most In_sokoban(&u.uz) tests to check it instead. It
gets set when a sokoban level is pre-mapped at the end of level creation,
and if it is set then whenever a trap is deleted, the flag gets cleared
if there are no more pits or holes present on the level.
Noticed while working on the "lava inconsistencies" patch: it was
possible for lava_effects() to be called recursively, despite a patch
five and half years ago which was supposed to prevent that. That patch
handled the case where the hero dies and gets life-saved, but it didn't
deal with a hero who survives due to water walking boots and then has
those burned away. [Not an issue in 3.4.3 because Boots_off() didn't
call spoteffects() for lava then, but it does in post-3.4.3 branch as
well as trunk. fixes34.4 has an entry about fixing an "object lost"
panic for this but I don't think it's accurate. I think that the panic
only became possible after the post-3.4.3 "handle lava when removing or
losing water walking boots" fix was introduced.]
From a bug report, if you move into lava, die,
and are life-saved or leave bones, your potions will remain intact,
whereas if you have fire resistance and survive, they'll be subjected to
destroy_item() and usually be destroyed (not always, because stacks of
more than 1 don't always destroy the whole stack). Also, wooden ring
will be destroyed even if it happens to be ring of fire resistance.
This addresses both of those bugs.
He also thought that all vulnerable armor should be destroyed rather
than just boots in the case where you have fire resistance and survive,
but I didn't change that. It is a little odd, but presumeably only your
feet are in lava at first (although later sinking further into lava
doesn't actually burn up any other stuff).
This is mostly groundwork prior to making the Protection intrinsic
become more meaningful. The Mitre of Holiness (priest quest artifact)
and the Tsurugi of Muramasa (samurai quest artifact) will now confer
Protection when worn/wielded (though at present that effectively does
nothing). While in there, this also changes the Eye of the Aethiopica
(wizard quest artifact), the Eyes of the Overworld (monk quest artifact),
and the Sceptre of Might (caveman quest artifact) so that they need to
be worn/wielded rather than just carried in order for them to confer
magic resistance. That way they're a little less attractive for wishing
by other roles and a little more likely to be actively used by their own
roles (not an issues for the Eyes, I'm sure). This change actually works
to the player's advantage, since it means that monsters who successfully
steal those items won't instantly obtain magic resistance in the process.
This adds protects() as a predicate routine to check an item for
conferring Protection. In order to do that, it renames the existing
protects() routine to defends_when_carried(), because that predicate is
actually a variant of defends() for items which aren't worn or wielded.
From a bug report,
when falling into a spiked pit and being killed and then life-saved, you
could immediately die from fatal poison. It isn't necessarily a bug and
there are other ways to be killed, life-saved, and re-killed (such as
zaps that bounce off walls or reflecting targets), but it does seem to be
somewhat unfair. This patch makes life-saving be more effective: in a
damage-plus-poison situation, if the damage triggers life-saving then the
poison won't deal out any further damage (including its nasty chance for
instant death). The poison still matters, but it will always target an
attribute stat--which is already one possible random outcome--instead of
maybe doing damage. [It is actually possible to get damage if stat loss
tries to take hero's strength below 3, but now there's no chance of that
being fatal immediately after savelife() has restored full hit points.]
Noticed while testing a forthcoming mimic patch: when blind, some
actions (open, close, #untrap, applying a key [as of a month ago],
possibly others) taken against a mimic posing as a door would yield
"Wait! That's a monster!" but leave the map showing the door instead
of replacing it with the unseen monster glyph. Similarly, using #untrap
towards a known trap location covered by a concealed mimic could yield
"It is in the way." or "It isn't trapped.", depending upon the type of
trap present, and not reveal the mimic. Same thing happened when not
blind, except the message would refer to "the <size> mimic" rather than
"it". Now it will expose the mimic, regardless of the type of trap.
From a bug report, if you entered water
while blind and any spellbooks got blanked, you would know they became
"plain spellbooks" iff their original description was known. The same
situation applied to scrolls and potions; if they had been previously
seen you'd learn they'd become blank or clear. This fix resets the
obj->dknown flag during transformation so that altered objects are only
known by their class when blind, never their description, the same as
when they hadn't been seen before being blanked. (When sighted, the
dknown flag gets set again the next time the object's name is formatted,
so the player shouldn't be able to notice that any reset took place.)
Unpaid objects which get blanked should be treated as used up for
shop billing purposes (force the hero to buy), but there aren't any pools
in shops so aside from the added comment I'm going to pretend I didn't
notice that that isn't being done....
Potions seen before becoming blind which become diluted while blind
will be known to be diluted since there's no way to know the description
without also knowing the dilution. I don't think that's important enough
to track known-dilution separately, although I suppose we could overload
the cknown (contents-known) flag for that if necessary.
This also removes an inaccurate comment about the effects of Luck.
Its maximum is always 13 regardless of whether the moon is full, so 5%
for the lowest chance of blanking via submersion was impossible.
During some recent newsgroup discussion, <Someone> posted an entry from
his personal bug list: energy draining damage from ordinary attacks is
implemented even though there are no monsters with that capability and it
was not implemented for engulf attacks even though energy vortices have
the capability. This implements energy drain engulf attacks against the
hero and also both modes of energy drain attacks for monsters and poly'd
hero against spellcasting monsters. Since monsters don't have energy,
they lose access to their special abilities (their spells, that is) for a
few turns, same as a post-3.4.3 change done for anti-magic traps.
water_damage() gave "A potion explodes!" when destroying potions of
acid even when it was a stack of multiple potions exploding. The vague
fixes entry "grammar, spelling and other typos" covers this one....
Full moon and Friday the 13th affect Luck's equilibrium point, but
not its range (which is always -10 to +10 for natural luck, -13 to +13
when extended by luck-conferring objects). The water_damage() comment
implying that max Luck could be 14 during a full moon was incorrect.
From the newsgroup: drowning on the Plane of Water gave cause of
death as "drowned in a moat". There was already some post-3.4.3 code to
handle naming of moat on Juiblex level as "swamp", but it wasn't used for
drowning's cause of death and we were still getting "drowned in a moat"
there too. Now the Plane of Water yields "drowned in deep water" and
Juiblex's level yields "drowned in a swamp".
For GOLDOBJ configuration, relax the 52 object limit for inventory
when gold uses the special $ slot instead of a letter. Takes care of an
old buglist entry from the beta testers. [It will need to be revisited
if we ever implement multiple coin types that can't all fit in one slot.]
Also for GOLDOBJ, prevents nymphs and monkeys from stealing coins,
since allowing that made their steal-item attack be a complete superset
of leprechaun's steal-gold attack.
Revise untrap() to handle being unable to reach the floor. That
whole routine is a mess and should probably be rewritten.
Included at no extra charge: #untrap didn't check whether player
picked a spot off the edge of the map so could go out of array bounds.
Reported two months ago by <email deleted>,
having a water elemental become trapped in a bear trap seems pretty
strange. Fixed by marking water elementals as M1_UNSOLID (like air and
fire elementals), which has a side-effect of making them immune to webs
as well. Tweaked some unused digging code which checks unsolid(), added
unsolid() to the types allowed to bar through iron bars, and brought the
check for whether a monster is willing to enter a bear trap location up
to date. That code also needed an update to reflect the change made to
anti-magic traps last year. Lastly, there was another report which
suggested that being hit by a bear trap should dish out some damage
(along with a suggestion that wand of opening should work to escape such
traps, which has already been done). This makes bear trap do 2d4 damage
(on entry, not when trying to pull out after becoming stuck).
Back in <email deleted> in #U1216
suggested that statues of stone golems which are hit by stone-to-flesh
spell should leave flesh golem corpses instead of meatballs. But they
should actually have revived as flesh golems. Stone-to-flesh revival of
golem statues and golem figurines didn't work as intended because golems
other than flesh or leather were considered to be vegan/vegatarian, which
caused them to produce meat rather than living monsters. Also, S-to-F of
a leather golem statue worked as intended and created a flesh golem, but
S-to-F of a leather golem firugine created a leather golem out of stone
object. This fixes it so that any type of golem statue or golem figurine
revives as a flesh golem.
Two other bugs noticed and fixed: (1) S-to-F cast on self while a
figurine of a non-veggy monster was "worn" in one of the three weapon
slots triggered an "extract_nobj: object lost" panic similar to several
similar cases which were recently fixed (that was 3.4.3; for development
code, it gave "obfree: deleting worn obj" warning instead). (2) S-to-F
activating a shop-owned figurine didn't charge for it.
<email deleted> reported back on 8/31/06 that elven weapons were not
affected when he poked a fire elemental with them. This is true, but
moreover, there was no code to have passive fire to affect attackers.
Now erode_obj() supports all the same damage types as rust_dmg(), and added
the connecting code to allow passive fire attacks do something.
There probably should be macros for the damage types used by rust_dmg
and erode_obj, and possibly these functions should be combined, but they
are slightly different and dealing with that requires more thought.
Noticed while checking out the report that you can #jump when riding
a sleeping steed: hero's sleep resistance or magical breathing prevented
sleeping gas traps from hitting steed. "You are enveloped in a cloud of
gas" but your steed is untouched? That didn't make sense.
Implement <Someone>'s suggestion/request that co-aligned unicorn not be
used for statue traps, so that the hero won't get hit with a big luck
penalty for killing such a unicorn when the trap releases one which is
hostile. I think that set_malign() probably ought to override that, but
this just changes the monster type selection for the trap's statue.
Also, noticed in adjoining code: avoid counting the template monster
used to generate inventory for the statue towards extinction. It gets
immediately discarded, and later statue activation counts the resulting
monster then.
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.
A suggestion from the newsgroup: when potions are hit by fire and
get the "boil and explode" result, potions of oil should burn instead of
boil. Even though oil can be heated to boiling, nethack's potions of oil
are noticeably flammable [just (a)pply one...] so having them burn makes
sense. It's just a message change; no actual explosion has been added.
destroy_strings[] was implemented as an {N} x {3} array that used
manually computed indices into one-dimension. This changes it into a two-
dimensional array instead. However, it's still being indexed by a bunch
of magic numbers.
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.
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.
Change safe_qbuf() so that instead of picking one of three strings
for sprintf() to plug into a prompt string, it actually constructs the
full prompt string itself. Also pass in the unformatted object and a pair
of formatting functions instead of performing dual formatting in advance.
The actual formatting is done via new routine short_oname() which also
takes an object and a pair of formatting routines plus a target length.
It uses the first routine, typically xname() or doname(), and formats the
object, then if the result is too long it makes some transformations, and
tries again. If truncating "called foo" and "named bar" down to 12 chars
and omitting "uncursed, rustproof, thoroughly corroded" attributes still
result in a string that's too long, it uses the other formatting routine.
The latter calls one of several jacket routines around simple_typename()
to produce a short result.
This has been through about four incarnations now and has gotten a
bit less testing each time, but I need to get it in place before I end up
running out of gas and abandoning it. I've got some changes to shk.c
(where safe_qbuf is needed but not currently used) that now need to be
redone and will come eventually.
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.
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.
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.
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.
From a bug report: you could end up with
gravestone/logfile result of "burned by burning" or "drowned in a drowning".
If you get life-saved when drowning in water or burning in lava, the game
tries to teleport you to safety. If the teleport fails for some reason--
such as lack of unoccupied non-water or non-lava locations--you drown or
burn again. But life-saving was resetting the killer reason and the repeat
drowning/burning wasn't setting it up again, so the default got used and
produced a silly result.
Recently reported to the list, a fireproof container dropped in lava would
catch fire and burn. Add the missing check; this looks an oversight when
the idea of fireproof was added, since other fireproof objects get handled
later in the cascading if().
Turn being unconscious (via several reasons, including fainted from
hunger) into a pseudo-property named `Unaware' and use it in several
places where only being asleep was checked. #H202 was about a stunned
character who got the recovery message when it timed out while fainted.
This suppresses messages for several difficulties when they begin or end
while hero is Unaware. Messages about fatal illness, sliming, or
petrification aren't suppressed; they're too important to hide from the
player. "You feel ..." messages come out as "You dream that you feel ..."
when Unaware; fairly lame but hopefully adequate.
From a bug report, it was possible
to fall from above the quest locate level to below it even though it has
nondiggable floors (hence no trapdoors or holes to pass through). Since
the game can't verify that it is nondiggable (which could vary on a role
by role basis depending upon their quest descriptions) when it is not the
current level, restrict falling past it only when it hasn't been visited
yet. Impose the same restriction for random level teleport. This enforces
proper sequencing of the quest feedback, which was the more significant
thing that went wrong in the reported case (player finally got the full
locate level message on a return visit, when descending from above, after
having already cleared out that level on his way back up from falling).
Once the locate level has been reached or passed, it is no longer a
barrier to falling or random teleport. (When it is eventually visited,
there's no attempt to remember whether it allows holes, since that
information and the corresponding fall check would need to be extended to
every level in the dungeon. Also, controlled teleport is still allowed to
bypass it even when it hasn't yet been visited, so the "enforces proper
sequencing" claim above is an exaggeration.)
From a bug report: [ slashem-Bugs-1206099 ] Torches are not extinguished with rust traps).
A rust trap that hits the torso candles causes all lit objects being carried
to be extinguished, but one which hit the weapon arm didn't have same affect
on a wielded light. This fix causes wielded candles or lamps (not Sunsword)
to go out if affected by any rust, such as hitting a rust monster with one,
rather than use his patch that just handled the trap case. It also excludes
wielded lights from the existing torso splash since having them be hit by
both instances is too obviously buggy.
I think brass lanterns ought to be exempt from being extinguished by
water (at least splashing which is less drastic than total submersion) since
there are references to them operating by batteries rather than fire, but I
didn't want to track all the places which would be affected.
Be deliberately careful with copies taken of
oextra pointers and clear the pointer if it
truly is a redundant copy that will become
invalid if/when the original holder is deallocated.
Fix the bug From a bug report.alt.org server, where killing a monster by closing the
castle drawbridge resulted in a panic after the dead monster's possessions
were dropped into the moat and a potion of acid exploded in the process.
water_damage() deleted the object but had no way to tell flooreffects()
that it was gone, so flooreffects() couldn't tell its own caller not to
place and stack the object. After that, a chunk of freed memory became
part of the floor objects chain and eventually triggered a panic which
tried to make a save file but whose reason didn't get logged properly.
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.