cursed potion of levitation

Reported directly to devteam 7-Jan-2016, two issues with cursed
potion of levitation:
1) the go-up-stairs effect for cursed potion still let you choose
not to escape the dungeon if it occurred on level 1 stairs.  I've
left that as-is; perhaps there's a gate across the entrance.
2) both the go-up-stairs and bonk-head-on-ceiling effects were
skipped if the hero was already levitating.  I don't know whether
that was intentional but there was no comment explaining why, so
I've changed it to happen regardless of whether already levitating.

In the process, I changed the head-bonk case to do more damage when
a helmet is worn:
 old: no helmet 1..10 hp, any helmet 1 hp damage;
 new: no helmet 1..10 hp, soft hat 1..6 hp, hard helmet 1..3 hp.

Also, not in the report:  when you aren't already levitating you
get the "you float up" message, but for cursed potion there was
never any corresponding "you float down" message because you ended
up not levitating.  Now you'll levitate for 1 turn and float down
on the next, landing in a trap if one is present.
This commit is contained in:
PatR
2016-05-07 17:26:01 -07:00
parent 995404f6ad
commit 70ff2c2b3e
4 changed files with 49 additions and 28 deletions

View File

@@ -230,6 +230,7 @@ when feel_location removed a remembered-unseen-monster glyph from a known
Vlad's tower2 and tower3 didn't show up in wizard-mode ^O output or ^V? menu
remove extra space from "All of your <stack-of-potions> boil and explode."
(also applies to potions freezing and to scrolls burning)
effects of cursed potion of levitation were skipped if already levitating
Fixes to Post-3.6.0 Problems that Were Exposed Via git Respository

View File

@@ -1317,7 +1317,7 @@ boolean at_stairs, falling, portal;
if (flags.verbose || great_effort)
pline("%s %s up%s the %s.",
great_effort ? "With great effort, you" : "You",
Flying ? "fly" : "climb",
Levitation ? "float" : Flying ? "fly" : "climb",
(Flying && at_ladder) ? " along" : "",
at_ladder ? "ladder" : "stairs");
} else { /* down */

View File

@@ -1950,8 +1950,8 @@ boolean pick;
turn, allowing it to do so could give the perception
that a trap here is being triggered twice, so adjust
the timeout to prevent that */
if (trap && (HLevitation & TIMEOUT) == 1L && !ELevitation
&& !(HLevitation & ~TIMEOUT)) {
if (trap && (HLevitation & TIMEOUT) == 1L
&& !(ELevitation || (HLevitation & ~(I_SPECIAL | TIMEOUT)))) {
if (rn2(2)) { /* defer timeout */
incr_itimeout(&HLevitation, 1L);
} else { /* timeout early */

View File

@@ -957,39 +957,59 @@ register struct obj *otmp;
break;
case POT_LEVITATION:
case SPE_LEVITATION:
if (otmp->cursed)
HLevitation &= ~I_SPECIAL;
/*
* BLevitation will be set if levitation is blocked due to being
* inside rock (currently or formerly in phazing xorn form, perhaps)
* but it doesn't prevent setting or incrementing Levitation timeout
* (which will take effect after escaping from the rock if it hasn't
* expired by then).
*/
if (!Levitation && !BLevitation) {
/* kludge to ensure proper operation of float_up() */
set_itimeout(&HLevitation, 1L);
float_up();
/* reverse kludge */
set_itimeout(&HLevitation, 0L);
if (otmp->cursed) {
if ((u.ux == xupstair && u.uy == yupstair)
|| (sstairs.up && u.ux == sstairs.sx
&& u.uy == sstairs.sy)
|| (xupladder && u.ux == xupladder
&& u.uy == yupladder)) {
(void) doup();
} else if (has_ceiling(&u.uz)) {
int dmg = uarmh ? 1 : rnd(10);
You("hit your %s on the %s.", body_part(HEAD),
ceiling(u.ux, u.uy));
losehp(Maybe_Half_Phys(dmg), "colliding with the ceiling",
KILLED_BY);
}
} /*cursed*/
} else
/* This used to set timeout back to 0, then increment it below
for blessed and uncursed effects. But now we leave it so
that cursed effect yields "you float down" on next turn.
Blessed and uncursed get one extra turn duration. */
} else /* already levitating, or can't levitate */
nothing++;
if (otmp->blessed) {
if (otmp->cursed) {
/* 'already levitating' used to block the cursed effect(s)
aside from ~I_SPECIAL; it was not clear whether that was
intentional; either way, it no longer does (as of 3.6.1) */
HLevitation &= ~I_SPECIAL; /* can't descend upon demand */
if (BLevitation) {
; /* rising via levitation is blocked */
} else if ((u.ux == xupstair && u.uy == yupstair)
|| (sstairs.up && u.ux == sstairs.sx && u.uy == sstairs.sy)
|| (xupladder && u.ux == xupladder && u.uy == yupladder)) {
(void) doup();
/* in case we're already Levitating, which would have
resulted in incrementing 'nothing' */
nothing = 0; /* not nothing after all */
} else if (has_ceiling(&u.uz)) {
int dmg = rnd(!uarmh ? 10 : !is_metallic(uarmh) ? 6 : 3);
You("hit your %s on the %s.", body_part(HEAD),
ceiling(u.ux, u.uy));
losehp(Maybe_Half_Phys(dmg), "colliding with the ceiling",
KILLED_BY);
nothing = 0; /* not nothing after all */
}
} else if (otmp->blessed) {
/* at this point, timeout is already at least 1 */
incr_itimeout(&HLevitation, rn1(50, 250));
/* can descend at will (stop levitating via '>') provided timeout
is the only factor (ie, not also wearing Lev ring or boots) */
HLevitation |= I_SPECIAL;
} else
} else /* timeout is already at least 1 */
incr_itimeout(&HLevitation, rn1(140, 10));
if (Levitation)
spoteffects(FALSE); /* for sinks */
if (Levitation && IS_SINK(levl[u.ux][u.uy].typ))
spoteffects(FALSE);
/* levitating blocks flying */
float_vs_flight();
break;
case POT_GAIN_ENERGY: { /* M. Stephenson */