[net.games.hack] Sorting your inventory

pld@mit-athena.UUCP (Peter L DeWolf) (07/03/85)

Someone recently posted a patch to hack that caused your pack to be
kept sorted by object type.  I tried this out and decided that I like
having a sorted inventory, but don't like having it done automatically --
I like knowing where certain things are in my pack without having to
use the "i" or "I" command every time I pick something up.  There were also
a few bugs in the code as given.

Here is my set of changes which provide:
1)	a "#sort" command to sort your inventory
2)	an "inventory:<chars>" option to specify the order of item
	types in the inventory.

context diffs for hack.cmd.c, hack.invent.c, hack.options.c, and hack.u_init.c
follow.
 
*** hack.cmd.c.orig	Fri Jun 14 13:52:18 1985
--- hack.cmd.c	Tue Jun 18 11:54:42 1985
***************
*** 9,15
  dosave(),dowield(),ddoinv(),dozap(),ddocall(),dowhatis(),doengrave(),dotele(),
  dohelp(),doeat(),doddrop(),do_mname(),doidtrap(),doprwep(),doprarm(),
  doprring(),doprgold(),dodiscovered(),dotypeinv(),dolook(),doset(),
! doup(), dodown(), done1(), donull(), dothrow(), doextcmd(), dodip();
  #ifdef SHELL
  int dosh();
  #endif SHELL

--- 9,15 -----
  dosave(),dowield(),ddoinv(),dozap(),ddocall(),dowhatis(),doengrave(),dotele(),
  dohelp(),doeat(),doddrop(),do_mname(),doidtrap(),doprwep(),doprarm(),
  doprring(),doprgold(),dodiscovered(),dotypeinv(),dolook(),doset(),
! doup(), dodown(), done1(), donull(), dothrow(), doextcmd(), dodip(), dosort();
  #ifdef SHELL
  int dosh();
  #endif SHELL
***************
*** 83,88
  
  struct ext_func_tab extcmdlist[] = {
  	"dip", dodip,
  	(char *) 0, donull
  };
  

--- 83,89 -----
  
  struct ext_func_tab extcmdlist[] = {
  	"dip", dodip,
+ 	"sort", dosort,
  	(char *) 0, donull
  };
  
*** hack.invent.c.orig	Fri Jun 14 13:52:43 1985
--- hack.invent.c	Wed Jul  3 10:19:22 1985
***************
*** 30,35
  	return(obj);
  }
  
  useup(obj)
  register struct obj *obj;
  {

--- 30,82 -----
  	return(obj);
  }
  
+ static
+ classLess(newLet,establishedLet) {
+ 	char	*nindex, *eindex;
+ 	extern	char	sortsequence[];
+ 
+ 	if (newLet == establishedLet) return(FALSE);	/* if same, not less */
+ 	nindex = index(sortsequence,newLet);		/* find new letter */
+ 	if (!nindex) return(FALSE);			/* if not, not less */
+ 	eindex = index(sortsequence,establishedLet);	/* find old letter */
+ 	return(eindex ? (nindex < eindex) : TRUE);
+ }
+ 
+ dosort() {
+ 	register struct obj *obj;
+ 	register struct obj *itmp;
+ 	register struct obj *otmp;
+ 
+ 	for (itmp = invent, invent = NULL; itmp;) {
+ 		obj = itmp;
+ 		itmp = obj->nobj;
+ 		if (!invent) {
+ 			invent = obj;
+ 			obj->nobj = NULL;
+ 			continue;
+ 		}
+ 		for(otmp = invent; otmp; otmp = otmp->nobj) {
+ 			/* this may go at head of inventory */
+ 			if (classLess(obj->olet,otmp->olet)) {
+ 				obj->nobj = otmp;
+ 				invent = obj;
+ 				break;
+ 			}
+ 			/* else, may go after current item */
+ 			if (	!otmp->nobj
+ 			   ||	(	(obj->olet == otmp->olet)
+ 				&&	(obj->olet != otmp->nobj->olet)
+ 				)
+ 			   ||	 classLess(obj->olet,otmp->nobj->olet)
+ 			   ) {
+ 				obj->nobj = otmp->nobj;
+ 				otmp->nobj = obj;
+ 				break;
+ 			}
+ 		}
+ 	}
+ }
+ 
  useup(obj)
  register struct obj *obj;
  {
*** hack.options.c.orig	Tue Jun 18 12:37:00 1985
--- hack.options.c	Wed Jul  3 10:18:36 1985
***************
*** 5,10
  #include "hack.h"
  extern char *eos();
  
  initoptions()
  {
  	register char *opts;

--- 5,16 -----
  #include "hack.h"
  extern char *eos();
  
+ /* Collating sequence for sorting objects in an inventory.
+    Just rearrange the characters in this string to change the sequence.
+    This can be done with the "inventory" option.
+ */
+ char	sortsequence[] = ")0[(%!?/=*\"";
+ 
  initoptions()
  {
  	register char *opts;
***************
*** 98,103
  		return;
  	}
  
  	/* endgame:5t[op] 5a[round] o[wn] */
  	if(!strncmp(opts,"endgame",3)) {
  		op = index(opts,':');

--- 104,117 -----
  		return;
  	}
  
+ 	/* inventory:string */
+ 	if(!strncmp(opts,"inventory",9)) {
+ 		op = index(opts,':');
+ 		if(!op) goto bad;
+ 		(void) strncpy(sortsequence, op+1, sizeof sortsequence-1);
+ 		return;
+ 	}
+ 
  	/* endgame:5t[op] 5a[round] o[wn] */
  	if(!strncmp(opts,"endgame",3)) {
  		op = index(opts,':');
***************
*** 178,183
  	    if(flags.notombstone) (void) strcat(buf,"notombstone,");
  	    if(flags.no_rest_on_space)
  		(void) strcat(buf,"!rest_on_space,");
  	    if(flags.end_top != 5 || flags.end_around != 4 || flags.end_own){
  		(void) sprintf(eos(buf), "endgame: %u topscores/%u around me",
  			flags.end_top, flags.end_around);

--- 192,198 -----
  	    if(flags.notombstone) (void) strcat(buf,"notombstone,");
  	    if(flags.no_rest_on_space)
  		(void) strcat(buf,"!rest_on_space,");
+ 	    (void) sprintf(eos(buf),"inventory:%s,",sortsequence);
  	    if(flags.end_top != 5 || flags.end_around != 4 || flags.end_own){
  		(void) sprintf(eos(buf), "endgame: %u topscores/%u around me",
  			flags.end_top, flags.end_around);
*** hack.u_init.c.orig	Fri Jun 14 13:53:15 1985
--- hack.u_init.c	Wed Jul  3 10:26:33 1985
***************
*** 244,249
  	if(wizard) wiz_inv();
  #endif WIZARD
  
  	/* make sure he can carry all he has - especially for T's */
  	while(inv_weight() > 0 && u.ustr < 118)
  		u.ustr++, u.ustrmax++;

--- 244,251 -----
  	if(wizard) wiz_inv();
  #endif WIZARD
  
+ 	dosort();				/* put inventory into order */
+ 
  	/* make sure he can carry all he has - especially for T's */
  	while(inv_weight() > 0 && u.ustr < 118)
  		u.ustr++, u.ustrmax++;