This patch adds a new "Held" status flag for the bottom line, which
kicks in when you get grabbed by a kraken, owlbear, large mimic, or
whatever.  I vote it "Most Likely To Prevent A Late Game YASD" from
among my patches.

This patch was built on patchable Nethack, so you have to apply that
patch first.  It's at http://www.argon.org/~roderick/nethack/#patchable.

Bones/save compatibility:  This patch doesn't affect saved games or bones
files.

This patch is available at http://www.argon.org/~roderick/nethack/.

Roderick Schertler <roderick@argon.org>


diff -r -X /home/roderick/.diff-exclude -uN base.patchable/include/hack.h work.botl-held/include/hack.h
--- base.patchable/include/hack.h	2003-02-23 09:43:20.000000000 -0500
+++ work.botl-held/include/hack.h	2003-03-18 17:08:58.000000000 -0500
@@ -279,6 +279,7 @@
 #define makeknown(x)	discover_object((x),TRUE,TRUE)
 #define distu(xx,yy)	dist2((int)(xx),(int)(yy),(int)u.ux,(int)u.uy)
 #define onlineu(xx,yy)	online2((int)(xx),(int)(yy),(int)u.ux,(int)u.uy)
+#define setustuck(v)	(flags.botl = 1, u.ustuck = (v))
 
 #define rn1(x,y)	(rn2(x)+(y))
 
diff -r -X /home/roderick/.diff-exclude -uN base.patchable/src/apply.c work.botl-held/src/apply.c
--- base.patchable/src/apply.c	2003-02-23 09:43:24.000000000 -0500
+++ work.botl-held/src/apply.c	2003-03-18 17:08:58.000000000 -0500
@@ -1221,7 +1221,7 @@
 	} else if (u.ustuck) {
 		if (u.ustuck->mtame && !Conflict && !u.ustuck->mconf) {
 		    You("pull free from %s.", mon_nam(u.ustuck));
-		    u.ustuck = 0;
+		    setustuck(0);
 		    return 1;
 		}
 		if (magic) {
diff -r -X /home/roderick/.diff-exclude -uN base.patchable/src/artifact.c work.botl-held/src/artifact.c
--- base.patchable/src/artifact.c	2003-02-23 09:43:24.000000000 -0500
+++ work.botl-held/src/artifact.c	2003-03-18 17:08:58.000000000 -0500
@@ -855,7 +855,7 @@
 		nomul(-3);
 		nomovemsg = "";
 		if (magr && magr == u.ustuck && sticks(youmonst.data)) {
-		    u.ustuck = (struct monst *)0;
+		    setustuck((struct monst *)0);
 		    You("release %s!", mon_nam(magr));
 		}
 	    }
diff -r -X /home/roderick/.diff-exclude -uN base.patchable/src/botl.c work.botl-held/src/botl.c
--- base.patchable/src/botl.c	2003-02-23 09:43:25.000000000 -0500
+++ work.botl-held/src/botl.c	2003-03-18 17:08:58.000000000 -0500
@@ -25,11 +25,12 @@
  *
  * longest practical second status line at the moment is
  *	Astral Plane $:12345 HP:700(700) Pw:111(111) AC:-127 Xp:30/123456789
- *	T:123456 Satiated Conf FoodPois Ill Blind Stun Hallu Overloaded
- * -- or somewhat over 130 characters
+ *	T:123456 Satiated Conf FoodPois Ill Blind Stun Hallu Slime
+ *	Held Overloaded
+ * -- or somewhat over 140 characters
  */
-#if COLNO <= 140
-#define MAXCO 160
+#if COLNO <= 150
+#define MAXCO 170
 #else
 #define MAXCO (COLNO+20)
 #endif
@@ -290,6 +291,8 @@
 	if(Stunned)	   Sprintf(nb = eos(nb), " Stun");
 	if(Hallucination)  Sprintf(nb = eos(nb), " Hallu");
 	if(Slimed)         Sprintf(nb = eos(nb), " Slime");
+	if(u.ustuck && !u.uswallow)
+			   Sprintf(nb = eos(nb), " Held");
 	if(cap > UNENCUMBERED)
 		Sprintf(nb = eos(nb), " %s", enc_stat[cap]);
 	curs(WIN_STATUS, 1, 1);
diff -r -X /home/roderick/.diff-exclude -uN base.patchable/src/do.c work.botl-held/src/do.c
--- base.patchable/src/do.c	2003-02-23 09:43:25.000000000 -0500
+++ work.botl-held/src/do.c	2003-03-18 17:08:58.000000000 -0500
@@ -1010,7 +1010,7 @@
 	if (Punished) unplacebc();
 	u.utrap = 0;				/* needed in level_tele */
 	fill_pit(u.ux, u.uy);
-	u.ustuck = 0;				/* idem */
+	setustuck(0);				/* idem */
 	u.uinwater = 0;
 	u.uundetected = 0;	/* not hidden, even if means are available */
 	keepdogs(FALSE);
diff -r -X /home/roderick/.diff-exclude -uN base.patchable/src/hack.c work.botl-held/src/hack.c
--- base.patchable/src/hack.c	2003-02-23 09:43:27.000000000 -0500
+++ work.botl-held/src/hack.c	2003-03-18 17:08:58.000000000 -0500
@@ -945,13 +945,13 @@
 		if (u.ustuck && (x != u.ustuck->mx || y != u.ustuck->my)) {
 		    if (distu(u.ustuck->mx, u.ustuck->my) > 2) {
 			/* perhaps it fled (or was teleported or ... ) */
-			u.ustuck = 0;
+			setustuck(0);
 		    } else if (sticks(youmonst.data)) {
 			/* When polymorphed into a sticking monster,
 			 * u.ustuck means it's stuck to you, not you to it.
 			 */
 			You("release %s.", mon_nam(u.ustuck));
-			u.ustuck = 0;
+			setustuck(0);
 		    } else {
 			/* If holder is asleep or paralyzed:
 			 *	37.5% chance of getting away,
@@ -966,7 +966,7 @@
 			case 0: case 1: case 2:
 			pull_free:
 			    You("pull free from %s.", mon_nam(u.ustuck));
-			    u.ustuck = 0;
+			    setustuck(0);
 			    break;
 			case 3:
 			    if (!u.ustuck->mcanmove) {
diff -r -X /home/roderick/.diff-exclude -uN base.patchable/src/mhitm.c work.botl-held/src/mhitm.c
--- base.patchable/src/mhitm.c	2003-02-23 09:43:27.000000000 -0500
+++ work.botl-held/src/mhitm.c	2003-03-18 17:08:58.000000000 -0500
@@ -133,7 +133,7 @@
 		    if(!u.uswallow && (mtmp == u.ustuck)) {
 			if(!rn2(4)) {
 			    pline("%s releases you!", Monnam(mtmp));
-			    u.ustuck = 0;
+			    setustuck(0);
 			} else
 			    break;
 		    }
diff -r -X /home/roderick/.diff-exclude -uN base.patchable/src/mhitu.c work.botl-held/src/mhitu.c
--- base.patchable/src/mhitu.c	2003-02-23 09:43:27.000000000 -0500
+++ work.botl-held/src/mhitu.c	2003-03-18 17:08:58.000000000 -0500
@@ -431,7 +431,7 @@
 		if (!youseeit) pline("It gets stuck on you.");
 		else pline("Wait, %s!  That's a %s named %s!",
 			   m_monnam(mtmp), youmonst.data->mname, plname);
-		u.ustuck = mtmp;
+		setustuck(mtmp);
 		youmonst.m_ap_type = M_AP_NOTHING;
 		youmonst.mappearance = 0;
 		newsym(u.ux,u.uy);
@@ -899,7 +899,7 @@
 			if (u_slip_free(mtmp, mattk)) {
 			    dmg = 0;
 			} else {
-			    u.ustuck = mtmp;
+			    setustuck(mtmp);
 			    pline("%s grabs you!", Monnam(mtmp));
 			}
 		    } else if(u.ustuck == mtmp) {
@@ -1182,7 +1182,7 @@
 	    case AD_STCK:
 		hitmsg(mtmp, mattk);
 		if (uncancelled && !u.ustuck && !sticks(youmonst.data))
-			u.ustuck = mtmp;
+			setustuck(mtmp);
 		break;
 	    case AD_WRAP:
 		if ((!mtmp->mcan || u.ustuck == mtmp) && !sticks(youmonst.data)) {
@@ -1192,7 +1192,7 @@
 			} else {
 			    pline("%s swings itself around you!",
 				  Monnam(mtmp));
-			    u.ustuck = mtmp;
+			    setustuck(mtmp);
 			}
 		    } else if(u.ustuck == mtmp) {
 			if (is_pool(mtmp->mx,mtmp->my) && !Swimming
@@ -1609,7 +1609,6 @@
 		remove_monster(mtmp->mx, mtmp->my);
 		mtmp->mtrapped = 0;		/* no longer on old trap */
 		place_monster(mtmp, u.ux, u.uy);
-		u.ustuck = mtmp;
 		newsym(mtmp->mx,mtmp->my);
 #ifdef STEED
 		if (is_animal(mtmp->data) && u.usteed) {
@@ -1650,6 +1649,7 @@
 		display_nhwindow(WIN_MESSAGE, FALSE);
 		vision_recalc(2);	/* hero can't see anything */
 		u.uswallow = 1;
+		setustuck(mtmp);
 		/* u.uswldtim always set > 1 */
 		tim_tmp = 25 - (int)mtmp->m_lev;
 		if (tim_tmp > 0) tim_tmp = rnd(tim_tmp) / 2;
diff -r -X /home/roderick/.diff-exclude -uN base.patchable/src/mon.c work.botl-held/src/mon.c
--- base.patchable/src/mon.c	2003-02-23 09:43:28.000000000 -0500
+++ work.botl-held/src/mon.c	2003-03-18 17:08:58.000000000 -0500
@@ -1254,7 +1254,7 @@
     }
     mtmp2->nmon = fmon;
     fmon = mtmp2;
-    if (u.ustuck == mtmp) u.ustuck = mtmp2;
+    if (u.ustuck == mtmp) setustuck(mtmp2);
 #ifdef STEED
     if (u.usteed == mtmp) u.usteed = mtmp2;
 #endif
@@ -1669,7 +1669,7 @@
 			vision_full_recalc = 1;
 			docrt();
 		}
-		u.ustuck = 0;
+		setustuck(0);
 	}
 }
 
diff -r -X /home/roderick/.diff-exclude -uN base.patchable/src/polyself.c work.botl-held/src/polyself.c
--- base.patchable/src/polyself.c	2003-02-23 09:43:29.000000000 -0500
+++ work.botl-held/src/polyself.c	2003-03-18 17:08:58.000000000 -0500
@@ -468,7 +468,7 @@
 	}
 	newsym(u.ux,u.uy);		/* Change symbol */
 
-	if (!sticky && !u.uswallow && u.ustuck && sticks(youmonst.data)) u.ustuck = 0;
+	if (!sticky && !u.uswallow && u.ustuck && sticks(youmonst.data)) setustuck(0);
 	else if (sticky && !sticks(youmonst.data)) uunstick();
 #ifdef STEED
 	if (u.usteed) {
@@ -1092,7 +1092,7 @@
 uunstick()
 {
 	pline("%s is no longer in your clutches.", Monnam(u.ustuck));
-	u.ustuck = 0;
+	setustuck(0);
 }
 
 void
diff -r -X /home/roderick/.diff-exclude -uN base.patchable/src/restore.c work.botl-held/src/restore.c
--- base.patchable/src/restore.c	2003-02-23 09:43:29.000000000 -0500
+++ work.botl-held/src/restore.c	2003-03-18 17:08:58.000000000 -0500
@@ -461,7 +461,7 @@
 		for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
 			if (mtmp->m_id == stuckid) break;
 		if (!mtmp) panic("Cannot find the monster ustuck.");
-		u.ustuck = mtmp;
+		setustuck(mtmp);
 	}
 #ifdef STEED
 	if (steedid) {
@@ -572,7 +572,7 @@
 	 * afterwards, and in the meantime at least u.usteed may mislead
 	 * place_monster() on other levels
 	 */
-	u.ustuck = (struct monst *)0;
+	setustuck((struct monst *)0);
 #ifdef STEED
 	u.usteed = (struct monst *)0;
 #endif
diff -r -X /home/roderick/.diff-exclude -uN base.patchable/src/save.c work.botl-held/src/save.c
--- base.patchable/src/save.c	2003-02-23 09:43:30.000000000 -0500
+++ work.botl-held/src/save.c	2003-03-18 17:08:58.000000000 -0500
@@ -223,7 +223,7 @@
 	/* these pointers are no longer valid, and at least u.usteed
 	 * may mislead place_monster() on other levels
 	 */
-	u.ustuck = (struct monst *)0;
+	setustuck((struct monst *)0);
 #ifdef STEED
 	u.usteed = (struct monst *)0;
 #endif
diff -r -X /home/roderick/.diff-exclude -uN base.patchable/src/teleport.c work.botl-held/src/teleport.c
--- base.patchable/src/teleport.c	2003-02-23 09:43:30.000000000 -0500
+++ work.botl-held/src/teleport.c	2003-03-18 17:08:58.000000000 -0500
@@ -264,7 +264,7 @@
 	    }
 	}
 	u.utrap = 0;
-	u.ustuck = 0;
+	setustuck(0);
 	u.ux0 = u.ux;
 	u.uy0 = u.uy;
 
@@ -917,7 +917,7 @@
 			u.ux = x;
 			u.uy = y;
 			docrt();
-		} else	u.ustuck = 0;
+		} else	setustuck(0);
 	}
 
 	newsym(x, y);				/* update new location */
diff -r -X /home/roderick/.diff-exclude -uN base.patchable/src/u_init.c work.botl-held/src/u_init.c
--- base.patchable/src/u_init.c	2003-02-23 09:43:31.000000000 -0500
+++ work.botl-held/src/u_init.c	2003-03-18 17:08:59.000000000 -0500
@@ -524,7 +524,7 @@
 	/* zero u, including pointer values --
 	 * necessary when aborting from a failed restore */
 	(void) memset((genericptr_t)&u, 0, sizeof(u));
-	u.ustuck = (struct monst *)0;
+	setustuck((struct monst *)0);
 
 #if 0	/* documentation of more zero values as desirable */
 	u.usick_cause[0] = 0;
diff -r -X /home/roderick/.diff-exclude -uN base.patchable/src/uhitm.c work.botl-held/src/uhitm.c
--- base.patchable/src/uhitm.c	2003-02-23 09:43:31.000000000 -0500
+++ work.botl-held/src/uhitm.c	2003-03-18 17:08:59.000000000 -0500
@@ -140,7 +140,7 @@
 		 */
 		if(mtmp->m_ap_type && !Protection_from_shape_changers) {
 		    if(!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data,AD_STCK))
-			u.ustuck = mtmp;
+			setustuck(mtmp);
 		}
 		wakeup(mtmp); /* always necessary; also un-mimics mimics */
 		return TRUE;
@@ -450,7 +450,7 @@
 		    } else monflee(mon, 0, FALSE, TRUE);
 
 		    if(u.ustuck == mon && !u.uswallow && !sticks(youmonst.data))
-			u.ustuck = 0;
+			setustuck(0);
 		}
 		/* Vorpal Blade hit converted to miss */
 		/* could be headless monster or worm tail */
@@ -1531,7 +1531,7 @@
 		break;
 	    case AD_STCK:
 		if (!negated && !sticks(mdef->data))
-		    u.ustuck = mdef; /* it's now stuck to you */
+		    setustuck(mdef); /* it's now stuck to you */
 		break;
 	    case AD_WRAP:
 		if (!sticks(mdef->data)) {
@@ -1541,7 +1541,7 @@
 			} else {
 			    You("swing yourself around %s!",
 				  mon_nam(mdef));
-			    u.ustuck = mdef;
+			    setustuck(mdef);
 			}
 		    } else if(u.ustuck == mdef) {
 			/* Monsters don't wear amulets of magical breathing */
@@ -2012,7 +2012,7 @@
 				sum[i] = damageum(mon, mattk);
 			    } else if(i >= 2 && sum[i-1] && sum[i-2]) {
 				You("grab %s!", mon_nam(mon));
-				u.ustuck = mon;
+				setustuck(mon);
 				sum[i] = damageum(mon, mattk);
 			    }
 			}
@@ -2365,7 +2365,7 @@
 		   *what = 0;
 
 	if(!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data,AD_STCK))
-	    u.ustuck = mtmp;
+	    setustuck(mtmp);
 
 	if (Blind) {
 	    if (!Blind_telepat)
diff -r -X /home/roderick/.diff-exclude -uN base.patchable/util/makedefs.c work.botl-held/util/makedefs.c
--- base.patchable/util/makedefs.c	2003-03-18 17:05:58.000000000 -0500
+++ work.botl-held/util/makedefs.c	2003-03-18 17:09:18.000000000 -0500
@@ -752,6 +752,10 @@
 		/*
 		 * patch list patch point; see $top/README.patchable
 		 */
+		"patch: botl-held 3.4.1-1",
+		/*
+		 * patch list patch point; see $top/README.patchable
+		 */
 		/*
 		 * patch list patch point; see $top/README.patchable
 		 */
