[CF-Devel] Autopickup patch

Nils Lohner lohner at debian.org
Tue Jul 31 11:22:19 CDT 2001


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;
 }

    
    


More information about the crossfire mailing list