Here was a request I made on c-list: - have better auto-pickup selections: allow for all-edible, coins and gems, missile weapons (daggers, arrows, etc). It's a pain to pick up individual daggers and arrows all the time!!! I think you understand what I mean. Also, right now they're exclusive, they should be individually selectable (i.e. automatically grab missile weapon stuff, magic items and coins). So I've programmed it into the server. It supplements the current mode so it shouldn't break anything. It's bit oriented (see define.h PU_* definitions) and takes effect if the high bit is set. To use it, try 'pickup 65511 and you should see: command_pickup: set_pickup_mode 64511, 0xfbff, 0b1 1111 0111 1111 111 NEWMODE FOOD VALUABLES MISSILEWEAPON BOW ARROW ARMOUR HELMET SHIELD KEY ...this is all except WEAPON which will grab chairs too. THere are a lot of debug printf's right now; they need to be cleaned out. SOmeone responsible for the server should take this and decide how it should be integrated and what should happen to the current code. The clients need to deal with this in some way as well, since currently you need to take the hex bitset nad translate it to decimal to input it... not exactly ideal :) In GTK this should be easy with selection boxes. For text, something like pickup +something or -something (or apickup+arrow etc.) would work well. I'll attach the patch as it currently is; it works well. Feel free to integrate it. Nils. ISSUES: BUG: If you change mode from uint16 to uint32 the server no longer works correctly. SOmeone who knows the internals should debug this. - class 'weapon' seems to grab a lot! You pick up the chair. Pickup mode: 0xffff WEAPON ...is this intended? - what are daggers? this doesn't pick them up: if(op->contr->mode & PU_MISSILEWEAPON) if(tmp->type == WEAPON && QUERY_FLAG(tmp, FLAG_IS_THROWN)) { pick_up(op, tmp); fprintf(stderr,"MISSILEWEAPON\n"); } ...how does this need to be done? Here's the patch. diff -ruN crossfire-1.0.0/include/define.h crossfire-1.0.0.new/include/define.h --- crossfire-1.0.0/include/define.h Sun May 13 23:55:41 2001 +++ crossfire-1.0.0.new/include/define.h Tue Jul 31 17:22:20 2001 @@ -257,6 +257,27 @@ #define MAX_NAME 16 #define BIG_NAME 32 + +/* definitions for detailed pickup descriptions. + * The objective is to define intelligent groups of items that the + * user can pick up or leave as he likes. */ + +/* high bit as flag for new pickup options */ +#define PU_NOTHING 0x0000 +#define PU_NEWMODE 0x8000 + +#define PU_FOOD 0x0001 +#define PU_VALUABLES 0x0002 +#define PU_WEAPON 0x0004 +#define PU_BOW 0x0008 +#define PU_ARROW 0x0010 +#define PU_HELMET 0x0020 +#define PU_SHIELD 0x0040 +#define PU_ARMOUR 0x0080 +#define PU_KEY 0x0100 +#define PU_MISSILEWEAPON 0x0200 +#define PU_ALLWEAPON 0x0400 + /* Instead of using arbitrary constants for indexing the * freearr, add these values. <= SIZEOFFREE1 will get you * within 1 space. <= SIZEOFFREE2 wll get you withing diff -ruN crossfire-1.0.0/server/c_object.c crossfire-1.0.0.new/server/c_object.c --- crossfire-1.0.0/server/c_object.c Sun May 13 23:55:41 2001 +++ crossfire-1.0.0.new/server/c_object.c Tue Jul 31 17:23:14 2001 @@ -1235,19 +1235,41 @@ int command_pickup (object *op, char *params) { - int i; + int i, j; if(!params) { + fprintf(stderr,"command_pickup: !params\n"); op->contr->count_left=0; set_pickup_mode(op, (op->contr->mode > 6)? 0: op->contr->mode+1); return 0; } if(params==NULL || !sscanf(params, "%d", &i) || i<0 ) { - new_draw_info(NDI_UNIQUE, 0,op,"Usage: pickup <0-7> or <value_density> ."); - return 1; - } - set_pickup_mode(op,i); - return 1; + fprintf(stderr,"command_pickup: params==NULL\n"); + new_draw_info(NDI_UNIQUE, 0,op,"Usage: pickup <0-7> or <value_density> ."); + return 1; + } + set_pickup_mode(op,i); + + fprintf(stderr,"command_pickup: set_pickup_mode %d, 0x%x, 0b", i, i); + for(j=0;j<16;j++) + { + fprintf(stderr,"%d",i>>(15-j)&0x01); + if(!(j%4))fprintf(stderr," "); + } + fprintf(stderr,"\n"); + if(i & PU_NEWMODE) fprintf(stderr,"NEWMODE\n"); + if(i & PU_FOOD) fprintf(stderr,"FOOD\n"); + if(i & PU_VALUABLES) fprintf(stderr,"VALUABLES\n"); + if(i & PU_ALLWEAPON) fprintf(stderr,"ALLWEAPON\n"); + if(i & PU_MISSILEWEAPON) fprintf(stderr,"MISSILEWEAPON\n"); + if(i & PU_BOW) fprintf(stderr,"BOW\n"); + if(i & PU_ARROW) fprintf(stderr,"ARROW\n"); + if(i & PU_ARMOUR) fprintf(stderr,"ARMOUR\n"); + if(i & PU_HELMET) fprintf(stderr,"HELMET\n"); + if(i & PU_SHIELD) fprintf(stderr,"SHIELD\n"); + if(i & PU_KEY) fprintf(stderr,"KEY\n"); + + return 1; } void set_pickup_mode(object *op,int i) { diff -ruN crossfire-1.0.0/server/player.c crossfire-1.0.0.new/server/player.c --- crossfire-1.0.0/server/player.c Sun May 13 23:55:41 2001 +++ crossfire-1.0.0.new/server/player.c Tue Jul 31 17:44:49 2001 @@ -864,6 +864,8 @@ tag_t next_tag=0, op_tag; int stop = 0; + + /* if you're flying, you cna't pick up anything */ if (QUERY_FLAG (op, FLAG_FLYING)) return 1; @@ -872,6 +874,9 @@ next = op->below; if (next) next_tag = next->count; + + /* loop while there are items onteh floor that are not marked as + * destroyed */ while (next && ! was_destroyed (next, next_tag)) { tmp = next; @@ -894,28 +899,23 @@ } #endif /* SEARCH_ITEMS */ + /* high bit set? We're using the new autopickup model */ + fprintf(stdout,"Pickup mode: 0x%x\n", op->contr->mode); + + if(!(op->contr->mode & PU_NEWMODE)) + { switch (op->contr->mode) { case 0: return 1; /* don't pick up */ - - case 1: - pick_up (op, tmp); + case 1: pick_up (op, tmp); return 1; - - case 2: - pick_up (op, tmp); + case 2: pick_up (op, tmp); return 0; - case 3: return 0; /* stop before pickup */ - - case 4: - pick_up (op, tmp); + case 4: pick_up (op, tmp); break; - - case 5: - pick_up (op, tmp); + case 5: pick_up (op, tmp); stop = 1; break; - case 6: if (QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && ! QUERY_FLAG(tmp, FLAG_KNOWN_CURSED)) @@ -935,6 +935,44 @@ >= op->contr->mode) pick_up(op,tmp); } + } /* old model */ + else + { + if(op->contr->mode & PU_FOOD) + if (tmp->type == FOOD) { pick_up(op, tmp); fprintf(stderr,"FOOD\n"); } + + if(op->contr->mode & PU_VALUABLES) + if (tmp->type == MONEY || tmp->type == GEM) + { pick_up(op, tmp); fprintf(stderr,"MONEY/GEM\n"); } + + if(op->contr->mode & PU_BOW) + if (tmp->type == BOW) + { pick_up(op, tmp); fprintf(stderr,"BOW\n"); } + if(op->contr->mode & PU_ARROW) + if (tmp->type == ARROW) + { pick_up(op, tmp); fprintf(stderr,"ARROW\n"); } + + if(op->contr->mode & PU_ARMOUR) + if (tmp->type == ARMOUR) + { pick_up(op, tmp); fprintf(stderr,"ARMOUR\n"); } + if(op->contr->mode & PU_HELMET) + if (tmp->type == HELMET) + { pick_up(op, tmp); fprintf(stderr,"HELMET\n"); } + if(op->contr->mode & PU_SHIELD) + if (tmp->type == SHIELD) + { pick_up(op, tmp); fprintf(stderr,"SHIELD\n"); } + + if(op->contr->mode & PU_MISSILEWEAPON) + if(tmp->type == WEAPON && QUERY_FLAG(tmp, FLAG_IS_THROWN)) + { pick_up(op, tmp); fprintf(stderr,"MISSILEWEAPON\n"); } + if(op->contr->mode & PU_ALLWEAPON) + if(tmp->type == WEAPON) + { pick_up(op, tmp); fprintf(stderr,"WEAPON\n"); } + + if(op->contr->mode & PU_KEY) + if (tmp->type == KEY) + { pick_up(op, tmp); fprintf(stderr,"KEY\n"); } + } /* the new pickup model */ } return ! stop; }