early post-3.4.3 tried to fix the "naming artifacts trick" which could be used
to distinguish the type of some undiscovered items, but using a name
that only matched an artifact after capitalization was exploitable
+the u.ustuck hierarchy is: swallowed by ustuck, hero poly'd into sticky form
+ is holding ustuck even if ustuck is sticky, ustuck is holding hero;
+ but some code assumed that the first two cases were reversed and
+ could make formerly sticky pold'd hero clear ustuck, leaving hero
+ swallowed by nothing (u.uswallow==1 with u.ustuck==NULL); that could
+ cause a crash if u.ustuck got dereferenced
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
&& !condtests[bl_tethered].test);
}
condtests[bl_grab].test = condtests[bl_held].test
+#if 0
+ = condtests[bl_engulfed].test
+#endif
= condtests[bl_holding].test = FALSE;
if (u.ustuck) {
- if (Upolyd && sticks(g.youmonst.data)) {
- test_if_enabled(bl_holding) = TRUE;
- } else {
- test_if_enabled(bl_grab) = (u.ustuck->data->mlet == S_EEL);
+ /* it is possible for a hero in sticks() form to be swallowed,
+ so swallowed needs to be checked first; it is not possible for
+ a hero in sticks() form to be held--sticky hero does the holding
+ even if u.ustuck is also a holder */
+ if (u.uswallow) {
+ /* engulfed/swallowed isn't currently a tracked status condition;
+ "held" might look odd for it but seems better than blank */
#if 0
- test_if_enabled(bl_engulfed) = u.uswallow ? TRUE : FALSE;
- test_if_enabled(bl_held) = (!condtests[bl_grab].test
- && !condtests[bl_engulfed].test);
+ test_if_enabled(bl_engulfed) = TRUE;
#else
- test_if_enabled(bl_held) = (!condtests[bl_grab].test
- /* engulfed/swallowed isn't currently a tracked condition
- and showing "held" when in that state looks a bit odd,
- so suppress "held" if swallowed */
- && !u.uswallow);
+ test_if_enabled(bl_held) = TRUE;
#endif
+ } else if (Upolyd && sticks(g.youmonst.data)) {
+ test_if_enabled(bl_holding) = TRUE;
+ } else {
+ /* grab == hero is held by sea monster and about to be drowned;
+ held == hero is held by something else and can't move away */
+ test_if_enabled(bl_grab) = (u.ustuck->data->mlet == S_EEL);
+ test_if_enabled(bl_held) = !condtests[bl_grab].test;
}
}
condtests[bl_blind].test = (Blind) ? TRUE : FALSE;
long *);
static void contained_stats(winid, const char *, long *, long *);
static void misc_stats(winid, long *, long *);
+static void you_sanity_check(void);
static boolean accept_menu_prefix(const struct ext_func_tab *);
static void reset_cmd_vars(boolean);
static void mcmd_addmenu(winid, int, const char *);
RESTORE_WARNING_FORMAT_NONLITERAL
+static void
+you_sanity_check(void)
+{
+ if (u.uswallow && !u.ustuck) {
+ /* this probably ought to be panic() */
+ impossible("sanity_check: swallowed by nothing?");
+ display_nhwindow(WIN_MESSAGE, TRUE);
+ /* try to recover from whatever the problem is */
+ u.uswallow = 0;
+ u.uswldtim = 0;
+ docrt();
+ }
+ (void) check_invent_gold("invent");
+}
+
void
sanity_check(void)
{
- (void) check_invent_gold("invent");
+ you_sanity_check();
obj_sanity_check();
timer_sanity_check();
mon_sanity_check();
if (!mtmp) {
impossible("release_hold when not held?");
- } else if (sticks(g.youmonst.data)) {
- /* order matters if 'holding' status condition is enabled;
- set_ustuck() will set flag for botl update, You() pline will
- trigger a status update with "UHold" removed */
- set_ustuck((struct monst *) 0);
- You("release %s.", mon_nam(mtmp));
- } else if (u.uswallow) {
+ } else if (u.uswallow) { /* possible for sticky hero to be swallowed */
if (is_animal(mtmp->data)) {
if (!Blind)
pline("%s opens its mouth!", Monnam(mtmp));
}
/* gives "you get regurgitated" or "you get expelled from <mon>" */
expels(mtmp, mtmp->data, TRUE);
+ } else if (sticks(g.youmonst.data)) {
+ /* order matters if 'holding' status condition is enabled;
+ set_ustuck() will set flag for botl update, You() pline will
+ trigger a status update with "UHold" removed */
+ set_ustuck((struct monst *) 0);
+ You("release %s.", mon_nam(mtmp));
} else { /* held but not swallowed */
char relbuf[BUFSZ];