This is based on the multiple-RNGs code fron NetHack4, but using
only the parts relevant to the display RNG (and with substantial
changes, both because of post-3.4.3 changes, and because Nethack4's
display code is based on Slash'EM's rather than NetHack's).
melt_ice can delete the fire trap, in the case where the trap
is on ice, and a monster carrying a boulder triggers it, then drowns.
mintrap -> minliquid -> mondead -> ... -> mdrop_obj ->
flooreffects -> boulder_hits_pool -> delfloortrap
Fixes#169
Monsters should not be afraid of stepping on the vibrating square
since it's only a trap for display purposes. [Perhaps they should
deliberately avoid it if the hero hasn't seen it yet, but I didn't
implement that.]
"You see a strange vibration beneath <mon's> <parts>." was strange
when <parts> was a wolf's "rear paws" or horse's "rear hooves"--was
the vibration magically skipping the front ones? And it sounded
naughty when it was a snake's "rear regions". If the creature has no
limbs or is floating or flying, just say "beneath <mon>"; otherwise,
if the part is "rear <something>", omit "rear ".
The message was weird in another way. Caller removes the monster
from it's old location and places it on the new one, calls newsym()
for the old location to show lack of monster, but then calls mintrap()
before newsym() for monster's new location (the trap's location). If
pline messages cause buffered map output to be flushed, the monster
will be missing during the time the messages are delivered. I fixed
that for vibrating square [seetrap()->newsym() before pline() rather
than after] but it should probably be fixed in the caller instead.
Fixes#164
No message was shown when riding a steed into a pit or spiked pit.
Setup for the message was done, but post-3.4.3 insertion of else-if
into the previous if/else/endif cut off its delivery.
Attempting to untrap an adjacent location failed if you had escaped a
pit, claiming that you couldn't reach. You can't reach the bottom of
the pit if you're not in it, but you should be able to reach adjacent
spots normally.
Clean up quite a bit of minor things found with simple grep patterns:
operator at end of continued line instead of beginning of continuation
(and a few comments which produced false matches, so that they won't
do so next time), trailing spaces (only one or two of those), tabs (a
dozen or so of those), several casts which didn't have a space between
the type and the expression (I wasn't systematic about finding these).
I think the only code change was in the function for the help command.
Force trap to activate during failed untrap attempt if done while
already at the trap's location, to match the recent change in
behavior when failed attempt occurs while adjacent to the trap.
Most noticeable while flying over bear traps, but affects all
failed untrap attempts.
Make being trapped in/on/over floor block Levitation and Flying, the
way that being inside solid rock already does, and the way levitating
blocks flight.
Blocked levitation still provides enhanced carrying capacity since
magic is attempting to make the hero's body be bouyant. I think that
that is appropriate but am not completely convinced.
One thing that almost certainly needs fixing is digging a hole when
trapped in the floor or tethered to a buried iron ball, where the
first part of digactualhole() releases the hero from being trapped.
If being released re-enables blocked levitation, the further stages
of digging might not make sense in some circumstances.
I recently realized that being held by a grabbing monster is similar
to being trapped so should also interfere with levitation and flying.
Nothing here attempts to address that.
Save files change, but in a compatible fashion unless trapped at the
time of saving. If someone saves while trapped prior to this patch,
then applies it and restores, the game will behave as if the patch
wasn't in place--until escape from trap is achieved. (Not verified.)
Fix the situation of Flying hero failing to untrap a bear trap that
was resulting in the trap becoming hidden. Previous fix prevented
hero from moving onto the trap's location so that the reason for
hiding it didn't occur. This moves the hero and forces the trap,
so it will become unhidden again before there's any chance to notice
that it had been hidden.
Status 'Flying' conflicts with being trapped at floor level, but that
is a separate, known issue. I'll have to resurrect my unfinished fix
for that sooner rather than later.
The original report stated:
"I located a bear trap as a human and just ignored it
for the time. I polymporphed into a Vampire Lord, then
went to #untrap the bear trap. On the first attempt,
I stood beside the trap and attempted to #untrap. I
received the 'Whoops!' message and automatically moved
onto the trap square as a result. The bear trap vanished!
I obviously wasn't trapped since I'm polymorphed into a
flying monster, but the trap glyph was no longer present.
The glyph looked like regular floor - as if I had
untrapped the bear trap and taken the trap with me."
The trap was actually still there but became hidden intentionally
for other valid scenarios, but was an unintended side-effect for
this scenario.
Fix it by failing the #untrap operation for a Flyer earlier on,
and in a more benign manner, since the Flyer ultimately doesn't
end up in the trap anyway. You'll still get the "Whoops!",
followed by a message, but that's as far as the "failed" #untrap
attempt will go under the circumstances.
Factor some common code for missile launching traps into a seprate
routine.
Reorder the prototypes for static routines in trap.c into the same
order as theose functions appear in the file.
Fixes#111
Casting stone-to-flesh at a random statue animates it as a monster
(created via direct call to makemon()) at an adjacent or nearby spot
if there is already a monster at the statue's spot, but doing so on
a statue of a petrified monster (create attempt via montraits() which
called makemon() without the ADJACENTOK flag) turned it into a corpse
instead. Pass an extra argument to montraits() so that it behaves
the same normal statue animation for stone-to-flesh without changing
how it behaves when reviving corpses for undead-turning.
H7074 1311
> When moving from a pit into an adjacent pit, you "fall into" the pit and take
> damage. This happens even when you are walking back and forth between two pits,
> repeatedly, where you should have no way to fall.
>
> The intent seems to be that you can move into the adjacent pit without having
> to climb out of the first one, and this works properly - the only problem is
> that the pit gets triggered when you ought to have no distance to fall.
This is really just stumbling over uncleared clutter, not a pit fall.
There was already a way to clear the clutter between adjacent pits.
Discovered while writing the previous commit. If you dipped a sack
full of potions into an uncursed potion of water, the potions would
dilute but you wouldn't lose the original potion, letting you repeat
until all were diluted.
Allowing people to do this trick to blank multiple potions from one
potion of water seems like it's not an abuse, given that it can be
done in a more tedious way with water walking or the like and it
costs resources, but it's definitely abusive to make it possible
entirely for free.
We can identify them by elimination in this case (they're the only
bag-like container that doesn't produce a message, the others all
do), so it's probably best to be more explicit as to what's going
on (for user interfaces and TDTTOE purposes).
When polymorphed into an iron golem (or gremlin with 2/3 chance),
triggering a rust trap would give "a gush of water hits <you or some
body part>" and then give a second "a gush of water hits you" when
dealing with golem or gremlin effects. That made it seem as if the
trap was hitting twice. This removes the redundant messages. (Rust
trap against monster iron golem or gremlin didn't have them.)
Make #untrap while carrying the non-cursed (for rogues) or blessed
(for non-rogues) Key work the same as #invoke has been doing (without
regard to its bless/curse state): when used on trapped door or chest,
that trap will always be found and disarming it will always succeed.
It should work when carried by monsters too: if they try to open a
trapped door while carrying the Key (must be blessed since they're
not rogues) the trap will be automatically disarmed. (Caveat: that
hasn't been adequately tested.)
TODO (maybe...): change the #invoke property to detect unseen/secret
door detection instead of #untrap. The latter isn't completely
redundant; it works when the Key is cursed. But quest artifacts
strongly resist becoming cursed so that isn't a particularly useful
distinction.
Also, trap hints when wielding the Key without gloves didn't notice
adjacent door and chest traps. Now it does. And the behavior is
slightly different: known traps covered by objects or monsters are
treated like unknown traps as far as the hot/cold hints go.
thitu() is mostly used for arrows and darts "thrown" by traps, but
scatter() uses it on items launched by a land mine explosion. Traps
had no need for potion handling, but scattering does. Changing thitu()
to call potionhit() required that more information be passed to the
latter in case killer reason was needed, and thitu()'s callers needed
to be updated since it now might use up its missile (only when that's
a potion, so scatter() is only caller which actually needed to care).
Quite a bit of work--especially the testing--for something which will
never be noticed in actual play. In hindsight, it would have been
much simpler just to make scatter destroy all potions rather than
allow the 1% chance of remaining intact (via obj_resists()), or else
leave any intact ones at the explosion spot instead of launching them.
Reported directly to devteam, player threw a troll corpse into lava and
then later got messages about it reviving and burning to death. Items
thrown, kicked, or dropped into lava were being subjected to fire damage
(so scrolls burned up, potions boiled, non-fireproofed flammable weapons
and armor eroded), but corpses and a lot of other stuff not subject to
erosion remained unaffected. This makes things that are made out of
wood, cloth, flesh and other flammable stuff burn up (when in lava, not
when hit by fire).
Report was for
You finish taking off your boots.
You float gently to the altar. [destination was a red herring]
[take some action to run through moveloop() for next turn]
Your movements are slowed slightly because of your load.
Having float_down() do the next encumbrance check instead of
waiting for moveloop() to do so was straightforward. However,
while testing I noticed the reverse situation (not due to the fix
for the above) when putting on levitation boots
Your movements are now unencumbered.
You finish your dressing maneuver.
You start to float in the air!
Having float_up() do the encumbrance check isn't adequate to fix
this, because it takes multiple turns to put on boots but the
properties they confer are enabled immediately, so moveloop() runs
while hero is already levitating even though the game hasn't told
the player about it yet. Fix is a hack to defer the effect of
levitation on encumbrance until the boots are fully worn, which
might lead to strangeness somewhere. It's also boot-specific so
will need to be updated if some other multi-turn armor that confers
levitation ever gets added.