fix #H6925 - being trapped vs Levitation/Flying

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.)
This commit is contained in:
PatR
2018-09-30 01:06:59 -07:00
parent 00dfed5b3a
commit 3e19858edd
20 changed files with 330 additions and 149 deletions

View File

@@ -339,8 +339,8 @@ dig(VOID_ARGS)
} else {
You("destroy the bear trap with %s.",
yobjnam(uwep, (const char *) 0));
u.utrap = 0; /* release from trap */
deltrap(ttmp);
reset_utrap(TRUE); /* release from trap, maybe Lev or Fly */
}
/* we haven't made any progress toward a pit yet */
context.digging.effort = 0;
@@ -557,7 +557,7 @@ int ttyp;
if (u.utraptype == TT_BURIEDBALL)
buried_ball_to_punishment();
else if (u.utraptype == TT_INFLOOR)
u.utrap = 0;
reset_utrap(FALSE);
}
/* these furniture checks were in dighole(), but wand
@@ -619,11 +619,10 @@ int ttyp;
if (at_u) {
if (!wont_fall) {
u.utrap = rn1(4, 2);
u.utraptype = TT_PIT;
set_utrap(rn1(4, 2), TT_PIT);
vision_full_recalc = 1; /* vision limits change */
} else
u.utrap = 0;
reset_utrap(TRUE);
if (oldobjs != newobjs) /* something unearthed */
(void) pickup(1); /* detects pit */
} else if (mtmp) {
@@ -1103,7 +1102,7 @@ struct obj *obj;
pline("You clear some debris from between the pits.");
}
} else if (u.utrap && u.utraptype == TT_PIT
&& (trap_with_u = t_at(u.ux, u.uy))) {
&& (trap_with_u = t_at(u.ux, u.uy)) != 0) {
You("swing %s, but the rubble has no place to go.",
yobjnam(obj, (char *) 0));
} else {
@@ -1775,8 +1774,7 @@ buried_ball_to_punishment()
(void) stop_timer(RUST_METAL, obj_to_any(ball));
#endif
punish(ball); /* use ball as flag for unearthed buried ball */
u.utrap = 0;
u.utraptype = 0;
reset_utrap(FALSE);
del_engr_at(cc.x, cc.y);
newsym(cc.x, cc.y);
}
@@ -1800,8 +1798,7 @@ buried_ball_to_freedom()
#endif
place_object(ball, cc.x, cc.y);
stackobj(ball);
u.utrap = 0;
u.utraptype = 0;
reset_utrap(TRUE);
del_engr_at(cc.x, cc.y);
newsym(cc.x, cc.y);
}