Crossfire Mailing List Archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: CF: auto pickup changes



On Tue, Jun 13, 2000 at 10:15:28PM +0200, Jan Echternach wrote:
> The attached patch changes behaviour of the 'pickup <num>' command.  If

I've rewritten the patch to use only one loop over all items on the map
square.  I've also added two was_destroyed() checks because picking up
an object might trigger something.

I will apply this patch to the CVS tree if there are no objections.

The following remarks still apply to the new version of the patch:

> the item on top of the map square couldn't be picked up, nothing was
> picked up (even with pickup 4).  With the patch, items that can't be
> picked up are always skipped.  For example, "pickup 4" will always pick
> up everything, and "pickup 1" will pick up the first item that can be
> picked up.
> 
> This fixes the nasty problem that the diamonds of a demilich couldn't
> be picked up automatically (demilichs have an invisible "insanity"
> object that used to prevent all forms of automatic pickup because it
> was above the diamonds after the demilich had been killed).
> 
> The patch conflicts with the patch by Darren O. Benham (see
> http://archives.real-time.com/rte-crossfire/2000/Jun/msg00094.html).

-- 
Jan
*** orig/crossfire-0.95.5-cvs3-patch27/server/player.c	Mon May 29 18:31:26 2000
--- crossfire-0.95.5-cvs3/server/player.c	Mon Jun 19 00:29:32 2000
***************
*** 795,886 ****
  /* check_pick sees if there is stuff to be picked up/picks up stuff.
   * IT returns 1 if the player should keep on moving, 0 if he should
   * stop.
   */
  int check_pick(object *op) {
  
!   if(QUERY_FLAG(op,FLAG_FLYING) || op->below==NULL || !can_pick(op,op->below))
      return 1;
  
  #ifdef SEARCH_ITEMS
!   if(op->contr->search_str[0]!='\0')
      {
!       object *next,*tmp;
!       tmp=op->below;
!       while(tmp!=NULL&&can_pick(op,tmp))
! 	{
! 	  next=tmp->below;
! 	  if(item_matched_string(op, tmp, op->contr->search_str)) {
! 	    pick_up(op,tmp);
! 	  }
! 	  tmp=next;
! 	}
      }
  #endif /* SEARCH_ITEMS */
  
! 
!   switch (op->contr->mode) {
  	case 0:	return 1;	/* don't pick up */
  
  	case 1:
! 		pick_up(op,op->below);
  		return 1;
  
  	case 2:
! 		pick_up(op,op->below);
  		return 0;
  
  	case 3: return 0;	/* stop before pickup */
  
  	case 4:
  	case 5: 
! 	case 6:
! 	case 7: {
! 	    object *item,*temp;
! 	    
! 	    for (item = op->below; item; item=temp) {
! 		temp = item->below;
! 		if (can_pick(op, item)) {
! 			if (op->contr->mode==6) {
! 			    if (QUERY_FLAG(item, FLAG_KNOWN_MAGICAL) &&
! 			      !QUERY_FLAG(item, FLAG_KNOWN_CURSED)) {
! 				pick_up(op, item);
! 			    }
! 			}
! 			else if (op->contr->mode==7) {
! 			    if (item->type==MONEY || item->type==GEM) {
! 				pick_up(op, item);
! 			    }
! 			} else {
! 			    pick_up(op, item);
! 			}
! 		}
! 		    item = temp;
! 	    }
! 	    if (op->contr->mode == 5) return 0;
! 	    else return 1;
! 	}
! 
! 	/* use value density */
! 	default: {
! 	    object * item,*temp;
! 
! 	    item=op->below;
! 	    while(item) {
! 		temp=item->below;
! 		if(can_pick(op, item) && !(QUERY_FLAG(item, FLAG_UNPAID)) &&
! 		 (query_cost(item,op,F_TRUE)*100/
! 		    (item->weight * MAX(item->nrof,1))>= op->contr->mode) ) {
! 			pick_up(op,item);
! 		}
! 		item=temp;
! 	    }
! 	    return 1;
! 	}
  
    }
!   return 1; /* Statement supposedly can't be reached */
  }
  
  /*
   *  Find an arrow in the inventory and after that
   *  in the right type container (quiver). Pointer to the 
--- 795,881 ----
  /* check_pick sees if there is stuff to be picked up/picks up stuff.
   * IT returns 1 if the player should keep on moving, 0 if he should
   * stop.
   */
  int check_pick(object *op) {
+   object *tmp, *next;
+   tag_t next_tag, op_tag;
+   int stop = 0;
  
!   if (QUERY_FLAG (op, FLAG_FLYING))
      return 1;
  
+   op_tag = op->count;
+ 
+   next = op->below;
+   if (next)
+     next_tag = next->count;
+   while (next && ! was_destroyed (next, next_tag))
+   {
+     tmp = next;
+     next = tmp->below;
+     if (next)
+       next_tag = next->count;
+ 
+     if (was_destroyed (op, op_tag))
+         return 0;
+ 
+     if ( ! can_pick (op, tmp))
+       continue;
+ 
  #ifdef SEARCH_ITEMS
!     if (op->contr->search_str[0]!='\0')
      {
!       if (item_matched_string (op, tmp, op->contr->search_str))
!         pick_up (op, tmp);
!       continue;
      }
  #endif /* SEARCH_ITEMS */
  
!     switch (op->contr->mode) {
  	case 0:	return 1;	/* don't pick up */
  
  	case 1:
! 		pick_up (op, tmp);
  		return 1;
  
  	case 2:
! 		pick_up (op, tmp);
  		return 0;
  
  	case 3: return 0;	/* stop before pickup */
  
  	case 4:
+ 		pick_up (op, tmp);
+ 		break;
+ 
  	case 5: 
! 		pick_up (op, tmp);
! 		stop = 1;
! 		break;
  
+ 	case 6:
+ 		if (QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) &&
+ 		    ! QUERY_FLAG(tmp, FLAG_KNOWN_CURSED))
+ 		  pick_up(op, tmp);
+ 		break;
+ 
+ 	case 7:
+ 		if (tmp->type == MONEY || tmp->type == GEM)
+ 		  pick_up(op, tmp);
+ 		break;
+ 
+ 	default:
+ 		/* use value density */
+ 		if ( ! QUERY_FLAG (tmp, FLAG_UNPAID)
+ 		    && (query_cost (tmp, op, F_TRUE) * 100
+ 		        / (tmp->weight * MAX (tmp->nrof, 1)))
+                        >= op->contr->mode)
+ 		  pick_up(op,tmp);
+     }
    }
!   return ! stop;
  }
  
  /*
   *  Find an arrow in the inventory and after that
   *  in the right type container (quiver). Pointer to the