Issue from youkan700: a previously undiscovered pit was being made
known before hero poly'd into clinging monster checked whether it was
already known. So it always gave "you see a pit below you" instead
of "a pit opens up under you!" combined with "you don't fall in!".
(I think those exclamations are excessive but haven't touched them.)
... unless there's some other form that would override the choice,
such as a worn dragon armor, lycanthropy, or vampirism.
The polymorph will be in effect for 10-24 turns.
My changes were too drastic, so reduce the drain and damage so it
matches all the other traps. Now the anti-magic trap will always
ding your max energy a bit, in addition to the physical damage done
if wearing magic resistance.
Make the trap routine claim the trap killed the monster even
though it was drowning that did it, otherwise callers cannot
rely on the trap routine return value.
When a monster with innate teleporting stepped on a fire trap on ice,
the ice melted and the monster teleported away before falling
into the pool. If the monster's new location had a trap, the code
tried to access the deleted fire trap.
The 1/3 likelihood of a monster setting off a landmine seemed a little
arbitrary to me, especially in that it applied equally to all monsters,
from giants to insects. Change the flat 33% chance to one based on the
monster's body weight, so that lightweight monsters have little to no
chance of setting off a mine, with the likelihood increasing from there
with the monster's weight.
With a trigger weight of 400, as it is in this commit, a dingo has a 0%
chance of setting off a landmine, a gelatinous cube the same 33% chance
as before, an elf a 50% chance, a human a 72% chance, and something the
size of a dragon (ignoring the reduced likelihood for flying monsters) a
91% chance.
One of the drivers of this change was that screen coordinates require a
type that can hold values greater than 127. Parameters to the window
port routines require a large type in order to be able to have values
a fair bit larger than COLNO and ROWNO passed to them, particularly for
their use to the right of the map window.
This splits the uses of xchar into 3 different situations, and adjusts
their type and size:
xchar
|
-----------------------
| | |
coordxy xint16 xint8
coordxy: Actual x or y coordinates for various things (moved to 16-bits).
xint16: Same data size as coordxy, but for non-coordinate use (16-bits).
xint8: There are only a few use cases initially, where it was very
plain to see that the variable could remain as 8-bits, rather
than be bumped to 16-bits. There are probably more such cases
that could be changed after additional review.
Note: This first changed all xchar variables to coordxy. Some were
reviewed and got changed to xint16 or xint8 when it became apparent that
their usage was not for coordinates.
This increments EDITLEVEL in patchlevel.h
Switch to using a macro invocation Verbos(n, s) in place of the
flags.verbose checks.
Provide the mechanics for individual suppression of any of the
existing messages that were considered verbose.
Mechanics only - this code update does not provide any means of
setting the suppression bits.
iflags.verbose = 0
is still a master suppression of all the verbose messages.
iflags.verbose = 1
turns on the verbose messages only for those whose suppression
bit is 0 (not set).
This is a descendent of an earlier patch I wrote. The main idea is still
to clearly communicate to the player *what* something is turning into,
without the need to farlook afterwards, and give them the opportunity to
add MSGTYPE for when something jumps on a polymorph trap and becomes an
arch-lich. If it happens out of sight, the player also might get a whiff
of the monster's smell, giving a bit of advance warning.
There is one new case in here, in normal_shape(), which came about
because I noticed a weird message sequence: "The magic-absorbing blade
cancels the python! You kill the chameleon!" with no intervening
message indicating the python reverted to a chameleon.
Implement 'untrap' as an 'autounlock' action. Quite a bit more work
than anticipated. The new documentation is rather clumsy; too many
if-this and if-not-that clauses have intruded.
I'll be astonished if all the return values are correct....
[A couple of places were checking for (rx != 0 && ry != 0) to decide
whether they were performating an autounlock action at <rx,ry> but
that erroneously excludes the top line of the map if the current
level extends that far. Just check rx for zero/non-zero.]
When trap detection finds trapped doors and trapped chests, it shows
those as bear traps. When the hero comes within view, they revert to
normal and the detected trap is forgotten. This doesn't change that,
it is just groundwork to be able to show them distinctly. Like the
TT_BEARTRAP patch, it increments EDITLEVEL so this seemed like a good
time to put the groudwork in place.
There shouldn't be any visible changes even though internal glyph and
tile values have been renumbered after inserting two new entries.
Adding traps after S_vibrating_square was quite a hassle and suffered
though a couple of off-by-one errors that weren't trivial to find and
fix.
From a report by a beta tester 8 years ago: kicking a chest gave
"THUD! The chest explodes!" but the chest remained intact. The
explosion was destroying all floor items at the hero's spot rather
than at the chest's spot. Fixing that results in the chest being
destroyed because it's one of the items at its own spot.
While fixing that I noticed that delobj() was only protecting the
Amulet and the invocation items from destruction, not Rider corpses.
You could destroy one or more of those by getting a trapped chest's
explosion while using a key at its spot rather than by kicking it
from adjacent. (Getting the exploding chest result is not easy,
particuarly with positive luck. I eventually resorted to forcing
it with a debugger.)
Life-saving has been setting u.uhpmax to max(2 * u.ulevel, 10)
and if it took place during level drain that could make u.uhpmax
increase instead of decrease, confusing healing which gets applied
to a monster who has drained the hero with Stormbringer or the
Staff of Aesculapius. Change the setting to be max(u.ulevel, 10)
(removing the times two part) and also have level drain force it
to be set back to previous value if/when it gets increased.
Max HP loss due to strength trying to drop below 3 or to fire trap
or to being hit by Death now uses a mininum max HP of u.ulevel
rather than 1. They don't have the alternate minimum of 10; I'm
uneasy that there are still two different minimum values.
I changed adjattrib() to set the flag to request a status update
before it gave its optional message rather than after so that the
new characteristic value would be visible during the message. That
resulted in not updating status when eating royal jelly changed HP
or max HP after boosting strength. But the same missing update
would have occurred--or rather, failed to occur--without the change
in sequencing if the strength boost causes a change in encumbrance.
If special level lua code creates a melting ice timeout, but
later in the code places stairs, or a trap which might change
the ice to room floor, the timer sanity checking doesn't
like that.
Allow defining rolling boulder launching location in special level
lua scripts:
des.trap({ type="rolling boulder", coord={7, 5}, launchfrom={-2, -2} });
launchfrom is relative to the trap coord.
Pull request from argrath: a check for null trap in untrap_prob()
comes after an unconditional use of that trap so doesn't server any
useful purpose.
Redo a couple of comments too. No fixes entry necessary.
Closes#694
A monster trapped in a bear trap on ice, exploding fiery monster
turned the ice into water turning the trap into object, the trapped
monster claimed to be still trapped in the nonexistent trap.
Demote "completed sokoban {1,2,3,4}" from major achievement to minor
at the request of hardfought. OR on the 'dump' flag so that those
entries appear in dumplog.
Change "completed Sokoban" (for the whole branch) to "acquired the
Sokoban <prize object>" since that's what triggers the event and it
is possible to pass through the first level without completing that.
This event is still classified as a major achievement. It has has
the 'spoiler' flag added to prevent #chronicle from showing that event
which now discloses the type of item the prize is. (Note: suppression
of spoiler events is ignored in wizard mode.)
The "attained rank N" achievements are classified as minor for ranks
1..3 (gaining levels 3, 6, 10); OR the 'dump' flag for those. [Rank 0
for levels 1 and 2 isn't an achievement and 4..8 for Xp levels 14, 18,
22, 26, and 30 are classified as 'major' achievements so don't need
that flag to make it into dumplog.]
Log a major event when the last hole or pit is plugged on a sokoban
level.
Event logging currently reports the got-sokoban-prize achievement as
completion of sokoban. That's misleading but this doesn't change it.
It was silly how some clearly mechanical traps didn't consider
flight or levitation when to trigger. Do those checks in dotrap/mintrap
making hero and monster trap triggering match more closely.
Instead of returning monster's mtrapped-state, return specific
trap return values.
Add one extra trap return value, for when a monster was
moved by the trap.
For testing mhurtle, which is used for jousting or
bare-handed combat.
Improve mhurtle_step to handle bumping into another monster,
and when the monster gets killed or stuck in a trap.