diff -pruN slashem-0.0.7E7/dat/opthelp slashem-0.0.7E7-sortloot/dat/opthelp
--- slashem-0.0.7E7/dat/opthelp	2005-02-19 11:13:49.000000000 +0100
+++ slashem-0.0.7E7-sortloot/dat/opthelp	2005-05-24 10:44:38.695113344 +0200
@@ -135,6 +135,12 @@ runmode       controls how often the map
 scores        the parts of the score list you wish to see when the game ends
               You choose a combination of top scores, scores around the top
               scores, and all of your own scores.  [!own/3 top/2 around]
+sortloot      controls the sortloot patch [none]:
+              full -- All pickup lists of items are sorted by item description
+              loot -- When inventory letters are shown, has no effect.
+                      Otherwise sorts by description
+              none -- Works the traditional way, like without the patch
+
 suppress_alert disable various version-specific warnings about changes
               in game play or the user interface, such as notification given
               for engravings that reading is now done via 'r.'
diff -pruN slashem-0.0.7E7/doc/Guidebook.mn slashem-0.0.7E7-sortloot/doc/Guidebook.mn
--- slashem-0.0.7E7/doc/Guidebook.mn	2005-02-19 11:13:49.000000000 +0100
+++ slashem-0.0.7E7-sortloot/doc/Guidebook.mn	2005-05-24 10:45:13.184870104 +0200
@@ -2222,6 +2222,18 @@ enough to quantify their damage.
 Show total weight in inventory on bottom line (default off).
 .lp "silent  "
 Suppress terminal beeps (default on).
+.lp sortloot
+Controls the behavior of the sortloot patch that sorts pickup lists for
+inventory and #loot commands and some others.
+The possible values are:
+.sd
+.si
+full - always sort the lists;
+loot - only sort the lists that don't use inventory
+       letters, like with the #loot and pickup commands;
+none - show lists the traditional way without sorting.
+.ei
+.ed
 .lp sortpack
 Sort the pack contents by type when displaying inventory (default on).
 .lp sound
diff -pruN slashem-0.0.7E7/doc/Guidebook.tex slashem-0.0.7E7-sortloot/doc/Guidebook.tex
--- slashem-0.0.7E7/doc/Guidebook.tex	2005-02-19 11:13:49.000000000 +0100
+++ slashem-0.0.7E7-sortloot/doc/Guidebook.tex	2005-05-24 10:46:06.378783400 +0200
@@ -3046,6 +3046,23 @@ Show total weight in inventory on bottom
 Suppress terminal beeps (default on).
 %.lp
 
+\item[\ib{sortloot}]
+Controls the behavior of the sortloot patch that sorts pickup lists for
+inventory and \#loot commands and some others.
+
+The possible values are:
+%.sd
+%.si
+{\tt full} --- always sort the lists;\\
+{\tt loot} --- only sort the lists that don't use inventory
+       letters, like with the \#loot and pickup commands;\\
+{\tt none} --- show lists the traditional way without sorting.
+%.ei
+%.ed
+%.lp
+The default is 'none', the way an unpatched game works.
+
+
 \item[\ib{sortpack}]
 Sort the pack contents by type when displaying inventory (default on).
 %.lp
diff -pruN slashem-0.0.7E7/doc/Guidebook.txt slashem-0.0.7E7-sortloot/doc/Guidebook.txt
--- slashem-0.0.7E7/doc/Guidebook.txt	2005-02-19 11:13:49.000000000 +0100
+++ slashem-0.0.7E7-sortloot/doc/Guidebook.txt	2005-05-24 10:46:38.769859208 +0200
@@ -2911,6 +2911,17 @@
           silent
             Suppress terminal beeps (default on).
 
+	    sortloot
+	    Controls the behavior of the sortloot patch that sorts
+	    pickup lists for inventory and #loot commands and some
+	    others.
+	    The possible values are:
+	    full - always sort the lists
+	    loot - only sort the lists that don't use inventory
+		    letters, like with the #loot and pickup commands
+	    none - show lists the traditional way without sorting
+	    The default is 'none', the way an unpatched game works.
+
           sortpack
             Sort  the  pack contents by type when displaying inventory (de-
             fault on).
diff -pruN slashem-0.0.7E7/include/extern.h slashem-0.0.7E7-sortloot/include/extern.h
--- slashem-0.0.7E7/include/extern.h	2005-02-19 11:13:50.000000000 +0100
+++ slashem-0.0.7E7-sortloot/include/extern.h	2005-05-24 10:47:00.853501984 +0200
@@ -1460,6 +1460,9 @@ E char *FDECL(doname, (struct obj *));
 E boolean FDECL(not_fully_identified, (struct obj *));
 E char *FDECL(corpse_xname, (struct obj *,BOOLEAN_P));
 E char *FDECL(cxname, (struct obj *));
+#ifdef SORTLOOT
+E char *FDECL(cxname2, (struct obj *));
+#endif
 E char *FDECL(killer_xname, (struct obj *));
 E char *FDECL(killer_cxname, (struct obj *,BOOLEAN_P));
 E const char *FDECL(singular, (struct obj *,char *(*)(OBJ_P)));
diff -pruN slashem-0.0.7E7/include/flag.h slashem-0.0.7E7-sortloot/include/flag.h
--- slashem-0.0.7E7/include/flag.h	2005-02-19 11:13:50.000000000 +0100
+++ slashem-0.0.7E7-sortloot/include/flag.h	2005-05-24 11:10:27.452666408 +0200
@@ -303,6 +303,9 @@ struct instance_flags {
 #define MAX_ALTKEYHANDLER 25
 	char	 altkeyhandler[MAX_ALTKEYHANDLER];
 #endif
+#ifdef SORTLOOT
+	uchar	sortloot;
+#endif
 };
 
 /*
diff -pruN slashem-0.0.7E7/src/end.c slashem-0.0.7E7-sortloot/src/end.c
--- slashem-0.0.7E7/src/end.c	2005-02-19 11:13:50.000000000 +0100
+++ slashem-0.0.7E7-sortloot/src/end.c	2005-05-24 10:48:54.807178392 +0200
@@ -977,6 +977,11 @@ struct obj *list;
 boolean identified, all_containers;
 {
 	register struct obj *box, *obj;
+#ifdef SORTLOOT
+        struct obj **oarray;
+        int i,j,n;
+        char *invlet;
+#endif /* SORTLOOT */
 	char buf[BUFSZ];
 
 	for (box = list; box; box = box->nobj) {
@@ -985,10 +990,49 @@ boolean identified, all_containers;
 		    continue;	/* wrong type of container */
 		} else if (box->cobj) {
 		    winid tmpwin = create_nhwindow(NHW_MENU);
+#ifdef SORTLOOT
+                   /* count the number of items */
+                   for (n = 0, obj = box->cobj; obj; obj = obj->nobj) n++;
+                   /* Make a temporary array to store the objects sorted */
+                   oarray = (struct obj **) alloc(n*sizeof(struct obj*));
+
+                   /* Add objects to the array */
+                   i = 0;
+                   invlet = flags.inv_order;
+               nextclass:
+                   for (obj = box->cobj; obj; obj = obj->nobj) {
+                      if (!flags.sortpack || obj->oclass == *invlet) {
+                       if (iflags.sortloot == 'f'
+                           || iflags.sortloot == 'l') {
+                         /* Insert object at correct index */
+                         for (j = i; j; j--) {
+                           if (strcmpi(cxname2(obj), cxname2(oarray[j-1]))>0
+                           || (flags.sortpack &&
+                               oarray[j-1]->oclass != obj->oclass))
+                             break;
+                           oarray[j] = oarray[j-1];
+                         }
+                         oarray[j] = obj;
+                         i++;
+                       } else {
+                         /* Just add it to the array */
+                         oarray[i++] = obj;
+                       }
+                     }
+                   } /* for loop */
+                   if (flags.sortpack) {
+                     if (*++invlet) goto nextclass;
+                   }
+#endif /* SORTLOOT */
 		    Sprintf(buf, "Contents of %s:", the(xname(box)));
 		    putstr(tmpwin, 0, buf);
 		    putstr(tmpwin, 0, "");
+#ifdef SORTLOOT
+                   for (i = 0; i < n; i++) {
+                       obj = oarray[i];
+#else
 		    for (obj = box->cobj; obj; obj = obj->nobj) {
+#endif
 			if (identified) {
 			    makeknown(obj->otyp);
 			    obj->known = obj->bknown =
diff -pruN slashem-0.0.7E7/src/invent.c slashem-0.0.7E7-sortloot/src/invent.c
--- slashem-0.0.7E7/src/invent.c	2005-02-19 11:13:50.000000000 +0100
+++ slashem-0.0.7E7-sortloot/src/invent.c	2005-05-24 10:51:31.519354520 +0200
@@ -1917,6 +1917,10 @@ boolean want_reply;
 long* out_cnt;
 {
 	struct obj *otmp;
+#ifdef SORTLOOT
+	struct obj **oarray;
+	int i, j;
+#endif
 	char ilet, ret;
 	char *invlet = flags.inv_order;
 	int n, classcount;
@@ -1986,10 +1990,67 @@ long* out_cnt;
 	    return ret;
 	}
 
+#ifdef SORTLOOT
+       /* count the number of items */
+       for (n = 0, otmp = invent; otmp; otmp = otmp->nobj)
+         if(!lets || !*lets || index(lets, otmp->invlet)) n++;
+
+       /* Make a temporary array to store the objects sorted */
+       oarray = (struct obj **)alloc(n*sizeof(struct obj*));
+
+       /* Add objects to the array */
+       i = 0;
+       for(otmp = invent; otmp; otmp = otmp->nobj)
+         if(!lets || !*lets || index(lets, otmp->invlet)) {
+           if (iflags.sortloot == 'f') {
+             /* Insert object at correct index */
+             for (j = i; j; j--) {
+               if (strcmpi(cxname2(otmp), cxname2(oarray[j-1]))>0) break;
+               oarray[j] = oarray[j-1];
+             }
+             oarray[j] = otmp;
+             i++;
+           } else {
+             /* Just add it to the array */
+             oarray[i++] = otmp;
+           }
+         }
+#endif /* SORTLOOT */
+
 	start_menu(win);
 nextclass:
 	classcount = 0;
 	any.a_void = 0;		/* set all bits to zero */
+#ifdef SORTLOOT
+       for(i = 0; i < n; i++) {
+         otmp = oarray[i];
+         ilet = otmp->invlet;
+         if (!flags.sortpack || otmp->oclass == *invlet) {
+           if (flags.sortpack && !classcount) {
+             any.a_void = 0;             /* zero */
+             add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
+                      let_to_name(*invlet, FALSE), MENU_UNSELECTED);
+#ifdef DUMP_LOG
+             if (want_dump)
+               dump("  ", let_to_name(*invlet, FALSE));
+#endif
+             classcount++;
+           }
+           any.a_char = ilet;
+           add_menu(win, obj_to_glyph(otmp),
+                    &any, ilet, 0, ATR_NONE, doname(otmp),
+                    MENU_UNSELECTED);
+#ifdef DUMP_LOG
+           if (want_dump) {
+             char letbuf[7];
+             sprintf(letbuf, "  %c - ", ilet);
+             dump(letbuf, doname(otmp));
+           }
+#endif
+         }
+       }
+#else /* SORTLOOT */
+
 	for(otmp = invent; otmp; otmp = otmp->nobj) {
 		ilet = otmp->invlet;
 		if(!lets || !*lets || index(lets, ilet)) {
@@ -2007,6 +2068,7 @@ nextclass:
 			}
 		}
 	}
+#endif /* SORTLOOT */
 	if (flags.sortpack) {
 		if (*++invlet) goto nextclass;
 #ifdef WIZARD
@@ -2016,6 +2078,9 @@ nextclass:
 		}
 #endif
 	}
+#ifdef SORTLOOT
+       free(oarray);
+#endif
 	end_menu(win, (char *) 0);
 
 	n = select_menu(win, want_reply ? PICK_ONE : PICK_NONE, &selected);
diff -pruN slashem-0.0.7E7/src/objnam.c slashem-0.0.7E7-sortloot/src/objnam.c
--- slashem-0.0.7E7/src/objnam.c	2005-02-19 11:13:50.000000000 +0100
+++ slashem-0.0.7E7-sortloot/src/objnam.c	2005-05-24 11:14:14.041219712 +0200
@@ -971,6 +971,16 @@ struct obj *obj;
 	    return corpse_xname(obj, FALSE);
 	return xname(obj);
 }
+#ifdef SORTLOOT
+char *
+cxname2(obj)
+struct obj *obj;
+{
+       if (obj->otyp == CORPSE)
+           return corpse_xname(obj, TRUE);
+       return xname2(obj);
+}
+#endif /* SORTLOOT */
 
 /* treat an object as fully ID'd when it might be used as reason for death */
 char *
diff -pruN slashem-0.0.7E7/src/options.c slashem-0.0.7E7-sortloot/src/options.c
--- slashem-0.0.7E7/src/options.c	2005-02-19 11:13:50.000000000 +0100
+++ slashem-0.0.7E7-sortloot/src/options.c	2005-05-24 11:02:40.859599336 +0200
@@ -361,6 +361,10 @@ static struct Comp_Opt
 	{ "scroll_amount", "amount to scroll map when scroll_margin is reached",
 						20, DISP_IN_GAME }, /*WC*/
 	{ "scroll_margin", "scroll map when this far from the edge", 20, DISP_IN_GAME }, /*WC*/
+#ifdef SORTLOOT
+	{ "sortloot", "sort object selection lists by description", 4, SET_IN_GAME },
+#endif
+
 #ifdef MSDOS
 	{ "soundcard", "type of sound card to use", 20, SET_IN_FILE },
 #endif
@@ -608,6 +612,9 @@ initoptions()
 		     (genericptr_t)def_inv_order, sizeof flags.inv_order);
 	flags.pickup_types[0] = '\0';
 	flags.pickup_burden = MOD_ENCUMBER;
+#ifdef SORTLOOT
+	iflags.sortloot = 'n';
+#endif
 
 	for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++)
 		flags.end_disclose[i] = DISCLOSE_PROMPT_DEFAULT_NO;
@@ -2120,6 +2127,24 @@ goodfruit:
 	    return;
 	}
 
+#ifdef SORTLOOT
+       fullname = "sortloot";
+       if (match_optname(opts, fullname, 4, TRUE)) {
+               op = string_for_env_opt(fullname, opts, FALSE);
+               if (op) {
+                       switch (tolower(*op)) {
+                        case 'n':
+                        case 'l':
+                        case 'f': iflags.sortloot = tolower(*op);
+                               break;
+                        default:  badoption(opts);
+                               return;
+                       }
+               }
+               return;
+       }
+#endif /* SORTLOOT */
+
 	fullname = "suppress_alert";
 	if (match_optname(opts, fullname, 4, TRUE)) {
 		op = string_for_opt(opts, negated);
@@ -2751,6 +2776,12 @@ static NEARDATA const char *runmodes[] =
 	"teleport", "run", "walk", "crawl"
 };
 
+#ifdef SORTLOOT
+static NEARDATA const char *sortltype[] = {
+       "none", "loot", "full"
+};
+#endif
+
 /*
  * Convert the given string of object classes to a string of default object
  * symbols.
@@ -3030,7 +3061,8 @@ boolean setinitial,setfromfile;
     boolean retval = FALSE;
     
     /* Special handling of menustyle, pickup_burden, pickup_types,
-     * disclose, runmode, msg_window, menu_headings, and number_pad options.
+     * disclose, runmode, msg_window, menu_headings, number_pad and sortloot
+
 #ifdef AUTOPICKUP_EXCEPTIONS
      * Also takes care of interactive autopickup_exception_handling changes.
 #endif
@@ -3185,6 +3217,26 @@ boolean setinitial,setfromfile;
 	}
 	destroy_nhwindow(tmpwin);
         retval = TRUE;
+#ifdef SORTLOOT
+    } else if (!strcmp("sortloot", optname)) {
+       const char *sortl_name;
+       menu_item *sortl_pick = (menu_item *)0;
+       tmpwin = create_nhwindow(NHW_MENU);
+       start_menu(tmpwin);
+       for (i = 0; i < SIZE(sortltype); i++) {
+           sortl_name = sortltype[i];
+           any.a_char = *sortl_name;
+           add_menu(tmpwin, NO_GLYPH, &any, *sortl_name, 0,
+                    ATR_NONE, sortl_name, MENU_UNSELECTED);
+       }
+       end_menu(tmpwin, "Select loot sorting type:");
+       if (select_menu(tmpwin, PICK_ONE, &sortl_pick) > 0) {
+           iflags.sortloot = sortl_pick->item.a_char;
+           free((genericptr_t)sortl_pick);
+       }
+       destroy_nhwindow(tmpwin);
+       retval = TRUE;
+#endif
     }
 #endif
      else if (!strcmp("align_message", optname) ||
@@ -3565,6 +3617,17 @@ char *buf;
 		if (iflags.wc_scroll_margin) Sprintf(buf, "%d",iflags.wc_scroll_margin);
 		else Strcpy(buf, defopt);
 	}
+#ifdef SORTLOOT
+       else if (!strcmp(optname, "sortloot")) {
+               char *sortname = (char *)NULL;
+               for (i=0; i < SIZE(sortltype) && sortname==(char *)NULL; i++) {
+                  if (iflags.sortloot == sortltype[i][0])
+                    sortname = (char *)sortltype[i];
+               }
+               if (sortname != (char *)NULL)
+                  Sprintf(buf, "%s", sortname);
+       }
+#endif
 	else if (!strcmp(optname, "player_selection"))
 		Sprintf(buf, "%s", iflags.wc_player_selection ? "prompts" : "dialog");
 #ifdef MSDOS
diff -pruN slashem-0.0.7E7/src/pickup.c slashem-0.0.7E7-sortloot/src/pickup.c
--- slashem-0.0.7E7/src/pickup.c	2005-02-19 11:13:50.000000000 +0100
+++ slashem-0.0.7E7-sortloot/src/pickup.c	2005-05-24 11:04:43.314983288 +0200
@@ -701,9 +701,15 @@ menu_item **pick_list;		/* return list o
 int how;			/* type of query */
 boolean FDECL((*allow), (OBJ_P));/* allow function */
 {
+#ifdef SORTLOOT
+       int i, j;
+#endif
 	int n;
 	winid win;
 	struct obj *curr, *last;
+#ifdef SORTLOOT
+       struct obj **oarray;
+#endif
 	char *pack;
 	anything any;
 	boolean printed_type_name;
@@ -727,6 +733,32 @@ boolean FDECL((*allow), (OBJ_P));/* allo
 	    (*pick_list)->count = last->quan;
 	    return 1;
 	}
+#ifdef SORTLOOT
+       /* Make a temporary array to store the objects sorted */
+       oarray = (struct obj **)alloc(n*sizeof(struct obj*));
+
+       /* Add objects to the array */
+       i = 0;
+       for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
+         if ((*allow)(curr)) {
+           if (iflags.sortloot == 'f' ||
+               (iflags.sortloot == 'l' && !(qflags & USE_INVLET)))
+             {
+               /* Insert object at correct index */
+               for (j = i; j; j--)
+                 {
+                   if (strcmpi(cxname2(curr), cxname2(oarray[j-1]))>0) break;
+                   oarray[j] = oarray[j-1];
+                 }
+               oarray[j] = curr;
+               i++;
+             } else {
+               /* Just add it to the array */
+               oarray[i++] = curr;
+             }
+         }
+       }
+#endif /* SORTLOOT */
 
 	win = create_nhwindow(NHW_MENU);
 	start_menu(win);
@@ -741,7 +773,12 @@ boolean FDECL((*allow), (OBJ_P));/* allo
 	pack = flags.inv_order;
 	do {
 	    printed_type_name = FALSE;
-	    for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
+#ifdef SORTLOOT
+           for (i = 0; i < n; i++) {
+               curr = oarray[i];
+#else /* SORTLOOT */
+            for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
+#endif /* SORTLOOT */
 		if ((qflags & FEEL_COCKATRICE) && curr->otyp == CORPSE &&
 		     will_feel_cockatrice(curr, FALSE)) {
 			destroy_nhwindow(win);	/* stop the menu and revert */
@@ -769,6 +806,10 @@ boolean FDECL((*allow), (OBJ_P));/* allo
 	    pack++;
 	} while (qflags & INVORDER_SORT && *pack);
 
+#ifdef SORTLOOT
+       free(oarray);
+#endif
+
 	end_menu(win, qstr);
 	n = select_menu(win, how, pick_list);
 	destroy_nhwindow(win);
