[CF-Devel] autopickup server patch

Nils Lohner lohner at debian.org
Fri Aug 3 08:39:56 CDT 2001


THis patch is for version 1.0.0 of the server.

It implements a new autopickup scheme that's basically a superset of the
old one, but it doesn't break compatibility so old clients will still
work normally with it.

One big change was turning mode from uint16->32; this requires all
server files to be recompiled otherwise you'll see nice segv's.

Nils.




-------------- next part --------------
diff -ruN crossfire-1.0.0/include/define.h crossfire-1.0.0.autopickup/include/define.h
--- crossfire-1.0.0/include/define.h	Sun May 13 23:55:41 2001
+++ crossfire-1.0.0.autopickup/include/define.h	Thu Aug  2 18:48:33 2001
@@ -257,6 +257,42 @@
 #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		0x00000000
+
+#define PU_DEBUG		0x10000000
+#define PU_INHIBIT		0x20000000
+#define PU_STOP			0x40000000
+#define PU_NEWMODE		0x80000000
+
+#define PU_RATIO		0x0000000F
+
+#define PU_FOOD			0x00000010
+#define PU_DRINK		0x00000020
+#define PU_VALUABLES		0x00000040
+#define PU_BOW			0x00000080
+
+#define PU_ARROW		0x00000100
+#define PU_HELMET		0x00000200
+#define PU_SHIELD		0x00000400
+#define PU_ARMOUR		0x00000800
+
+#define PU_BOOTS		0x00001000
+#define PU_GLOVES		0x00002000
+#define PU_CLOAK		0x00004000
+#define PU_KEY			0x00008000
+
+#define PU_MISSILEWEAPON	0x00010000
+#define PU_ALLWEAPON		0x00020000
+#define PU_MAGICAL		0x00040000
+#define PU_POTION		0x00080000
+
+
 /* Instead of using arbitrary constants for indexing the
  * freearr, add these values.  <= SIZEOFFREE1 will get you
  * within 1 space.  <= SIZEOFFREE2 wll get you withing 
@@ -354,6 +390,7 @@
 #define FLAG_APPLIED	 	5 /* Object is ready for use by living */
 #define FLAG_UNPAID	 	6 /* Object hasn't been paid for yet */
 #define FLAG_AN		 	7 /* Name must be prepended by "an", not "a"*/
+
 #define FLAG_NO_PICK	 	8 /* Object can't be picked up */
 #define FLAG_WALK_ON	 	9 /* Applied when it's walked upon */
 #define FLAG_NO_PASS		10 /* Nothing can pass (wall() is true) */
@@ -362,6 +399,7 @@
 #define FLAG_FLYING		13 /* Not affected by WALK_ON or SLOW_MOVE) */
 #define FLAG_MONSTER		14 /* Will attack players */
 #define FLAG_FRIENDLY		15 /* Will help players */
+
 #define FLAG_GENERATOR		16 /* Will generate type ob->stats.food */
 #define FLAG_IS_THROWN		17 /* Object is designed to be thrown. */
 #define FLAG_AUTO_APPLY		18 /* Will be applied when created */
@@ -371,6 +409,7 @@
 #define FLAG_CAN_ROLL		22 /* Object can be rolled */
 /* FLAG_IS_TURNING is no longer used */
 /*#define FLAG_IS_TURNING		23 *//* Object will turn after player */
+
 #define FLAG_IS_TURNABLE 	24 /* Object can change face with direction */
 #define FLAG_WALK_OFF		25 /* Object is applied when left */
 #define FLAG_FLY_ON		26 /* As WALK_ON, but only with FLAG_FLYING */
@@ -379,6 +418,7 @@
 #define FLAG_IDENTIFIED		29 /* Not implemented yet */
 #define FLAG_REFLECTING		30 /* Object reflects from walls (lightning) */
 #define FLAG_CHANGING		31 /* Changes to other_arch when anim is done*/
+
 /* Start of values in flags[1] */
 #define FLAG_SPLITTING		32 /* Object splits into stats.food other objs */
 #define FLAG_HITBACK		33 /* Object will hit back when hit */
@@ -388,6 +428,7 @@
 #define FLAG_SCARED		37 /* Monster is scared (mb player in future)*/
 #define FLAG_UNAGGRESSIVE	38 /* Monster doesn't attack players */
 #define FLAG_REFL_MISSILE	39 /* Arrows will reflect from object */
+
 #define FLAG_REFL_SPELL		40 /* Spells (some) will reflect from object */
 #define FLAG_NO_MAGIC		41 /* Spells (some) can't pass this object */
 #define FLAG_NO_FIX_PLAYER	42 /* fix_player() won't be called */
@@ -398,6 +439,7 @@
 #define FLAG_PASS_THRU		46 /* Objects with can_pass_thru can pass \
 				      thru this object as if it wasn't there */
 #define FLAG_CAN_PASS_THRU	47 /* Can pass thru... */
+
 #define FLAG_PICK_UP		48 /* Can pick up */
 #define FLAG_UNIQUE		49 /* Item is really unique (UNIQUE_ITEMS) */
 #define FLAG_NO_DROP		50 /* Object can't be dropped */
@@ -406,6 +448,7 @@
 #define FLAG_USE_SCROLL		53 /* (Monster) can read scroll */
 #define FLAG_USE_WAND		54 /* (Monster) can apply and use wands */
 #define FLAG_USE_BOW		55 /* (Monster) can apply and fire bows */
+
 #define FLAG_USE_ARMOUR		56 /* (Monster) can wear armour/shield/helmet */
 #define FLAG_USE_WEAPON		57 /* (Monster) can wield weapons */
 #define FLAG_USE_RING		58 /* (Monster) can use rings, boots, gauntlets, etc */
@@ -414,8 +457,9 @@
 #define FLAG_XRAYS		61 /* X-ray vision */
 #define FLAG_NO_APPLY		62 /* Avoids step_on/fly_on to this object */
 #define FLAG_IS_FLOOR		63 /* Can't see what's underneath this object */
-#define FLAG_LIFESAVE		64 /* Saves a players' life once, then destr. */
+
 /* Start of values in flags[2] */
+#define FLAG_LIFESAVE		64 /* Saves a players' life once, then destr. */
 #define FLAG_NO_STRENGTH	65 /* Strength-bonus not added to wc/dam */
 #define FLAG_SLEEP		66 /* NPC is sleeping */
 #define FLAG_STAND_STILL	67 /* NPC will not (ever) move */
@@ -423,6 +467,7 @@
 #define FLAG_ONLY_ATTACK	69 /* NPC will evaporate if there is no enemy */
 #define FLAG_CONFUSED		70 /* Will also be unable to cast spells */
 #define FLAG_STEALTH		71 /* Will wake monsters with less range */
+
 #define FLAG_WIZPASS		72 /* The wizard can go through walls */
 #define FLAG_IS_LINKED		73 /* The object is linked with other objects */
 #define FLAG_CURSED		74 /* The object is cursed */
@@ -431,6 +476,7 @@
 #define FLAG_KNOWN_MAGICAL	77 /* The object is known to be magical */
 #define FLAG_KNOWN_CURSED	78 /* The object is known to be cursed */
 #define FLAG_CAN_USE_SKILL	79 /* The monster can use skills */
+
 #define FLAG_BEEN_APPLIED	80 /* The object has been applied */
 #define FLAG_READY_ROD		81 /* (Monster) has a rod readied... 8) */
 #define FLAG_USE_ROD		82 /* (Monster) can apply and use rods */
@@ -439,6 +485,7 @@
 #define FLAG_MAKE_INVIS	        85 /* (Item) gives invisibility when applied */
 #define FLAG_INV_LOCKED		86 /* Item will not be dropped from inventory */
 #define FLAG_IS_WOODED		87 /* Item is wooded terrain */
+
 #define FLAG_IS_HILLY		88 /* Item is hilly/mountain terrain */
 #define FLAG_READY_SKILL	89 /* (Monster or Player) has a skill readied */
 #define FLAG_READY_WEAPON	90 /* (Monster or Player) has a weapon readied */
@@ -447,6 +494,7 @@
 #define FLAG_SEE_IN_DARK	93 /* if set ob not effected by darkness */ 
 #define FLAG_IS_CAULDRON	94 /* container can make alchemical stuff */
 #define FLAG_DUST		95 /* item is a 'powder', effects throwing */
+
 /* Start of values in flags[3] */
 #define FLAG_NO_STEAL		96 /* Item can't be stolen */
 #define FLAG_ONE_HIT		97 /* Monster can only hit once before going
diff -ruN crossfire-1.0.0/include/player.h crossfire-1.0.0.autopickup/include/player.h
--- crossfire-1.0.0/include/player.h	Sun May 13 23:55:41 2001
+++ crossfire-1.0.0.autopickup/include/player.h	Thu Aug  2 12:58:59 2001
@@ -89,7 +89,7 @@
   unsigned char prev_fire_on;
   unsigned char prev_keycode; /* Previous command executed */
   unsigned char key_down;     /* Last move-key still held down */
-  uint16 mode;			/* Mode of player for pickup. */
+  uint32 mode;			/* Mode of player for pickup. */
   signed char digestion;	/* Any bonuses/penalties to digestion */
   signed char gen_hp;		/* Bonuses to regeneration speed of hp */
   signed char gen_sp;		/* Bonuses to regeneration speed of sp */
Binary files crossfire-1.0.0/random_maps/standalone.o and crossfire-1.0.0.autopickup/random_maps/standalone.o differ
diff -ruN crossfire-1.0.0/server/c_object.c crossfire-1.0.0.autopickup/server/c_object.c
--- crossfire-1.0.0/server/c_object.c	Sun May 13 23:55:41 2001
+++ crossfire-1.0.0.autopickup/server/c_object.c	Thu Aug  2 21:27:46 2001
@@ -1235,19 +1235,99 @@
 
 int command_pickup (object *op, char *params)
 {
-      int i;
+  unsigned int i, j;
+  char putstring[128];
 
   if(!params) {
+    /* if the new mode is used, just print the settings */
+    /* yes, a GOTO is ugly, but its simpple and should stay until this
+     * mode is cleanly integrated and the old one deprecated */
+    if(op->contr->mode & PU_NEWMODE) 
+    {
+      i=op->contr->mode;
+      goto NEWPICKUP;
+    }
+    if(1)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;
+    if(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);
+  
+
+  sprintf(putstring,"command_pickup: set_pickup_mode\ndec %u, 0x%x", i, i);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+
+  sprintf(putstring,"0b");
+  for(j=0;j<32;j++) 
+  {
+    strcat(putstring,((i>>(31-j))&0x01)?"1":"0");
+    if(!((j+1)%4))strcat(putstring," ");
+  }
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+
+#if 1
+NEWPICKUP:
+  if(!(i & PU_NEWMODE)) return 1;
+
+  sprintf(putstring,"%d NEWMODE",i & PU_NEWMODE?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+  sprintf(putstring,"%d DEBUG",i & PU_DEBUG?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+  sprintf(putstring,"%d INHIBIT",i & PU_INHIBIT?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+  sprintf(putstring,"%d STOP",i & PU_STOP?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+
+  sprintf(putstring,"%d <= x pickup weight/value RATIO (0==off)",(i & PU_RATIO)*5);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+
+  sprintf(putstring,"%d FOOD",i & PU_FOOD?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+  sprintf(putstring,"%d DRINK",i & PU_DRINK?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+  sprintf(putstring,"%d VALUABLES",i & PU_VALUABLES?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+
+  sprintf(putstring,"%d BOW",i & PU_BOW?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+  sprintf(putstring,"%d ARROW",i & PU_ARROW?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+
+  sprintf(putstring,"%d HELMET",i & PU_HELMET?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+  sprintf(putstring,"%d SHIELD",i & PU_SHIELD?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+  sprintf(putstring,"%d ARMOUR",i & PU_ARMOUR?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+
+  sprintf(putstring,"%d BOOTS",i & PU_BOOTS?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+  sprintf(putstring,"%d GLOVES",i & PU_GLOVES?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+  sprintf(putstring,"%d CLOAK",i & PU_CLOAK?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+  sprintf(putstring,"%d KEY",i & PU_KEY?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+
+  sprintf(putstring,"%d MISSILEWEAPON",i & PU_MISSILEWEAPON?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+  sprintf(putstring,"%d ALLWEAPON",i & PU_ALLWEAPON?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+  sprintf(putstring,"%d MAGICAL",i & PU_MAGICAL?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+  sprintf(putstring,"%d POTION",i & PU_POTION?1:0);
+  new_draw_info(NDI_UNIQUE, 0,op,putstring);
+
+  new_draw_info(NDI_UNIQUE, 0,op,"");
+#endif
+
+  return 1;
 }
 
 void set_pickup_mode(object *op,int i) {
diff -ruN crossfire-1.0.0/server/player.c crossfire-1.0.0.autopickup/server/player.c
--- crossfire-1.0.0/server/player.c	Sun May 13 23:55:41 2001
+++ crossfire-1.0.0.autopickup/server/player.c	Fri Aug  3 15:21:19 2001
@@ -184,7 +184,7 @@
      */
 
     if (checkbanned (defname, ns->host)){
-	fprintf (logfile, "Banned player tryed to add. [%s@%s]\n", defname, ns->host);
+	fprintf (logfile, "Banned player tried to add. [%s@%s]\n", defname, ns->host);
 	fflush (logfile);
 	return 0;
     }
@@ -863,7 +863,11 @@
   object *tmp, *next;
   tag_t next_tag=0, op_tag;
   int stop = 0;
+  int j, k, wvratio;
+  char putstring[128], tmpstr[16];
 
+
+  /* if you're flying, you cna't pick up anything */
   if (QUERY_FLAG (op, FLAG_FLYING))
     return 1;
 
@@ -872,6 +876,9 @@
   next = op->below;
   if (next)
     next_tag = next->count;
+
+  /* loop while there are items on the floor that are not marked as
+   * destroyed */
   while (next && ! was_destroyed (next, next_tag))
   {
     tmp = next;
@@ -894,28 +901,21 @@
     }
 #endif /* SEARCH_ITEMS */
 
+    /* high bit set?  We're using the new autopickup model */
+    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,179 @@
                        >= op->contr->mode)
 		  pick_up(op,tmp);
     }
+    } /* old model */
+    else
+    {
+      /* NEW pickup handling */
+      if(op->contr->mode & PU_DEBUG)
+      {
+	/* some debugging code to figure out item information */
+	if(tmp->name!=NULL)
+	  sprintf(putstring,"item name: %s    item type: %d    weight/value: %d",
+	      tmp->name, tmp->type,
+	      (query_cost(tmp, op, F_TRUE)*100 / (tmp->weight * MAX(tmp->nrof,1))));
+	else
+	  sprintf(putstring,"item name: %s    item type: %d    weight/value: %d",
+	      tmp->arch->name, tmp->type,
+	      (query_cost(tmp, op, F_TRUE)*100 / (tmp->weight * MAX(tmp->nrof,1))));
+	new_draw_info(NDI_UNIQUE, 0,op,putstring);
+
+	sprintf(putstring,"...flags: ");
+	for(k=0;k<4;k++)
+	{
+	  for(j=0;j<32;j++)
+	  {
+	    if((tmp->flags[k]>>j)&0x01)
+	    {
+	      sprintf(tmpstr,"%d ",k*32+j);
+	      strcat(putstring, tmpstr);
+	    }
+	  }
+	}
+	new_draw_info(NDI_UNIQUE, 0,op,putstring);
+
+#if 0
+	/* print the flags too */
+	for(k=0;k<4;k++)
+	{
+	  fprintf(stderr,"%d [%d] ", k, k*32+31);
+	  for(j=0;j<32;j++)
+	  {
+	    fprintf(stderr,"%d",tmp->flags[k]>>(31-j)&0x01);
+	    if(!((j+1)%4))fprintf(stderr," ");
+	  }
+	  fprintf(stderr," [%d]\n", k*32);
+	}
+#endif
+      }
+      /* philosophy:
+       * It's easy to grab an item type from a pile, as long as it's
+       * generic.  This takes no game-time.  For more detailed pickups
+       * and selections, select-items shoul dbe used.  This is a
+       * grab-as-you-run type mode that's really useful for arrows for
+       * example.
+       * The drawback: right now it has no frontend, so you need to
+       * stick the bits you want into a calculator in hex mode and then
+       * convert to decimal and then 'pickup <#>
+       */
+
+      /* the first two modes are exclusive: if NOTHING we return, if
+       * STOP then we stop.  All the rest are applied sequentially,
+       * meaning if any test passes, the item gets picked up. */
+
+      /* if mode is set to pick nothing up, return */
+      if(op->contr->mode & PU_NOTHING) return 1;
+      /* if mode is set to stop when encountering objects, return */
+      /* take STOP before INHIBIT since it doesn't actually pick
+       * anything up */
+      if(op->contr->mode & PU_STOP) return 0;
+      /* useful for going into stores and not losing your settings... */
+      /* and for battles wher you don't want to get loaded down while
+       * fighting *.
+      if(op->contr->mode & PU_INHIBIT) return 1;
+
+      /* prevent us from turning into auto-thieves :) */
+      if (QUERY_FLAG (tmp, FLAG_UNPAID)) continue;
+
+      /* all food and drink if desired */
+      /* question: don't pick up known-poisonous stuff? */
+      if(op->contr->mode & PU_FOOD)
+	if (tmp->type == FOOD)
+	{ pick_up(op, tmp); if(0)fprintf(stderr,"FOOD\n"); continue; }
+      if(op->contr->mode & PU_DRINK)
+	if (tmp->type == DRINK)
+	{ pick_up(op, tmp); if(0)fprintf(stderr,"DRINK\n"); continue; }
+      if(op->contr->mode & PU_POTION)
+	if (tmp->type == POTION)
+	{ pick_up(op, tmp); if(0)fprintf(stderr,"POTION\n"); continue; }
+
+      /* pick up all magical items */
+      if(op->contr->mode & PU_MAGICAL)
+	if (QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && ! QUERY_FLAG(tmp, FLAG_KNOWN_CURSED))
+	{ pick_up(op, tmp); if(0)fprintf(stderr,"MAGICAL\n"); continue; }
+
+      if(op->contr->mode & PU_VALUABLES)
+      {
+	if (tmp->type == MONEY || tmp->type == GEM) 
+	{ pick_up(op, tmp); if(0)fprintf(stderr,"MONEY/GEM\n"); continue; }
+      }
+
+      /* bows and arrows. Bows are good for selling! */
+      if(op->contr->mode & PU_BOW)
+	if (tmp->type == BOW) 
+	{ pick_up(op, tmp); if(0)fprintf(stderr,"BOW\n"); continue; }
+      if(op->contr->mode & PU_ARROW)
+	if (tmp->type == ARROW) 
+	{ pick_up(op, tmp); if(0)fprintf(stderr,"ARROW\n"); continue; }
+
+      /* all kinds of armor etc. */
+      if(op->contr->mode & PU_ARMOUR)
+	if (tmp->type == ARMOUR) 
+	{ pick_up(op, tmp); if(0)fprintf(stderr,"ARMOUR\n"); continue; }
+      if(op->contr->mode & PU_HELMET)
+	if (tmp->type == HELMET) 
+	{ pick_up(op, tmp); if(0)fprintf(stderr,"HELMET\n"); continue; }
+      if(op->contr->mode & PU_SHIELD)
+	if (tmp->type == SHIELD) 
+	{ pick_up(op, tmp); if(0)fprintf(stderr,"SHIELD\n"); continue; }
+      if(op->contr->mode & PU_BOOTS)
+	if (tmp->type == BOOTS) 
+	{ pick_up(op, tmp); if(0)fprintf(stderr,"BOOTS\n"); continue; }
+      if(op->contr->mode & PU_GLOVES)
+	if (tmp->type == GLOVES) 
+	{ pick_up(op, tmp); if(0)fprintf(stderr,"GLOVES\n"); continue; }
+      if(op->contr->mode & PU_CLOAK)
+	if (tmp->type == CLOAK) 
+	{ pick_up(op, tmp); if(0)fprintf(stderr,"GLOVES\n"); continue; }
+
+      /* hoping to catch throwing daggers here */
+      if(op->contr->mode & PU_MISSILEWEAPON)
+	if(tmp->type == WEAPON && QUERY_FLAG(tmp, FLAG_IS_THROWN)) 
+	{ pick_up(op, tmp); if(0)fprintf(stderr,"MISSILEWEAPON\n"); continue; }
+
+      /* careful: chairs and tables are weapons! */
+      if(op->contr->mode & PU_ALLWEAPON)
+      {
+	if(tmp->type == WEAPON && tmp->name!=NULL) 
+	{
+	  if(strstr(tmp->name,"table")==NULL &&
+	      strstr(tmp->name,"chair")==NULL) 
+	  { pick_up(op, tmp); if(0)fprintf(stderr,"WEAPON\n"); continue; }
+	}
+	if(tmp->type == WEAPON && tmp->name==NULL) 
+	{
+	  if(strstr(tmp->arch->name,"table")==NULL &&
+	      strstr(tmp->arch->name,"chair")==NULL) 
+	  { pick_up(op, tmp); if(0)fprintf(stderr,"WEAPON\n"); continue; }
+	}
+      }
+
+      /* misc stuff that's useful */
+      if(op->contr->mode & PU_KEY)
+	if (tmp->type == KEY || tmp->type == SPECIAL_KEY) 
+	{ pick_up(op, tmp); if(0)fprintf(stderr,"KEY\n"); continue; }
+
+      /* any of the last 4 bits set means we use the ratio for value
+       * pickups */
+      if(op->contr->mode & PU_RATIO)
+      {
+	/* use value density to decide what else to grab */
+	/* >=7 was >= op->contr->mode */
+	/* >=7 is the old standard setting.  Now we take the last 4 bits
+	 * and multiply them by 5, giving 0..15*5== 5..75 */
+	wvratio=(op->contr->mode & PU_RATIO) * 5;
+	if ((query_cost(tmp, op, F_TRUE)*100 / (tmp->weight * MAX(tmp->nrof, 1))) >= wvratio)
+	{
+	  pick_up(op, tmp);
+	  if(0)fprintf(stderr,"HIGH WEIGHT/VALUE [");
+	  if(tmp->name!=NULL) if(0)fprintf(stderr,"%s", tmp->name);
+	  else if(0)fprintf(stderr,"%s",tmp->arch->name);
+	  if(0)fprintf(stderr,",%d] = ", tmp->type);
+	  if(0)fprintf(stderr,"%d\n",query_cost(tmp,op,F_TRUE)*100 / (tmp->weight * MAX(tmp->nrof,1)));
+	  continue;
+	}
+      }
+    } /* the new pickup model */
   }
   return ! stop;
 }
    
    


More information about the crossfire mailing list